@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.
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 'ammojs-typed';
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 'ammojs-typed';
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(ammoId(this.nativeBody), this);
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(ammoId(this._nativeBody));
38
+ AmmoBodyComponent.nativeBodyReverseMap.delete(Ammo.getPointer(this._nativeBody));
40
39
  this._nativeBody = value;
41
- AmmoBodyComponent.nativeBodyReverseMap.set(ammoId(value), this);
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(ammoId(this.nativeBody));
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 'ammojs-typed';
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 Ammo from 'ammojs-typed';
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.nativeVehicle = new Ammo.btRaycastVehicle(this.vehicleTuning, this.chassisBody.nativeBody, new Ammo.btDefaultVehicleRaycaster(world.dynamicAmmoWorld));
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
- (_a = this.world.dynamicAmmoWorld) === null || _a === void 0 ? void 0 : _a.addRigidBody(this.chassisBody.nativeBody);
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 'ammojs-typed';
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 'ammojs-typed';
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.isStaticObject(),
27
- mass: 5,
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 'ammojs-typed';
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(ammoId(overlap));
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(ammoId(newOverlap));
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(ammoId(body));
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 'ammojs-typed';
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 'ammojs-typed';
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
@@ -1,3 +1,4 @@
1
+ export { default as Ammo } from './ammo.js/ammo';
1
2
  export * from './components/ammo-rigid-body.component';
2
3
  export * from './components/ammo-trigger.component';
3
4
  export * from './components/ammo-raycast-vehicle.component';
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export { default as Ammo } from './ammo.js/ammo';
1
2
  export * from './components/ammo-rigid-body.component';
2
3
  export * from './components/ammo-trigger.component';
3
4
  export * from './components/ammo-raycast-vehicle.component';
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@gg-web-engine/ammo",
3
- "version": "0.0.30",
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": "echo \"Error: no test specified\" && exit 1",
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.30",
38
- "ammojs-typed": "1.0.6",
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.30",
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
@@ -2,7 +2,7 @@
2
2
  "extends": "./../../tsconfig.base.json",
3
3
  "compilerOptions": {
4
4
  "baseUrl": "./src/",
5
- "outDir": "./dist/",
5
+ "outDir": "./dist/"
6
6
  },
7
- "include": ["*.ts", "**/*.ts"],
7
+ "include": ["src/*.ts", "src/**/*.ts"],
8
8
  }
@@ -1,2 +0,0 @@
1
- import Ammo from 'ammojs-typed';
2
- export declare const ammoId: (body: Ammo.btCollisionObject) => number;
@@ -1 +0,0 @@
1
- export const ammoId = body => body.a;