dacha 0.18.0-alpha.8 → 0.18.0-alpha.9
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/build/contrib/components/rigid-body/index.d.ts +100 -14
- package/build/contrib/components/rigid-body/index.js +183 -22
- package/build/contrib/systems/animator/index.d.ts +3 -2
- package/build/contrib/systems/animator/index.js +6 -3
- package/build/contrib/systems/behavior-system/system.d.ts +4 -2
- package/build/contrib/systems/behavior-system/system.js +11 -3
- package/build/contrib/systems/behavior-system/types.d.ts +7 -10
- package/build/contrib/systems/character-controller/index.d.ts +4 -2
- package/build/contrib/systems/character-controller/index.js +22 -17
- package/build/contrib/systems/character-controller/one-way-validator.d.ts +15 -0
- package/build/contrib/systems/character-controller/one-way-validator.js +73 -0
- package/build/contrib/systems/game-stats-meter/index.d.ts +4 -3
- package/build/contrib/systems/game-stats-meter/index.js +11 -10
- package/build/contrib/systems/physics-system/consts.d.ts +11 -0
- package/build/contrib/systems/physics-system/consts.js +14 -0
- package/build/contrib/systems/physics-system/physics-system.d.ts +2 -2
- package/build/contrib/systems/physics-system/physics-system.js +18 -4
- package/build/contrib/systems/physics-system/subsystems/collision-detection/index.js +3 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/check-boxes-intersection.js +5 -3
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/utils.d.ts +1 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/utils.js +2 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-capsule/check-box-and-capsule-intersection.js +4 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/check-box-and-segment-intersection.js +4 -2
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/common/points.d.ts +2 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/common/points.js +16 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/index.js +2 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/tests/helpers.js +3 -14
- package/build/contrib/systems/physics-system/subsystems/collision-detection/shape-cast-checkers/tests/helpers.js +2 -7
- package/build/contrib/systems/physics-system/subsystems/collision-detection/tests/assertions.d.ts +1 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/tests/assertions.js +7 -0
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/contact-state-manager.d.ts +63 -0
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/contact-state-manager.js +170 -0
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/contact-utils.d.ts +5 -0
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/contact-utils.js +41 -0
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/impulse-utils.d.ts +16 -0
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/impulse-utils.js +77 -0
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.d.ts +53 -4
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.js +334 -116
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/one-way-validator.d.ts +11 -0
- package/build/contrib/{utils → systems/physics-system/subsystems/constraint-solver}/one-way-validator.js +22 -25
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/sleep-support-tracker.d.ts +13 -0
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/sleep-support-tracker.js +42 -0
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/tests/helpers.d.ts +4 -0
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/tests/helpers.js +20 -0
- package/build/contrib/systems/physics-system/subsystems/physics/index.d.ts +15 -4
- package/build/contrib/systems/physics-system/subsystems/physics/index.js +131 -53
- package/build/contrib/systems/physics-system/subsystems/physics/mass-properties.d.ts +2 -0
- package/build/contrib/systems/physics-system/subsystems/physics/mass-properties.js +55 -0
- package/build/contrib/systems/physics-system/tests/helpers.d.ts +5 -2
- package/build/contrib/systems/physics-system/tests/helpers.js +11 -2
- package/build/contrib/systems/physics-system/types.d.ts +6 -0
- package/build/contrib/systems/renderer/filters/index.d.ts +1 -1
- package/build/contrib/systems/renderer/filters/index.js +1 -1
- package/build/contrib/systems/renderer/material/index.d.ts +2 -1
- package/build/contrib/systems/renderer/material/index.js +1 -1
- package/build/contrib/systems/renderer/renderer.d.ts +2 -2
- package/build/contrib/systems/renderer/renderer.js +3 -4
- package/build/contrib/systems/renderer/types.d.ts +0 -3
- package/build/engine/engine.js +4 -1
- package/build/engine/game-loop.d.ts +3 -1
- package/build/engine/game-loop.js +8 -5
- package/build/engine/scene/scene-manager.d.ts +4 -1
- package/build/engine/scene/scene-manager.js +5 -1
- package/build/engine/system/index.d.ts +1 -1
- package/build/engine/system/system.d.ts +10 -11
- package/build/engine/system/system.js +5 -2
- package/build/engine/time.d.ts +54 -0
- package/build/engine/time.js +77 -0
- package/build/index.d.ts +2 -1
- package/package.json +1 -1
- package/build/contrib/utils/one-way-validator.d.ts +0 -12
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
import { Component } from '../../../engine/component';
|
|
2
|
-
import { Vector2 } from '../../../engine/math-lib';
|
|
2
|
+
import { Vector2, type Point } from '../../../engine/math-lib';
|
|
3
3
|
export type RigidBodyType = 'dynamic' | 'static' | 'kinematic';
|
|
4
4
|
export interface RigidBodyConfig {
|
|
5
5
|
type: RigidBodyType;
|
|
6
6
|
mass?: number;
|
|
7
7
|
gravityScale?: number;
|
|
8
8
|
linearDamping?: number;
|
|
9
|
+
angularDamping?: number;
|
|
10
|
+
lockRotation?: boolean;
|
|
11
|
+
autoSleep?: boolean;
|
|
12
|
+
restitution?: number;
|
|
13
|
+
friction?: number;
|
|
9
14
|
disabled: boolean;
|
|
10
15
|
oneWay: boolean;
|
|
11
16
|
oneWayNormalX?: number;
|
|
12
17
|
oneWayNormalY?: number;
|
|
13
18
|
}
|
|
19
|
+
interface PointForce {
|
|
20
|
+
force: Vector2;
|
|
21
|
+
position: Point;
|
|
22
|
+
}
|
|
23
|
+
interface PointImpulse {
|
|
24
|
+
impulse: Vector2;
|
|
25
|
+
position: Point;
|
|
26
|
+
}
|
|
14
27
|
/**
|
|
15
28
|
* RigidBody component for defining rigid body physics.
|
|
16
29
|
*
|
|
17
|
-
* Defines the physics properties for an actor.
|
|
18
|
-
*
|
|
30
|
+
* Defines the physics properties for an actor. Dynamic bodies react to forces,
|
|
31
|
+
* impulses, gravity, collisions, and rotation. Static and kinematic bodies can
|
|
32
|
+
* participate in collisions but are not moved by solver impulses.
|
|
19
33
|
*
|
|
20
34
|
* @example
|
|
21
35
|
* ```typescript
|
|
@@ -40,24 +54,54 @@ export interface RigidBodyConfig {
|
|
|
40
54
|
export declare class RigidBody extends Component {
|
|
41
55
|
private _mass;
|
|
42
56
|
private _inverseMass;
|
|
57
|
+
private _inertia;
|
|
58
|
+
private _inverseInertia;
|
|
59
|
+
private _restitution;
|
|
60
|
+
private _friction;
|
|
43
61
|
/** @internal Pending one-step kinematic movement target */
|
|
44
62
|
_movementTarget: Vector2 | null;
|
|
63
|
+
/** @internal Linear velocity from the start of the current physics step */
|
|
64
|
+
_prevLinearVelocity: Vector2;
|
|
65
|
+
/** @internal Angular velocity from the start of the current physics step */
|
|
66
|
+
_prevAngularVelocity: number;
|
|
67
|
+
/** @internal Temporary solver velocity used for contact separation */
|
|
68
|
+
_biasLinearVelocity: Vector2;
|
|
69
|
+
/** @internal Temporary solver angular velocity used for contact separation */
|
|
70
|
+
_biasAngularVelocity: number;
|
|
71
|
+
/** @internal Time this body has stayed below automatic sleep thresholds */
|
|
72
|
+
_sleepTime: number;
|
|
45
73
|
/** Body type that defines how the rigid body participates in simulation */
|
|
46
74
|
readonly type: RigidBodyType;
|
|
47
|
-
/** Gravity
|
|
75
|
+
/** Gravity multiplier. `0` ignores gravity, `1` uses normal world gravity. */
|
|
48
76
|
gravityScale: number;
|
|
49
|
-
/** Linear damping
|
|
77
|
+
/** Linear damping used to slow down movement over time */
|
|
50
78
|
linearDamping: number;
|
|
51
|
-
/**
|
|
79
|
+
/** Angular damping used to slow down rotation over time */
|
|
80
|
+
angularDamping: number;
|
|
81
|
+
/** Current linear velocity in world units per second */
|
|
52
82
|
linearVelocity: Vector2;
|
|
83
|
+
/** Current angular velocity of the rigid body in radians per second */
|
|
84
|
+
angularVelocity: number;
|
|
85
|
+
/** Whether dynamic rotation is locked. Locked bodies do not spin from torque or contacts. */
|
|
86
|
+
lockRotation: boolean;
|
|
53
87
|
/** Whether rigid body simulation is disabled */
|
|
54
88
|
disabled: boolean;
|
|
55
89
|
/** Whether rigid body is sleeping */
|
|
56
90
|
sleeping: boolean;
|
|
57
|
-
/**
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
|
|
91
|
+
/** Whether this body may be put to sleep automatically when settled */
|
|
92
|
+
autoSleep: boolean;
|
|
93
|
+
/** @internal Force applied at the rigid body center */
|
|
94
|
+
_centralForce: Vector2;
|
|
95
|
+
/** @internal Impulse applied at the rigid body center */
|
|
96
|
+
_centralImpulse: Vector2;
|
|
97
|
+
/** @internal Forces applied at world-space positions */
|
|
98
|
+
_pointForces: PointForce[];
|
|
99
|
+
/** @internal Impulses applied at world-space positions */
|
|
100
|
+
_pointImpulses: PointImpulse[];
|
|
101
|
+
/** @internal Torque applied to the rigid body */
|
|
102
|
+
_torque: number;
|
|
103
|
+
/** @internal Angular impulse applied to the rigid body */
|
|
104
|
+
_angularImpulse: number;
|
|
61
105
|
/** Whether contacts should only be resolved from one side */
|
|
62
106
|
oneWay: boolean;
|
|
63
107
|
/** Local-space normal that points toward the blocking side */
|
|
@@ -80,18 +124,59 @@ export declare class RigidBody extends Component {
|
|
|
80
124
|
* Bodies with zero or negative mass return `0`.
|
|
81
125
|
*/
|
|
82
126
|
get inverseMass(): number;
|
|
127
|
+
get inertia(): number;
|
|
128
|
+
/**
|
|
129
|
+
* Moment of inertia used by dynamic bodies.
|
|
130
|
+
*
|
|
131
|
+
* Inertia is the rotational equivalent of mass: higher values make the body
|
|
132
|
+
* harder to spin. It is automatically computed from the collider shape, mass,
|
|
133
|
+
* and collider offset every physics step, so user code usually should only
|
|
134
|
+
* read this value.
|
|
135
|
+
*/
|
|
136
|
+
set inertia(value: number);
|
|
137
|
+
/**
|
|
138
|
+
* Returns the inverse moment of inertia.
|
|
139
|
+
*
|
|
140
|
+
* This is the solver-friendly form of inertia. Static bodies, kinematic
|
|
141
|
+
* bodies, locked rotation, or non-positive inertia return `0`.
|
|
142
|
+
*/
|
|
143
|
+
get inverseInertia(): number;
|
|
144
|
+
/** Bounciness used by contact resolution. `0` does not bounce, `1` keeps full bounce speed. */
|
|
145
|
+
get restitution(): number;
|
|
146
|
+
set restitution(value: number);
|
|
147
|
+
/** Surface friction used by contact resolution. Higher values reduce sliding more strongly. */
|
|
148
|
+
get friction(): number;
|
|
149
|
+
set friction(value: number);
|
|
83
150
|
/**
|
|
84
151
|
* Adds a continuous force to a dynamic body for the next physics step.
|
|
85
152
|
*
|
|
86
|
-
* Affects only active dynamic bodies.
|
|
153
|
+
* Affects only active dynamic bodies. When `position` is provided, it is a
|
|
154
|
+
* world-space point where the force is applied; off-center forces can also
|
|
155
|
+
* rotate the body.
|
|
87
156
|
*/
|
|
88
|
-
applyForce(force: Vector2): void;
|
|
157
|
+
applyForce(force: Vector2, position?: Point): void;
|
|
89
158
|
/**
|
|
90
159
|
* Adds an instantaneous impulse to a dynamic body for the next physics step.
|
|
91
160
|
*
|
|
92
|
-
* Affects only active dynamic bodies.
|
|
161
|
+
* Affects only active dynamic bodies. An impulse is a one-step velocity kick.
|
|
162
|
+
* When `position` is provided, it is a world-space point where the impulse is
|
|
163
|
+
* applied; off-center impulses can also rotate the body.
|
|
164
|
+
*/
|
|
165
|
+
applyImpulse(impulse: Vector2, position?: Point): void;
|
|
166
|
+
/**
|
|
167
|
+
* Adds a continuous torque to a dynamic body for the next physics step.
|
|
168
|
+
*
|
|
169
|
+
* Torque is rotational force: it changes angular velocity over time. Affects
|
|
170
|
+
* only active dynamic bodies with unlocked rotation.
|
|
171
|
+
*/
|
|
172
|
+
applyTorque(torque: number): void;
|
|
173
|
+
/**
|
|
174
|
+
* Adds an instantaneous angular impulse to a dynamic body for the next physics step.
|
|
175
|
+
*
|
|
176
|
+
* Angular impulse is an immediate rotational kick. Affects only active dynamic
|
|
177
|
+
* bodies with unlocked rotation.
|
|
93
178
|
*/
|
|
94
|
-
|
|
179
|
+
applyAngularImpulse(impulse: number): void;
|
|
95
180
|
/**
|
|
96
181
|
* Marks the rigid body as awake so it can be simulated.
|
|
97
182
|
*/
|
|
@@ -112,3 +197,4 @@ export declare class RigidBody extends Component {
|
|
|
112
197
|
*/
|
|
113
198
|
movePosition(position: Vector2): void;
|
|
114
199
|
}
|
|
200
|
+
export {};
|
|
@@ -3,8 +3,9 @@ import { Vector2 } from '../../../engine/math-lib';
|
|
|
3
3
|
/**
|
|
4
4
|
* RigidBody component for defining rigid body physics.
|
|
5
5
|
*
|
|
6
|
-
* Defines the physics properties for an actor.
|
|
7
|
-
*
|
|
6
|
+
* Defines the physics properties for an actor. Dynamic bodies react to forces,
|
|
7
|
+
* impulses, gravity, collisions, and rotation. Static and kinematic bodies can
|
|
8
|
+
* participate in collisions but are not moved by solver impulses.
|
|
8
9
|
*
|
|
9
10
|
* @example
|
|
10
11
|
* ```typescript
|
|
@@ -29,24 +30,54 @@ import { Vector2 } from '../../../engine/math-lib';
|
|
|
29
30
|
export class RigidBody extends Component {
|
|
30
31
|
_mass;
|
|
31
32
|
_inverseMass;
|
|
33
|
+
_inertia;
|
|
34
|
+
_inverseInertia;
|
|
35
|
+
_restitution;
|
|
36
|
+
_friction;
|
|
32
37
|
/** @internal Pending one-step kinematic movement target */
|
|
33
38
|
_movementTarget;
|
|
39
|
+
/** @internal Linear velocity from the start of the current physics step */
|
|
40
|
+
_prevLinearVelocity;
|
|
41
|
+
/** @internal Angular velocity from the start of the current physics step */
|
|
42
|
+
_prevAngularVelocity;
|
|
43
|
+
/** @internal Temporary solver velocity used for contact separation */
|
|
44
|
+
_biasLinearVelocity;
|
|
45
|
+
/** @internal Temporary solver angular velocity used for contact separation */
|
|
46
|
+
_biasAngularVelocity;
|
|
47
|
+
/** @internal Time this body has stayed below automatic sleep thresholds */
|
|
48
|
+
_sleepTime;
|
|
34
49
|
/** Body type that defines how the rigid body participates in simulation */
|
|
35
50
|
type;
|
|
36
|
-
/** Gravity
|
|
51
|
+
/** Gravity multiplier. `0` ignores gravity, `1` uses normal world gravity. */
|
|
37
52
|
gravityScale;
|
|
38
|
-
/** Linear damping
|
|
53
|
+
/** Linear damping used to slow down movement over time */
|
|
39
54
|
linearDamping;
|
|
40
|
-
/**
|
|
55
|
+
/** Angular damping used to slow down rotation over time */
|
|
56
|
+
angularDamping;
|
|
57
|
+
/** Current linear velocity in world units per second */
|
|
41
58
|
linearVelocity;
|
|
59
|
+
/** Current angular velocity of the rigid body in radians per second */
|
|
60
|
+
angularVelocity;
|
|
61
|
+
/** Whether dynamic rotation is locked. Locked bodies do not spin from torque or contacts. */
|
|
62
|
+
lockRotation;
|
|
42
63
|
/** Whether rigid body simulation is disabled */
|
|
43
64
|
disabled;
|
|
44
65
|
/** Whether rigid body is sleeping */
|
|
45
66
|
sleeping;
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
|
|
67
|
+
/** Whether this body may be put to sleep automatically when settled */
|
|
68
|
+
autoSleep;
|
|
69
|
+
/** @internal Force applied at the rigid body center */
|
|
70
|
+
_centralForce;
|
|
71
|
+
/** @internal Impulse applied at the rigid body center */
|
|
72
|
+
_centralImpulse;
|
|
73
|
+
/** @internal Forces applied at world-space positions */
|
|
74
|
+
_pointForces;
|
|
75
|
+
/** @internal Impulses applied at world-space positions */
|
|
76
|
+
_pointImpulses;
|
|
77
|
+
/** @internal Torque applied to the rigid body */
|
|
78
|
+
_torque;
|
|
79
|
+
/** @internal Angular impulse applied to the rigid body */
|
|
80
|
+
_angularImpulse;
|
|
50
81
|
/** Whether contacts should only be resolved from one side */
|
|
51
82
|
oneWay;
|
|
52
83
|
/** Local-space normal that points toward the blocking side */
|
|
@@ -59,16 +90,36 @@ export class RigidBody extends Component {
|
|
|
59
90
|
super();
|
|
60
91
|
this._mass = 0;
|
|
61
92
|
this._inverseMass = 0;
|
|
93
|
+
this._inertia = 0;
|
|
94
|
+
this._inverseInertia = 0;
|
|
95
|
+
this._restitution = 0;
|
|
96
|
+
this._friction = 0;
|
|
62
97
|
this._movementTarget = null;
|
|
98
|
+
this._prevLinearVelocity = new Vector2(0, 0);
|
|
99
|
+
this._prevAngularVelocity = 0;
|
|
100
|
+
this._biasLinearVelocity = new Vector2(0, 0);
|
|
101
|
+
this._biasAngularVelocity = 0;
|
|
102
|
+
this._sleepTime = 0;
|
|
63
103
|
this.type = config.type;
|
|
64
|
-
this.mass = config.mass ?? 0;
|
|
65
|
-
this.gravityScale =
|
|
104
|
+
this.mass = config.mass ?? (this.type === 'dynamic' ? 1 : 0);
|
|
105
|
+
this.gravityScale =
|
|
106
|
+
config.gravityScale ?? (this.type === 'dynamic' ? 1 : 0);
|
|
66
107
|
this.linearDamping = config.linearDamping ?? 0;
|
|
67
|
-
this.
|
|
108
|
+
this.angularDamping = config.angularDamping ?? 0;
|
|
109
|
+
this.restitution = config.restitution ?? 0;
|
|
110
|
+
this.friction = config.friction ?? 0.6;
|
|
111
|
+
this.lockRotation = config.lockRotation ?? false;
|
|
112
|
+
this.autoSleep = config.autoSleep ?? true;
|
|
68
113
|
this.disabled = config.disabled;
|
|
114
|
+
this.linearVelocity = new Vector2(0, 0);
|
|
115
|
+
this.angularVelocity = 0;
|
|
69
116
|
this.sleeping = false;
|
|
70
|
-
this.
|
|
71
|
-
this.
|
|
117
|
+
this._centralForce = new Vector2(0, 0);
|
|
118
|
+
this._centralImpulse = new Vector2(0, 0);
|
|
119
|
+
this._pointForces = [];
|
|
120
|
+
this._pointImpulses = [];
|
|
121
|
+
this._torque = 0;
|
|
122
|
+
this._angularImpulse = 0;
|
|
72
123
|
this.oneWay = config.oneWay ?? false;
|
|
73
124
|
if (this.oneWay) {
|
|
74
125
|
this.oneWayNormal = new Vector2(config.oneWayNormalX ?? 0, config.oneWayNormalY ?? 0).normalize();
|
|
@@ -95,50 +146,160 @@ export class RigidBody extends Component {
|
|
|
95
146
|
* Bodies with zero or negative mass return `0`.
|
|
96
147
|
*/
|
|
97
148
|
get inverseMass() {
|
|
149
|
+
if (this.type === 'static' || this.type === 'kinematic' || this.sleeping) {
|
|
150
|
+
return 0;
|
|
151
|
+
}
|
|
98
152
|
return this._inverseMass;
|
|
99
153
|
}
|
|
154
|
+
get inertia() {
|
|
155
|
+
return this._inertia;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Moment of inertia used by dynamic bodies.
|
|
159
|
+
*
|
|
160
|
+
* Inertia is the rotational equivalent of mass: higher values make the body
|
|
161
|
+
* harder to spin. It is automatically computed from the collider shape, mass,
|
|
162
|
+
* and collider offset every physics step, so user code usually should only
|
|
163
|
+
* read this value.
|
|
164
|
+
*/
|
|
165
|
+
set inertia(value) {
|
|
166
|
+
this._inertia = value;
|
|
167
|
+
this._inverseInertia = value > 0 ? 1 / value : 0;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Returns the inverse moment of inertia.
|
|
171
|
+
*
|
|
172
|
+
* This is the solver-friendly form of inertia. Static bodies, kinematic
|
|
173
|
+
* bodies, locked rotation, or non-positive inertia return `0`.
|
|
174
|
+
*/
|
|
175
|
+
get inverseInertia() {
|
|
176
|
+
if (this.type === 'static' ||
|
|
177
|
+
this.type === 'kinematic' ||
|
|
178
|
+
this.sleeping ||
|
|
179
|
+
this.lockRotation) {
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
return this._inverseInertia;
|
|
183
|
+
}
|
|
184
|
+
/** Bounciness used by contact resolution. `0` does not bounce, `1` keeps full bounce speed. */
|
|
185
|
+
get restitution() {
|
|
186
|
+
return this._restitution;
|
|
187
|
+
}
|
|
188
|
+
set restitution(value) {
|
|
189
|
+
this._restitution = Math.max(0, Math.min(value, 1));
|
|
190
|
+
}
|
|
191
|
+
/** Surface friction used by contact resolution. Higher values reduce sliding more strongly. */
|
|
192
|
+
get friction() {
|
|
193
|
+
return this._friction;
|
|
194
|
+
}
|
|
195
|
+
set friction(value) {
|
|
196
|
+
this._friction = Math.max(0, value);
|
|
197
|
+
}
|
|
100
198
|
/**
|
|
101
199
|
* Adds a continuous force to a dynamic body for the next physics step.
|
|
102
200
|
*
|
|
103
|
-
* Affects only active dynamic bodies.
|
|
201
|
+
* Affects only active dynamic bodies. When `position` is provided, it is a
|
|
202
|
+
* world-space point where the force is applied; off-center forces can also
|
|
203
|
+
* rotate the body.
|
|
104
204
|
*/
|
|
105
|
-
applyForce(force) {
|
|
205
|
+
applyForce(force, position) {
|
|
106
206
|
if (this.disabled || this.type !== 'dynamic') {
|
|
107
207
|
return;
|
|
108
208
|
}
|
|
109
209
|
this.wakeUp();
|
|
110
|
-
|
|
210
|
+
if (!position) {
|
|
211
|
+
this._centralForce.add(force);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
this._pointForces.push({
|
|
215
|
+
force: force.clone(),
|
|
216
|
+
position: { x: position.x, y: position.y },
|
|
217
|
+
});
|
|
111
218
|
}
|
|
112
219
|
/**
|
|
113
220
|
* Adds an instantaneous impulse to a dynamic body for the next physics step.
|
|
114
221
|
*
|
|
115
|
-
* Affects only active dynamic bodies.
|
|
222
|
+
* Affects only active dynamic bodies. An impulse is a one-step velocity kick.
|
|
223
|
+
* When `position` is provided, it is a world-space point where the impulse is
|
|
224
|
+
* applied; off-center impulses can also rotate the body.
|
|
116
225
|
*/
|
|
117
|
-
applyImpulse(impulse) {
|
|
226
|
+
applyImpulse(impulse, position) {
|
|
118
227
|
if (this.disabled || this.type !== 'dynamic') {
|
|
119
228
|
return;
|
|
120
229
|
}
|
|
121
230
|
this.wakeUp();
|
|
122
|
-
|
|
231
|
+
if (!position) {
|
|
232
|
+
this._centralImpulse.add(impulse);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
this._pointImpulses.push({
|
|
236
|
+
impulse: impulse.clone(),
|
|
237
|
+
position: { x: position.x, y: position.y },
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Adds a continuous torque to a dynamic body for the next physics step.
|
|
242
|
+
*
|
|
243
|
+
* Torque is rotational force: it changes angular velocity over time. Affects
|
|
244
|
+
* only active dynamic bodies with unlocked rotation.
|
|
245
|
+
*/
|
|
246
|
+
applyTorque(torque) {
|
|
247
|
+
if (this.disabled || this.type !== 'dynamic' || this.lockRotation) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
this.wakeUp();
|
|
251
|
+
this._torque += torque;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Adds an instantaneous angular impulse to a dynamic body for the next physics step.
|
|
255
|
+
*
|
|
256
|
+
* Angular impulse is an immediate rotational kick. Affects only active dynamic
|
|
257
|
+
* bodies with unlocked rotation.
|
|
258
|
+
*/
|
|
259
|
+
applyAngularImpulse(impulse) {
|
|
260
|
+
if (this.disabled || this.type !== 'dynamic' || this.lockRotation) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
this.wakeUp();
|
|
264
|
+
this._angularImpulse += impulse;
|
|
123
265
|
}
|
|
124
266
|
/**
|
|
125
267
|
* Marks the rigid body as awake so it can be simulated.
|
|
126
268
|
*/
|
|
127
269
|
wakeUp() {
|
|
270
|
+
if (this.disabled || this.type !== 'dynamic') {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
128
273
|
this.sleeping = false;
|
|
274
|
+
this._sleepTime = 0;
|
|
129
275
|
}
|
|
130
276
|
/**
|
|
131
277
|
* Marks the rigid body as sleeping so dynamic integration can skip it.
|
|
132
278
|
*/
|
|
133
279
|
sleep() {
|
|
280
|
+
if (this.disabled || this.type !== 'dynamic') {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
134
283
|
this.sleeping = true;
|
|
284
|
+
this._sleepTime = 0;
|
|
285
|
+
this._prevLinearVelocity.multiplyNumber(0);
|
|
286
|
+
this._prevAngularVelocity = 0;
|
|
287
|
+
this.linearVelocity.multiplyNumber(0);
|
|
288
|
+
this.angularVelocity = 0;
|
|
289
|
+
this._biasLinearVelocity.multiplyNumber(0);
|
|
290
|
+
this._biasAngularVelocity = 0;
|
|
291
|
+
this.clearForces();
|
|
135
292
|
}
|
|
136
293
|
/**
|
|
137
294
|
* Clears all accumulated force and impulse values.
|
|
138
295
|
*/
|
|
139
296
|
clearForces() {
|
|
140
|
-
this.
|
|
141
|
-
this.
|
|
297
|
+
this._centralForce.multiplyNumber(0);
|
|
298
|
+
this._centralImpulse.multiplyNumber(0);
|
|
299
|
+
this._pointForces.length = 0;
|
|
300
|
+
this._pointImpulses.length = 0;
|
|
301
|
+
this._torque = 0;
|
|
302
|
+
this._angularImpulse = 0;
|
|
142
303
|
}
|
|
143
304
|
/**
|
|
144
305
|
* Moves a kinematic body to a target position on the next physics step.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SceneSystem } from '../../../engine/system';
|
|
2
|
-
import type {
|
|
2
|
+
import type { SceneSystemOptions } from '../../../engine/system';
|
|
3
3
|
/**
|
|
4
4
|
* Animator system that manages the animation of actors with {@link Animatable} components
|
|
5
5
|
* using the state machine approach
|
|
@@ -10,6 +10,7 @@ import type { UpdateOptions, SceneSystemOptions } from '../../../engine/system';
|
|
|
10
10
|
*/
|
|
11
11
|
export declare class Animator extends SceneSystem {
|
|
12
12
|
private actorQuery;
|
|
13
|
+
private time;
|
|
13
14
|
private substatePickers;
|
|
14
15
|
private actorConditions;
|
|
15
16
|
constructor(options: SceneSystemOptions);
|
|
@@ -18,5 +19,5 @@ export declare class Animator extends SceneSystem {
|
|
|
18
19
|
private setUpConditionControllers;
|
|
19
20
|
private updateFrame;
|
|
20
21
|
private pickSubstate;
|
|
21
|
-
update(
|
|
22
|
+
update(): void;
|
|
22
23
|
}
|
|
@@ -5,7 +5,8 @@ import { RemoveActor } from '../../../engine/events';
|
|
|
5
5
|
import { conditionControllers } from './condition-controllers';
|
|
6
6
|
import { substatePickers } from './substate-pickers';
|
|
7
7
|
import { setValue } from './utils';
|
|
8
|
-
|
|
8
|
+
// Seconds per animation frame at speed 1.
|
|
9
|
+
const FRAME_RATE = 0.1;
|
|
9
10
|
/**
|
|
10
11
|
* Animator system that manages the animation of actors with {@link Animatable} components
|
|
11
12
|
* using the state machine approach
|
|
@@ -16,10 +17,12 @@ const FRAME_RATE = 100;
|
|
|
16
17
|
*/
|
|
17
18
|
export class Animator extends SceneSystem {
|
|
18
19
|
actorQuery;
|
|
20
|
+
time;
|
|
19
21
|
substatePickers;
|
|
20
22
|
actorConditions;
|
|
21
23
|
constructor(options) {
|
|
22
24
|
super();
|
|
25
|
+
this.time = options.time;
|
|
23
26
|
this.actorQuery = new ActorQuery({
|
|
24
27
|
scene: options.scene,
|
|
25
28
|
filter: [Animatable],
|
|
@@ -64,8 +67,8 @@ export class Animator extends SceneSystem {
|
|
|
64
67
|
const substatePicker = this.substatePickers[state.pickMode];
|
|
65
68
|
return substatePicker.getSubstate(actor, state.substates, state.pickProps);
|
|
66
69
|
}
|
|
67
|
-
update(
|
|
68
|
-
const { deltaTime } =
|
|
70
|
+
update() {
|
|
71
|
+
const { deltaTime } = this.time;
|
|
69
72
|
this.actorQuery.getActors().forEach((actor) => {
|
|
70
73
|
const animatable = actor.getComponent(Animatable);
|
|
71
74
|
if (animatable.currentState === void 0) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SceneSystem } from '../../../engine/system';
|
|
2
|
-
import type { SceneSystemOptions
|
|
2
|
+
import type { SceneSystemOptions } from '../../../engine/system';
|
|
3
3
|
/**
|
|
4
4
|
* Behavior system that manages custom behavior execution for actors
|
|
5
5
|
* with {@link Behaviors} components
|
|
@@ -15,6 +15,7 @@ export declare class BehaviorSystem extends SceneSystem {
|
|
|
15
15
|
private behaviors;
|
|
16
16
|
private world;
|
|
17
17
|
private scene;
|
|
18
|
+
private time;
|
|
18
19
|
private activeBehaviors;
|
|
19
20
|
constructor(options: SceneSystemOptions);
|
|
20
21
|
onSceneEnter(): void;
|
|
@@ -22,5 +23,6 @@ export declare class BehaviorSystem extends SceneSystem {
|
|
|
22
23
|
private handleActorAdd;
|
|
23
24
|
private handleActorRemove;
|
|
24
25
|
private setUpBehavior;
|
|
25
|
-
update(
|
|
26
|
+
update(): void;
|
|
27
|
+
fixedUpdate(): void;
|
|
26
28
|
}
|
|
@@ -17,12 +17,14 @@ export class BehaviorSystem extends SceneSystem {
|
|
|
17
17
|
behaviors;
|
|
18
18
|
world;
|
|
19
19
|
scene;
|
|
20
|
+
time;
|
|
20
21
|
activeBehaviors;
|
|
21
22
|
constructor(options) {
|
|
22
23
|
super();
|
|
23
|
-
const { actorSpawner, world, scene, globalOptions, resources = [], } = options;
|
|
24
|
+
const { actorSpawner, world, scene, globalOptions, time, resources = [], } = options;
|
|
24
25
|
this.world = world;
|
|
25
26
|
this.scene = scene;
|
|
27
|
+
this.time = time;
|
|
26
28
|
this.behaviorQuery = new ActorQuery({
|
|
27
29
|
scene,
|
|
28
30
|
filter: [Behaviors],
|
|
@@ -79,14 +81,20 @@ export class BehaviorSystem extends SceneSystem {
|
|
|
79
81
|
world: this.world,
|
|
80
82
|
scene: this.scene,
|
|
81
83
|
globalOptions: this.globalOptions,
|
|
84
|
+
time: this.time,
|
|
82
85
|
};
|
|
83
86
|
const BehaviorClass = this.behaviors[config.name];
|
|
84
87
|
return new BehaviorClass(options);
|
|
85
88
|
});
|
|
86
89
|
}
|
|
87
|
-
update(
|
|
90
|
+
update() {
|
|
88
91
|
this.behaviorQuery.getActors().forEach((actor) => {
|
|
89
|
-
this.activeBehaviors[actor.id].forEach((behavior) => behavior.update?.(
|
|
92
|
+
this.activeBehaviors[actor.id].forEach((behavior) => behavior.update?.());
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
fixedUpdate() {
|
|
96
|
+
this.behaviorQuery.getActors().forEach((actor) => {
|
|
97
|
+
this.activeBehaviors[actor.id].forEach((behavior) => behavior.fixedUpdate?.());
|
|
90
98
|
});
|
|
91
99
|
}
|
|
92
100
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Actor, ActorSpawner } from '../../../engine/actor';
|
|
2
2
|
import type { World } from '../../../engine/world';
|
|
3
3
|
import type { Scene } from '../../../engine/scene';
|
|
4
|
+
import type { Time } from '../../../engine/time';
|
|
4
5
|
import type { Constructor } from '../../../types/utils';
|
|
5
6
|
/**
|
|
6
7
|
* Options for the behavior
|
|
@@ -16,13 +17,8 @@ export interface BehaviorOptions {
|
|
|
16
17
|
actorSpawner: ActorSpawner;
|
|
17
18
|
/** Global game options */
|
|
18
19
|
globalOptions: Record<string, unknown>;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
* Options for the update method
|
|
22
|
-
*/
|
|
23
|
-
interface UpdateOptions {
|
|
24
|
-
/** Time elapsed since the last update in milliseconds */
|
|
25
|
-
deltaTime: number;
|
|
20
|
+
/** Shared timing state */
|
|
21
|
+
time: Time;
|
|
26
22
|
}
|
|
27
23
|
/**
|
|
28
24
|
* Base class for all behaviors
|
|
@@ -35,8 +31,10 @@ export declare abstract class Behavior {
|
|
|
35
31
|
static behaviorName: string;
|
|
36
32
|
/** Destroy the behavior */
|
|
37
33
|
destroy?(): void;
|
|
38
|
-
/** Update the behavior */
|
|
39
|
-
update?(
|
|
34
|
+
/** Update the behavior every frame with a variable timestep */
|
|
35
|
+
update?(): void;
|
|
36
|
+
/** Update the behavior with a fixed timestep, aligned with physics */
|
|
37
|
+
fixedUpdate?(): void;
|
|
40
38
|
}
|
|
41
39
|
/**
|
|
42
40
|
* Constructor for all behaviors
|
|
@@ -44,4 +42,3 @@ export declare abstract class Behavior {
|
|
|
44
42
|
export type BehaviorConstructor = Constructor<Behavior> & {
|
|
45
43
|
behaviorName: string;
|
|
46
44
|
};
|
|
47
|
-
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SceneSystem } from '../../../engine/system';
|
|
2
|
-
import type { SceneSystemOptions
|
|
2
|
+
import type { SceneSystemOptions } from '../../../engine/system';
|
|
3
3
|
/**
|
|
4
4
|
* Kinematic character controller system with sweep/slide collision movement.
|
|
5
5
|
*
|
|
@@ -13,9 +13,11 @@ import type { SceneSystemOptions, UpdateOptions } from '../../../engine/system';
|
|
|
13
13
|
export declare class CharacterController extends SceneSystem {
|
|
14
14
|
private actorQuery;
|
|
15
15
|
private world;
|
|
16
|
+
private time;
|
|
16
17
|
private oneWayValidator;
|
|
17
18
|
constructor(options: SceneSystemOptions);
|
|
18
19
|
onSceneDestroy(): void;
|
|
20
|
+
private handleRemoveActor;
|
|
19
21
|
private isBlockingHit;
|
|
20
22
|
private isWalkable;
|
|
21
23
|
private isRecoverableOverlap;
|
|
@@ -28,5 +30,5 @@ export declare class CharacterController extends SceneSystem {
|
|
|
28
30
|
private handleHit;
|
|
29
31
|
private move;
|
|
30
32
|
private updateGroundState;
|
|
31
|
-
fixedUpdate(
|
|
33
|
+
fixedUpdate(): void;
|
|
32
34
|
}
|