excalibur 0.32.0-alpha.19 → 0.32.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/CHANGELOG.md +42 -0
- package/build/dist/Collision/BodyComponent.d.ts +11 -5
- package/build/dist/Collision/CollisionSystem.d.ts +3 -0
- package/build/dist/Collision/Detection/CollisionContact.d.ts +0 -4
- package/build/dist/Collision/Island.d.ts +13 -0
- package/build/dist/Collision/MotionSystem.d.ts +1 -0
- package/build/dist/Collision/PhysicsConfig.d.ts +16 -4
- package/build/dist/Collision/PhysicsWorld.d.ts +1 -0
- package/build/dist/Collision/Solver/Solver.d.ts +1 -1
- package/build/dist/Debug/DebugConfig.d.ts +5 -0
- package/build/dist/Math/util.d.ts +4 -0
- package/build/dist/excalibur.development.js +227 -75
- package/build/dist/excalibur.js +227 -75
- package/build/dist/excalibur.min.development.js +50 -50
- package/build/dist/excalibur.min.js +50 -50
- package/build/esm/excalibur.development.js +227 -75
- package/build/esm/excalibur.js +227 -75
- package/build/esm/excalibur.min.development.js +1372 -1295
- package/build/esm/excalibur.min.js +1372 -1295
- package/package.json +2 -2
package/build/esm/excalibur.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! excalibur - 0.32.0
|
|
1
|
+
/*! excalibur - 0.32.0 - 2025-12-23
|
|
2
2
|
https://github.com/excaliburjs/Excalibur
|
|
3
3
|
Copyright (c) 2025 Excalibur.js <https://github.com/excaliburjs/Excalibur/graphs/contributors>
|
|
4
4
|
Licensed BSD-2-Clause
|
|
@@ -508,18 +508,13 @@ function approximatelyEqual(val1, val2, tolerance) {
|
|
|
508
508
|
return Math.abs(val1 - val2) < tolerance;
|
|
509
509
|
}
|
|
510
510
|
function canonicalizeAngle(angle) {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
while (tmpAngle < 0) {
|
|
519
|
-
tmpAngle += TwoPI;
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
return tmpAngle;
|
|
511
|
+
const TWO_PI = 2 * Math.PI;
|
|
512
|
+
return (angle % TWO_PI + TWO_PI) % TWO_PI;
|
|
513
|
+
}
|
|
514
|
+
function angleDifference(angle1, angle2) {
|
|
515
|
+
const TWO_PI = 2 * Math.PI;
|
|
516
|
+
const diff = Math.abs(angle1 - angle2);
|
|
517
|
+
return Math.min(diff, TWO_PI - diff);
|
|
523
518
|
}
|
|
524
519
|
function toDegrees(radians) {
|
|
525
520
|
return 180 / Math.PI * radians;
|
|
@@ -5923,18 +5918,32 @@ class SystemManager {
|
|
|
5923
5918
|
* @param elapsed time in milliseconds
|
|
5924
5919
|
*/
|
|
5925
5920
|
updateSystems(type, scene, elapsed) {
|
|
5921
|
+
var _a, _b, _c;
|
|
5926
5922
|
const systems = this.systems.filter((s) => s.systemType === type);
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5923
|
+
const stats = (_c = (_b = (_a = scene == null ? void 0 : scene.engine) == null ? void 0 : _a.stats) == null ? void 0 : _b.currFrame) != null ? _c : { systemDuration: {} };
|
|
5924
|
+
let startTime;
|
|
5925
|
+
let endTime;
|
|
5926
|
+
const systemsLength = systems.length;
|
|
5927
|
+
for (let i = 0; i < systemsLength; i++) {
|
|
5928
|
+
if (systems[i].preupdate) {
|
|
5929
|
+
startTime = performance.now();
|
|
5930
|
+
systems[i].preupdate(scene, elapsed);
|
|
5931
|
+
endTime = performance.now();
|
|
5932
|
+
stats.systemDuration[`${type}:${systems[i].constructor.name}.preupdate`] = endTime - startTime;
|
|
5930
5933
|
}
|
|
5931
5934
|
}
|
|
5932
|
-
for (
|
|
5933
|
-
|
|
5935
|
+
for (let i = 0; i < systemsLength; i++) {
|
|
5936
|
+
startTime = performance.now();
|
|
5937
|
+
systems[i].update(elapsed);
|
|
5938
|
+
endTime = performance.now();
|
|
5939
|
+
stats.systemDuration[`${type}:${systems[i].constructor.name}.update`] = endTime - startTime;
|
|
5934
5940
|
}
|
|
5935
|
-
for (
|
|
5936
|
-
if (
|
|
5937
|
-
|
|
5941
|
+
for (let i = 0; i < systemsLength; i++) {
|
|
5942
|
+
if (systems[i].postupdate) {
|
|
5943
|
+
startTime = performance.now();
|
|
5944
|
+
systems[i].postupdate(scene, elapsed);
|
|
5945
|
+
endTime = performance.now();
|
|
5946
|
+
stats.systemDuration[`${type}:${systems[i].constructor.name}.postupdate`] = endTime - startTime;
|
|
5938
5947
|
}
|
|
5939
5948
|
}
|
|
5940
5949
|
}
|
|
@@ -7192,10 +7201,11 @@ const getDefaultPhysicsConfig = () => ({
|
|
|
7192
7201
|
surfaceEpsilon: 0.1
|
|
7193
7202
|
},
|
|
7194
7203
|
bodies: {
|
|
7195
|
-
canSleepByDefault:
|
|
7204
|
+
canSleepByDefault: true,
|
|
7196
7205
|
sleepEpsilon: 0.07,
|
|
7197
7206
|
wakeThreshold: 0.07 * 3,
|
|
7198
|
-
sleepBias: 0.
|
|
7207
|
+
sleepBias: 0.5,
|
|
7208
|
+
sleepTimeThreshold: 1e3,
|
|
7199
7209
|
defaultMass: 10
|
|
7200
7210
|
},
|
|
7201
7211
|
spatialPartition: SpatialPartitionStrategy.SparseHashGrid,
|
|
@@ -7835,23 +7845,6 @@ class CollisionContact {
|
|
|
7835
7845
|
this.bodyB = this.colliderB.owner.get(BodyComponent);
|
|
7836
7846
|
}
|
|
7837
7847
|
}
|
|
7838
|
-
/**
|
|
7839
|
-
* Match contact awake state, except if body's are Fixed
|
|
7840
|
-
*/
|
|
7841
|
-
matchAwake() {
|
|
7842
|
-
const bodyA = this.bodyA;
|
|
7843
|
-
const bodyB = this.bodyB;
|
|
7844
|
-
if (bodyA && bodyB) {
|
|
7845
|
-
if (bodyA.isSleeping !== bodyB.isSleeping) {
|
|
7846
|
-
if (bodyA.isSleeping && bodyA.collisionType !== CollisionType.Fixed && bodyB.sleepMotion >= bodyA.wakeThreshold) {
|
|
7847
|
-
bodyA.isSleeping = false;
|
|
7848
|
-
}
|
|
7849
|
-
if (bodyB.isSleeping && bodyB.collisionType !== CollisionType.Fixed && bodyA.sleepMotion >= bodyB.wakeThreshold) {
|
|
7850
|
-
bodyB.isSleeping = false;
|
|
7851
|
-
}
|
|
7852
|
-
}
|
|
7853
|
-
}
|
|
7854
|
-
}
|
|
7855
7848
|
isCanceled() {
|
|
7856
7849
|
return this._canceled;
|
|
7857
7850
|
}
|
|
@@ -12079,7 +12072,7 @@ class GraphicsSystem extends System {
|
|
|
12079
12072
|
const optionalBody = ancestor == null ? void 0 : ancestor.get(BodyComponent);
|
|
12080
12073
|
if (transform) {
|
|
12081
12074
|
let tx = transform.get();
|
|
12082
|
-
if (optionalBody) {
|
|
12075
|
+
if (optionalBody && !optionalBody.isSleeping) {
|
|
12083
12076
|
if (this._engine.fixedUpdateTimestep && optionalBody.__oldTransformCaptured && optionalBody.enableFixedUpdateInterpolate) {
|
|
12084
12077
|
const blend = this._engine.currentFrameLagMs / this._engine.fixedUpdateTimestep;
|
|
12085
12078
|
tx = blendTransform(optionalBody.oldTransform, transform.get(), blend, this._targetInterpolationTransform);
|
|
@@ -20746,11 +20739,14 @@ const _BodyComponent = class _BodyComponent2 extends Component {
|
|
|
20746
20739
|
this.dependencies = [TransformComponent, MotionComponent];
|
|
20747
20740
|
this.id = createId("body", _BodyComponent2._ID++);
|
|
20748
20741
|
this.events = new EventEmitter();
|
|
20742
|
+
this.island = null;
|
|
20749
20743
|
this.oldTransform = new Transform();
|
|
20750
20744
|
this.__oldTransformCaptured = false;
|
|
20751
20745
|
this.enableFixedUpdateInterpolate = true;
|
|
20746
|
+
this.sleepTime = 0;
|
|
20752
20747
|
this.collisionType = CollisionType.PreventCollision;
|
|
20753
20748
|
this.group = CollisionGroup.All;
|
|
20749
|
+
this.canSleep = this.collisionType === CollisionType.Active;
|
|
20754
20750
|
this._sleeping = false;
|
|
20755
20751
|
this.bounciness = 0.2;
|
|
20756
20752
|
this.friction = 0.99;
|
|
@@ -20793,6 +20789,12 @@ const _BodyComponent = class _BodyComponent2 extends Component {
|
|
|
20793
20789
|
this.sleepMotion = this._bodyConfig.sleepEpsilon * 5;
|
|
20794
20790
|
this.wakeThreshold = this._bodyConfig.wakeThreshold;
|
|
20795
20791
|
}
|
|
20792
|
+
get canFallAsleep() {
|
|
20793
|
+
return this.canSleep && this.collisionType === CollisionType.Active && this.sleepMotion < this._bodyConfig.sleepEpsilon;
|
|
20794
|
+
}
|
|
20795
|
+
get canWakeUp() {
|
|
20796
|
+
return this.collisionType === CollisionType.Active && this.sleepMotion > this.wakeThreshold;
|
|
20797
|
+
}
|
|
20796
20798
|
/**
|
|
20797
20799
|
* Called by excalibur to update defaults
|
|
20798
20800
|
* @param config
|
|
@@ -20825,7 +20827,7 @@ const _BodyComponent = class _BodyComponent2 extends Component {
|
|
|
20825
20827
|
* Whether this body is sleeping or not
|
|
20826
20828
|
*/
|
|
20827
20829
|
get isSleeping() {
|
|
20828
|
-
return this._sleeping;
|
|
20830
|
+
return this.canSleep && this._sleeping;
|
|
20829
20831
|
}
|
|
20830
20832
|
/**
|
|
20831
20833
|
* Set the sleep state of the body
|
|
@@ -20835,30 +20837,51 @@ const _BodyComponent = class _BodyComponent2 extends Component {
|
|
|
20835
20837
|
setSleeping(sleeping) {
|
|
20836
20838
|
this.isSleeping = sleeping;
|
|
20837
20839
|
}
|
|
20838
|
-
|
|
20839
|
-
|
|
20840
|
-
if (
|
|
20841
|
-
this.
|
|
20842
|
-
|
|
20840
|
+
wake() {
|
|
20841
|
+
var _a;
|
|
20842
|
+
if (this._sleeping && this.collisionType === CollisionType.Active) {
|
|
20843
|
+
this._sleeping = false;
|
|
20844
|
+
(_a = this.owner) == null ? void 0 : _a.removeTag("ex.is_sleeping");
|
|
20845
|
+
this.sleepMotion = this._bodyConfig.sleepEpsilon * 2;
|
|
20846
|
+
this.sleepTime = 0;
|
|
20847
|
+
}
|
|
20848
|
+
}
|
|
20849
|
+
sleep() {
|
|
20850
|
+
var _a;
|
|
20851
|
+
if (!this._sleeping && this.canSleep) {
|
|
20852
|
+
this._sleeping = true;
|
|
20853
|
+
(_a = this.owner) == null ? void 0 : _a.addTag("ex.is_sleeping");
|
|
20843
20854
|
this.vel = Vector.Zero;
|
|
20844
20855
|
this.acc = Vector.Zero;
|
|
20845
20856
|
this.angularVelocity = 0;
|
|
20846
20857
|
this.sleepMotion = 0;
|
|
20847
20858
|
}
|
|
20848
20859
|
}
|
|
20860
|
+
set isSleeping(sleeping) {
|
|
20861
|
+
if (sleeping) {
|
|
20862
|
+
this.sleep();
|
|
20863
|
+
} else {
|
|
20864
|
+
this.wake();
|
|
20865
|
+
}
|
|
20866
|
+
}
|
|
20849
20867
|
/**
|
|
20850
20868
|
* Update body's {@apilink BodyComponent.sleepMotion} for the purpose of sleeping
|
|
20851
20869
|
*/
|
|
20852
|
-
updateMotion() {
|
|
20853
|
-
if (this.
|
|
20854
|
-
|
|
20870
|
+
updateMotion(duration) {
|
|
20871
|
+
if (this.collisionType !== CollisionType.Active) {
|
|
20872
|
+
return;
|
|
20855
20873
|
}
|
|
20856
|
-
const
|
|
20857
|
-
const
|
|
20858
|
-
|
|
20874
|
+
const effectiveVel = this.pos.sub(this.oldPos);
|
|
20875
|
+
const effectiveAngularVel = angleDifference(canonicalizeAngle(this.rotation), canonicalizeAngle(this.oldRotation));
|
|
20876
|
+
const vel = effectiveVel.magnitude;
|
|
20877
|
+
const omega = effectiveAngularVel;
|
|
20878
|
+
const currentMotion = vel * vel + omega * omega;
|
|
20879
|
+
const bias = Math.pow(this._bodyConfig.sleepBias, duration / 1e3);
|
|
20880
|
+
const previousMotion = this.sleepMotion;
|
|
20881
|
+
this.sleepMotion = bias * previousMotion + (1 - bias) * currentMotion;
|
|
20859
20882
|
this.sleepMotion = clamp(this.sleepMotion, 0, 10 * this._bodyConfig.sleepEpsilon);
|
|
20860
|
-
if (this.
|
|
20861
|
-
this.
|
|
20883
|
+
if (this.canFallAsleep) {
|
|
20884
|
+
this.sleepTime += duration;
|
|
20862
20885
|
}
|
|
20863
20886
|
}
|
|
20864
20887
|
/**
|
|
@@ -22087,7 +22110,6 @@ class RealisticSolver {
|
|
|
22087
22110
|
"beforecollisionresolve",
|
|
22088
22111
|
new CollisionPreSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact)
|
|
22089
22112
|
);
|
|
22090
|
-
contact.matchAwake();
|
|
22091
22113
|
}
|
|
22092
22114
|
const finishedContactIds = Array.from(this.idToContactConstraint.keys());
|
|
22093
22115
|
for (let i = 0; i < contacts.length; i++) {
|
|
@@ -22102,7 +22124,7 @@ class RealisticSolver {
|
|
|
22102
22124
|
const colliderA = contact.colliderA;
|
|
22103
22125
|
const bodyB = contact.bodyB;
|
|
22104
22126
|
const colliderB = contact.colliderB;
|
|
22105
|
-
if (bodyA && bodyB) {
|
|
22127
|
+
if (bodyA && bodyB && (!bodyA.isSleeping || !bodyB.isSleeping)) {
|
|
22106
22128
|
for (let j = 0; j < contact.points.length; j++) {
|
|
22107
22129
|
const point2 = contact.points[j];
|
|
22108
22130
|
const normal = contact.normal;
|
|
@@ -22161,8 +22183,6 @@ class RealisticSolver {
|
|
|
22161
22183
|
if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {
|
|
22162
22184
|
continue;
|
|
22163
22185
|
}
|
|
22164
|
-
bodyA.updateMotion();
|
|
22165
|
-
bodyB.updateMotion();
|
|
22166
22186
|
}
|
|
22167
22187
|
const side = Side.fromDirection(contact.mtv);
|
|
22168
22188
|
contact.colliderA.events.emit(
|
|
@@ -22198,6 +22218,9 @@ class RealisticSolver {
|
|
|
22198
22218
|
const contact = contacts[i];
|
|
22199
22219
|
const bodyA = contact.bodyA;
|
|
22200
22220
|
const bodyB = contact.bodyB;
|
|
22221
|
+
if (bodyA.isSleeping && bodyB.isSleeping) {
|
|
22222
|
+
continue;
|
|
22223
|
+
}
|
|
22201
22224
|
if (bodyA && bodyB) {
|
|
22202
22225
|
const contactPoints = (_a = this.idToContactConstraint.get(contact.id)) != null ? _a : [];
|
|
22203
22226
|
for (const point2 of contactPoints) {
|
|
@@ -22226,6 +22249,9 @@ class RealisticSolver {
|
|
|
22226
22249
|
const contact = contacts[i2];
|
|
22227
22250
|
const bodyA = contact.bodyA;
|
|
22228
22251
|
const bodyB = contact.bodyB;
|
|
22252
|
+
if (bodyA.isSleeping && bodyB.isSleeping) {
|
|
22253
|
+
continue;
|
|
22254
|
+
}
|
|
22229
22255
|
if (bodyA && bodyB) {
|
|
22230
22256
|
if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {
|
|
22231
22257
|
continue;
|
|
@@ -22277,6 +22303,9 @@ class RealisticSolver {
|
|
|
22277
22303
|
const contact = contacts[i2];
|
|
22278
22304
|
const bodyA = contact.bodyA;
|
|
22279
22305
|
const bodyB = contact.bodyB;
|
|
22306
|
+
if (bodyA.isSleeping && bodyB.isSleeping) {
|
|
22307
|
+
continue;
|
|
22308
|
+
}
|
|
22280
22309
|
if (bodyA && bodyB) {
|
|
22281
22310
|
if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {
|
|
22282
22311
|
continue;
|
|
@@ -22318,17 +22347,20 @@ class MotionSystem extends System {
|
|
|
22318
22347
|
this.physics = physics;
|
|
22319
22348
|
this.systemType = SystemType.Update;
|
|
22320
22349
|
this._physicsConfigDirty = false;
|
|
22321
|
-
this.query = this.world
|
|
22350
|
+
this.query = this._createPhysicsQuery(world, physics);
|
|
22351
|
+
physics.$configUpdate.subscribe(() => {
|
|
22352
|
+
this._physicsConfigDirty = true;
|
|
22353
|
+
});
|
|
22354
|
+
}
|
|
22355
|
+
_createPhysicsQuery(world, physics) {
|
|
22356
|
+
return world.query({
|
|
22322
22357
|
components: {
|
|
22323
22358
|
all: [TransformComponent, MotionComponent]
|
|
22324
22359
|
},
|
|
22325
22360
|
tags: {
|
|
22326
|
-
not:
|
|
22361
|
+
not: physics.config.integration.onScreenOnly ? ["ex.offscreen", "ex.is_sleeping"] : ["ex.is_sleeping"]
|
|
22327
22362
|
}
|
|
22328
22363
|
});
|
|
22329
|
-
physics.$configUpdate.subscribe(() => {
|
|
22330
|
-
this._physicsConfigDirty = true;
|
|
22331
|
-
});
|
|
22332
22364
|
}
|
|
22333
22365
|
update(elapsed) {
|
|
22334
22366
|
let transform;
|
|
@@ -22360,14 +22392,7 @@ class MotionSystem extends System {
|
|
|
22360
22392
|
}
|
|
22361
22393
|
if (this._physicsConfigDirty) {
|
|
22362
22394
|
this._physicsConfigDirty = false;
|
|
22363
|
-
this.query = this.world.
|
|
22364
|
-
components: {
|
|
22365
|
-
all: [TransformComponent, MotionComponent]
|
|
22366
|
-
},
|
|
22367
|
-
tags: {
|
|
22368
|
-
not: this.physics.config.integration.onScreenOnly ? ["ex.offscreen"] : []
|
|
22369
|
-
}
|
|
22370
|
-
});
|
|
22395
|
+
this.query = this._createPhysicsQuery(this.world, this.physics);
|
|
22371
22396
|
}
|
|
22372
22397
|
}
|
|
22373
22398
|
captureOldTransformWithChildren(entity) {
|
|
@@ -22379,6 +22404,105 @@ class MotionSystem extends System {
|
|
|
22379
22404
|
}
|
|
22380
22405
|
}
|
|
22381
22406
|
MotionSystem.priority = SystemPriority.Higher;
|
|
22407
|
+
class Island {
|
|
22408
|
+
constructor(config) {
|
|
22409
|
+
this.config = config;
|
|
22410
|
+
this.bodies = [];
|
|
22411
|
+
this.contacts = [];
|
|
22412
|
+
this.isSleeping = false;
|
|
22413
|
+
}
|
|
22414
|
+
wake() {
|
|
22415
|
+
this.isSleeping = false;
|
|
22416
|
+
for (const body of this.bodies) {
|
|
22417
|
+
body.wake();
|
|
22418
|
+
}
|
|
22419
|
+
}
|
|
22420
|
+
sleep() {
|
|
22421
|
+
this.isSleeping = true;
|
|
22422
|
+
for (const body of this.bodies) {
|
|
22423
|
+
body.sleep();
|
|
22424
|
+
}
|
|
22425
|
+
}
|
|
22426
|
+
updateSleepState(elapsed) {
|
|
22427
|
+
let islandHasMotion = false;
|
|
22428
|
+
let allBodiesCanSleep = true;
|
|
22429
|
+
for (const body of this.bodies) {
|
|
22430
|
+
body.updateMotion(elapsed);
|
|
22431
|
+
if (!body.canFallAsleep) {
|
|
22432
|
+
allBodiesCanSleep && (allBodiesCanSleep = false);
|
|
22433
|
+
}
|
|
22434
|
+
if (body.canWakeUp) {
|
|
22435
|
+
islandHasMotion || (islandHasMotion = true);
|
|
22436
|
+
}
|
|
22437
|
+
}
|
|
22438
|
+
if (islandHasMotion) {
|
|
22439
|
+
this.wake();
|
|
22440
|
+
} else if (allBodiesCanSleep) {
|
|
22441
|
+
let minSleepTime = Infinity;
|
|
22442
|
+
for (const body of this.bodies) {
|
|
22443
|
+
minSleepTime = Math.min(minSleepTime, body.sleepTime);
|
|
22444
|
+
}
|
|
22445
|
+
if (minSleepTime > this.config.sleepTimeThreshold) {
|
|
22446
|
+
this.sleep();
|
|
22447
|
+
}
|
|
22448
|
+
}
|
|
22449
|
+
}
|
|
22450
|
+
}
|
|
22451
|
+
function buildContactIslands(config, bodies, contacts) {
|
|
22452
|
+
const parent = /* @__PURE__ */ new Map();
|
|
22453
|
+
function find(body) {
|
|
22454
|
+
if (!parent.has(body)) {
|
|
22455
|
+
parent.set(body, body);
|
|
22456
|
+
}
|
|
22457
|
+
if (parent.get(body) !== body) {
|
|
22458
|
+
parent.set(body, find(parent.get(body)));
|
|
22459
|
+
}
|
|
22460
|
+
return parent.get(body);
|
|
22461
|
+
}
|
|
22462
|
+
function union(bodyA, bodyB) {
|
|
22463
|
+
const rootA = find(bodyA);
|
|
22464
|
+
const rootB = find(bodyB);
|
|
22465
|
+
if (rootA !== rootB) {
|
|
22466
|
+
parent.set(rootA, rootB);
|
|
22467
|
+
}
|
|
22468
|
+
}
|
|
22469
|
+
const bodyToContacts = /* @__PURE__ */ new Map();
|
|
22470
|
+
for (const contact of contacts) {
|
|
22471
|
+
if (contact.bodyA.collisionType === CollisionType.Active && contact.bodyB.collisionType === CollisionType.Active) {
|
|
22472
|
+
union(contact.bodyA, contact.bodyB);
|
|
22473
|
+
}
|
|
22474
|
+
if (!bodyToContacts.has(contact.bodyA)) {
|
|
22475
|
+
bodyToContacts.set(contact.bodyA, []);
|
|
22476
|
+
}
|
|
22477
|
+
if (!bodyToContacts.has(contact.bodyB)) {
|
|
22478
|
+
bodyToContacts.set(contact.bodyB, []);
|
|
22479
|
+
}
|
|
22480
|
+
if (contact.bodyA.collisionType === CollisionType.Active) {
|
|
22481
|
+
bodyToContacts.get(contact.bodyA).push(contact);
|
|
22482
|
+
}
|
|
22483
|
+
if (contact.bodyB.collisionType === CollisionType.Active) {
|
|
22484
|
+
bodyToContacts.get(contact.bodyB).push(contact);
|
|
22485
|
+
}
|
|
22486
|
+
}
|
|
22487
|
+
const islandMap = /* @__PURE__ */ new Map();
|
|
22488
|
+
for (const body of bodies) {
|
|
22489
|
+
if (body.collisionType !== CollisionType.Active) {
|
|
22490
|
+
continue;
|
|
22491
|
+
}
|
|
22492
|
+
const root = find(body);
|
|
22493
|
+
if (!islandMap.has(root)) {
|
|
22494
|
+
islandMap.set(root, []);
|
|
22495
|
+
}
|
|
22496
|
+
islandMap.get(root).push(body);
|
|
22497
|
+
}
|
|
22498
|
+
return Array.from(islandMap.values()).map((bodies2) => {
|
|
22499
|
+
const island = new Island(config);
|
|
22500
|
+
island.bodies = bodies2;
|
|
22501
|
+
bodies2.forEach((b) => b.island = island);
|
|
22502
|
+
island.contacts = Array.from(new Set(bodies2.flatMap((b) => bodyToContacts.get(b))));
|
|
22503
|
+
return island;
|
|
22504
|
+
});
|
|
22505
|
+
}
|
|
22382
22506
|
class CollisionSystem extends System {
|
|
22383
22507
|
constructor(world, _physics) {
|
|
22384
22508
|
super();
|
|
@@ -22387,6 +22511,7 @@ class CollisionSystem extends System {
|
|
|
22387
22511
|
this._configDirty = false;
|
|
22388
22512
|
this._lastFrameContacts = /* @__PURE__ */ new Map();
|
|
22389
22513
|
this._currentFrameContacts = /* @__PURE__ */ new Map();
|
|
22514
|
+
this._bodies = [];
|
|
22390
22515
|
this._arcadeSolver = new ArcadeSolver(_physics.config.arcade);
|
|
22391
22516
|
this._realisticSolver = new RealisticSolver(_physics.config.realistic);
|
|
22392
22517
|
this._physics.$configUpdate.subscribe(() => this._configDirty = true);
|
|
@@ -22410,6 +22535,17 @@ class CollisionSystem extends System {
|
|
|
22410
22535
|
}
|
|
22411
22536
|
});
|
|
22412
22537
|
this._motionSystem = world.get(MotionSystem);
|
|
22538
|
+
this.bodyQuery = world.query([BodyComponent]);
|
|
22539
|
+
this.bodyQuery.entityAdded$.subscribe((e) => {
|
|
22540
|
+
this._bodies.push(e.get(BodyComponent));
|
|
22541
|
+
});
|
|
22542
|
+
this.bodyQuery.entityRemoved$.subscribe((e) => {
|
|
22543
|
+
const body = e.get(BodyComponent);
|
|
22544
|
+
const indexOf = this._bodies.indexOf(body);
|
|
22545
|
+
if (indexOf > -1) {
|
|
22546
|
+
this._bodies.splice(indexOf, 1);
|
|
22547
|
+
}
|
|
22548
|
+
});
|
|
22413
22549
|
}
|
|
22414
22550
|
get _processor() {
|
|
22415
22551
|
return this._physics.collisionProcessor;
|
|
@@ -22455,7 +22591,13 @@ class CollisionSystem extends System {
|
|
|
22455
22591
|
}
|
|
22456
22592
|
if (pairs.length) {
|
|
22457
22593
|
contacts = this._processor.narrowphase(pairs, (_d = (_c = (_b = this._engine) == null ? void 0 : _b.debug) == null ? void 0 : _c.stats) == null ? void 0 : _d.currFrame);
|
|
22458
|
-
|
|
22594
|
+
if (this._physics.config.solver === SolverStrategy.Realistic) {
|
|
22595
|
+
const islands = buildContactIslands(this._physics.config.bodies, this._bodies, contacts);
|
|
22596
|
+
for (const island of islands) {
|
|
22597
|
+
island.updateSleepState(elapsed / substep);
|
|
22598
|
+
}
|
|
22599
|
+
}
|
|
22600
|
+
contacts = solver.solve(contacts, elapsed / substep);
|
|
22459
22601
|
for (const contact of contacts) {
|
|
22460
22602
|
if (contact.isCanceled()) {
|
|
22461
22603
|
continue;
|
|
@@ -22511,6 +22653,8 @@ class CollisionSystem extends System {
|
|
|
22511
22653
|
if (!this._currentFrameContacts.has(id)) {
|
|
22512
22654
|
const colliderA = c.colliderA;
|
|
22513
22655
|
const colliderB = c.colliderB;
|
|
22656
|
+
c.bodyA.isSleeping = false;
|
|
22657
|
+
c.bodyB.isSleeping = false;
|
|
22514
22658
|
const side = Side.fromDirection(c.mtv);
|
|
22515
22659
|
const opposite = Side.getOpposite(side);
|
|
22516
22660
|
colliderA.events.emit("collisionend", new CollisionEndEvent(colliderA, colliderB, side, c));
|
|
@@ -27150,7 +27294,7 @@ class DebugSystem extends System {
|
|
|
27150
27294
|
cursor = cursor.add(lineHeight);
|
|
27151
27295
|
}
|
|
27152
27296
|
if (bodySettings.showAll || bodySettings.showMotion) {
|
|
27153
|
-
this._graphicsContext.debug.drawText(`motion(${body.sleepMotion})`, cursor);
|
|
27297
|
+
this._graphicsContext.debug.drawText(`motion(${body.sleepMotion.toFixed(3)})`, cursor);
|
|
27154
27298
|
cursor = cursor.add(lineHeight);
|
|
27155
27299
|
}
|
|
27156
27300
|
if (bodySettings.showAll || bodySettings.showSleeping) {
|
|
@@ -29457,6 +29601,7 @@ class FrameStats {
|
|
|
29457
29601
|
drawnImages: 0,
|
|
29458
29602
|
rendererSwaps: 0
|
|
29459
29603
|
};
|
|
29604
|
+
this.systemDuration = {};
|
|
29460
29605
|
}
|
|
29461
29606
|
/**
|
|
29462
29607
|
* Zero out values or clone other IFrameStat stats. Allows instance reuse.
|
|
@@ -29472,6 +29617,9 @@ class FrameStats {
|
|
|
29472
29617
|
this.actors.ui = otherStats.actors.ui;
|
|
29473
29618
|
this.duration.update = otherStats.duration.update;
|
|
29474
29619
|
this.duration.draw = otherStats.duration.draw;
|
|
29620
|
+
for (const key in otherStats.systemDuration) {
|
|
29621
|
+
this.systemDuration[key] = otherStats.systemDuration[key];
|
|
29622
|
+
}
|
|
29475
29623
|
this._physicsStats.reset(otherStats.physics);
|
|
29476
29624
|
this.graphics.drawCalls = otherStats.graphics.drawCalls;
|
|
29477
29625
|
this.graphics.drawnImages = otherStats.graphics.drawnImages;
|
|
@@ -29482,6 +29630,9 @@ class FrameStats {
|
|
|
29482
29630
|
this.duration.update = this.duration.draw = 0;
|
|
29483
29631
|
this._physicsStats.reset();
|
|
29484
29632
|
this.graphics.drawnImages = this.graphics.drawCalls = this.graphics.rendererSwaps = 0;
|
|
29633
|
+
for (const key in this.systemDuration) {
|
|
29634
|
+
this.systemDuration[key] = 0;
|
|
29635
|
+
}
|
|
29485
29636
|
}
|
|
29486
29637
|
}
|
|
29487
29638
|
/**
|
|
@@ -33627,7 +33778,7 @@ class Semaphore {
|
|
|
33627
33778
|
this._count += count;
|
|
33628
33779
|
}
|
|
33629
33780
|
}
|
|
33630
|
-
const EX_VERSION = "0.32.0
|
|
33781
|
+
const EX_VERSION = "0.32.0";
|
|
33631
33782
|
polyfill();
|
|
33632
33783
|
export {
|
|
33633
33784
|
ActionCompleteEvent,
|
|
@@ -33950,6 +34101,7 @@ export {
|
|
|
33950
34101
|
WheelDeltaMode,
|
|
33951
34102
|
WheelEvent,
|
|
33952
34103
|
World,
|
|
34104
|
+
angleDifference,
|
|
33953
34105
|
approximatelyEqual,
|
|
33954
34106
|
assert,
|
|
33955
34107
|
canonicalizeAngle,
|