@certe/atmos-physics 0.1.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.
- package/LICENCE +674 -0
- package/README.md +152 -0
- package/dist/collider-offset.d.ts +19 -0
- package/dist/collider-offset.d.ts.map +1 -0
- package/dist/collider-offset.js +33 -0
- package/dist/collider-offset.js.map +1 -0
- package/dist/collider.d.ts +75 -0
- package/dist/collider.d.ts.map +1 -0
- package/dist/collider.js +223 -0
- package/dist/collider.js.map +1 -0
- package/dist/fixed-joint.d.ts +8 -0
- package/dist/fixed-joint.d.ts.map +1 -0
- package/dist/fixed-joint.js +10 -0
- package/dist/fixed-joint.js.map +1 -0
- package/dist/hinge-joint.d.ts +78 -0
- package/dist/hinge-joint.d.ts.map +1 -0
- package/dist/hinge-joint.js +271 -0
- package/dist/hinge-joint.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +8 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +98 -0
- package/dist/init.js.map +1 -0
- package/dist/joint.d.ts +52 -0
- package/dist/joint.d.ts.map +1 -0
- package/dist/joint.js +143 -0
- package/dist/joint.js.map +1 -0
- package/dist/physics-hierarchy.d.ts +8 -0
- package/dist/physics-hierarchy.d.ts.map +1 -0
- package/dist/physics-hierarchy.js +32 -0
- package/dist/physics-hierarchy.js.map +1 -0
- package/dist/physics-query.d.ts +30 -0
- package/dist/physics-query.d.ts.map +1 -0
- package/dist/physics-query.js +139 -0
- package/dist/physics-query.js.map +1 -0
- package/dist/physics-system.d.ts +17 -0
- package/dist/physics-system.d.ts.map +1 -0
- package/dist/physics-system.js +133 -0
- package/dist/physics-system.js.map +1 -0
- package/dist/physics-world.d.ts +33 -0
- package/dist/physics-world.d.ts.map +1 -0
- package/dist/physics-world.js +65 -0
- package/dist/physics-world.js.map +1 -0
- package/dist/register-builtins.d.ts +2 -0
- package/dist/register-builtins.d.ts.map +1 -0
- package/dist/register-builtins.js +84 -0
- package/dist/register-builtins.js.map +1 -0
- package/dist/rigid-body.d.ts +42 -0
- package/dist/rigid-body.d.ts.map +1 -0
- package/dist/rigid-body.js +189 -0
- package/dist/rigid-body.js.map +1 -0
- package/dist/spring-joint.d.ts +23 -0
- package/dist/spring-joint.d.ts.map +1 -0
- package/dist/spring-joint.js +26 -0
- package/dist/spring-joint.js.map +1 -0
- package/package.json +29 -0
- package/src/index.ts +26 -0
package/dist/joint.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { Component } from '@certe/atmos-core';
|
|
2
|
+
import { Vec3 } from '@certe/atmos-math';
|
|
3
|
+
import { RigidBody } from './rigid-body.js';
|
|
4
|
+
export class Joint extends Component {
|
|
5
|
+
joint = null;
|
|
6
|
+
_connectedObject = null;
|
|
7
|
+
_world = null;
|
|
8
|
+
_anchor = Vec3.create();
|
|
9
|
+
_connectedAnchor = Vec3.create();
|
|
10
|
+
_autoConfigureConnectedAnchor = true;
|
|
11
|
+
get anchor() { return this._anchor; }
|
|
12
|
+
set anchor(v) {
|
|
13
|
+
Vec3.copy(this._anchor, v);
|
|
14
|
+
this._recreateJoint();
|
|
15
|
+
}
|
|
16
|
+
get connectedAnchor() { return this._connectedAnchor; }
|
|
17
|
+
set connectedAnchor(v) {
|
|
18
|
+
Vec3.copy(this._connectedAnchor, v);
|
|
19
|
+
this._recreateJoint();
|
|
20
|
+
}
|
|
21
|
+
get autoConfigureConnectedAnchor() { return this._autoConfigureConnectedAnchor; }
|
|
22
|
+
set autoConfigureConnectedAnchor(v) {
|
|
23
|
+
this._autoConfigureConnectedAnchor = v;
|
|
24
|
+
if (v)
|
|
25
|
+
this._recreateJoint();
|
|
26
|
+
}
|
|
27
|
+
get connectedObject() {
|
|
28
|
+
return this._connectedObject;
|
|
29
|
+
}
|
|
30
|
+
set connectedObject(value) {
|
|
31
|
+
if (this._connectedObject === value)
|
|
32
|
+
return;
|
|
33
|
+
this._removeJoint();
|
|
34
|
+
this._connectedObject = value;
|
|
35
|
+
this._tryCreateJoint();
|
|
36
|
+
}
|
|
37
|
+
init(world, options) {
|
|
38
|
+
this._world = world;
|
|
39
|
+
if (options?.anchor) {
|
|
40
|
+
Vec3.set(this._anchor, options.anchor.x, options.anchor.y, options.anchor.z);
|
|
41
|
+
}
|
|
42
|
+
if (options?.connectedAnchor) {
|
|
43
|
+
Vec3.set(this._connectedAnchor, options.connectedAnchor.x, options.connectedAnchor.y, options.connectedAnchor.z);
|
|
44
|
+
}
|
|
45
|
+
if (options?.autoConfigureConnectedAnchor !== undefined) {
|
|
46
|
+
this._autoConfigureConnectedAnchor = options.autoConfigureConnectedAnchor;
|
|
47
|
+
}
|
|
48
|
+
if (options?.connectedObject) {
|
|
49
|
+
this._connectedObject = options.connectedObject;
|
|
50
|
+
this._tryCreateJoint();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
_toXYZ(v) {
|
|
54
|
+
return { x: v[0], y: v[1], z: v[2] };
|
|
55
|
+
}
|
|
56
|
+
_tryCreateJoint() {
|
|
57
|
+
if (!this._world || !this._connectedObject)
|
|
58
|
+
return;
|
|
59
|
+
const rb = this.gameObject.getComponent(RigidBody);
|
|
60
|
+
if (!rb?.body)
|
|
61
|
+
return;
|
|
62
|
+
const targetRb = this._connectedObject.getComponent(RigidBody);
|
|
63
|
+
if (!targetRb?.body)
|
|
64
|
+
return;
|
|
65
|
+
if (this._autoConfigureConnectedAnchor) {
|
|
66
|
+
this._computeConnectedAnchor();
|
|
67
|
+
}
|
|
68
|
+
let data;
|
|
69
|
+
try {
|
|
70
|
+
data = this._createJointData();
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return; // invalid parameters (e.g. zero-length axis) — skip creation
|
|
74
|
+
}
|
|
75
|
+
this.joint = this._world.createJoint(data, rb.body, targetRb.body);
|
|
76
|
+
}
|
|
77
|
+
/** Destroy current joint and recreate it (used when creation-time params change). */
|
|
78
|
+
_recreateJoint() {
|
|
79
|
+
if (!this.joint)
|
|
80
|
+
return;
|
|
81
|
+
this._removeJoint();
|
|
82
|
+
this._tryCreateJoint();
|
|
83
|
+
}
|
|
84
|
+
/** Recompute auto-configured values (anchor/axis) without recreating the Rapier joint. */
|
|
85
|
+
refreshAutoConfig() {
|
|
86
|
+
if (this._autoConfigureConnectedAnchor) {
|
|
87
|
+
this._computeConnectedAnchor();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/** Recreate the joint so auto-configured anchors/axes update after transforms change. */
|
|
91
|
+
syncAutoConfig() {
|
|
92
|
+
if (!this.joint)
|
|
93
|
+
return;
|
|
94
|
+
this._recreateJoint();
|
|
95
|
+
}
|
|
96
|
+
_computeConnectedAnchor() {
|
|
97
|
+
const thisTransform = this.gameObject.transform;
|
|
98
|
+
const otherTransform = this._connectedObject.transform;
|
|
99
|
+
thisTransform.updateWorldMatrix();
|
|
100
|
+
otherTransform.updateWorldMatrix();
|
|
101
|
+
// Rapier joints use body-local space = position + rotation only (no scale).
|
|
102
|
+
// Extract rotation (scale-free) from world matrices to match Rapier's interpretation.
|
|
103
|
+
const mA = thisTransform.worldMatrix;
|
|
104
|
+
const ax = this._anchor[0], ay = this._anchor[1], az = this._anchor[2];
|
|
105
|
+
// Extract rotation columns from body A (normalize to remove scale)
|
|
106
|
+
const sAx = Math.sqrt(mA[0] * mA[0] + mA[1] * mA[1] + mA[2] * mA[2]) || 1;
|
|
107
|
+
const sAy = Math.sqrt(mA[4] * mA[4] + mA[5] * mA[5] + mA[6] * mA[6]) || 1;
|
|
108
|
+
const sAz = Math.sqrt(mA[8] * mA[8] + mA[9] * mA[9] + mA[10] * mA[10]) || 1;
|
|
109
|
+
const rA00 = mA[0] / sAx, rA10 = mA[1] / sAx, rA20 = mA[2] / sAx;
|
|
110
|
+
const rA01 = mA[4] / sAy, rA11 = mA[5] / sAy, rA21 = mA[6] / sAy;
|
|
111
|
+
const rA02 = mA[8] / sAz, rA12 = mA[9] / sAz, rA22 = mA[10] / sAz;
|
|
112
|
+
// World anchor = posA + rotA * anchor (no scale)
|
|
113
|
+
const wx = mA[12] + rA00 * ax + rA01 * ay + rA02 * az;
|
|
114
|
+
const wy = mA[13] + rA10 * ax + rA11 * ay + rA12 * az;
|
|
115
|
+
const wz = mA[14] + rA20 * ax + rA21 * ay + rA22 * az;
|
|
116
|
+
// Extract rotation columns from body B (normalize to remove scale)
|
|
117
|
+
const mB = otherTransform.worldMatrix;
|
|
118
|
+
const sBx = Math.sqrt(mB[0] * mB[0] + mB[1] * mB[1] + mB[2] * mB[2]) || 1;
|
|
119
|
+
const sBy = Math.sqrt(mB[4] * mB[4] + mB[5] * mB[5] + mB[6] * mB[6]) || 1;
|
|
120
|
+
const sBz = Math.sqrt(mB[8] * mB[8] + mB[9] * mB[9] + mB[10] * mB[10]) || 1;
|
|
121
|
+
const rB00 = mB[0] / sBx, rB10 = mB[1] / sBx, rB20 = mB[2] / sBx;
|
|
122
|
+
const rB01 = mB[4] / sBy, rB11 = mB[5] / sBy, rB21 = mB[6] / sBy;
|
|
123
|
+
const rB02 = mB[8] / sBz, rB12 = mB[9] / sBz, rB22 = mB[10] / sBz;
|
|
124
|
+
// connectedAnchor = inverse(rotB) * (worldAnchor - posB)
|
|
125
|
+
// For a rotation matrix, inverse = transpose
|
|
126
|
+
const dx = wx - mB[12], dy = wy - mB[13], dz = wz - mB[14];
|
|
127
|
+
const lx = rB00 * dx + rB10 * dy + rB20 * dz;
|
|
128
|
+
const ly = rB01 * dx + rB11 * dy + rB21 * dz;
|
|
129
|
+
const lz = rB02 * dx + rB12 * dy + rB22 * dz;
|
|
130
|
+
Vec3.set(this._connectedAnchor, lx, ly, lz);
|
|
131
|
+
}
|
|
132
|
+
_removeJoint() {
|
|
133
|
+
if (this.joint && this._world) {
|
|
134
|
+
this._world.removeJoint(this.joint);
|
|
135
|
+
this.joint = null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
onDestroy() {
|
|
139
|
+
this._removeJoint();
|
|
140
|
+
this._connectedObject = null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=joint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"joint.js","sourceRoot":"","sources":["../src/joint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { GameObject, Component } from '@certe/atmos-core';
|
|
2
|
+
/** Walk up the parent chain (including self) to find the first component of type Ctor. */
|
|
3
|
+
export declare function findAncestorComponent<T extends Component>(go: GameObject, Ctor: new (...args: never[]) => T): T | null;
|
|
4
|
+
/** Check whether any ancestor (excluding self) has a component of type Ctor. */
|
|
5
|
+
export declare function hasAncestorComponent<T extends Component>(go: GameObject, Ctor: new (...args: never[]) => T): boolean;
|
|
6
|
+
/** Check whether any descendant (excluding self) has a component of type Ctor. */
|
|
7
|
+
export declare function hasDescendantComponent<T extends Component>(go: GameObject, Ctor: new (...args: never[]) => T): boolean;
|
|
8
|
+
//# sourceMappingURL=physics-hierarchy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physics-hierarchy.d.ts","sourceRoot":"","sources":["../src/physics-hierarchy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE/D,0FAA0F;AAC1F,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,SAAS,EACvD,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,GAChC,CAAC,GAAG,IAAI,CAQV;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,SAAS,EACtD,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,GAChC,OAAO,CAOT;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,SAAS,EACxD,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,GAChC,OAAO,CAMT"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Walk up the parent chain (including self) to find the first component of type Ctor. */
|
|
2
|
+
export function findAncestorComponent(go, Ctor) {
|
|
3
|
+
let current = go;
|
|
4
|
+
while (current) {
|
|
5
|
+
const c = current.getComponent(Ctor);
|
|
6
|
+
if (c)
|
|
7
|
+
return c;
|
|
8
|
+
current = current.parent;
|
|
9
|
+
}
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
/** Check whether any ancestor (excluding self) has a component of type Ctor. */
|
|
13
|
+
export function hasAncestorComponent(go, Ctor) {
|
|
14
|
+
let current = go.parent;
|
|
15
|
+
while (current) {
|
|
16
|
+
if (current.getComponent(Ctor))
|
|
17
|
+
return true;
|
|
18
|
+
current = current.parent;
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
/** Check whether any descendant (excluding self) has a component of type Ctor. */
|
|
23
|
+
export function hasDescendantComponent(go, Ctor) {
|
|
24
|
+
for (const child of go.children) {
|
|
25
|
+
if (child.getComponent(Ctor))
|
|
26
|
+
return true;
|
|
27
|
+
if (hasDescendantComponent(child, Ctor))
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=physics-hierarchy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physics-hierarchy.js","sourceRoot":"","sources":["../src/physics-hierarchy.ts"],"names":[],"mappings":"AAEA,0FAA0F;AAC1F,MAAM,UAAU,qBAAqB,CACnC,EAAc,EACd,IAAiC;IAEjC,IAAI,OAAO,GAAsB,EAAE,CAAC;IACpC,OAAO,OAAO,EAAE,CAAC;QACf,MAAM,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;QAChB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAC3B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,oBAAoB,CAClC,EAAc,EACd,IAAiC;IAEjC,IAAI,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC;IACxB,OAAO,OAAO,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5C,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAC3B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,sBAAsB,CACpC,EAAc,EACd,IAAiC;IAEjC,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;QAChC,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,IAAI,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IACvD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PhysicsWorld } from './physics-world.js';
|
|
2
|
+
import { Collider } from './collider.js';
|
|
3
|
+
export interface HitResult {
|
|
4
|
+
collider: Collider;
|
|
5
|
+
gameObject: import('@certe/atmos-core').GameObject;
|
|
6
|
+
point: Float32Array;
|
|
7
|
+
normal: Float32Array;
|
|
8
|
+
distance: number;
|
|
9
|
+
}
|
|
10
|
+
/** Invalidate the cached collider map. Call once per frame or when colliders change. */
|
|
11
|
+
export declare function invalidateColliderMap(): void;
|
|
12
|
+
/**
|
|
13
|
+
* Stateless physics query utilities.
|
|
14
|
+
* All methods require a PhysicsWorld and use Scene.current to resolve collider ownership.
|
|
15
|
+
*/
|
|
16
|
+
export declare class Physics {
|
|
17
|
+
/** Cast a ray and return the first hit, or null. */
|
|
18
|
+
static raycast(world: PhysicsWorld, origin: Float32Array, dir: Float32Array, maxDist: number): HitResult | null;
|
|
19
|
+
/** Cast a ray and return all hits. */
|
|
20
|
+
static raycastAll(world: PhysicsWorld, origin: Float32Array, dir: Float32Array, maxDist: number): HitResult[];
|
|
21
|
+
/** Find the first collider overlapping a sphere at the given center and radius. */
|
|
22
|
+
static sphereCast(world: PhysicsWorld, center: Float32Array, radius: number): HitResult | null;
|
|
23
|
+
/** Find all colliders overlapping a sphere. */
|
|
24
|
+
static sphereCastAll(world: PhysicsWorld, center: Float32Array, radius: number): HitResult[];
|
|
25
|
+
/** Find the first collider overlapping a box at the given center with half-extents. */
|
|
26
|
+
static boxCast(world: PhysicsWorld, center: Float32Array, halfExtents: Float32Array): HitResult | null;
|
|
27
|
+
/** Find all colliders overlapping a box. */
|
|
28
|
+
static boxCastAll(world: PhysicsWorld, center: Float32Array, halfExtents: Float32Array): HitResult[];
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=physics-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physics-query.d.ts","sourceRoot":"","sources":["../src/physics-query.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,OAAO,mBAAmB,EAAE,UAAU,CAAC;IACnD,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAwBD,wFAAwF;AACxF,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AA4ED;;;GAGG;AACH,qBAAa,OAAO;IAClB,oDAAoD;IACpD,MAAM,CAAC,OAAO,CACZ,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,YAAY,EACpB,GAAG,EAAE,YAAY,EACjB,OAAO,EAAE,MAAM,GACd,SAAS,GAAG,IAAI;IAQnB,sCAAsC;IACtC,MAAM,CAAC,UAAU,CACf,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,YAAY,EACpB,GAAG,EAAE,YAAY,EACjB,OAAO,EAAE,MAAM,GACd,SAAS,EAAE;IAYd,mFAAmF;IACnF,MAAM,CAAC,UAAU,CACf,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,GACb,SAAS,GAAG,IAAI;IAKnB,+CAA+C;IAC/C,MAAM,CAAC,aAAa,CAClB,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,GACb,SAAS,EAAE;IAId,uFAAuF;IACvF,MAAM,CAAC,OAAO,CACZ,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,YAAY,EACpB,WAAW,EAAE,YAAY,GACxB,SAAS,GAAG,IAAI;IAMnB,4CAA4C;IAC5C,MAAM,CAAC,UAAU,CACf,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,YAAY,EACpB,WAAW,EAAE,YAAY,GACxB,SAAS,EAAE;CAGf"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import RAPIER from '@dimforge/rapier3d-compat';
|
|
2
|
+
import { Scene } from '@certe/atmos-core';
|
|
3
|
+
import { Vec3 } from '@certe/atmos-math';
|
|
4
|
+
import { Collider } from './collider.js';
|
|
5
|
+
// Scratch ray reused across calls
|
|
6
|
+
let _scratchRay = null;
|
|
7
|
+
function getScratchRay(ox, oy, oz, dx, dy, dz) {
|
|
8
|
+
if (!_scratchRay) {
|
|
9
|
+
_scratchRay = new RAPIER.Ray({ x: ox, y: oy, z: oz }, { x: dx, y: dy, z: dz });
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
_scratchRay.origin.x = ox;
|
|
13
|
+
_scratchRay.origin.y = oy;
|
|
14
|
+
_scratchRay.origin.z = oz;
|
|
15
|
+
_scratchRay.dir.x = dx;
|
|
16
|
+
_scratchRay.dir.y = dy;
|
|
17
|
+
_scratchRay.dir.z = dz;
|
|
18
|
+
}
|
|
19
|
+
return _scratchRay;
|
|
20
|
+
}
|
|
21
|
+
// Cached collider map — rebuilt once per invalidation cycle
|
|
22
|
+
let _cachedMap = new Map();
|
|
23
|
+
let _cachedScene = null;
|
|
24
|
+
let _cacheValid = false;
|
|
25
|
+
/** Invalidate the cached collider map. Call once per frame or when colliders change. */
|
|
26
|
+
export function invalidateColliderMap() {
|
|
27
|
+
_cacheValid = false;
|
|
28
|
+
}
|
|
29
|
+
/** Build handle→Collider reverse map. Cached until invalidated to avoid repeated traversals. */
|
|
30
|
+
function buildColliderMap() {
|
|
31
|
+
const scene = Scene.current;
|
|
32
|
+
if (!scene)
|
|
33
|
+
return new Map();
|
|
34
|
+
if (_cacheValid && scene === _cachedScene)
|
|
35
|
+
return _cachedMap;
|
|
36
|
+
_cachedScene = scene;
|
|
37
|
+
_cacheValid = true;
|
|
38
|
+
_cachedMap = new Map();
|
|
39
|
+
const colliders = scene.findAll(Collider);
|
|
40
|
+
for (const c of colliders) {
|
|
41
|
+
if (c.collider) {
|
|
42
|
+
_cachedMap.set(c.collider.handle, c);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return _cachedMap;
|
|
46
|
+
}
|
|
47
|
+
function hitFromRapier(rapierCollider, toi, normal, origin, dir, map) {
|
|
48
|
+
const comp = map.get(rapierCollider.handle);
|
|
49
|
+
if (!comp)
|
|
50
|
+
return null;
|
|
51
|
+
const point = Vec3.create();
|
|
52
|
+
const scaled = Vec3.create();
|
|
53
|
+
Vec3.scale(scaled, dir, toi);
|
|
54
|
+
Vec3.add(point, origin, scaled);
|
|
55
|
+
const norm = Vec3.create();
|
|
56
|
+
norm[0] = normal.x;
|
|
57
|
+
norm[1] = normal.y;
|
|
58
|
+
norm[2] = normal.z;
|
|
59
|
+
return {
|
|
60
|
+
collider: comp,
|
|
61
|
+
gameObject: comp.gameObject,
|
|
62
|
+
point,
|
|
63
|
+
normal: norm,
|
|
64
|
+
distance: toi,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** Shared overlap query helper: runs intersectionsWithShape and maps results to HitResults. */
|
|
68
|
+
function overlapQuery(world, center, shape, firstOnly) {
|
|
69
|
+
const pos = { x: center[0], y: center[1], z: center[2] };
|
|
70
|
+
const rot = { x: 0, y: 0, z: 0, w: 1 };
|
|
71
|
+
const map = buildColliderMap();
|
|
72
|
+
const results = [];
|
|
73
|
+
world.world.intersectionsWithShape(pos, rot, shape, (rapierCol) => {
|
|
74
|
+
const comp = map.get(rapierCol.handle);
|
|
75
|
+
if (comp) {
|
|
76
|
+
const point = Vec3.create();
|
|
77
|
+
Vec3.set(point, center[0], center[1], center[2]);
|
|
78
|
+
results.push({
|
|
79
|
+
collider: comp,
|
|
80
|
+
gameObject: comp.gameObject,
|
|
81
|
+
point,
|
|
82
|
+
normal: Vec3.create(),
|
|
83
|
+
distance: 0,
|
|
84
|
+
});
|
|
85
|
+
if (firstOnly)
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
});
|
|
90
|
+
return results;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Stateless physics query utilities.
|
|
94
|
+
* All methods require a PhysicsWorld and use Scene.current to resolve collider ownership.
|
|
95
|
+
*/
|
|
96
|
+
export class Physics {
|
|
97
|
+
/** Cast a ray and return the first hit, or null. */
|
|
98
|
+
static raycast(world, origin, dir, maxDist) {
|
|
99
|
+
const ray = getScratchRay(origin[0], origin[1], origin[2], dir[0], dir[1], dir[2]);
|
|
100
|
+
const hit = world.world.castRayAndGetNormal(ray, maxDist, true);
|
|
101
|
+
if (!hit)
|
|
102
|
+
return null;
|
|
103
|
+
const map = buildColliderMap();
|
|
104
|
+
return hitFromRapier(hit.collider, hit.timeOfImpact, hit.normal, origin, dir, map);
|
|
105
|
+
}
|
|
106
|
+
/** Cast a ray and return all hits. */
|
|
107
|
+
static raycastAll(world, origin, dir, maxDist) {
|
|
108
|
+
const ray = getScratchRay(origin[0], origin[1], origin[2], dir[0], dir[1], dir[2]);
|
|
109
|
+
const map = buildColliderMap();
|
|
110
|
+
const results = [];
|
|
111
|
+
world.world.intersectionsWithRay(ray, maxDist, true, (intersection) => {
|
|
112
|
+
const result = hitFromRapier(intersection.collider, intersection.timeOfImpact, intersection.normal, origin, dir, map);
|
|
113
|
+
if (result)
|
|
114
|
+
results.push(result);
|
|
115
|
+
return true;
|
|
116
|
+
});
|
|
117
|
+
return results;
|
|
118
|
+
}
|
|
119
|
+
/** Find the first collider overlapping a sphere at the given center and radius. */
|
|
120
|
+
static sphereCast(world, center, radius) {
|
|
121
|
+
const results = overlapQuery(world, center, new RAPIER.Ball(radius), true);
|
|
122
|
+
return results[0] ?? null;
|
|
123
|
+
}
|
|
124
|
+
/** Find all colliders overlapping a sphere. */
|
|
125
|
+
static sphereCastAll(world, center, radius) {
|
|
126
|
+
return overlapQuery(world, center, new RAPIER.Ball(radius), false);
|
|
127
|
+
}
|
|
128
|
+
/** Find the first collider overlapping a box at the given center with half-extents. */
|
|
129
|
+
static boxCast(world, center, halfExtents) {
|
|
130
|
+
const shape = new RAPIER.Cuboid(halfExtents[0], halfExtents[1], halfExtents[2]);
|
|
131
|
+
const results = overlapQuery(world, center, shape, true);
|
|
132
|
+
return results[0] ?? null;
|
|
133
|
+
}
|
|
134
|
+
/** Find all colliders overlapping a box. */
|
|
135
|
+
static boxCastAll(world, center, halfExtents) {
|
|
136
|
+
return overlapQuery(world, center, new RAPIER.Cuboid(halfExtents[0], halfExtents[1], halfExtents[2]), false);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=physics-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physics-query.js","sourceRoot":"","sources":["../src/physics-query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Scene, PhysicsStepper } from '@certe/atmos-core';
|
|
2
|
+
import type { PhysicsWorld } from './physics-world.js';
|
|
3
|
+
export declare class PhysicsSystem implements PhysicsStepper {
|
|
4
|
+
private readonly _world;
|
|
5
|
+
private _scene;
|
|
6
|
+
/** Cached previous scale per GameObject id to detect changes */
|
|
7
|
+
private readonly _prevScales;
|
|
8
|
+
/** Cached previous position for fixed bodies (avoids WASM FFI when unchanged) */
|
|
9
|
+
private readonly _prevFixedPos;
|
|
10
|
+
/** Cached previous local transform (pos3+rot4+scale3) for child collider GOs */
|
|
11
|
+
private readonly _prevChildTransforms;
|
|
12
|
+
constructor(world: PhysicsWorld, scene: Scene);
|
|
13
|
+
set scene(s: Scene);
|
|
14
|
+
step(dt: number): void;
|
|
15
|
+
private _syncChildColliderOffset;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=physics-system.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physics-system.d.ts","sourceRoot":"","sources":["../src/physics-system.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAG/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKvD,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,MAAM,CAAQ;IACtB,gEAAgE;IAChE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmC;IAC/D,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmC;IACjE,gFAAgF;IAChF,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAmC;gBAE5D,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK;IAK7C,IAAI,KAAK,CAAC,CAAC,EAAE,KAAK,EAKjB;IAED,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IA2EtB,OAAO,CAAC,wBAAwB;CAiCjC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Vec3 } from '@certe/atmos-math';
|
|
2
|
+
import { RigidBody } from './rigid-body.js';
|
|
3
|
+
import { Collider } from './collider.js';
|
|
4
|
+
import { invalidateColliderMap } from './physics-query.js';
|
|
5
|
+
export class PhysicsSystem {
|
|
6
|
+
_world;
|
|
7
|
+
_scene;
|
|
8
|
+
/** Cached previous scale per GameObject id to detect changes */
|
|
9
|
+
_prevScales = new Map();
|
|
10
|
+
/** Cached previous position for fixed bodies (avoids WASM FFI when unchanged) */
|
|
11
|
+
_prevFixedPos = new Map();
|
|
12
|
+
/** Cached previous local transform (pos3+rot4+scale3) for child collider GOs */
|
|
13
|
+
_prevChildTransforms = new Map();
|
|
14
|
+
constructor(world, scene) {
|
|
15
|
+
this._world = world;
|
|
16
|
+
this._scene = scene;
|
|
17
|
+
}
|
|
18
|
+
set scene(s) {
|
|
19
|
+
this._scene = s;
|
|
20
|
+
this._prevScales.clear();
|
|
21
|
+
this._prevFixedPos.clear();
|
|
22
|
+
this._prevChildTransforms.clear();
|
|
23
|
+
}
|
|
24
|
+
step(dt) {
|
|
25
|
+
// Invalidate physics query collider map cache for this frame
|
|
26
|
+
invalidateColliderMap();
|
|
27
|
+
// Pre-step: push transforms into Rapier + detect changes
|
|
28
|
+
for (const obj of this._scene.getAllObjects()) {
|
|
29
|
+
const rb = obj.getComponent(RigidBody);
|
|
30
|
+
if (rb && rb.enabled && rb.body) {
|
|
31
|
+
// --- Scale change detection (all body types) ---
|
|
32
|
+
const scale = obj.transform.scale;
|
|
33
|
+
const prev = this._prevScales.get(obj.id);
|
|
34
|
+
if (!prev) {
|
|
35
|
+
this._prevScales.set(obj.id, new Float32Array([scale[0], scale[1], scale[2]]));
|
|
36
|
+
}
|
|
37
|
+
else if (prev[0] !== scale[0] || prev[1] !== scale[1] || prev[2] !== scale[2]) {
|
|
38
|
+
const col = obj.getComponent(Collider);
|
|
39
|
+
if (col) {
|
|
40
|
+
col.applyScale(scale[0], scale[1], scale[2]);
|
|
41
|
+
}
|
|
42
|
+
Vec3.set(prev, scale[0], scale[1], scale[2]);
|
|
43
|
+
}
|
|
44
|
+
// --- Position / rotation sync ---
|
|
45
|
+
if (rb.bodyType === 'kinematic') {
|
|
46
|
+
rb.syncFromTransform();
|
|
47
|
+
}
|
|
48
|
+
else if (rb.bodyType === 'dynamic') {
|
|
49
|
+
// Interpolated bodies hold extrapolated positions — skip false teleport
|
|
50
|
+
if (!rb.interpolate) {
|
|
51
|
+
const pos = obj.transform.position;
|
|
52
|
+
const bpos = rb.body.translation();
|
|
53
|
+
const dx = pos[0] - bpos.x;
|
|
54
|
+
const dy = pos[1] - bpos.y;
|
|
55
|
+
const dz = pos[2] - bpos.z;
|
|
56
|
+
if (dx * dx + dy * dy + dz * dz > 1e-6) {
|
|
57
|
+
rb.teleportToTransform();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (rb.bodyType === 'fixed') {
|
|
62
|
+
// Fixed bodies only change via editor — compare against JS-side cache
|
|
63
|
+
const pos = obj.transform.position;
|
|
64
|
+
const prev = this._prevFixedPos.get(obj.id);
|
|
65
|
+
if (!prev) {
|
|
66
|
+
this._prevFixedPos.set(obj.id, new Float32Array([pos[0], pos[1], pos[2]]));
|
|
67
|
+
rb.teleportToTransform();
|
|
68
|
+
}
|
|
69
|
+
else if (prev[0] !== pos[0] || prev[1] !== pos[1] || prev[2] !== pos[2]) {
|
|
70
|
+
rb.teleportToTransform();
|
|
71
|
+
Vec3.set(prev, pos[0], pos[1], pos[2]);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// --- Child collider offset sync ---
|
|
76
|
+
const col = obj.getComponent(Collider);
|
|
77
|
+
if (col && col.enabled && col.isChildCollider && col.collider) {
|
|
78
|
+
this._syncChildColliderOffset(obj, col);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Step physics world (fixed timestep accumulator)
|
|
82
|
+
this._world.step(dt);
|
|
83
|
+
// Post-step: pull dynamic body transforms back
|
|
84
|
+
const remaining = this._world.accumulator;
|
|
85
|
+
for (const obj of this._scene.getAllObjects()) {
|
|
86
|
+
const rb = obj.getComponent(RigidBody);
|
|
87
|
+
if (!rb || !rb.enabled || !rb.body)
|
|
88
|
+
continue;
|
|
89
|
+
if (rb.bodyType === 'dynamic') {
|
|
90
|
+
if (rb.interpolate && remaining > 0) {
|
|
91
|
+
rb.extrapolateTransform(remaining);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
rb.syncToTransform();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
_syncChildColliderOffset(obj, col) {
|
|
100
|
+
const pos = obj.transform.position;
|
|
101
|
+
const rot = obj.transform.rotation;
|
|
102
|
+
const scale = obj.transform.scale;
|
|
103
|
+
const prev = this._prevChildTransforms.get(obj.id);
|
|
104
|
+
if (!prev) {
|
|
105
|
+
const data = new Float32Array(10);
|
|
106
|
+
data.set(pos, 0);
|
|
107
|
+
data.set(rot, 3);
|
|
108
|
+
data.set(scale, 7);
|
|
109
|
+
this._prevChildTransforms.set(obj.id, data);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
let changed = false;
|
|
113
|
+
for (let i = 0; i < 3 && !changed; i++) {
|
|
114
|
+
if (prev[i] !== pos[i])
|
|
115
|
+
changed = true;
|
|
116
|
+
}
|
|
117
|
+
for (let i = 0; i < 4 && !changed; i++) {
|
|
118
|
+
if (prev[3 + i] !== rot[i])
|
|
119
|
+
changed = true;
|
|
120
|
+
}
|
|
121
|
+
for (let i = 0; i < 3 && !changed; i++) {
|
|
122
|
+
if (prev[7 + i] !== scale[i])
|
|
123
|
+
changed = true;
|
|
124
|
+
}
|
|
125
|
+
if (changed) {
|
|
126
|
+
col.syncOffset();
|
|
127
|
+
prev.set(pos, 0);
|
|
128
|
+
prev.set(rot, 3);
|
|
129
|
+
prev.set(scale, 7);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=physics-system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physics-system.js","sourceRoot":"","sources":["../src/physics-system.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import RAPIER from '@dimforge/rapier3d-compat';
|
|
2
|
+
export interface PhysicsWorldOptions {
|
|
3
|
+
gravity?: {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
z: number;
|
|
7
|
+
};
|
|
8
|
+
fixedTimestep?: number;
|
|
9
|
+
solverIterations?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class PhysicsWorld {
|
|
12
|
+
readonly world: RAPIER.World;
|
|
13
|
+
fixedTimestep: number;
|
|
14
|
+
substeps: number;
|
|
15
|
+
private _accumulator;
|
|
16
|
+
/** Time remaining after the last fixed step (for interpolation/extrapolation). */
|
|
17
|
+
get accumulator(): number;
|
|
18
|
+
constructor(options?: PhysicsWorldOptions);
|
|
19
|
+
setGravity(x: number, y: number, z: number): void;
|
|
20
|
+
setSolverIterations(n: number): void;
|
|
21
|
+
/** Advance the simulation by dt seconds using fixed timestep accumulator. Returns steps taken. */
|
|
22
|
+
step(dt: number): number;
|
|
23
|
+
createRigidBody(desc: RAPIER.RigidBodyDesc): RAPIER.RigidBody;
|
|
24
|
+
createCollider(desc: RAPIER.ColliderDesc, body: RAPIER.RigidBody): RAPIER.Collider;
|
|
25
|
+
removeRigidBody(body: RAPIER.RigidBody): void;
|
|
26
|
+
removeCollider(collider: RAPIER.Collider): void;
|
|
27
|
+
createJoint(data: RAPIER.JointData, body1: RAPIER.RigidBody, body2: RAPIER.RigidBody): RAPIER.ImpulseJoint;
|
|
28
|
+
removeJoint(joint: RAPIER.ImpulseJoint): void;
|
|
29
|
+
/** Reset the fixed-timestep accumulator (e.g. after pause→play). */
|
|
30
|
+
resetAccumulator(): void;
|
|
31
|
+
destroy(): void;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=physics-world.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physics-world.d.ts","sourceRoot":"","sources":["../src/physics-world.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,2BAA2B,CAAC;AAE/C,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,YAAY;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,SAAK;IACb,OAAO,CAAC,YAAY,CAAK;IAEzB,kFAAkF;IAClF,IAAI,WAAW,IAAI,MAAM,CAA8B;gBAE3C,OAAO,GAAE,mBAAwB;IAS7C,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAIjD,mBAAmB,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAIpC,kGAAkG;IAClG,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAgBxB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,SAAS;IAI7D,cAAc,CACZ,IAAI,EAAE,MAAM,CAAC,YAAY,EACzB,IAAI,EAAE,MAAM,CAAC,SAAS,GACrB,MAAM,CAAC,QAAQ;IAIlB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,GAAG,IAAI;IAI7C,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAG,IAAI;IAI/C,WAAW,CACT,IAAI,EAAE,MAAM,CAAC,SAAS,EACtB,KAAK,EAAE,MAAM,CAAC,SAAS,EACvB,KAAK,EAAE,MAAM,CAAC,SAAS,GACtB,MAAM,CAAC,YAAY;IAItB,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,GAAG,IAAI;IAI7C,oEAAoE;IACpE,gBAAgB,IAAI,IAAI;IAIxB,OAAO,IAAI,IAAI;CAGhB"}
|