dacha 0.18.1 → 0.18.3

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.
@@ -8,7 +8,6 @@ export interface RigidBodyConfig {
8
8
  linearDamping?: number;
9
9
  angularDamping?: number;
10
10
  lockRotation?: boolean;
11
- autoSleep?: boolean;
12
11
  restitution?: number;
13
12
  friction?: number;
14
13
  disabled: boolean;
@@ -75,8 +74,6 @@ export declare class RigidBody extends Component {
75
74
  _biasLinearVelocity: Vector2;
76
75
  /** @internal Temporary solver angular velocity used for contact separation */
77
76
  _biasAngularVelocity: number;
78
- /** @internal Time this body has stayed below automatic sleep thresholds */
79
- _sleepTime: number;
80
77
  /** Body type that defines how the rigid body participates in simulation */
81
78
  readonly type: RigidBodyType;
82
79
  /** Gravity multiplier. `0` ignores gravity, `1` uses normal world gravity. */
@@ -93,10 +90,6 @@ export declare class RigidBody extends Component {
93
90
  lockRotation: boolean;
94
91
  /** Whether rigid body simulation is disabled */
95
92
  disabled: boolean;
96
- /** Whether rigid body is sleeping */
97
- sleeping: boolean;
98
- /** Whether this body may be put to sleep automatically when settled */
99
- autoSleep: boolean;
100
93
  /** @internal Force applied at the rigid body center */
101
94
  _centralForce: Vector2;
102
95
  /** @internal Impulse applied at the rigid body center */
@@ -185,14 +178,6 @@ export declare class RigidBody extends Component {
185
178
  * bodies with unlocked rotation.
186
179
  */
187
180
  applyAngularImpulse(impulse: number): void;
188
- /**
189
- * Marks the rigid body as awake so it can be simulated.
190
- */
191
- wakeUp(): void;
192
- /**
193
- * Marks the rigid body as sleeping so dynamic integration can skip it.
194
- */
195
- sleep(): void;
196
181
  /**
197
182
  * Clears all accumulated force and impulse values.
198
183
  */
@@ -51,8 +51,6 @@ export class RigidBody extends Component {
51
51
  _biasLinearVelocity;
52
52
  /** @internal Temporary solver angular velocity used for contact separation */
53
53
  _biasAngularVelocity;
54
- /** @internal Time this body has stayed below automatic sleep thresholds */
55
- _sleepTime;
56
54
  /** Body type that defines how the rigid body participates in simulation */
57
55
  type;
58
56
  /** Gravity multiplier. `0` ignores gravity, `1` uses normal world gravity. */
@@ -69,10 +67,6 @@ export class RigidBody extends Component {
69
67
  lockRotation;
70
68
  /** Whether rigid body simulation is disabled */
71
69
  disabled;
72
- /** Whether rigid body is sleeping */
73
- sleeping;
74
- /** Whether this body may be put to sleep automatically when settled */
75
- autoSleep;
76
70
  /** @internal Force applied at the rigid body center */
77
71
  _centralForce;
78
72
  /** @internal Impulse applied at the rigid body center */
@@ -106,7 +100,6 @@ export class RigidBody extends Component {
106
100
  this._prevAngularVelocity = 0;
107
101
  this._biasLinearVelocity = new Vector2(0, 0);
108
102
  this._biasAngularVelocity = 0;
109
- this._sleepTime = 0;
110
103
  this.type = config.type;
111
104
  this.mass = config.mass ?? (this.type === 'dynamic' ? 1 : 0);
112
105
  this.gravityScale =
@@ -116,11 +109,9 @@ export class RigidBody extends Component {
116
109
  this.restitution = config.restitution ?? 0;
117
110
  this.friction = config.friction ?? 0.6;
118
111
  this.lockRotation = config.lockRotation ?? false;
119
- this.autoSleep = config.autoSleep ?? true;
120
112
  this.disabled = config.disabled;
121
113
  this.linearVelocity = new Vector2(0, 0);
122
114
  this.angularVelocity = 0;
123
- this.sleeping = false;
124
115
  this._centralForce = new Vector2(0, 0);
125
116
  this._centralImpulse = new Vector2(0, 0);
126
117
  this._pointForces = [];
@@ -154,7 +145,7 @@ export class RigidBody extends Component {
154
145
  * Bodies with zero or negative mass return `0`.
155
146
  */
156
147
  get inverseMass() {
157
- if (this.type === 'static' || this.type === 'kinematic' || this.sleeping) {
148
+ if (this.type === 'static' || this.type === 'kinematic') {
158
149
  return 0;
159
150
  }
160
151
  return this._inverseMass;
@@ -183,7 +174,6 @@ export class RigidBody extends Component {
183
174
  get inverseInertia() {
184
175
  if (this.type === 'static' ||
185
176
  this.type === 'kinematic' ||
186
- this.sleeping ||
187
177
  this.lockRotation) {
188
178
  return 0;
189
179
  }
@@ -214,7 +204,6 @@ export class RigidBody extends Component {
214
204
  if (this.disabled || this.type !== 'dynamic') {
215
205
  return;
216
206
  }
217
- this.wakeUp();
218
207
  if (!position) {
219
208
  this._centralForce.add(force);
220
209
  return;
@@ -235,7 +224,6 @@ export class RigidBody extends Component {
235
224
  if (this.disabled || this.type !== 'dynamic') {
236
225
  return;
237
226
  }
238
- this.wakeUp();
239
227
  if (!position) {
240
228
  this._centralImpulse.add(impulse);
241
229
  return;
@@ -255,7 +243,6 @@ export class RigidBody extends Component {
255
243
  if (this.disabled || this.type !== 'dynamic' || this.lockRotation) {
256
244
  return;
257
245
  }
258
- this.wakeUp();
259
246
  this._torque += torque;
260
247
  }
261
248
  /**
@@ -268,36 +255,8 @@ export class RigidBody extends Component {
268
255
  if (this.disabled || this.type !== 'dynamic' || this.lockRotation) {
269
256
  return;
270
257
  }
271
- this.wakeUp();
272
258
  this._angularImpulse += impulse;
273
259
  }
274
- /**
275
- * Marks the rigid body as awake so it can be simulated.
276
- */
277
- wakeUp() {
278
- if (this.disabled || this.type !== 'dynamic') {
279
- return;
280
- }
281
- this.sleeping = false;
282
- this._sleepTime = 0;
283
- }
284
- /**
285
- * Marks the rigid body as sleeping so dynamic integration can skip it.
286
- */
287
- sleep() {
288
- if (this.disabled || this.type !== 'dynamic') {
289
- return;
290
- }
291
- this.sleeping = true;
292
- this._sleepTime = 0;
293
- this._prevLinearVelocity.multiplyNumber(0);
294
- this._prevAngularVelocity = 0;
295
- this.linearVelocity.multiplyNumber(0);
296
- this.angularVelocity = 0;
297
- this._biasLinearVelocity.multiplyNumber(0);
298
- this._biasAngularVelocity = 0;
299
- this.clearForces();
300
- }
301
260
  /**
302
261
  * Clears all accumulated force and impulse values.
303
262
  */
@@ -1,13 +1,7 @@
1
1
  export declare const DEFAULT_SOLVER_ITERATIONS = 8;
2
- export declare const DEFAULT_LINEAR_SLEEP_THRESHOLD = 1;
3
- export declare const DEFAULT_ANGULAR_SLEEP_THRESHOLD = 0.05;
4
- export declare const DEFAULT_SLEEP_TIME_THRESHOLD = 0.5;
5
2
  export declare const DEFAULT_MAX_BIAS_VELOCITY = 60;
6
3
  export declare const DEFAULT_CONTACT_MAX_ALLOWED_PENETRATION = 0.5;
7
4
  export declare const CONTACT_BIAS = 0.2;
8
- export declare const BIAS_ANGULAR_SLEEP_MULTIPLIER = 2;
9
5
  export declare const RESTITUTION_VELOCITY_THRESHOLD = 1;
10
- export declare const PENETRATION_SLEEP_MARGIN = 0.25;
11
- export declare const SUPPORT_MIN_GRAVITY_DOT = 0.5;
12
6
  export declare const DEFAULT_GRAVITY_X = 0;
13
7
  export declare const DEFAULT_GRAVITY_Y = 980;
@@ -1,17 +1,8 @@
1
1
  export const DEFAULT_SOLVER_ITERATIONS = 8;
2
- export const DEFAULT_LINEAR_SLEEP_THRESHOLD = 1;
3
- export const DEFAULT_ANGULAR_SLEEP_THRESHOLD = 0.05;
4
- export const DEFAULT_SLEEP_TIME_THRESHOLD = 0.5;
5
2
  export const DEFAULT_MAX_BIAS_VELOCITY = 60;
6
3
  export const DEFAULT_CONTACT_MAX_ALLOWED_PENETRATION = 0.5;
7
4
  export const CONTACT_BIAS = 0.2;
8
- export const BIAS_ANGULAR_SLEEP_MULTIPLIER = 2;
9
5
  export const RESTITUTION_VELOCITY_THRESHOLD = 1;
10
- // Kept above maxAllowedPenetration so a settled stack resting at the
11
- // allowed slop does not wake itself from its own steady-state penetration.
12
- export const PENETRATION_SLEEP_MARGIN = 0.25;
13
- // 0.5 treats surfaces up to ~60° from horizontal as holding a body up.
14
- export const SUPPORT_MIN_GRAVITY_DOT = 0.5;
15
6
  // Default gravity in world units (px/s²).
16
7
  export const DEFAULT_GRAVITY_X = 0;
17
8
  export const DEFAULT_GRAVITY_Y = 980;
@@ -22,16 +22,13 @@ export class PhysicsSystem extends SceneSystem {
22
22
  gravity;
23
23
  constructor(options) {
24
24
  super();
25
- const { gravityX = DEFAULT_GRAVITY_X, gravityY = DEFAULT_GRAVITY_Y, solverIterations, linearSleepThreshold, angularSleepThreshold, sleepTimeThreshold, maxAllowedPenetration, maxBiasVelocity, } = options;
25
+ const { gravityX = DEFAULT_GRAVITY_X, gravityY = DEFAULT_GRAVITY_Y, solverIterations, maxAllowedPenetration, maxBiasVelocity, } = options;
26
26
  this.gravity = new Vector2(gravityX, gravityY);
27
27
  this.world = options.world;
28
28
  this.physicsSubsystem = new PhysicsSubsystem({
29
29
  scene: options.scene,
30
30
  time: options.time,
31
31
  getGravity: () => this.gravity,
32
- linearSleepThreshold,
33
- angularSleepThreshold,
34
- sleepTimeThreshold,
35
32
  });
36
33
  this.collisionDetectionSubsystem = new CollisionDetectionSubsystem(options);
37
34
  this.collisionBroadcastSubsystem = new CollisionBroadcastSubsystem();
@@ -41,7 +38,6 @@ export class PhysicsSystem extends SceneSystem {
41
38
  solverIterations,
42
39
  maxAllowedPenetration,
43
40
  maxBiasVelocity,
44
- linearSleepThreshold,
45
41
  });
46
42
  this.physicsApi = new PhysicsAPI({
47
43
  raycast: (params) => this.collisionDetectionSubsystem.raycast(params),
@@ -79,7 +75,6 @@ export class PhysicsSystem extends SceneSystem {
79
75
  const contacts = this.collisionDetectionSubsystem.update();
80
76
  this.constraintSolver.update(contacts);
81
77
  this.physicsSubsystem.integrateDynamicPositions();
82
- this.physicsSubsystem.updateSleepTimers();
83
78
  this.collisionBroadcastSubsystem.update(contacts);
84
79
  this.physicsSubsystem.lateUpdate();
85
80
  }
@@ -52,8 +52,7 @@ export class ContactStateManager {
52
52
  pruneStaleStates() {
53
53
  let stateIndex = 0;
54
54
  for (const state of this.states) {
55
- if (state.version === this.version ||
56
- (state.bodyA.sleeping && state.bodyB.sleeping)) {
55
+ if (state.version === this.version) {
57
56
  this.states[stateIndex] = state;
58
57
  stateIndex += 1;
59
58
  continue;
@@ -7,27 +7,22 @@ interface ConstraintSolverOptions {
7
7
  solverIterations?: number;
8
8
  maxAllowedPenetration?: number;
9
9
  maxBiasVelocity?: number;
10
- linearSleepThreshold?: number;
11
10
  }
12
11
  export declare class ConstraintSolver {
13
12
  private oneWayValidator;
14
13
  private contactStateManager;
15
- private sleepSupportTracker;
16
14
  private time;
17
15
  private getGravity;
18
16
  private restitutionThreshold;
19
17
  private solverIterations;
20
18
  private maxAllowedPenetration;
21
19
  private maxBiasVelocity;
22
- private linearSleepThreshold;
23
- private penetrationSleepThreshold;
24
20
  private flippedNormal;
25
21
  private blockImpulse0;
26
22
  private blockImpulse1;
27
23
  constructor(options: ConstraintSolverOptions);
28
24
  private validateCollision;
29
25
  private validateOneWayContact;
30
- private validateSleepContact;
31
26
  private getPoint;
32
27
  private prepareContact;
33
28
  private prepareBlockSolver;
@@ -1,12 +1,10 @@
1
1
  import { MathOps, } from '../../../../../engine/math-lib';
2
2
  import { RigidBody } from '../../../../components/rigid-body';
3
3
  import { Transform } from '../../../../components/transform';
4
- import { DEFAULT_SOLVER_ITERATIONS, DEFAULT_CONTACT_MAX_ALLOWED_PENETRATION, CONTACT_BIAS, DEFAULT_MAX_BIAS_VELOCITY, RESTITUTION_VELOCITY_THRESHOLD, DEFAULT_LINEAR_SLEEP_THRESHOLD, PENETRATION_SLEEP_MARGIN, } from '../../consts';
4
+ import { DEFAULT_SOLVER_ITERATIONS, DEFAULT_CONTACT_MAX_ALLOWED_PENETRATION, CONTACT_BIAS, DEFAULT_MAX_BIAS_VELOCITY, RESTITUTION_VELOCITY_THRESHOLD, } from '../../consts';
5
5
  import { ContactStateManager, } from './contact-state-manager';
6
6
  import { OneWayValidator } from './one-way-validator';
7
7
  import { getContactFriction, getContactRestitution, getEffectiveMass, getNormalVelocity, getTangentVelocity, getPrevNormalVelocity, getBiasNormalVelocity, applyImpulse, applyBiasImpulse, } from './impulse-utils';
8
- import { shouldWakeSleepingContact } from './contact-utils';
9
- import { SleepSupportTracker } from './sleep-support-tracker';
10
8
  const BLOCK_SOLVER_MIN_DETERMINANT = 1e-8;
11
9
  const BLOCK_SOLVER_TOLERANCE = 1e-8;
12
10
  /**
@@ -21,22 +19,18 @@ const RESTITUTION_GRAVITY_THRESHOLD_FACTOR = 2;
21
19
  export class ConstraintSolver {
22
20
  oneWayValidator;
23
21
  contactStateManager;
24
- sleepSupportTracker;
25
22
  time;
26
23
  getGravity;
27
24
  restitutionThreshold;
28
25
  solverIterations;
29
26
  maxAllowedPenetration;
30
27
  maxBiasVelocity;
31
- linearSleepThreshold;
32
- penetrationSleepThreshold;
33
28
  flippedNormal;
34
29
  blockImpulse0;
35
30
  blockImpulse1;
36
31
  constructor(options) {
37
32
  this.oneWayValidator = new OneWayValidator();
38
33
  this.contactStateManager = new ContactStateManager();
39
- this.sleepSupportTracker = new SleepSupportTracker(options.getGravity);
40
34
  this.time = options.time;
41
35
  this.getGravity = options.getGravity;
42
36
  this.restitutionThreshold = RESTITUTION_VELOCITY_THRESHOLD;
@@ -45,10 +39,6 @@ export class ConstraintSolver {
45
39
  this.maxAllowedPenetration =
46
40
  options.maxAllowedPenetration ?? DEFAULT_CONTACT_MAX_ALLOWED_PENETRATION;
47
41
  this.maxBiasVelocity = options.maxBiasVelocity ?? DEFAULT_MAX_BIAS_VELOCITY;
48
- this.linearSleepThreshold =
49
- options.linearSleepThreshold ?? DEFAULT_LINEAR_SLEEP_THRESHOLD;
50
- this.penetrationSleepThreshold =
51
- this.maxAllowedPenetration + PENETRATION_SLEEP_MARGIN;
52
42
  this.flippedNormal = { x: 0, y: 0 };
53
43
  this.blockImpulse0 = 0;
54
44
  this.blockImpulse1 = 0;
@@ -82,24 +72,6 @@ export class ConstraintSolver {
82
72
  this.flippedNormal.y = -contact.normal.y;
83
73
  return this.oneWayValidator.shouldBlock(contact.actor2, contact.actor1, this.flippedNormal);
84
74
  }
85
- validateSleepContact(contact) {
86
- const rigidBody1 = contact.actor1.getComponent(RigidBody);
87
- const rigidBody2 = contact.actor2.getComponent(RigidBody);
88
- const isDeepContact = contact.penetration > this.penetrationSleepThreshold;
89
- const isFastContact = shouldWakeSleepingContact(contact, this.linearSleepThreshold);
90
- if (!isDeepContact && !isFastContact) {
91
- this.sleepSupportTracker.trackContact(contact);
92
- }
93
- if (rigidBody1.sleeping && rigidBody2.sleeping) {
94
- return false;
95
- }
96
- if ((rigidBody1.sleeping || rigidBody2.sleeping) &&
97
- (isDeepContact || isFastContact)) {
98
- rigidBody1.wakeUp();
99
- rigidBody2.wakeUp();
100
- }
101
- return true;
102
- }
103
75
  getPoint(state, index) {
104
76
  return index === 0 ? state.point0 : state.point1;
105
77
  }
@@ -182,9 +154,7 @@ export class ConstraintSolver {
182
154
  prepareDecisions(state, minPrevNormalVelocity) {
183
155
  const hasRestitution = state.restitution > 0;
184
156
  const isBouncing = hasRestitution && -minPrevNormalVelocity > this.restitutionThreshold;
185
- const eitherSleeping = state.bodyA.sleeping || state.bodyB.sleeping;
186
- state.warmStartAllowed =
187
- (!hasRestitution || !isBouncing) && !eitherSleeping;
157
+ state.warmStartAllowed = !hasRestitution || !isBouncing;
188
158
  state.skipBias =
189
159
  isBouncing && (state.invMassA === 0 || state.invMassB === 0);
190
160
  }
@@ -352,7 +322,6 @@ export class ConstraintSolver {
352
322
  update(contacts) {
353
323
  this.oneWayValidator.updateVersion();
354
324
  this.contactStateManager.updateVersion();
355
- this.sleepSupportTracker.beginFrame();
356
325
  const deltaTime = this.time.fixedDeltaTime;
357
326
  this.restitutionThreshold = Math.max(RESTITUTION_VELOCITY_THRESHOLD, RESTITUTION_GRAVITY_THRESHOLD_FACTOR *
358
327
  this.getGravity().magnitude *
@@ -364,14 +333,10 @@ export class ConstraintSolver {
364
333
  if (!this.validateOneWayContact(contact)) {
365
334
  return;
366
335
  }
367
- if (!this.validateSleepContact(contact)) {
368
- return;
369
- }
370
336
  const state = this.contactStateManager.acquire(contact);
371
337
  this.prepareContact(state);
372
338
  this.applyWarmStartImpulse(state);
373
339
  });
374
- this.sleepSupportTracker.wakeUnsupportedBodies();
375
340
  this.contactStateManager.pruneStaleStates();
376
341
  for (let iteration = 0; iteration < this.solverIterations; iteration += 1) {
377
342
  this.contactStateManager.forEach((state) => {
@@ -386,6 +351,5 @@ export class ConstraintSolver {
386
351
  });
387
352
  }
388
353
  this.oneWayValidator.clearOneWayContacts();
389
- this.sleepSupportTracker.endFrame();
390
354
  }
391
355
  }
@@ -5,18 +5,11 @@ export interface PhysicsSubsystemOptions {
5
5
  scene: Scene;
6
6
  time: Time;
7
7
  getGravity: () => Vector2;
8
- linearSleepThreshold?: number;
9
- angularSleepThreshold?: number;
10
- sleepTimeThreshold?: number;
11
8
  }
12
9
  export declare class PhysicsSubsystem {
13
10
  private actorQuery;
14
11
  private time;
15
12
  private getGravity;
16
- private linearSleepThreshold;
17
- private angularSleepThreshold;
18
- private biasAngularSleepThreshold;
19
- private sleepTimeThreshold;
20
13
  private kinematicMovedActors;
21
14
  constructor(options: PhysicsSubsystemOptions);
22
15
  destroy(): void;
@@ -25,6 +18,5 @@ export declare class PhysicsSubsystem {
25
18
  integrateVelocities(): void;
26
19
  integrateKinematicPositions(): void;
27
20
  integrateDynamicPositions(): void;
28
- updateSleepTimers(): void;
29
21
  lateUpdate(): void;
30
22
  }
@@ -2,30 +2,17 @@ import { ActorQuery } from '../../../../../engine/actor';
2
2
  import { RigidBody } from '../../../../components/rigid-body';
3
3
  import { Transform } from '../../../../components/transform';
4
4
  import { Collider } from '../../../../components/collider';
5
- import { DEFAULT_LINEAR_SLEEP_THRESHOLD, DEFAULT_ANGULAR_SLEEP_THRESHOLD, DEFAULT_SLEEP_TIME_THRESHOLD, BIAS_ANGULAR_SLEEP_MULTIPLIER, } from '../../consts';
6
5
  import { calculateInertia } from './mass-properties';
7
6
  export class PhysicsSubsystem {
8
7
  actorQuery;
9
8
  time;
10
9
  getGravity;
11
- linearSleepThreshold;
12
- angularSleepThreshold;
13
- biasAngularSleepThreshold;
14
- sleepTimeThreshold;
15
10
  kinematicMovedActors;
16
11
  constructor(options) {
17
12
  const { scene, time, getGravity } = options;
18
13
  this.actorQuery = new ActorQuery({ scene, filter: [RigidBody, Transform] });
19
14
  this.time = time;
20
15
  this.getGravity = getGravity;
21
- this.linearSleepThreshold =
22
- options.linearSleepThreshold ?? DEFAULT_LINEAR_SLEEP_THRESHOLD;
23
- this.angularSleepThreshold =
24
- options.angularSleepThreshold ?? DEFAULT_ANGULAR_SLEEP_THRESHOLD;
25
- this.biasAngularSleepThreshold =
26
- this.angularSleepThreshold * BIAS_ANGULAR_SLEEP_MULTIPLIER;
27
- this.sleepTimeThreshold =
28
- options.sleepTimeThreshold ?? DEFAULT_SLEEP_TIME_THRESHOLD;
29
16
  this.kinematicMovedActors = new Set();
30
17
  }
31
18
  destroy() {
@@ -93,10 +80,7 @@ export class PhysicsSubsystem {
93
80
  (position.x - transform.world.position.x) * impulse.y -
94
81
  (position.y - transform.world.position.y) * impulse.x;
95
82
  });
96
- const { _centralForce, _centralImpulse, linearVelocity, mass, inverseMass, inverseInertia, gravityScale, lockRotation, sleeping, } = rigidBody;
97
- if (sleeping) {
98
- return;
99
- }
83
+ const { _centralForce, _centralImpulse, linearVelocity, mass, inverseMass, inverseInertia, gravityScale, lockRotation, } = rigidBody;
100
84
  if (gravityScale) {
101
85
  const gravity = this.getGravity();
102
86
  _centralForce.x += mass * gravity.x * gravityScale;
@@ -150,7 +134,7 @@ export class PhysicsSubsystem {
150
134
  if (rigidBody.disabled || rigidBody.type !== 'dynamic') {
151
135
  return;
152
136
  }
153
- if (rigidBody.mass <= 0 || rigidBody.sleeping) {
137
+ if (rigidBody.mass <= 0) {
154
138
  return;
155
139
  }
156
140
  transform.world.position.x +=
@@ -166,37 +150,6 @@ export class PhysicsSubsystem {
166
150
  }
167
151
  });
168
152
  }
169
- updateSleepTimers() {
170
- const deltaTime = this.time.fixedDeltaTime;
171
- this.actorQuery.getActors().forEach((actor) => {
172
- const rigidBody = actor.getComponent(RigidBody);
173
- if (rigidBody.disabled ||
174
- rigidBody.type !== 'dynamic' ||
175
- rigidBody.mass <= 0 ||
176
- !rigidBody.autoSleep) {
177
- rigidBody._sleepTime = 0;
178
- return;
179
- }
180
- if (rigidBody.sleeping) {
181
- return;
182
- }
183
- const realMotionIsSmall = rigidBody.linearVelocity.squaredMagnitude <=
184
- this.linearSleepThreshold * this.linearSleepThreshold &&
185
- Math.abs(rigidBody.angularVelocity) <= this.angularSleepThreshold;
186
- const biasMotionIsSmall = rigidBody._biasLinearVelocity.squaredMagnitude <=
187
- this.linearSleepThreshold * this.linearSleepThreshold &&
188
- Math.abs(rigidBody._biasAngularVelocity) <=
189
- this.biasAngularSleepThreshold;
190
- if (!realMotionIsSmall || !biasMotionIsSmall) {
191
- rigidBody._sleepTime = 0;
192
- return;
193
- }
194
- rigidBody._sleepTime += deltaTime;
195
- if (rigidBody._sleepTime >= this.sleepTimeThreshold) {
196
- rigidBody.sleep();
197
- }
198
- });
199
- }
200
153
  lateUpdate() {
201
154
  this.kinematicMovedActors.forEach((actor) => {
202
155
  const rigidBody = actor.getComponent(RigidBody);
@@ -7,7 +7,7 @@ import { PhysicsSystem } from '../index';
7
7
  import type { PhysicsSettings, PhysicsSystemOptions } from '../types';
8
8
  export declare const createTime: (fixedDeltaTime?: number) => Time;
9
9
  export declare const createScene: () => Scene;
10
- export declare const createPhysicsSystem: (scene: Scene, settings?: PhysicsSettings, gravityY?: number, gravityX?: number, solverOptions?: Partial<Pick<PhysicsSystemOptions, 'solverIterations' | 'linearSleepThreshold' | 'angularSleepThreshold' | 'sleepTimeThreshold' | 'maxAllowedPenetration' | 'maxBiasVelocity'>>) => {
10
+ export declare const createPhysicsSystem: (scene: Scene, settings?: PhysicsSettings, gravityY?: number, gravityX?: number, solverOptions?: Partial<Pick<PhysicsSystemOptions, 'solverIterations' | 'maxAllowedPenetration' | 'maxBiasVelocity'>>) => {
11
11
  physicsSystem: PhysicsSystem;
12
12
  world: World;
13
13
  time: Time;
@@ -5,9 +5,6 @@ export interface PhysicsSystemOptions extends SceneSystemOptions {
5
5
  gravityX?: number;
6
6
  gravityY?: number;
7
7
  solverIterations?: number;
8
- linearSleepThreshold?: number;
9
- angularSleepThreshold?: number;
10
- sleepTimeThreshold?: number;
11
8
  maxAllowedPenetration?: number;
12
9
  maxBiasVelocity?: number;
13
10
  }
@@ -97,7 +97,8 @@ export class RendererAPI {
97
97
  const inverseMatrix = this.worldContainer.worldTransform.clone().invert();
98
98
  VIEW_COMPONENTS.forEach((ViewComponent) => {
99
99
  const viewComponent = actor.getComponent(ViewComponent);
100
- if (!viewComponent?.renderData?.view?.__dacha.isReady) {
100
+ if (viewComponent?.disabled ||
101
+ !viewComponent?.renderData?.view?.__dacha.isReady) {
101
102
  return;
102
103
  }
103
104
  const bounds = convertBounds(viewComponent.renderData.view, inverseMatrix);
@@ -20,6 +20,7 @@ export interface Bounds {
20
20
  height: number;
21
21
  }
22
22
  export interface ViewComponent extends Component {
23
+ disabled?: boolean;
23
24
  renderData?: {
24
25
  view: ViewContainer;
25
26
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dacha",
3
- "version": "0.18.1",
3
+ "version": "0.18.3",
4
4
  "main": "./build/index.js",
5
5
  "types": "./build/index.d.ts",
6
6
  "exports": {
@@ -1,5 +0,0 @@
1
- import type { Actor } from '../../../../../engine/actor';
2
- import { type Vector2 } from '../../../../../engine/math-lib';
3
- import type { Contact } from '../collision-detection/types';
4
- export declare const shouldWakeSleepingContact: (contact: Contact, contactSpeedThreshold: number) => boolean;
5
- export declare const isSleepSupportContact: (contact: Contact, actor: Actor, gravity: Vector2) => boolean;
@@ -1,41 +0,0 @@
1
- import { VectorOps } from '../../../../../engine/math-lib';
2
- import { RigidBody } from '../../../../components/rigid-body';
3
- import { Transform } from '../../../../components/transform';
4
- import { SUPPORT_MIN_GRAVITY_DOT } from '../../consts';
5
- const getMinNormalVelocity = (contact) => {
6
- const rigidBody1 = contact.actor1.getComponent(RigidBody);
7
- const rigidBody2 = contact.actor2.getComponent(RigidBody);
8
- const transform1 = contact.actor1.getComponent(Transform);
9
- const transform2 = contact.actor2.getComponent(Transform);
10
- const { normal } = contact;
11
- let minVelocity = null;
12
- for (const point of contact.contactPoints) {
13
- const anchor1X = point.x - transform1.world.position.x;
14
- const anchor1Y = point.y - transform1.world.position.y;
15
- const anchor2X = point.x - transform2.world.position.x;
16
- const anchor2Y = point.y - transform2.world.position.y;
17
- const velocity1X = rigidBody1.linearVelocity.x - rigidBody1.angularVelocity * anchor1Y;
18
- const velocity1Y = rigidBody1.linearVelocity.y + rigidBody1.angularVelocity * anchor1X;
19
- const velocity2X = rigidBody2.linearVelocity.x - rigidBody2.angularVelocity * anchor2Y;
20
- const velocity2Y = rigidBody2.linearVelocity.y + rigidBody2.angularVelocity * anchor2X;
21
- const velocity = (velocity2X - velocity1X) * normal.x +
22
- (velocity2Y - velocity1Y) * normal.y;
23
- if (minVelocity === null || velocity < minVelocity) {
24
- minVelocity = velocity;
25
- }
26
- }
27
- return minVelocity;
28
- };
29
- export const shouldWakeSleepingContact = (contact, contactSpeedThreshold) => {
30
- const minNormalVelocity = getMinNormalVelocity(contact);
31
- return (minNormalVelocity !== null && -minNormalVelocity > contactSpeedThreshold);
32
- };
33
- export const isSleepSupportContact = (contact, actor, gravity) => {
34
- const gravityMagnitude = gravity.magnitude;
35
- if (gravityMagnitude === 0) {
36
- return false;
37
- }
38
- const normalGravityDot = VectorOps.dotProduct(contact.normal, gravity);
39
- const supportDot = contact.actor1 === actor ? normalGravityDot : -normalGravityDot;
40
- return supportDot / gravityMagnitude > SUPPORT_MIN_GRAVITY_DOT;
41
- };
@@ -1,13 +0,0 @@
1
- import type { Vector2 } from '../../../../../engine/math-lib';
2
- import type { Contact } from '../collision-detection/types';
3
- export declare class SleepSupportTracker {
4
- private currentSupportedActors;
5
- private previousSupportedActors;
6
- private getGravity;
7
- constructor(getGravity: () => Vector2);
8
- beginFrame(): void;
9
- trackContact(contact: Contact): void;
10
- wakeUnsupportedBodies(): void;
11
- endFrame(): void;
12
- private trackActor;
13
- }
@@ -1,42 +0,0 @@
1
- import { RigidBody } from '../../../../components/rigid-body';
2
- import { isSleepSupportContact } from './contact-utils';
3
- export class SleepSupportTracker {
4
- currentSupportedActors;
5
- previousSupportedActors;
6
- getGravity;
7
- constructor(getGravity) {
8
- this.currentSupportedActors = new Set();
9
- this.previousSupportedActors = new Set();
10
- this.getGravity = getGravity;
11
- }
12
- beginFrame() {
13
- this.currentSupportedActors.clear();
14
- }
15
- trackContact(contact) {
16
- this.trackActor(contact.actor1, contact);
17
- this.trackActor(contact.actor2, contact);
18
- }
19
- wakeUnsupportedBodies() {
20
- this.previousSupportedActors.forEach((actor) => {
21
- if (this.currentSupportedActors.has(actor)) {
22
- return;
23
- }
24
- const rigidBody = actor.getComponent(RigidBody);
25
- rigidBody?.wakeUp();
26
- });
27
- }
28
- endFrame() {
29
- const previousSupportedActors = this.previousSupportedActors;
30
- this.previousSupportedActors = this.currentSupportedActors;
31
- this.currentSupportedActors = previousSupportedActors;
32
- }
33
- trackActor(actor, contact) {
34
- const gravity = this.getGravity();
35
- const rigidBody = actor.getComponent(RigidBody);
36
- if (rigidBody.type !== 'dynamic' ||
37
- !isSleepSupportContact(contact, actor, gravity)) {
38
- return;
39
- }
40
- this.currentSupportedActors.add(actor);
41
- }
42
- }