@forgeax/engine-physics-rapier3d 0.1.32 → 0.1.34
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/dist/__tests__/state-reconcile.unit.test.d.ts +2 -0
- package/dist/__tests__/state-reconcile.unit.test.d.ts.map +1 -0
- package/dist/index.mjs +60 -153
- package/dist/index.mjs.map +1 -1
- package/dist/rapier-physics-world-3d.d.ts +0 -2
- package/dist/rapier-physics-world-3d.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/__tests__/state-reconcile.unit.test.ts +55 -0
- package/src/rapier-physics-world-3d.ts +81 -203
|
@@ -255,8 +255,6 @@ export declare class RapierPhysicsWorld3D implements PhysicsWorld {
|
|
|
255
255
|
private bodyForEntity;
|
|
256
256
|
private isCommittedFixedBody;
|
|
257
257
|
private reconcileTransformlessCompatibility;
|
|
258
|
-
private resetForFullReconcile;
|
|
259
|
-
private fullReconcilePhysicsState;
|
|
260
258
|
private reconcilePhysicsDelta;
|
|
261
259
|
private syncDerivedCompatibleEcsMutation;
|
|
262
260
|
/** @internal ECS system bridge; consumers should register PhysicsSyncBackend. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rapier-physics-world-3d.d.ts","sourceRoot":"","sources":["../src/rapier-physics-world-3d.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"rapier-physics-world-3d.d.ts","sourceRoot":"","sources":["../src/rapier-physics-world-3d.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgeax/engine-physics-rapier3d",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -23,15 +23,15 @@
|
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@dimforge/rapier3d-compat": "0.20.0",
|
|
26
|
-
"@forgeax/engine-ecs": "0.1.
|
|
27
|
-
"@forgeax/engine-math": "0.1.
|
|
28
|
-
"@forgeax/engine-physics": "0.1.
|
|
29
|
-
"@forgeax/engine-scene": "0.1.
|
|
30
|
-
"@forgeax/engine-types": "0.1.
|
|
26
|
+
"@forgeax/engine-ecs": "0.1.34",
|
|
27
|
+
"@forgeax/engine-math": "0.1.34",
|
|
28
|
+
"@forgeax/engine-physics": "0.1.34",
|
|
29
|
+
"@forgeax/engine-scene": "0.1.34",
|
|
30
|
+
"@forgeax/engine-types": "0.1.34"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@dimforge/rapier3d": "0.20.0",
|
|
34
|
-
"@forgeax/engine-runtime": "0.1.
|
|
34
|
+
"@forgeax/engine-runtime": "0.1.34"
|
|
35
35
|
},
|
|
36
36
|
"forgeax": {
|
|
37
37
|
"metrics": {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { RigidBody as NativeRigidBody, World as NativeWorld } from '@dimforge/rapier3d-compat';
|
|
2
|
+
import { World } from '@forgeax/engine-ecs';
|
|
3
|
+
import {
|
|
4
|
+
Collider,
|
|
5
|
+
ColliderShapeValue,
|
|
6
|
+
RigidBody,
|
|
7
|
+
RigidBodyTypeValue,
|
|
8
|
+
registerPhysicsComponents,
|
|
9
|
+
} from '@forgeax/engine-physics';
|
|
10
|
+
import { GlobalTransform, Transform } from '@forgeax/engine-scene';
|
|
11
|
+
import { expect, test } from 'vitest';
|
|
12
|
+
import { createRapier3DPhysicsWorld, loadRapier3D } from '../index';
|
|
13
|
+
|
|
14
|
+
const rapier = await loadRapier3D();
|
|
15
|
+
if ('code' in rapier) throw rapier;
|
|
16
|
+
function physicsCase(unrelatedSpawns: number) {
|
|
17
|
+
const world = new World();
|
|
18
|
+
world.components.register(Transform).unwrap();
|
|
19
|
+
world.components.register(GlobalTransform).unwrap();
|
|
20
|
+
registerPhysicsComponents(world);
|
|
21
|
+
const entity = world
|
|
22
|
+
.spawn(
|
|
23
|
+
{ component: Transform, data: { pos: [0, 4, 0] } },
|
|
24
|
+
{ component: RigidBody, data: { type: RigidBodyTypeValue.dynamic } },
|
|
25
|
+
{ component: Collider, data: { shape: ColliderShapeValue.sphere, radius: 0.5 } },
|
|
26
|
+
)
|
|
27
|
+
.unwrap();
|
|
28
|
+
const physics = createRapier3DPhysicsWorld(rapier);
|
|
29
|
+
const findBody = () => {
|
|
30
|
+
let result: NativeRigidBody | undefined;
|
|
31
|
+
(physics.raw as NativeWorld).forEachRigidBody((body) => {
|
|
32
|
+
if (body.userData === entity) result = body;
|
|
33
|
+
});
|
|
34
|
+
if (result === undefined) throw new Error('native body missing');
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
try {
|
|
38
|
+
physics._syncFromEcs(world, Transform, GlobalTransform);
|
|
39
|
+
findBody().setLinvel({ x: 3, y: 4, z: 5 }, true);
|
|
40
|
+
const before = { ...findBody().linvel() };
|
|
41
|
+
for (let i = 0; i < unrelatedSpawns; i++) world.spawn().unwrap();
|
|
42
|
+
physics._syncFromEcs(world, Transform, GlobalTransform);
|
|
43
|
+
const after = { ...findBody().linvel() };
|
|
44
|
+
return { unrelatedSpawns, before, after };
|
|
45
|
+
} finally {
|
|
46
|
+
physics.dispose();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
test.each([
|
|
51
|
+
0, 1024, 1025, 4096,
|
|
52
|
+
])('preserves native velocity after %i unrelated mutations', (count) => {
|
|
53
|
+
const sample = physicsCase(count);
|
|
54
|
+
expect(sample.after).toEqual(sample.before);
|
|
55
|
+
});
|
|
@@ -17,10 +17,9 @@ import { componentDefinition, Disabled, FixedTime, FixedUpdate } from '@forgeax/
|
|
|
17
17
|
// Despawn cleanup (plan-strategy D-5): removeEntity() removes the Rapier body
|
|
18
18
|
// and colliders from the physics world.
|
|
19
19
|
|
|
20
|
-
import type { Component, EntityHandle,
|
|
20
|
+
import type { Component, EntityHandle, SystemHandle, World } from '@forgeax/engine-ecs';
|
|
21
21
|
import { defineSystem } from '@forgeax/engine-ecs';
|
|
22
|
-
import {
|
|
23
|
-
import { readStructuralEvidence } from '@forgeax/engine-ecs/projection';
|
|
22
|
+
import { createStateProjection, type StateProjection } from '@forgeax/engine-ecs/projection';
|
|
24
23
|
import { mat4, quat, type Vec3, vec3 } from '@forgeax/engine-math';
|
|
25
24
|
import {
|
|
26
25
|
CharacterController,
|
|
@@ -120,15 +119,8 @@ interface PhysicsSyncState {
|
|
|
120
119
|
readonly transformComponent: Component;
|
|
121
120
|
readonly globalTransformComponent: Component;
|
|
122
121
|
readonly queries: readonly PhysicsSyncQuery[];
|
|
123
|
-
readonly
|
|
124
|
-
|
|
125
|
-
structureEpoch: number;
|
|
126
|
-
initialized: boolean;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
interface PhysicsChangeQuery {
|
|
130
|
-
readonly component: Component;
|
|
131
|
-
readonly query: Query;
|
|
122
|
+
readonly projection: StateProjection;
|
|
123
|
+
readonly accepted: Map<number, PhysicsSyncDescriptor>;
|
|
132
124
|
}
|
|
133
125
|
|
|
134
126
|
interface PhysicsSyncDescriptor {
|
|
@@ -155,41 +147,23 @@ interface PhysicsEntityDelta {
|
|
|
155
147
|
characterControllerStructureChanged: boolean;
|
|
156
148
|
}
|
|
157
149
|
|
|
158
|
-
function
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
function ensurePhysicsDelta(
|
|
178
|
-
deltas: Map<EntityHandle, PhysicsEntityDelta>,
|
|
179
|
-
entity: EntityHandle,
|
|
180
|
-
): PhysicsEntityDelta {
|
|
181
|
-
let delta = deltas.get(entity);
|
|
182
|
-
if (delta === undefined) {
|
|
183
|
-
delta = {
|
|
184
|
-
transformChanged: false,
|
|
185
|
-
colliderChanged: false,
|
|
186
|
-
rigidBodyChanged: false,
|
|
187
|
-
characterControllerChanged: false,
|
|
188
|
-
characterControllerStructureChanged: false,
|
|
189
|
-
};
|
|
190
|
-
deltas.set(entity, delta);
|
|
191
|
-
}
|
|
192
|
-
return delta;
|
|
150
|
+
function samePhysicsValue(left: unknown, right: unknown): boolean {
|
|
151
|
+
if (Object.is(left, right)) return true;
|
|
152
|
+
if (
|
|
153
|
+
left === undefined ||
|
|
154
|
+
right === undefined ||
|
|
155
|
+
left === null ||
|
|
156
|
+
right === null ||
|
|
157
|
+
typeof left !== 'object' ||
|
|
158
|
+
typeof right !== 'object'
|
|
159
|
+
)
|
|
160
|
+
return false;
|
|
161
|
+
const a = left as Record<string, unknown>;
|
|
162
|
+
const b = right as Record<string, unknown>;
|
|
163
|
+
const keys = Object.keys(a);
|
|
164
|
+
return (
|
|
165
|
+
keys.length === Object.keys(b).length && keys.every((key) => samePhysicsValue(a[key], b[key]))
|
|
166
|
+
);
|
|
193
167
|
}
|
|
194
168
|
|
|
195
169
|
export interface Rapier3DCollisionEvent {
|
|
@@ -2759,73 +2733,6 @@ export class RapierPhysicsWorld3D implements PhysicsWorld {
|
|
|
2759
2733
|
this.removeKccController(entity);
|
|
2760
2734
|
}
|
|
2761
2735
|
|
|
2762
|
-
private resetForFullReconcile(transformlessStatic: ReadonlySet<number>): void {
|
|
2763
|
-
// Without a descriptor/hash mirror, an overflow cannot prove which existing
|
|
2764
|
-
// Transform-backed body changed. Recreate those bodies from the final ECS
|
|
2765
|
-
// combination. Dynamic velocity/contact state is intentionally reset during
|
|
2766
|
-
// this recovery path so stale motion type or collider data cannot survive.
|
|
2767
|
-
for (const entity of [...this.entityMap.keys()]) {
|
|
2768
|
-
if (transformlessStatic.has(entity) && this.isCommittedFixedBody(entity)) {
|
|
2769
|
-
this.removeKccController(entity);
|
|
2770
|
-
continue;
|
|
2771
|
-
}
|
|
2772
|
-
this.removeEntity(entity);
|
|
2773
|
-
}
|
|
2774
|
-
}
|
|
2775
|
-
|
|
2776
|
-
private fullReconcilePhysicsState(state: PhysicsSyncState): void {
|
|
2777
|
-
const descriptors: PhysicsSyncDescriptor[] = [];
|
|
2778
|
-
const transformlessStatic = new Set<number>();
|
|
2779
|
-
const committedDerived =
|
|
2780
|
-
this.derivedBodies.size > 0 ? this.captureDerivedPhysicsState() : undefined;
|
|
2781
|
-
for (const query of state.queries)
|
|
2782
|
-
for (const row of query) {
|
|
2783
|
-
if (!row.has(state.transformComponent)) {
|
|
2784
|
-
if (physicsRowIsStatic(row)) transformlessStatic.add(row.entity);
|
|
2785
|
-
continue;
|
|
2786
|
-
}
|
|
2787
|
-
const descriptor = readPhysicsSyncDescriptor(
|
|
2788
|
-
row,
|
|
2789
|
-
state.transformComponent,
|
|
2790
|
-
state.globalTransformComponent,
|
|
2791
|
-
);
|
|
2792
|
-
if (descriptor !== undefined) descriptors.push(descriptor);
|
|
2793
|
-
}
|
|
2794
|
-
|
|
2795
|
-
this.resetForFullReconcile(transformlessStatic);
|
|
2796
|
-
for (const descriptor of descriptors) {
|
|
2797
|
-
this.ensureBody(
|
|
2798
|
-
descriptor.entity,
|
|
2799
|
-
descriptor.transform,
|
|
2800
|
-
descriptor.rigidBody,
|
|
2801
|
-
descriptor.collider,
|
|
2802
|
-
);
|
|
2803
|
-
}
|
|
2804
|
-
if (committedDerived !== undefined) {
|
|
2805
|
-
const restorableBodies = committedDerived.bodies.filter(
|
|
2806
|
-
(body) => this.entityMap.has(body.entity) && !this.derivedBodies.has(body.entity),
|
|
2807
|
-
);
|
|
2808
|
-
if (restorableBodies.length > 0) {
|
|
2809
|
-
const restorable = Object.freeze({
|
|
2810
|
-
...committedDerived,
|
|
2811
|
-
bodies: Object.freeze(restorableBodies),
|
|
2812
|
-
});
|
|
2813
|
-
const restored = this.restoreDerivedPhysicsState(restorable);
|
|
2814
|
-
if (!restored.ok) {
|
|
2815
|
-
// A full ECS rebuild has already replaced native bodies. Keep the
|
|
2816
|
-
// rebuilt ordinary state queryable, but do not expose a mixed derived
|
|
2817
|
-
// result: pending candidates are invalidated and the next consumer
|
|
2818
|
-
// submission is the explicit recovery boundary.
|
|
2819
|
-
this.invalidateDerivedShapeCandidates('full-reconcile-restore-failed');
|
|
2820
|
-
}
|
|
2821
|
-
}
|
|
2822
|
-
}
|
|
2823
|
-
drainPhysicsChangeQueries(state.changeQueries);
|
|
2824
|
-
state.structuralCursor = readStructuralEvidence(state.world, state.structuralCursor).cursor;
|
|
2825
|
-
state.structureEpoch = state.world.getStructureEpoch();
|
|
2826
|
-
state.initialized = true;
|
|
2827
|
-
}
|
|
2828
|
-
|
|
2829
2736
|
private reconcilePhysicsDelta(
|
|
2830
2737
|
state: PhysicsSyncState,
|
|
2831
2738
|
entity: EntityHandle,
|
|
@@ -2989,103 +2896,74 @@ export class RapierPhysicsWorld3D implements PhysicsWorld {
|
|
|
2989
2896
|
transformComponent,
|
|
2990
2897
|
globalTransformComponent,
|
|
2991
2898
|
queries: [queryResult.value, bodyQuery.value] as unknown as readonly PhysicsSyncQuery[],
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
2899
|
+
projection: createStateProjection(
|
|
2900
|
+
world,
|
|
2901
|
+
[
|
|
2902
|
+
transformComponent,
|
|
2903
|
+
globalTransformComponent,
|
|
2904
|
+
Collider,
|
|
2905
|
+
RigidBody,
|
|
2906
|
+
CharacterController,
|
|
2907
|
+
ChildOf,
|
|
2908
|
+
Disabled,
|
|
2909
|
+
],
|
|
2910
|
+
[Collider, RigidBody],
|
|
2911
|
+
),
|
|
2912
|
+
accepted: new Map(),
|
|
3003
2913
|
};
|
|
3004
2914
|
this.syncState = state;
|
|
3005
2915
|
}
|
|
3006
2916
|
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
state.structureEpoch = world.getStructureEpoch();
|
|
3017
|
-
if (structural.status === 'overflow') {
|
|
3018
|
-
this.fullReconcilePhysicsState(state);
|
|
3019
|
-
return;
|
|
2917
|
+
const batch = state.projection.read();
|
|
2918
|
+
const updates: { index: number; descriptor: PhysicsSyncDescriptor | undefined }[] = [];
|
|
2919
|
+
for (const index of batch.indices) {
|
|
2920
|
+
const entity = state.projection.entity(index);
|
|
2921
|
+
const previous = state.accepted.get(index);
|
|
2922
|
+
if (previous !== undefined && previous.entity !== entity) this.removeEntity(previous.entity);
|
|
2923
|
+
if (entity === undefined) {
|
|
2924
|
+
updates.push({ index, descriptor: undefined });
|
|
2925
|
+
continue;
|
|
3020
2926
|
}
|
|
3021
|
-
|
|
3022
|
-
const
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
const rigidBodyId = componentId(RigidBody);
|
|
3026
|
-
const characterControllerId = componentId(CharacterController);
|
|
3027
|
-
const childOfId = componentId(ChildOf);
|
|
3028
|
-
const disabledId = componentId(Disabled);
|
|
3029
|
-
for (const evidence of structural.events) {
|
|
3030
|
-
const id = evidence.componentId;
|
|
3031
|
-
if (
|
|
3032
|
-
evidence.kind !== 'spawn' &&
|
|
3033
|
-
evidence.kind !== 'despawn' &&
|
|
3034
|
-
id !== transformId &&
|
|
3035
|
-
id !== globalTransformId &&
|
|
3036
|
-
id !== colliderId &&
|
|
3037
|
-
id !== rigidBodyId &&
|
|
3038
|
-
id !== characterControllerId &&
|
|
3039
|
-
id !== childOfId &&
|
|
3040
|
-
id !== disabledId
|
|
3041
|
-
) {
|
|
3042
|
-
continue;
|
|
3043
|
-
}
|
|
3044
|
-
const delta = ensurePhysicsDelta(deltas, evidence.entity);
|
|
3045
|
-
if (evidence.kind === 'spawn' || evidence.kind === 'despawn') {
|
|
3046
|
-
delta.transformChanged = true;
|
|
3047
|
-
delta.colliderChanged = true;
|
|
3048
|
-
delta.rigidBodyChanged = true;
|
|
3049
|
-
delta.characterControllerChanged = true;
|
|
3050
|
-
delta.characterControllerStructureChanged = true;
|
|
3051
|
-
} else if (id === transformId || id === globalTransformId || id === childOfId) {
|
|
3052
|
-
delta.transformChanged = true;
|
|
3053
|
-
} else if (id === colliderId || id === disabledId) {
|
|
3054
|
-
delta.colliderChanged = true;
|
|
3055
|
-
} else if (id === rigidBodyId) {
|
|
3056
|
-
delta.rigidBodyChanged = true;
|
|
3057
|
-
} else if (id === characterControllerId) {
|
|
3058
|
-
delta.characterControllerChanged = true;
|
|
3059
|
-
delta.characterControllerStructureChanged = true;
|
|
3060
|
-
}
|
|
2927
|
+
let row: PhysicsSyncQueryRow | undefined;
|
|
2928
|
+
for (const query of state.queries) {
|
|
2929
|
+
row = query.at(entity);
|
|
2930
|
+
if (row !== undefined) break;
|
|
3061
2931
|
}
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
for (const rawEntity of span.entities) {
|
|
3067
|
-
const entity = rawEntity as EntityHandle;
|
|
3068
|
-
const delta = ensurePhysicsDelta(deltas, entity);
|
|
3069
|
-
if (
|
|
3070
|
-
entry.component === transformComponent ||
|
|
3071
|
-
entry.component === globalTransformComponent ||
|
|
3072
|
-
entry.component === ChildOf
|
|
3073
|
-
) {
|
|
3074
|
-
delta.transformChanged = true;
|
|
3075
|
-
} else if (entry.component === Collider) {
|
|
3076
|
-
delta.colliderChanged = true;
|
|
3077
|
-
} else if (entry.component === RigidBody) {
|
|
3078
|
-
delta.rigidBodyChanged = true;
|
|
3079
|
-
} else if (entry.component === CharacterController) {
|
|
3080
|
-
delta.characterControllerChanged = true;
|
|
3081
|
-
}
|
|
3082
|
-
}
|
|
2932
|
+
if (row === undefined) {
|
|
2933
|
+
this.removeEntity(entity);
|
|
2934
|
+
updates.push({ index, descriptor: undefined });
|
|
2935
|
+
continue;
|
|
3083
2936
|
}
|
|
2937
|
+
const descriptor = readPhysicsSyncDescriptor(
|
|
2938
|
+
row,
|
|
2939
|
+
transformComponent,
|
|
2940
|
+
globalTransformComponent,
|
|
2941
|
+
);
|
|
2942
|
+
const prior = previous?.entity === entity ? previous : undefined;
|
|
2943
|
+
const delta: PhysicsEntityDelta = {
|
|
2944
|
+
transformChanged: !samePhysicsValue(prior?.transform, descriptor?.transform),
|
|
2945
|
+
colliderChanged:
|
|
2946
|
+
descriptor === undefined
|
|
2947
|
+
? state.projection.changed(entity, Collider)
|
|
2948
|
+
: !samePhysicsValue(prior?.collider, descriptor.collider),
|
|
2949
|
+
rigidBodyChanged:
|
|
2950
|
+
descriptor === undefined
|
|
2951
|
+
? state.projection.changed(entity, RigidBody)
|
|
2952
|
+
: !samePhysicsValue(prior?.rigidBody, descriptor.rigidBody),
|
|
2953
|
+
characterControllerChanged:
|
|
2954
|
+
prior?.characterControllerOffset !== descriptor?.characterControllerOffset ||
|
|
2955
|
+
prior?.hasCharacterController !== descriptor?.hasCharacterController,
|
|
2956
|
+
characterControllerStructureChanged:
|
|
2957
|
+
prior?.hasCharacterController !== descriptor?.hasCharacterController,
|
|
2958
|
+
};
|
|
2959
|
+
this.reconcilePhysicsDelta(state, entity, delta);
|
|
2960
|
+
updates.push({ index, descriptor: descriptor ?? (this.hasBody(entity) ? prior : undefined) });
|
|
2961
|
+
}
|
|
2962
|
+
batch.accept();
|
|
2963
|
+
for (const { index, descriptor } of updates) {
|
|
2964
|
+
if (descriptor === undefined) state.accepted.delete(index);
|
|
2965
|
+
else state.accepted.set(index, descriptor);
|
|
3084
2966
|
}
|
|
3085
|
-
|
|
3086
|
-
if (deltas.size === 0) return;
|
|
3087
|
-
|
|
3088
|
-
for (const [entity, delta] of deltas) this.reconcilePhysicsDelta(state, entity, delta);
|
|
3089
2967
|
}
|
|
3090
2968
|
|
|
3091
2969
|
/**
|