@gg-web-engine/ammo 0.0.30 → 0.0.37
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/README.md +7 -0
- package/build_gg_ammo/Makefile +41 -0
- package/build_gg_ammo/README.md +17 -0
- package/build_gg_ammo/ammo_patches.txt +20 -0
- package/build_gg_ammo/bullet_patches.txt +27 -0
- package/build_gg_ammo/patch_files/ammo.idl +2380 -0
- package/dist/ammo-debugger.d.ts +1 -1
- package/dist/ammo-debugger.js +1 -1
- package/dist/ammo-factory.d.ts +1 -1
- package/dist/ammo-factory.js +1 -1
- package/dist/ammo.js/ammo-ambient.d.ts +2577 -0
- package/dist/ammo.js/ammo.d.ts +2578 -0
- package/dist/ammo.js/ammo.js +43 -0
- package/dist/ammo.js/ammo.wasm.js +1315 -0
- package/dist/ammo.js/ammo.wasm.wasm +0 -0
- package/dist/components/ammo-body.component.d.ts +1 -1
- package/dist/components/ammo-body.component.js +5 -6
- package/dist/components/ammo-raycast-vehicle.component.d.ts +9 -2
- package/dist/components/ammo-raycast-vehicle.component.js +32 -4
- package/dist/components/ammo-rigid-body.component.d.ts +1 -1
- package/dist/components/ammo-rigid-body.component.js +3 -3
- package/dist/components/ammo-trigger.component.d.ts +1 -1
- package/dist/components/ammo-trigger.component.js +4 -4
- package/dist/components/ammo-world.component.d.ts +1 -1
- package/dist/components/ammo-world.component.js +4 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +32 -8
- package/test/components/ammo-trigger.component.spec.ts +122 -0
- package/tsconfig.json +2 -2
- package/dist/ammo-utils.d.ts +0 -2
- package/dist/ammo-utils.js +0 -1
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CollisionGroup, Gg3dWorld, IEntity, Point3, Point4, VisualTypeDocRepo3D } from '@gg-web-engine/core';
|
|
2
2
|
import { AmmoWorldComponent } from './ammo-world.component';
|
|
3
|
-
import Ammo from '
|
|
3
|
+
import Ammo from '../ammo.js/ammo';
|
|
4
4
|
import { AmmoPhysicsTypeDocRepo } from '../types';
|
|
5
5
|
export declare abstract class AmmoBodyComponent<T extends Ammo.btCollisionObject> {
|
|
6
6
|
protected readonly world: AmmoWorldComponent;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { BitMask } from '@gg-web-engine/core';
|
|
2
|
-
import Ammo from '
|
|
3
|
-
import { ammoId } from '../ammo-utils';
|
|
2
|
+
import Ammo from '../ammo.js/ammo';
|
|
4
3
|
export class AmmoBodyComponent {
|
|
5
4
|
constructor(world, _nativeBody) {
|
|
6
5
|
this.world = world;
|
|
@@ -9,7 +8,7 @@ export class AmmoBodyComponent {
|
|
|
9
8
|
this.addedToWorld = false;
|
|
10
9
|
this._interactWithCGsMask = BitMask.full(16);
|
|
11
10
|
this._ownCGsMask = BitMask.full(16);
|
|
12
|
-
AmmoBodyComponent.nativeBodyReverseMap.set(
|
|
11
|
+
AmmoBodyComponent.nativeBodyReverseMap.set(Ammo.getPointer(this.nativeBody), this);
|
|
13
12
|
}
|
|
14
13
|
get position() {
|
|
15
14
|
const origin = this.nativeBody.getWorldTransform().getOrigin();
|
|
@@ -36,9 +35,9 @@ export class AmmoBodyComponent {
|
|
|
36
35
|
if (value == this._nativeBody) {
|
|
37
36
|
return;
|
|
38
37
|
}
|
|
39
|
-
AmmoBodyComponent.nativeBodyReverseMap.delete(
|
|
38
|
+
AmmoBodyComponent.nativeBodyReverseMap.delete(Ammo.getPointer(this._nativeBody));
|
|
40
39
|
this._nativeBody = value;
|
|
41
|
-
AmmoBodyComponent.nativeBodyReverseMap.set(
|
|
40
|
+
AmmoBodyComponent.nativeBodyReverseMap.set(Ammo.getPointer(value), this);
|
|
42
41
|
}
|
|
43
42
|
get interactWithCollisionGroups() {
|
|
44
43
|
return BitMask.unpack(this._interactWithCGsMask, 16);
|
|
@@ -95,7 +94,7 @@ export class AmmoBodyComponent {
|
|
|
95
94
|
catch (_a) {
|
|
96
95
|
// pass
|
|
97
96
|
}
|
|
98
|
-
AmmoBodyComponent.nativeBodyReverseMap.delete(
|
|
97
|
+
AmmoBodyComponent.nativeBodyReverseMap.delete(Ammo.getPointer(this.nativeBody));
|
|
99
98
|
}
|
|
100
99
|
}
|
|
101
100
|
AmmoBodyComponent.nativeBodyReverseMap = new Map();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Gg3dWorld, IRaycastVehicleComponent, Point3, Point4, RaycastVehicle3dEntity, SuspensionOptions, VisualTypeDocRepo3D, WheelOptions } from '@gg-web-engine/core';
|
|
2
|
-
import Ammo from '
|
|
1
|
+
import { CollisionGroup, Gg3dWorld, IRaycastVehicleComponent, Point3, Point4, RaycastVehicle3dEntity, SuspensionOptions, VisualTypeDocRepo3D, WheelOptions } from '@gg-web-engine/core';
|
|
2
|
+
import Ammo from '../ammo.js/ammo';
|
|
3
3
|
import { AmmoRigidBodyComponent } from './ammo-rigid-body.component';
|
|
4
4
|
import { AmmoWorldComponent } from './ammo-world.component';
|
|
5
5
|
import { AmmoPhysicsTypeDocRepo } from '../types';
|
|
@@ -11,9 +11,16 @@ export declare class AmmoRaycastVehicleComponent extends AmmoRigidBodyComponent
|
|
|
11
11
|
protected readonly wheelDirectionCS0: Ammo.btVector3;
|
|
12
12
|
protected readonly wheelAxleCS: Ammo.btVector3;
|
|
13
13
|
entity: RaycastVehicle3dEntity | null;
|
|
14
|
+
protected readonly raycaster: Ammo.btDefaultVehicleRaycaster;
|
|
15
|
+
get interactWithCollisionGroups(): CollisionGroup[];
|
|
16
|
+
set interactWithCollisionGroups(value: CollisionGroup[] | 'all');
|
|
17
|
+
get ownCollisionGroups(): CollisionGroup[];
|
|
18
|
+
set ownCollisionGroups(value: CollisionGroup[] | 'all');
|
|
19
|
+
refreshCG(): void;
|
|
14
20
|
constructor(world: AmmoWorldComponent, chassisBody: AmmoRigidBodyComponent);
|
|
15
21
|
get wheelSpeed(): number;
|
|
16
22
|
addToWorld(world: Gg3dWorld<VisualTypeDocRepo3D, AmmoPhysicsTypeDocRepo>): void;
|
|
23
|
+
removeFromWorld(world: Gg3dWorld<VisualTypeDocRepo3D, AmmoPhysicsTypeDocRepo>): void;
|
|
17
24
|
addWheel(options: WheelOptions, suspensionOptions: SuspensionOptions): void;
|
|
18
25
|
setSteering(wheelIndex: number, steering: number): void;
|
|
19
26
|
applyEngineForce(wheelIndex: number, force: number): void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { BitMask, } from '@gg-web-engine/core';
|
|
2
|
+
import Ammo from '../ammo.js/ammo';
|
|
2
3
|
import { AmmoRigidBodyComponent } from './ammo-rigid-body.component';
|
|
3
4
|
export class AmmoRaycastVehicleComponent extends AmmoRigidBodyComponent {
|
|
4
5
|
constructor(world, chassisBody) {
|
|
@@ -9,23 +10,46 @@ export class AmmoRaycastVehicleComponent extends AmmoRigidBodyComponent {
|
|
|
9
10
|
this.wheelDirectionCS0 = new Ammo.btVector3(0, 0, -1);
|
|
10
11
|
this.wheelAxleCS = new Ammo.btVector3(1, 0, 0);
|
|
11
12
|
this.entity = null;
|
|
12
|
-
this.
|
|
13
|
+
this.raycaster = new Ammo.btDefaultVehicleRaycaster(world.dynamicAmmoWorld);
|
|
14
|
+
this.nativeVehicle = new Ammo.btRaycastVehicle(this.vehicleTuning, this.chassisBody.nativeBody, this.raycaster);
|
|
15
|
+
this.raycaster.set_m_collisionFilterGroup(BitMask.pack(this.chassisBody.ownCollisionGroups, 16));
|
|
16
|
+
this.raycaster.set_m_collisionFilterMask(BitMask.pack(this.chassisBody.interactWithCollisionGroups, 16));
|
|
13
17
|
this.nativeVehicle.setCoordinateSystem(0, 2, 1);
|
|
14
18
|
}
|
|
19
|
+
get interactWithCollisionGroups() {
|
|
20
|
+
return this.chassisBody.interactWithCollisionGroups;
|
|
21
|
+
}
|
|
22
|
+
set interactWithCollisionGroups(value) {
|
|
23
|
+
this.chassisBody.interactWithCollisionGroups = value;
|
|
24
|
+
this.raycaster.set_m_collisionFilterMask(BitMask.pack(this.chassisBody.interactWithCollisionGroups, 16));
|
|
25
|
+
}
|
|
26
|
+
get ownCollisionGroups() {
|
|
27
|
+
return this.chassisBody.ownCollisionGroups;
|
|
28
|
+
}
|
|
29
|
+
set ownCollisionGroups(value) {
|
|
30
|
+
this.chassisBody.ownCollisionGroups = value;
|
|
31
|
+
this.raycaster.set_m_collisionFilterGroup(BitMask.pack(this.chassisBody.ownCollisionGroups, 16));
|
|
32
|
+
}
|
|
33
|
+
refreshCG() {
|
|
34
|
+
this.chassisBody.refreshCG();
|
|
35
|
+
}
|
|
15
36
|
get wheelSpeed() {
|
|
16
37
|
// FIXME not correct (shows chassis speed in world)
|
|
17
38
|
return this.nativeVehicle.getCurrentSpeedKmHour() / 3.6;
|
|
18
39
|
}
|
|
19
40
|
addToWorld(world) {
|
|
20
|
-
var _a;
|
|
21
41
|
if (world.physicsWorld != this.world) {
|
|
22
42
|
throw new Error('Ammo raycast vehicle cannot be shared between different worlds');
|
|
23
43
|
}
|
|
24
44
|
// TODO parked cars can be deactivated until we start handling them. Needs explicit activation call
|
|
25
45
|
this.chassisBody.nativeBody.setActivationState(4); // btCollisionObject::DISABLE_DEACTIVATION
|
|
26
|
-
|
|
46
|
+
this.chassisBody.addToWorld(world);
|
|
27
47
|
this.world.dynamicAmmoWorld.addAction(this.nativeVehicle);
|
|
28
48
|
}
|
|
49
|
+
removeFromWorld(world) {
|
|
50
|
+
this.chassisBody.removeFromWorld(world);
|
|
51
|
+
this.world.dynamicAmmoWorld.removeAction(this.nativeVehicle);
|
|
52
|
+
}
|
|
29
53
|
addWheel(options, suspensionOptions) {
|
|
30
54
|
const wheelInfo = this.nativeVehicle.addWheel(new Ammo.btVector3(options.position.x, options.position.y, options.position.z), this.wheelDirectionCS0, this.wheelAxleCS, suspensionOptions.restLength, options.tyreRadius, this.vehicleTuning, options.isFront);
|
|
31
55
|
wheelInfo.set_m_suspensionStiffness(suspensionOptions.stiffness);
|
|
@@ -48,11 +72,15 @@ export class AmmoRaycastVehicleComponent extends AmmoRigidBodyComponent {
|
|
|
48
72
|
return this.nativeVehicle.getWheelInfo(wheelIndex).get_m_raycastInfo().get_m_groundObject() > 0;
|
|
49
73
|
}
|
|
50
74
|
getWheelTransform(wheelIndex) {
|
|
75
|
+
// Ammo.js provides wrong wheel rotation when using coordinate system `0, 2, 1`, but it is correct if set `0, 1, 2`
|
|
76
|
+
this.nativeVehicle.setCoordinateSystem(0, 1, 2);
|
|
51
77
|
// when interpolated transform set to `true`, wheels are jittering relatively to car on high speeds
|
|
52
78
|
this.nativeVehicle.updateWheelTransform(wheelIndex, false);
|
|
79
|
+
this.nativeVehicle.setCoordinateSystem(0, 2, 1);
|
|
53
80
|
const transform = this.nativeVehicle.getWheelTransformWS(wheelIndex);
|
|
54
81
|
const origin = transform.getOrigin();
|
|
55
82
|
const quaternion = transform.getRotation();
|
|
83
|
+
quaternion.normalize();
|
|
56
84
|
return {
|
|
57
85
|
position: { x: origin.x(), y: origin.y(), z: origin.z() },
|
|
58
86
|
rotation: { x: quaternion.x(), y: quaternion.y(), z: quaternion.z(), w: quaternion.w() },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AmmoWorldComponent } from './ammo-world.component';
|
|
2
|
-
import Ammo from '
|
|
2
|
+
import Ammo from '../ammo.js/ammo';
|
|
3
3
|
import { AmmoBodyComponent } from './ammo-body.component';
|
|
4
4
|
import { Entity3d, Gg3dWorld, IRigidBody3dComponent, Point3, VisualTypeDocRepo3D } from '@gg-web-engine/core';
|
|
5
5
|
import { AmmoPhysicsTypeDocRepo } from '../types';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Ammo from '
|
|
1
|
+
import Ammo from '../ammo.js/ammo';
|
|
2
2
|
import { AmmoBodyComponent } from './ammo-body.component';
|
|
3
3
|
export class AmmoRigidBodyComponent extends AmmoBodyComponent {
|
|
4
4
|
constructor(world, _nativeBody) {
|
|
@@ -23,8 +23,8 @@ export class AmmoRigidBodyComponent extends AmmoBodyComponent {
|
|
|
23
23
|
}
|
|
24
24
|
clone() {
|
|
25
25
|
return this.world.factory.createRigidBodyFromShape(this._nativeBody.getCollisionShape(), {
|
|
26
|
-
dynamic: !this._nativeBody.
|
|
27
|
-
mass:
|
|
26
|
+
dynamic: !this._nativeBody.isStaticOrKinematicObject(),
|
|
27
|
+
mass: this._nativeBody.getMass(),
|
|
28
28
|
friction: this._nativeBody.getFriction(),
|
|
29
29
|
restitution: this._nativeBody.getRestitution(),
|
|
30
30
|
}, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Gg3dWorld, IEntity, ITrigger3dComponent, VisualTypeDocRepo3D } from '@gg-web-engine/core';
|
|
2
2
|
import { AmmoWorldComponent } from './ammo-world.component';
|
|
3
3
|
import { Observable, Subject } from 'rxjs';
|
|
4
|
-
import Ammo from '
|
|
4
|
+
import Ammo from '../ammo.js/ammo';
|
|
5
5
|
import { AmmoBodyComponent } from './ammo-body.component';
|
|
6
6
|
import { AmmoRigidBodyComponent } from './ammo-rigid-body.component';
|
|
7
7
|
import { AmmoPhysicsTypeDocRepo } from '../types';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { filter, map, Subject } from 'rxjs';
|
|
2
|
+
import Ammo from '../ammo.js/ammo';
|
|
2
3
|
import { AmmoBodyComponent } from './ammo-body.component';
|
|
3
|
-
import { ammoId } from '../ammo-utils';
|
|
4
4
|
export class AmmoTriggerComponent extends AmmoBodyComponent {
|
|
5
5
|
constructor(world, _nativeBody) {
|
|
6
6
|
super(world, _nativeBody);
|
|
@@ -23,7 +23,7 @@ export class AmmoTriggerComponent extends AmmoBodyComponent {
|
|
|
23
23
|
for (const overlap of this.overlaps.keys()) {
|
|
24
24
|
if (!newOverlaps.has(overlap)) {
|
|
25
25
|
this.overlaps.delete(overlap);
|
|
26
|
-
this.onLeft$.next(
|
|
26
|
+
this.onLeft$.next(Ammo.getPointer(overlap));
|
|
27
27
|
}
|
|
28
28
|
else {
|
|
29
29
|
newOverlaps.delete(overlap);
|
|
@@ -31,7 +31,7 @@ export class AmmoTriggerComponent extends AmmoBodyComponent {
|
|
|
31
31
|
}
|
|
32
32
|
for (const newOverlap of newOverlaps) {
|
|
33
33
|
this.overlaps.add(newOverlap);
|
|
34
|
-
this.onEnter$.next(
|
|
34
|
+
this.onEnter$.next(Ammo.getPointer(newOverlap));
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
clone() {
|
|
@@ -50,7 +50,7 @@ export class AmmoTriggerComponent extends AmmoBodyComponent {
|
|
|
50
50
|
var _a;
|
|
51
51
|
super.removeFromWorld(world);
|
|
52
52
|
for (const body of this.overlaps) {
|
|
53
|
-
this.onLeft$.next(
|
|
53
|
+
this.onLeft$.next(Ammo.getPointer(body));
|
|
54
54
|
}
|
|
55
55
|
this.overlaps.clear();
|
|
56
56
|
(_a = this.world.dynamicAmmoWorld) === null || _a === void 0 ? void 0 : _a.removeCollisionObject(this.nativeBody);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CollisionGroup, Gg3dWorld, IDebugPhysicsDrawer, IPhysicsWorld3dComponent, Point3, Point4, VisualTypeDocRepo3D } from '@gg-web-engine/core';
|
|
2
|
-
import Ammo from '
|
|
2
|
+
import Ammo from '../ammo.js/ammo';
|
|
3
3
|
import { AmmoFactory } from '../ammo-factory';
|
|
4
4
|
import { AmmoLoader } from '../ammo-loader';
|
|
5
5
|
import { AmmoPhysicsTypeDocRepo } from '../types';
|
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import Ammo from '
|
|
10
|
+
import Ammo from '../ammo.js/ammo';
|
|
11
11
|
import { AmmoFactory } from '../ammo-factory';
|
|
12
12
|
import { AmmoLoader } from '../ammo-loader';
|
|
13
13
|
import { AmmoDebugger, AmmoDebugMode } from '../ammo-debugger';
|
|
@@ -66,6 +66,9 @@ export class AmmoWorldComponent {
|
|
|
66
66
|
this.solver = new Ammo.btSequentialImpulseConstraintSolver();
|
|
67
67
|
this.gravityVector = new Ammo.btVector3(this._gravity.x, this._gravity.y, this._gravity.z);
|
|
68
68
|
this._dynamicAmmoWorld = new Ammo.btDiscreteDynamicsWorld(this.dispatcher, this.broadphase, this.solver, this.collisionConfiguration);
|
|
69
|
+
// fix the problem when dynamic objects clip in the static/kinematic objects, moved manually.
|
|
70
|
+
// the problem is introduced in bullet here: https://github.com/bulletphysics/bullet3/commit/96c1ee42565d951347e515e40f41f71d0963d2d0
|
|
71
|
+
this._dynamicAmmoWorld.getSolverInfo().set_m_erp2(0.8);
|
|
69
72
|
this._dynamicAmmoWorld.getPairCache().setInternalGhostPairCallback(this.ghostPairCallback);
|
|
70
73
|
this._dynamicAmmoWorld.setGravity(this.gravityVector);
|
|
71
74
|
this._factory = new AmmoFactory(this);
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gg-web-engine/ammo",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.37",
|
|
4
4
|
"description": "An attempt to create open source game engine for browser",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"test": "
|
|
8
|
+
"test": "jest",
|
|
9
9
|
"prettier-format": "prettier --config ../core/.prettierrc 'src/**/*.ts' --write",
|
|
10
|
-
"prepublish": "rm -rf ./dist/ && tsc",
|
|
11
|
-
"build": "tsc"
|
|
10
|
+
"prepublish": "rm -rf ./dist/ && tsc && cp -R ./src/ammo.js ./dist",
|
|
11
|
+
"build": "rm -rf ./dist/ && tsc && cp -R ./src/ammo.js ./dist"
|
|
12
12
|
},
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
@@ -34,15 +34,39 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@gg-web-engine/core": "0.0.
|
|
38
|
-
"
|
|
37
|
+
"@gg-web-engine/core": "0.0.37",
|
|
38
|
+
"@types/jest": "^29.5.0",
|
|
39
|
+
"jest": "^29.5.0",
|
|
40
|
+
"jest-environment-jsdom": "^29.5.0",
|
|
39
41
|
"mini-signals": "2.0.0",
|
|
40
42
|
"prettier": "^2.8.6",
|
|
43
|
+
"ts-jest": "^29.0.5",
|
|
41
44
|
"typescript": "~4.7.2"
|
|
42
45
|
},
|
|
43
46
|
"peerDependencies": {
|
|
44
|
-
"@gg-web-engine/core": "0.0.
|
|
45
|
-
"ammojs-typed": "1.0.6",
|
|
47
|
+
"@gg-web-engine/core": "0.0.37",
|
|
46
48
|
"mini-signals": "2.0.0"
|
|
49
|
+
},
|
|
50
|
+
"jest": {
|
|
51
|
+
"rootDir": ".",
|
|
52
|
+
"testRegex": "\\.spec\\.ts$",
|
|
53
|
+
"transform": {
|
|
54
|
+
"^.+\\.(t|j)s$": ["ts-jest", { "tsconfig": { "esModuleInterop": true } }]
|
|
55
|
+
},
|
|
56
|
+
"moduleNameMapper": {
|
|
57
|
+
"@gg-web-engine/core": "<rootDir>/../core/src/index.ts"
|
|
58
|
+
},
|
|
59
|
+
"preset": "ts-jest/presets/default",
|
|
60
|
+
"collectCoverageFrom": [
|
|
61
|
+
"**/*.ts",
|
|
62
|
+
"!**/*.module.ts"
|
|
63
|
+
],
|
|
64
|
+
"coveragePathIgnorePatterns": [
|
|
65
|
+
"<rootDir>/node_modules/",
|
|
66
|
+
"<rootDir>/dist/",
|
|
67
|
+
"<rootDir>/test/"
|
|
68
|
+
],
|
|
69
|
+
"coverageDirectory": "./coverage",
|
|
70
|
+
"testEnvironment": "jsdom"
|
|
47
71
|
}
|
|
48
72
|
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Pnt3 } from '@gg-web-engine/core';
|
|
2
|
+
import { AmmoFactory, AmmoWorldComponent } from '../../src';
|
|
3
|
+
|
|
4
|
+
describe(`AmmoTriggerComponent`, () => {
|
|
5
|
+
|
|
6
|
+
let world: AmmoWorldComponent;
|
|
7
|
+
let factory: AmmoFactory;
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
if (world) {
|
|
10
|
+
world.dispose();
|
|
11
|
+
}
|
|
12
|
+
world = new AmmoWorldComponent();
|
|
13
|
+
factory = new AmmoFactory(world);
|
|
14
|
+
await world.init();
|
|
15
|
+
world.gravity = Pnt3.O;
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
afterAll(() => {
|
|
19
|
+
world.dispose();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it(`should detect object intersection`, async () => {
|
|
23
|
+
const trigger = factory.createTrigger({ shape: 'BOX', dimensions: { x: 10, y: 10, z: 10 } });
|
|
24
|
+
trigger.addToWorld({ physicsWorld: world } as any);
|
|
25
|
+
const ball = factory.createRigidBody({
|
|
26
|
+
shape: { shape: 'SPHERE', radius: 1 },
|
|
27
|
+
body: { dynamic: true, mass: 1 },
|
|
28
|
+
}, { position: { x: 0, y: 0, z: 12 } });
|
|
29
|
+
ball.addToWorld({ physicsWorld: world } as any);
|
|
30
|
+
ball.linearVelocity = { x: 0, y: 0, z: -10 };
|
|
31
|
+
let enterRegistered = false;
|
|
32
|
+
let exitRegistered = false;
|
|
33
|
+
trigger.onEntityEntered.subscribe(((obj) => {
|
|
34
|
+
enterRegistered = obj === ball;
|
|
35
|
+
}));
|
|
36
|
+
trigger.onEntityLeft.subscribe(((obj) => {
|
|
37
|
+
exitRegistered = obj === ball;
|
|
38
|
+
}));
|
|
39
|
+
world.simulate(500);
|
|
40
|
+
trigger.checkOverlaps(); // trigger entity performs that on tick
|
|
41
|
+
expect(enterRegistered).toBe(false);
|
|
42
|
+
expect(exitRegistered).toBe(false);
|
|
43
|
+
|
|
44
|
+
world.simulate(500);
|
|
45
|
+
trigger.checkOverlaps();
|
|
46
|
+
expect(enterRegistered).toBe(true);
|
|
47
|
+
expect(exitRegistered).toBe(false);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it(`should detect end of object intersection`, async () => {
|
|
51
|
+
const trigger = factory.createTrigger({ shape: 'BOX', dimensions: { x: 10, y: 10, z: 10 } });
|
|
52
|
+
trigger.addToWorld({ physicsWorld: world } as any);
|
|
53
|
+
const ball = factory.createRigidBody({
|
|
54
|
+
shape: { shape: 'SPHERE', radius: 1 },
|
|
55
|
+
body: { dynamic: true, mass: 1 },
|
|
56
|
+
}, { position: { x: 0, y: 0, z: 12 } });
|
|
57
|
+
ball.addToWorld({ physicsWorld: world } as any);
|
|
58
|
+
ball.linearVelocity = { x: 0, y: 0, z: -10 };
|
|
59
|
+
let exitRegistered = false;
|
|
60
|
+
trigger.onEntityLeft.subscribe(((obj) => {
|
|
61
|
+
exitRegistered = obj === ball;
|
|
62
|
+
}));
|
|
63
|
+
world.simulate(1000);
|
|
64
|
+
trigger.checkOverlaps();
|
|
65
|
+
expect(exitRegistered).toBe(false);
|
|
66
|
+
world.simulate(1000);
|
|
67
|
+
trigger.checkOverlaps();
|
|
68
|
+
expect(exitRegistered).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it(`should fire object intersection if spawned inside`, async () => {
|
|
72
|
+
const trigger = factory.createTrigger({ shape: 'BOX', dimensions: { x: 10, y: 10, z: 10 } });
|
|
73
|
+
trigger.addToWorld({ physicsWorld: world } as any);
|
|
74
|
+
const ball = factory.createRigidBody({
|
|
75
|
+
shape: { shape: 'SPHERE', radius: 1 },
|
|
76
|
+
body: { dynamic: true, mass: 1 },
|
|
77
|
+
}, { position: { x: 0, y: 0, z: 0 } });
|
|
78
|
+
ball.addToWorld({ physicsWorld: world } as any);
|
|
79
|
+
let enterRegistered = false;
|
|
80
|
+
trigger.onEntityEntered.subscribe(((obj) => {
|
|
81
|
+
enterRegistered = obj === ball;
|
|
82
|
+
}));
|
|
83
|
+
world.simulate(1000);
|
|
84
|
+
trigger.checkOverlaps();
|
|
85
|
+
expect(enterRegistered).toBe(true);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it(`should fire end of object intersection if trigger removed`, async () => {
|
|
89
|
+
const trigger = factory.createTrigger({ shape: 'BOX', dimensions: { x: 10, y: 10, z: 10 } });
|
|
90
|
+
trigger.addToWorld({ physicsWorld: world } as any);
|
|
91
|
+
const ball = factory.createRigidBody({
|
|
92
|
+
shape: { shape: 'SPHERE', radius: 1 },
|
|
93
|
+
body: { dynamic: true, mass: 1 },
|
|
94
|
+
}, { position: { x: 0, y: 0, z: 0 } });
|
|
95
|
+
ball.addToWorld({ physicsWorld: world } as any);
|
|
96
|
+
let exitRegistered = false;
|
|
97
|
+
trigger.onEntityLeft.subscribe(((obj) => {
|
|
98
|
+
exitRegistered = obj === ball;
|
|
99
|
+
}));
|
|
100
|
+
trigger.checkOverlaps();
|
|
101
|
+
trigger.removeFromWorld({ physicsWorld: world } as any);
|
|
102
|
+
expect(exitRegistered).toBe(true);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it(`should fire end of object intersection if object removed`, async () => {
|
|
106
|
+
const trigger = factory.createTrigger({ shape: 'BOX', dimensions: { x: 10, y: 10, z: 10 } });
|
|
107
|
+
trigger.addToWorld({ physicsWorld: world } as any);
|
|
108
|
+
const ball = factory.createRigidBody({
|
|
109
|
+
shape: { shape: 'SPHERE', radius: 1 },
|
|
110
|
+
body: { dynamic: true, mass: 1 },
|
|
111
|
+
}, { position: { x: 0, y: 0, z: 0 } });
|
|
112
|
+
ball.addToWorld({ physicsWorld: world } as any);
|
|
113
|
+
let exitRegistered = false;
|
|
114
|
+
trigger.onEntityLeft.subscribe(((obj) => {
|
|
115
|
+
exitRegistered = obj === ball;
|
|
116
|
+
}));
|
|
117
|
+
trigger.checkOverlaps();
|
|
118
|
+
ball.removeFromWorld({ physicsWorld: world } as any);
|
|
119
|
+
trigger.checkOverlaps();
|
|
120
|
+
expect(exitRegistered).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
});
|
package/tsconfig.json
CHANGED
package/dist/ammo-utils.d.ts
DELETED
package/dist/ammo-utils.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const ammoId = body => body.a;
|