@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/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# ⚡ @certe/atmos-physics
|
|
2
|
+
|
|
3
|
+
Physics integration for the Atmos Engine, wrapping [Rapier](https://rapier.rs/) (WASM). Provides rigid bodies, collider shapes, joints, and stateless physics queries — all as components that sync automatically with the engine's Transform system.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🚀 Quick Start
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { initRapier, PhysicsWorld, PhysicsSystem,
|
|
11
|
+
RigidBody, Collider } from '@certe/atmos-physics';
|
|
12
|
+
|
|
13
|
+
await initRapier();
|
|
14
|
+
const world = new PhysicsWorld({ gravity: { x: 0, y: -9.81, z: 0 } });
|
|
15
|
+
|
|
16
|
+
// Dynamic cube
|
|
17
|
+
const cube = new GameObject('Cube');
|
|
18
|
+
const rb = cube.addComponent(RigidBody);
|
|
19
|
+
rb.init(world, { type: 'dynamic', mass: 1 });
|
|
20
|
+
const col = cube.addComponent(Collider);
|
|
21
|
+
col.init(world, { shape: { type: 'box', halfExtents: { x: 0.5, y: 0.5, z: 0.5 } } });
|
|
22
|
+
|
|
23
|
+
// Static floor
|
|
24
|
+
const floor = new GameObject('Floor');
|
|
25
|
+
const floorRb = floor.addComponent(RigidBody);
|
|
26
|
+
floorRb.init(world, { type: 'fixed' });
|
|
27
|
+
const floorCol = floor.addComponent(Collider);
|
|
28
|
+
floorCol.init(world, { shape: { type: 'box', halfExtents: { x: 50, y: 0.5, z: 50 } } });
|
|
29
|
+
|
|
30
|
+
// Wire into engine
|
|
31
|
+
const physicsSystem = new PhysicsSystem(world, scene);
|
|
32
|
+
engine.setPhysics(physicsSystem);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 📖 API Overview
|
|
38
|
+
|
|
39
|
+
### Initialization
|
|
40
|
+
|
|
41
|
+
| Function | Description |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `initRapier()` | Load Rapier WASM (idempotent, call once at startup) |
|
|
44
|
+
| `new PhysicsWorld(opts?)` | Create simulation with gravity, timestep, solver iterations |
|
|
45
|
+
|
|
46
|
+
### RigidBody Component
|
|
47
|
+
|
|
48
|
+
| Property | Description |
|
|
49
|
+
|---|---|
|
|
50
|
+
| `type` | `'dynamic'` · `'fixed'` · `'kinematic'` |
|
|
51
|
+
| `mass` | Mass for dynamic bodies |
|
|
52
|
+
| `linearDamping` / `angularDamping` | Velocity damping |
|
|
53
|
+
| `gravityScale` | Per-body gravity multiplier |
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
rb.addForce(0, 100, 0); // continuous force
|
|
57
|
+
rb.addImpulse(0, 10, 0); // instant impulse
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Collider Component
|
|
61
|
+
|
|
62
|
+
Supported shapes:
|
|
63
|
+
|
|
64
|
+
| Shape | Parameters |
|
|
65
|
+
|---|---|
|
|
66
|
+
| `box` | `halfExtents: {x, y, z}` |
|
|
67
|
+
| `sphere` | `radius` |
|
|
68
|
+
| `capsule` | `halfHeight, radius` |
|
|
69
|
+
| `cylinder` | `halfHeight, radius` |
|
|
70
|
+
| `convexHull` | `vertices: Float32Array` |
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
col.init(world, {
|
|
74
|
+
shape: { type: 'sphere', radius: 1.0 },
|
|
75
|
+
friction: 0.5,
|
|
76
|
+
restitution: 0.3,
|
|
77
|
+
isSensor: false, // true = trigger volume
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Colliders auto-attach to the nearest ancestor `RigidBody` and compute offsets for child GameObjects.
|
|
82
|
+
|
|
83
|
+
### Joints
|
|
84
|
+
|
|
85
|
+
| Joint Type | Description |
|
|
86
|
+
|---|---|
|
|
87
|
+
| `FixedJoint` | Rigid constraint (no relative motion) |
|
|
88
|
+
| `HingeJoint` | Revolute (rotation around one axis), with optional limits and motor |
|
|
89
|
+
| `SpringJoint` | Spring with rest length, stiffness, and damping |
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
const hinge = obj.addComponent(HingeJoint);
|
|
93
|
+
hinge.init(world, {
|
|
94
|
+
connectedObject: otherObj,
|
|
95
|
+
axis: { x: 0, y: 1, z: 0 },
|
|
96
|
+
limitsEnabled: true,
|
|
97
|
+
limitMin: -Math.PI / 4,
|
|
98
|
+
limitMax: Math.PI / 4,
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Physics Queries
|
|
103
|
+
|
|
104
|
+
Stateless raycasting and shape-casting via the `Physics` class:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import { Physics } from '@certe/atmos-physics';
|
|
108
|
+
|
|
109
|
+
const hit = Physics.raycast(world, origin, direction, 100);
|
|
110
|
+
if (hit) {
|
|
111
|
+
console.log(hit.gameObject.name, hit.point, hit.normal, hit.distance);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const hits = Physics.sphereCastAll(world, center, radius);
|
|
115
|
+
const boxHit = Physics.boxCast(world, center, halfExtents);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### PhysicsSystem
|
|
119
|
+
|
|
120
|
+
Runs each frame via the engine. Handles:
|
|
121
|
+
|
|
122
|
+
- **Pre-step**: Detects external transform changes → teleports dynamic bodies; syncs kinematic bodies
|
|
123
|
+
- **Step**: Fixed-timestep accumulator (`world.step(dt)`)
|
|
124
|
+
- **Post-step**: Copies Rapier transforms back to engine Transforms
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 📁 Structure
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
packages/physics/src/
|
|
132
|
+
index.ts # Public API
|
|
133
|
+
rapier-init.ts # WASM loader
|
|
134
|
+
physics-world.ts # Rapier world wrapper
|
|
135
|
+
physics-system.ts # Per-frame sync orchestrator
|
|
136
|
+
rigid-body.ts # RigidBody component
|
|
137
|
+
collider.ts # Collider component + shapes
|
|
138
|
+
joint.ts # Abstract Joint base
|
|
139
|
+
fixed-joint.ts # FixedJoint
|
|
140
|
+
hinge-joint.ts # HingeJoint (limits, motor)
|
|
141
|
+
spring-joint.ts # SpringJoint
|
|
142
|
+
physics-query.ts # Raycast, sphere/box cast
|
|
143
|
+
helpers.ts # Ancestor traversal utilities
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## 🔗 Dependencies
|
|
149
|
+
|
|
150
|
+
- `@certe/atmos-core` — Component, GameObject, Transform, Scene
|
|
151
|
+
- `@certe/atmos-math` — Vec3, Quat for transform sync
|
|
152
|
+
- `@dimforge/rapier3d-compat` — WASM physics engine
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { GameObject } from '@certe/atmos-core';
|
|
2
|
+
export interface ColliderOffset {
|
|
3
|
+
tx: number;
|
|
4
|
+
ty: number;
|
|
5
|
+
tz: number;
|
|
6
|
+
rx: number;
|
|
7
|
+
ry: number;
|
|
8
|
+
rz: number;
|
|
9
|
+
rw: number;
|
|
10
|
+
sx: number;
|
|
11
|
+
sy: number;
|
|
12
|
+
sz: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Compute the offset of a child collider GO relative to its body's GO.
|
|
16
|
+
* Both transforms must have up-to-date world matrices before calling.
|
|
17
|
+
*/
|
|
18
|
+
export declare function computeColliderOffset(bodyGo: GameObject, childGo: GameObject): ColliderOffset;
|
|
19
|
+
//# sourceMappingURL=collider-offset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collider-offset.d.ts","sourceRoot":"","sources":["../src/collider-offset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IACnC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAC/C,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;CACpC;AAOD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,UAAU,GAClB,cAAc,CA0BhB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Mat4, Quat } from '@certe/atmos-math';
|
|
2
|
+
// Scratch arrays — reused to avoid heap allocs
|
|
3
|
+
const _invParent = Mat4.create();
|
|
4
|
+
const _relative = Mat4.create();
|
|
5
|
+
const _tmpQuat = Quat.create();
|
|
6
|
+
/**
|
|
7
|
+
* Compute the offset of a child collider GO relative to its body's GO.
|
|
8
|
+
* Both transforms must have up-to-date world matrices before calling.
|
|
9
|
+
*/
|
|
10
|
+
export function computeColliderOffset(bodyGo, childGo) {
|
|
11
|
+
// relative = inv(bodyWorld) * childWorld
|
|
12
|
+
if (!Mat4.invert(_invParent, bodyGo.transform.worldMatrix)) {
|
|
13
|
+
// Singular body world matrix (e.g. zero scale) — return identity offset
|
|
14
|
+
return { tx: 0, ty: 0, tz: 0, rx: 0, ry: 0, rz: 0, rw: 1, sx: 1, sy: 1, sz: 1 };
|
|
15
|
+
}
|
|
16
|
+
Mat4.multiply(_relative, _invParent, childGo.transform.worldMatrix);
|
|
17
|
+
// Translation from column 3
|
|
18
|
+
const tx = _relative[12];
|
|
19
|
+
const ty = _relative[13];
|
|
20
|
+
const tz = _relative[14];
|
|
21
|
+
// Scale from column lengths
|
|
22
|
+
const sx = Math.sqrt(_relative[0] ** 2 + _relative[1] ** 2 + _relative[2] ** 2);
|
|
23
|
+
const sy = Math.sqrt(_relative[4] ** 2 + _relative[5] ** 2 + _relative[6] ** 2);
|
|
24
|
+
const sz = Math.sqrt(_relative[8] ** 2 + _relative[9] ** 2 + _relative[10] ** 2);
|
|
25
|
+
// Rotation (Quat.fromMat4 normalizes columns internally)
|
|
26
|
+
Quat.fromMat4(_tmpQuat, _relative);
|
|
27
|
+
return {
|
|
28
|
+
tx, ty, tz,
|
|
29
|
+
rx: _tmpQuat[0], ry: _tmpQuat[1], rz: _tmpQuat[2], rw: _tmpQuat[3],
|
|
30
|
+
sx, sy, sz,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=collider-offset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collider-offset.js","sourceRoot":"","sources":["../src/collider-offset.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAQ/C,+CAA+C;AAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;AACjC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;AAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;AAE/B;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAkB,EAClB,OAAmB;IAEnB,yCAAyC;IACzC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;QAC3D,wEAAwE;QACxE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;IAClF,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAEpE,4BAA4B;IAC5B,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,CAAE,CAAC;IAC1B,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,CAAE,CAAC;IAC1B,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,CAAE,CAAC;IAE1B,4BAA4B;IAC5B,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,CAAC;IACnF,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,CAAC;IACnF,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE,CAAE,IAAI,CAAC,CAAC,CAAC;IAEpF,yDAAyD;IACzD,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAEnC,OAAO;QACL,EAAE,EAAE,EAAE,EAAE,EAAE;QACV,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAE;QACtE,EAAE,EAAE,EAAE,EAAE,EAAE;KACX,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import RAPIER from '@dimforge/rapier3d-compat';
|
|
2
|
+
import { Component } from '@certe/atmos-core';
|
|
3
|
+
import type { PhysicsWorld } from './physics-world.js';
|
|
4
|
+
import { RigidBody } from './rigid-body.js';
|
|
5
|
+
export type ColliderShape = {
|
|
6
|
+
type: 'box';
|
|
7
|
+
halfExtents: {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
z: number;
|
|
11
|
+
};
|
|
12
|
+
center?: {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
z: number;
|
|
16
|
+
};
|
|
17
|
+
} | {
|
|
18
|
+
type: 'sphere';
|
|
19
|
+
radius: number;
|
|
20
|
+
} | {
|
|
21
|
+
type: 'capsule';
|
|
22
|
+
halfHeight: number;
|
|
23
|
+
radius: number;
|
|
24
|
+
} | {
|
|
25
|
+
type: 'cylinder';
|
|
26
|
+
halfHeight: number;
|
|
27
|
+
radius: number;
|
|
28
|
+
} | {
|
|
29
|
+
type: 'convexHull';
|
|
30
|
+
vertices: Float32Array;
|
|
31
|
+
};
|
|
32
|
+
export interface ColliderOptions {
|
|
33
|
+
shape: ColliderShape;
|
|
34
|
+
friction?: number;
|
|
35
|
+
restitution?: number;
|
|
36
|
+
density?: number;
|
|
37
|
+
isSensor?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export declare class Collider extends Component {
|
|
40
|
+
collider: RAPIER.Collider | null;
|
|
41
|
+
/** Unscaled base shape dimensions, stored at init time */
|
|
42
|
+
private _baseShape;
|
|
43
|
+
private _options;
|
|
44
|
+
private _world;
|
|
45
|
+
/** The RigidBody this collider is attached to (may be on an ancestor) */
|
|
46
|
+
private _bodyRb;
|
|
47
|
+
/** The GameObject that owns the RigidBody */
|
|
48
|
+
private _bodyGo;
|
|
49
|
+
private _friction;
|
|
50
|
+
private _restitution;
|
|
51
|
+
private _density;
|
|
52
|
+
private _isSensor;
|
|
53
|
+
get friction(): number;
|
|
54
|
+
set friction(v: number);
|
|
55
|
+
get restitution(): number;
|
|
56
|
+
set restitution(v: number);
|
|
57
|
+
get density(): number;
|
|
58
|
+
set density(v: number);
|
|
59
|
+
get isSensor(): boolean;
|
|
60
|
+
set isSensor(v: boolean);
|
|
61
|
+
get attachedBody(): RigidBody | null;
|
|
62
|
+
get shape(): ColliderShape | null;
|
|
63
|
+
get isChildCollider(): boolean;
|
|
64
|
+
init(world: PhysicsWorld, options: ColliderOptions): void;
|
|
65
|
+
/** Recompute this child collider's offset from the current transform hierarchy. */
|
|
66
|
+
syncOffset(): void;
|
|
67
|
+
/** Destroy and re-create the collider (e.g. after reparenting). */
|
|
68
|
+
reattach(world: PhysicsWorld): void;
|
|
69
|
+
applyScale(sx: number, sy: number, sz: number): void;
|
|
70
|
+
/** Apply shape center offset (scaled), e.g. for plane collider where top face = visual surface. */
|
|
71
|
+
private _applyCenterOffset;
|
|
72
|
+
onDestroy(): void;
|
|
73
|
+
private _createDesc;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=collider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collider.d.ts","sourceRoot":"","sources":["../src/collider.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,2BAA2B,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,WAAW,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,MAAM,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC/G;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAOD,qBAAa,QAAS,SAAQ,SAAS;IACrC,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAQ;IAExC,0DAA0D;IAC1D,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,MAAM,CAA6B;IAC3C,yEAAyE;IACzE,OAAO,CAAC,OAAO,CAA0B;IACzC,6CAA6C;IAC7C,OAAO,CAAC,OAAO,CAA2B;IAE1C,OAAO,CAAC,SAAS,CAAO;IACxB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAS;IAE1B,IAAI,QAAQ,IAAI,MAAM,CAA2B;IACjD,IAAI,QAAQ,CAAC,CAAC,EAAE,MAAM,EAGrB;IAED,IAAI,WAAW,IAAI,MAAM,CAA8B;IACvD,IAAI,WAAW,CAAC,CAAC,EAAE,MAAM,EAGxB;IAED,IAAI,OAAO,IAAI,MAAM,CAA0B;IAC/C,IAAI,OAAO,CAAC,CAAC,EAAE,MAAM,EAGpB;IAED,IAAI,QAAQ,IAAI,OAAO,CAA2B;IAClD,IAAI,QAAQ,CAAC,CAAC,EAAE,OAAO,EAGtB;IAED,IAAI,YAAY,IAAI,SAAS,GAAG,IAAI,CAEnC;IAED,IAAI,KAAK,IAAI,aAAa,GAAG,IAAI,CAEhC;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED,IAAI,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI;IAiDzD,mFAAmF;IACnF,UAAU,IAAI,IAAI;IAalB,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAWnC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAiCpD,mGAAmG;IACnG,OAAO,CAAC,kBAAkB;IAY1B,SAAS,IAAI,IAAI;IASjB,OAAO,CAAC,WAAW;CA8BpB"}
|
package/dist/collider.js
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import RAPIER from '@dimforge/rapier3d-compat';
|
|
2
|
+
import { Component } from '@certe/atmos-core';
|
|
3
|
+
import { RigidBody } from './rigid-body.js';
|
|
4
|
+
import { findAncestorComponent } from './physics-hierarchy.js';
|
|
5
|
+
import { computeColliderOffset } from './collider-offset.js';
|
|
6
|
+
// Scratch vectors reused to avoid allocations
|
|
7
|
+
const _scaleVec = new RAPIER.Vector3(0, 0, 0);
|
|
8
|
+
const _offsetVec = new RAPIER.Vector3(0, 0, 0);
|
|
9
|
+
const _offsetRot = new RAPIER.Quaternion(0, 0, 0, 1);
|
|
10
|
+
export class Collider extends Component {
|
|
11
|
+
collider = null;
|
|
12
|
+
/** Unscaled base shape dimensions, stored at init time */
|
|
13
|
+
_baseShape = null;
|
|
14
|
+
_options = null;
|
|
15
|
+
_world = null;
|
|
16
|
+
/** The RigidBody this collider is attached to (may be on an ancestor) */
|
|
17
|
+
_bodyRb = null;
|
|
18
|
+
/** The GameObject that owns the RigidBody */
|
|
19
|
+
_bodyGo = null;
|
|
20
|
+
_friction = 0.5;
|
|
21
|
+
_restitution = 0;
|
|
22
|
+
_density = 1;
|
|
23
|
+
_isSensor = false;
|
|
24
|
+
get friction() { return this._friction; }
|
|
25
|
+
set friction(v) {
|
|
26
|
+
this._friction = v;
|
|
27
|
+
if (this.collider)
|
|
28
|
+
this.collider.setFriction(v);
|
|
29
|
+
}
|
|
30
|
+
get restitution() { return this._restitution; }
|
|
31
|
+
set restitution(v) {
|
|
32
|
+
this._restitution = v;
|
|
33
|
+
if (this.collider)
|
|
34
|
+
this.collider.setRestitution(v);
|
|
35
|
+
}
|
|
36
|
+
get density() { return this._density; }
|
|
37
|
+
set density(v) {
|
|
38
|
+
this._density = v;
|
|
39
|
+
if (this.collider)
|
|
40
|
+
this.collider.setDensity(v);
|
|
41
|
+
}
|
|
42
|
+
get isSensor() { return this._isSensor; }
|
|
43
|
+
set isSensor(v) {
|
|
44
|
+
this._isSensor = v;
|
|
45
|
+
if (this.collider)
|
|
46
|
+
this.collider.setSensor(v);
|
|
47
|
+
}
|
|
48
|
+
get attachedBody() {
|
|
49
|
+
return this._bodyRb;
|
|
50
|
+
}
|
|
51
|
+
get shape() {
|
|
52
|
+
return this._baseShape;
|
|
53
|
+
}
|
|
54
|
+
get isChildCollider() {
|
|
55
|
+
return this._bodyGo !== null && this._bodyGo !== this.gameObject;
|
|
56
|
+
}
|
|
57
|
+
init(world, options) {
|
|
58
|
+
this._world = world;
|
|
59
|
+
this._baseShape = options.shape;
|
|
60
|
+
this._options = options;
|
|
61
|
+
if (options.friction !== undefined)
|
|
62
|
+
this._friction = options.friction;
|
|
63
|
+
if (options.restitution !== undefined)
|
|
64
|
+
this._restitution = options.restitution;
|
|
65
|
+
if (options.density !== undefined)
|
|
66
|
+
this._density = options.density;
|
|
67
|
+
if (options.isSensor !== undefined)
|
|
68
|
+
this._isSensor = options.isSensor;
|
|
69
|
+
// Find body: self first, then walk up hierarchy
|
|
70
|
+
const rb = findAncestorComponent(this.gameObject, RigidBody);
|
|
71
|
+
if (!rb || !rb.body) {
|
|
72
|
+
throw new Error('Collider requires a RigidBody on this GameObject or an ancestor');
|
|
73
|
+
}
|
|
74
|
+
this._bodyRb = rb;
|
|
75
|
+
this._bodyGo = rb.gameObject;
|
|
76
|
+
const desc = this._createDesc(options);
|
|
77
|
+
// If attached to an ancestor's body, compute offset from hierarchy transforms
|
|
78
|
+
if (this._bodyGo !== this.gameObject) {
|
|
79
|
+
this._bodyGo.transform.updateWorldMatrix();
|
|
80
|
+
this.gameObject.transform.updateWorldMatrix();
|
|
81
|
+
const offset = computeColliderOffset(this._bodyGo, this.gameObject);
|
|
82
|
+
desc.setTranslation(offset.tx, offset.ty, offset.tz);
|
|
83
|
+
desc.setRotation({ x: offset.rx, y: offset.ry, z: offset.rz, w: offset.rw });
|
|
84
|
+
}
|
|
85
|
+
this.collider = world.createCollider(desc, rb.body);
|
|
86
|
+
// Apply scale: use accumulated scale for child colliders, local for self
|
|
87
|
+
if (this._bodyGo !== this.gameObject) {
|
|
88
|
+
const offset = computeColliderOffset(this._bodyGo, this.gameObject);
|
|
89
|
+
this.applyScale(offset.sx, offset.sy, offset.sz);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
const scale = this.gameObject.transform.scale;
|
|
93
|
+
if (scale[0] !== 1 || scale[1] !== 1 || scale[2] !== 1) {
|
|
94
|
+
this.applyScale(scale[0], scale[1], scale[2]);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
this._applyCenterOffset();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
rb.body.wakeUp();
|
|
101
|
+
}
|
|
102
|
+
/** Recompute this child collider's offset from the current transform hierarchy. */
|
|
103
|
+
syncOffset() {
|
|
104
|
+
if (!this.collider || !this._bodyGo || this._bodyGo === this.gameObject)
|
|
105
|
+
return;
|
|
106
|
+
this._bodyGo.transform.updateWorldMatrix();
|
|
107
|
+
this.gameObject.transform.updateWorldMatrix();
|
|
108
|
+
const offset = computeColliderOffset(this._bodyGo, this.gameObject);
|
|
109
|
+
_offsetVec.x = offset.tx;
|
|
110
|
+
_offsetVec.y = offset.ty;
|
|
111
|
+
_offsetVec.z = offset.tz;
|
|
112
|
+
this.collider.setTranslationWrtParent(_offsetVec);
|
|
113
|
+
_offsetRot.x = offset.rx;
|
|
114
|
+
_offsetRot.y = offset.ry;
|
|
115
|
+
_offsetRot.z = offset.rz;
|
|
116
|
+
_offsetRot.w = offset.rw;
|
|
117
|
+
this.collider.setRotationWrtParent(_offsetRot);
|
|
118
|
+
this.applyScale(offset.sx, offset.sy, offset.sz);
|
|
119
|
+
}
|
|
120
|
+
/** Destroy and re-create the collider (e.g. after reparenting). */
|
|
121
|
+
reattach(world) {
|
|
122
|
+
if (!this._options)
|
|
123
|
+
return;
|
|
124
|
+
if (this.collider && this._world) {
|
|
125
|
+
try {
|
|
126
|
+
this._world.removeCollider(this.collider);
|
|
127
|
+
}
|
|
128
|
+
catch { /* already removed */ }
|
|
129
|
+
this.collider = null;
|
|
130
|
+
}
|
|
131
|
+
this._bodyRb = null;
|
|
132
|
+
this._bodyGo = null;
|
|
133
|
+
this.init(world, this._options);
|
|
134
|
+
}
|
|
135
|
+
applyScale(sx, sy, sz) {
|
|
136
|
+
if (!this.collider || !this._baseShape)
|
|
137
|
+
return;
|
|
138
|
+
switch (this._baseShape.type) {
|
|
139
|
+
case 'box': {
|
|
140
|
+
const h = this._baseShape.halfExtents;
|
|
141
|
+
_scaleVec.x = h.x * Math.abs(sx);
|
|
142
|
+
_scaleVec.y = h.y * Math.abs(sy);
|
|
143
|
+
_scaleVec.z = h.z * Math.abs(sz);
|
|
144
|
+
this.collider.setHalfExtents(_scaleVec);
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
case 'sphere':
|
|
148
|
+
this.collider.setRadius(this._baseShape.radius * Math.max(Math.abs(sx), Math.abs(sy), Math.abs(sz)));
|
|
149
|
+
break;
|
|
150
|
+
case 'cylinder':
|
|
151
|
+
this.collider.setHalfHeight(this._baseShape.halfHeight * Math.abs(sy));
|
|
152
|
+
this.collider.setRadius(this._baseShape.radius * Math.max(Math.abs(sx), Math.abs(sz)));
|
|
153
|
+
break;
|
|
154
|
+
case 'capsule':
|
|
155
|
+
this.collider.setHalfHeight(this._baseShape.halfHeight * Math.abs(sy));
|
|
156
|
+
this.collider.setRadius(this._baseShape.radius * Math.max(Math.abs(sx), Math.abs(sz)));
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
this._applyCenterOffset(sx, sy, sz);
|
|
160
|
+
}
|
|
161
|
+
/** Apply shape center offset (scaled), e.g. for plane collider where top face = visual surface. */
|
|
162
|
+
_applyCenterOffset(sx = 1, sy = 1, sz = 1) {
|
|
163
|
+
if (!this.collider || !this._baseShape || this._baseShape.type !== 'box')
|
|
164
|
+
return;
|
|
165
|
+
const c = this._baseShape.center;
|
|
166
|
+
if (!c)
|
|
167
|
+
return;
|
|
168
|
+
// Only apply for self-colliders (not child colliders, which use hierarchy offset)
|
|
169
|
+
if (this._bodyGo && this._bodyGo !== this.gameObject)
|
|
170
|
+
return;
|
|
171
|
+
_offsetVec.x = c.x * sx;
|
|
172
|
+
_offsetVec.y = c.y * sy;
|
|
173
|
+
_offsetVec.z = c.z * sz;
|
|
174
|
+
this.collider.setTranslationWrtParent(_offsetVec);
|
|
175
|
+
}
|
|
176
|
+
onDestroy() {
|
|
177
|
+
if (this.collider && this._world) {
|
|
178
|
+
try {
|
|
179
|
+
this._world.removeCollider(this.collider);
|
|
180
|
+
}
|
|
181
|
+
catch { /* stale handle */ }
|
|
182
|
+
this.collider = null;
|
|
183
|
+
}
|
|
184
|
+
this._bodyRb = null;
|
|
185
|
+
this._bodyGo = null;
|
|
186
|
+
}
|
|
187
|
+
_createDesc(options) {
|
|
188
|
+
let desc;
|
|
189
|
+
switch (options.shape.type) {
|
|
190
|
+
case 'box': {
|
|
191
|
+
const h = options.shape.halfExtents;
|
|
192
|
+
desc = RAPIER.ColliderDesc.cuboid(h.x, h.y, h.z);
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
case 'sphere':
|
|
196
|
+
desc = RAPIER.ColliderDesc.ball(options.shape.radius);
|
|
197
|
+
break;
|
|
198
|
+
case 'capsule':
|
|
199
|
+
desc = RAPIER.ColliderDesc.capsule(options.shape.halfHeight, options.shape.radius);
|
|
200
|
+
break;
|
|
201
|
+
case 'cylinder':
|
|
202
|
+
desc = RAPIER.ColliderDesc.cylinder(options.shape.halfHeight, options.shape.radius);
|
|
203
|
+
break;
|
|
204
|
+
case 'convexHull': {
|
|
205
|
+
const hull = RAPIER.ColliderDesc.convexHull(options.shape.vertices);
|
|
206
|
+
if (!hull)
|
|
207
|
+
throw new Error('Failed to compute convex hull from vertices');
|
|
208
|
+
desc = hull;
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (options.friction !== undefined)
|
|
213
|
+
desc.setFriction(options.friction);
|
|
214
|
+
if (options.restitution !== undefined)
|
|
215
|
+
desc.setRestitution(options.restitution);
|
|
216
|
+
if (options.density !== undefined)
|
|
217
|
+
desc.setDensity(options.density);
|
|
218
|
+
if (options.isSensor)
|
|
219
|
+
desc.setSensor(true);
|
|
220
|
+
return desc;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=collider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collider.js","sourceRoot":"","sources":["../src/collider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import RAPIER from '@dimforge/rapier3d-compat';
|
|
2
|
+
import { Joint } from './joint.js';
|
|
3
|
+
import type { JointOptions } from './joint.js';
|
|
4
|
+
export type FixedJointOptions = JointOptions;
|
|
5
|
+
export declare class FixedJoint extends Joint {
|
|
6
|
+
protected _createJointData(): RAPIER.JointData;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=fixed-joint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixed-joint.d.ts","sourceRoot":"","sources":["../src/fixed-joint.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,2BAA2B,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAE7C,qBAAa,UAAW,SAAQ,KAAK;IACnC,SAAS,CAAC,gBAAgB,IAAI,MAAM,CAAC,SAAS;CAK/C"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import RAPIER from '@dimforge/rapier3d-compat';
|
|
2
|
+
import { Joint } from './joint.js';
|
|
3
|
+
export class FixedJoint extends Joint {
|
|
4
|
+
_createJointData() {
|
|
5
|
+
const frame1 = { x: 0, y: 0, z: 0, w: 1 };
|
|
6
|
+
const frame2 = { x: 0, y: 0, z: 0, w: 1 };
|
|
7
|
+
return RAPIER.JointData.fixed(this._toXYZ(this.anchor), frame1, this._toXYZ(this.connectedAnchor), frame2);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=fixed-joint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixed-joint.js","sourceRoot":"","sources":["../src/fixed-joint.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,2BAA2B,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAKnC,MAAM,OAAO,UAAW,SAAQ,KAAK;IACzB,gBAAgB;QACxB,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QAC1C,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC,CAAC;IAC7G,CAAC;CACF"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import RAPIER from '@dimforge/rapier3d-compat';
|
|
2
|
+
import type { Vec3Type } from '@certe/atmos-math';
|
|
3
|
+
import { Joint } from './joint.js';
|
|
4
|
+
import type { JointOptions } from './joint.js';
|
|
5
|
+
import type { PhysicsWorld } from './physics-world.js';
|
|
6
|
+
type AxisOption = {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
z: number;
|
|
10
|
+
} | Float32Array;
|
|
11
|
+
export interface HingeJointOptions extends JointOptions {
|
|
12
|
+
axis?: AxisOption;
|
|
13
|
+
connectedAxis?: AxisOption;
|
|
14
|
+
autoConfigureConnectedAxis?: boolean;
|
|
15
|
+
limitsEnabled?: boolean;
|
|
16
|
+
limitMin?: number;
|
|
17
|
+
limitMax?: number;
|
|
18
|
+
motorEnabled?: boolean;
|
|
19
|
+
motorMode?: 'velocity' | 'position';
|
|
20
|
+
motorTargetVelocity?: number;
|
|
21
|
+
motorMaxForce?: number;
|
|
22
|
+
motorTargetPosition?: number;
|
|
23
|
+
motorStiffness?: number;
|
|
24
|
+
motorDamping?: number;
|
|
25
|
+
}
|
|
26
|
+
export declare class HingeJoint extends Joint {
|
|
27
|
+
private readonly _axis;
|
|
28
|
+
private readonly _connectedAxisVec;
|
|
29
|
+
private _autoConfigureConnectedAxis;
|
|
30
|
+
private _limitsEnabled;
|
|
31
|
+
private _limitMin;
|
|
32
|
+
private _limitMax;
|
|
33
|
+
private _motorEnabled;
|
|
34
|
+
private _motorMode;
|
|
35
|
+
private _motorTargetVelocity;
|
|
36
|
+
private _motorMaxForce;
|
|
37
|
+
private _motorTargetPosition;
|
|
38
|
+
private _motorStiffness;
|
|
39
|
+
private _motorDamping;
|
|
40
|
+
/** Current joint angle in radians. Computed from body orientations and joint frames. */
|
|
41
|
+
get angle(): number;
|
|
42
|
+
get axis(): Vec3Type;
|
|
43
|
+
set axis(v: Vec3Type);
|
|
44
|
+
get connectedAxis(): Vec3Type;
|
|
45
|
+
set connectedAxis(v: Vec3Type);
|
|
46
|
+
get autoConfigureConnectedAxis(): boolean;
|
|
47
|
+
set autoConfigureConnectedAxis(v: boolean);
|
|
48
|
+
get limitsEnabled(): boolean;
|
|
49
|
+
set limitsEnabled(v: boolean);
|
|
50
|
+
get limitMin(): number;
|
|
51
|
+
set limitMin(v: number);
|
|
52
|
+
get limitMax(): number;
|
|
53
|
+
set limitMax(v: number);
|
|
54
|
+
get motorEnabled(): boolean;
|
|
55
|
+
set motorEnabled(v: boolean);
|
|
56
|
+
get motorMode(): 'velocity' | 'position';
|
|
57
|
+
set motorMode(v: 'velocity' | 'position');
|
|
58
|
+
get motorTargetVelocity(): number;
|
|
59
|
+
set motorTargetVelocity(v: number);
|
|
60
|
+
get motorMaxForce(): number;
|
|
61
|
+
set motorMaxForce(v: number);
|
|
62
|
+
get motorTargetPosition(): number;
|
|
63
|
+
set motorTargetPosition(v: number);
|
|
64
|
+
get motorStiffness(): number;
|
|
65
|
+
set motorStiffness(v: number);
|
|
66
|
+
get motorDamping(): number;
|
|
67
|
+
set motorDamping(v: number);
|
|
68
|
+
init(world: PhysicsWorld, options?: HingeJointOptions): void;
|
|
69
|
+
refreshAutoConfig(): void;
|
|
70
|
+
protected _tryCreateJoint(): void;
|
|
71
|
+
private _computeConnectedAxis;
|
|
72
|
+
private _setVec3;
|
|
73
|
+
private _applyLimits;
|
|
74
|
+
private _applyMotor;
|
|
75
|
+
protected _createJointData(): RAPIER.JointData;
|
|
76
|
+
}
|
|
77
|
+
export {};
|
|
78
|
+
//# sourceMappingURL=hinge-joint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hinge-joint.d.ts","sourceRoot":"","sources":["../src/hinge-joint.ts"],"names":[],"mappings":"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"}
|