@gg-web-engine/ammo 0.0.28 → 0.0.30

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.
@@ -1,3 +1,4 @@
1
+ import Ammo from 'ammojs-typed';
1
2
  export const DebugBufferSize = 3 * 1000000;
2
3
  export var AmmoDebugMode;
3
4
  (function (AmmoDebugMode) {
@@ -19,9 +20,9 @@ export var AmmoDebugMode;
19
20
  AmmoDebugMode[AmmoDebugMode["DrawNormals"] = 16384] = "DrawNormals";
20
21
  AmmoDebugMode[AmmoDebugMode["MAX_DEBUG_DRAW_MODE"] = 4294967295] = "MAX_DEBUG_DRAW_MODE";
21
22
  })(AmmoDebugMode || (AmmoDebugMode = {}));
22
- const deserializeVector = function (ammo, vec) {
23
+ const deserializeVector = function (vec) {
23
24
  if (!isNaN(+vec)) {
24
- const heap = ammo.HEAPF32;
25
+ const heap = Ammo.HEAPF32;
25
26
  return {
26
27
  x: heap[+vec / 4],
27
28
  y: heap[(+vec + 4) / 4],
@@ -35,7 +36,7 @@ export class AmmoDebugger {
35
36
  this.world = world;
36
37
  this.drawer = drawer;
37
38
  this.debugMode = AmmoDebugMode.DrawWireframe;
38
- this.ammoInstance = new this.world.ammo.DebugDrawer();
39
+ this.ammoInstance = new Ammo.DebugDrawer();
39
40
  this.ammoInstance.drawLine = this.drawLine.bind(this);
40
41
  this.ammoInstance.drawContactPoint = this.drawContactPoint.bind(this);
41
42
  this.ammoInstance.reportErrorWarning = this.reportErrorWarning.bind(this);
@@ -47,10 +48,10 @@ export class AmmoDebugger {
47
48
  console.log('DRAWER DEBUG', 'draw3dtext');
48
49
  }
49
50
  drawContactPoint(pointOnB, normalOnB, distance, lifeTime, color) {
50
- this.drawer.drawContactPoint(deserializeVector(this.world.ammo, pointOnB), deserializeVector(this.world.ammo, normalOnB), deserializeVector(this.world.ammo, color));
51
+ this.drawer.drawContactPoint(deserializeVector(pointOnB), deserializeVector(normalOnB), deserializeVector(color));
51
52
  }
52
53
  drawLine(from, to, color) {
53
- this.drawer.drawLine(deserializeVector(this.world.ammo, from), deserializeVector(this.world.ammo, to), deserializeVector(this.world.ammo, color));
54
+ this.drawer.drawLine(deserializeVector(from), deserializeVector(to), deserializeVector(color));
54
55
  }
55
56
  getDebugMode() {
56
57
  return this.debugMode;
@@ -3,7 +3,9 @@ import Ammo from 'ammojs-typed';
3
3
  import { AmmoRigidBodyComponent } from './components/ammo-rigid-body.component';
4
4
  import { AmmoTriggerComponent } from './components/ammo-trigger.component';
5
5
  import { AmmoWorldComponent } from './components/ammo-world.component';
6
- export declare class AmmoFactory implements IPhysicsBody3dComponentFactory<AmmoRigidBodyComponent, AmmoTriggerComponent> {
6
+ import { AmmoPhysicsTypeDocRepo } from './types';
7
+ import { AmmoRaycastVehicleComponent } from './components/ammo-raycast-vehicle.component';
8
+ export declare class AmmoFactory implements IPhysicsBody3dComponentFactory<AmmoPhysicsTypeDocRepo> {
7
9
  protected readonly world: AmmoWorldComponent;
8
10
  constructor(world: AmmoWorldComponent);
9
11
  createRigidBody(descriptor: BodyShape3DDescriptor, transform?: {
@@ -14,6 +16,7 @@ export declare class AmmoFactory implements IPhysicsBody3dComponentFactory<AmmoR
14
16
  position?: Point3;
15
17
  rotation?: Point4;
16
18
  }): AmmoTriggerComponent;
19
+ createRaycastVehicle(chassis: AmmoRigidBodyComponent): AmmoRaycastVehicleComponent;
17
20
  protected createShape(descriptor: Shape3DDescriptor): Ammo.btCollisionShape;
18
21
  createRigidBodyFromShape(shape: Ammo.btCollisionShape, options: Partial<Body3DOptions>, transform?: {
19
22
  position?: Point3;
@@ -1,6 +1,8 @@
1
1
  import { Pnt3, Qtrn, } from '@gg-web-engine/core';
2
+ import Ammo from 'ammojs-typed';
2
3
  import { AmmoRigidBodyComponent } from './components/ammo-rigid-body.component';
3
4
  import { AmmoTriggerComponent } from './components/ammo-trigger.component';
5
+ import { AmmoRaycastVehicleComponent } from './components/ammo-raycast-vehicle.component';
4
6
  export class AmmoFactory {
5
7
  constructor(world) {
6
8
  this.world = world;
@@ -11,49 +13,54 @@ export class AmmoFactory {
11
13
  createTrigger(descriptor, transform) {
12
14
  return this.createTriggerFromShape(this.createShape(descriptor), transform);
13
15
  }
16
+ createRaycastVehicle(chassis) {
17
+ return new AmmoRaycastVehicleComponent(this.world, chassis);
18
+ }
14
19
  createShape(descriptor) {
15
20
  switch (descriptor.shape) {
21
+ case 'PLANE':
22
+ return new Ammo.btStaticPlaneShape(new Ammo.btVector3(0, 0, 1), 0);
16
23
  case 'BOX':
17
- return new this.world.ammo.btBoxShape(new this.world.ammo.btVector3(descriptor.dimensions.x / 2, descriptor.dimensions.y / 2, descriptor.dimensions.z / 2));
24
+ return new Ammo.btBoxShape(new Ammo.btVector3(descriptor.dimensions.x / 2, descriptor.dimensions.y / 2, descriptor.dimensions.z / 2));
18
25
  case 'CAPSULE':
19
- return new this.world.ammo.btCapsuleShapeZ(descriptor.radius, descriptor.centersDistance);
26
+ return new Ammo.btCapsuleShapeZ(descriptor.radius, descriptor.centersDistance);
20
27
  case 'CYLINDER':
21
- return new this.world.ammo.btCylinderShapeZ(new this.world.ammo.btVector3(descriptor.radius, descriptor.radius, descriptor.height / 2));
28
+ return new Ammo.btCylinderShapeZ(new Ammo.btVector3(descriptor.radius, descriptor.radius, descriptor.height / 2));
22
29
  case 'CONE':
23
- return new this.world.ammo.btConeShapeZ(descriptor.radius, descriptor.height);
30
+ return new Ammo.btConeShapeZ(descriptor.radius, descriptor.height);
24
31
  case 'SPHERE':
25
- return new this.world.ammo.btSphereShape(descriptor.radius);
32
+ return new Ammo.btSphereShape(descriptor.radius);
26
33
  case 'COMPOUND':
27
- const compoundShape = new this.world.ammo.btCompoundShape();
34
+ const compoundShape = new Ammo.btCompoundShape();
28
35
  for (const item of descriptor.children) {
29
36
  const subShape = this.createShape(item.shape);
30
37
  if (!subShape) {
31
38
  continue;
32
39
  }
33
- const subShapeTransform = new this.world.ammo.btTransform();
40
+ const subShapeTransform = new Ammo.btTransform();
34
41
  const pos = item.position || Pnt3.O;
35
42
  const rot = item.rotation || Qtrn.O;
36
- subShapeTransform.setOrigin(new this.world.ammo.btVector3(pos.x, pos.y, pos.z));
37
- subShapeTransform.setRotation(new this.world.ammo.btQuaternion(rot.x, rot.y, rot.z, rot.w));
43
+ subShapeTransform.setOrigin(new Ammo.btVector3(pos.x, pos.y, pos.z));
44
+ subShapeTransform.setRotation(new Ammo.btQuaternion(rot.x, rot.y, rot.z, rot.w));
38
45
  compoundShape.addChildShape(subShapeTransform, subShape);
39
46
  }
40
47
  return compoundShape;
41
48
  case 'CONVEX_HULL':
42
- const shape = new this.world.ammo.btConvexHullShape();
43
- const tmpVector = new this.world.ammo.btVector3();
49
+ const shape = new Ammo.btConvexHullShape();
50
+ const tmpVector = new Ammo.btVector3();
44
51
  for (const v of descriptor.vertices) {
45
52
  tmpVector.setValue(v.x, v.y, v.z);
46
53
  shape.addPoint(tmpVector);
47
54
  }
48
- this.world.ammo.destroy(tmpVector);
55
+ Ammo.destroy(tmpVector);
49
56
  shape.recalcLocalAabb();
50
57
  return shape;
51
58
  case 'MESH':
52
- const mesh = new this.world.ammo.btTriangleMesh(true, true);
59
+ const mesh = new Ammo.btTriangleMesh(true, true);
53
60
  const tmpVectors = [
54
- new this.world.ammo.btVector3(),
55
- new this.world.ammo.btVector3(),
56
- new this.world.ammo.btVector3(),
61
+ new Ammo.btVector3(),
62
+ new Ammo.btVector3(),
63
+ new Ammo.btVector3(),
57
64
  ];
58
65
  for (const f of descriptor.faces) {
59
66
  for (let j = 0; j < 3; j++) {
@@ -62,9 +69,9 @@ export class AmmoFactory {
62
69
  mesh.addTriangle(...tmpVectors, true);
63
70
  }
64
71
  tmpVectors.forEach(v => {
65
- this.world.ammo.destroy(v);
72
+ Ammo.destroy(v);
66
73
  });
67
- return new this.world.ammo.btBvhTriangleMeshShape(mesh, false, true);
74
+ return new Ammo.btBvhTriangleMeshShape(mesh, false, true);
68
75
  }
69
76
  throw new Error(`Shape "${descriptor.shape}" not implemented for Ammo.js`);
70
77
  }
@@ -74,14 +81,13 @@ export class AmmoFactory {
74
81
  }
75
82
  const pos = (transform === null || transform === void 0 ? void 0 : transform.position) || Pnt3.O;
76
83
  const rot = (transform === null || transform === void 0 ? void 0 : transform.rotation) || Qtrn.O;
77
- const ammo = this.world.ammo;
78
- const ammoTransform = new ammo.btTransform();
79
- ammoTransform.setOrigin(new ammo.btVector3(pos.x, pos.y, pos.z));
80
- ammoTransform.setRotation(new ammo.btQuaternion(rot.x, rot.y, rot.z, rot.w));
81
- const motionState = new ammo.btDefaultMotionState(ammoTransform);
82
- const localInertia = new ammo.btVector3(0, 0, 0);
84
+ const ammoTransform = new Ammo.btTransform();
85
+ ammoTransform.setOrigin(new Ammo.btVector3(pos.x, pos.y, pos.z));
86
+ ammoTransform.setRotation(new Ammo.btQuaternion(rot.x, rot.y, rot.z, rot.w));
87
+ const motionState = new Ammo.btDefaultMotionState(ammoTransform);
88
+ const localInertia = new Ammo.btVector3(0, 0, 0);
83
89
  shape.calculateLocalInertia(options.mass || 0, localInertia);
84
- const environmentBodyCI = new ammo.btRigidBodyConstructionInfo(options.mass || 0, motionState, shape, localInertia);
90
+ const environmentBodyCI = new Ammo.btRigidBodyConstructionInfo(options.mass || 0, motionState, shape, localInertia);
85
91
  if (options.friction) {
86
92
  environmentBodyCI.set_m_friction(options.friction);
87
93
  environmentBodyCI.set_m_rollingFriction(options.friction);
@@ -89,20 +95,26 @@ export class AmmoFactory {
89
95
  if (options.restitution) {
90
96
  environmentBodyCI.set_m_restitution(options.restitution);
91
97
  }
92
- const body = new this.world.ammo.btRigidBody(environmentBodyCI);
93
- return new AmmoRigidBodyComponent(this.world, body);
98
+ const comp = new AmmoRigidBodyComponent(this.world, new Ammo.btRigidBody(environmentBodyCI));
99
+ if (options.ownCollisionGroups && options.ownCollisionGroups !== 'all') {
100
+ comp.ownCollisionGroups = options.ownCollisionGroups;
101
+ }
102
+ if (options.interactWithCollisionGroups && options.interactWithCollisionGroups !== 'all') {
103
+ comp.interactWithCollisionGroups = options.interactWithCollisionGroups;
104
+ }
105
+ return comp;
94
106
  }
95
107
  createTriggerFromShape(shape, transform) {
96
108
  var _a, _b, _c, _d, _e, _f, _g;
97
- const ghostObject = new this.world.ammo.btPairCachingGhostObject();
109
+ const ghostObject = new Ammo.btPairCachingGhostObject();
98
110
  ghostObject.setCollisionShape(shape);
99
111
  ghostObject.setCollisionFlags(ghostObject.getCollisionFlags() | 4); // 4 is a CF_NO_CONTACT_RESPONSE collision flag
100
112
  ghostObject
101
113
  .getWorldTransform()
102
- .setOrigin(new this.world.ammo.btVector3(((_a = transform === null || transform === void 0 ? void 0 : transform.position) === null || _a === void 0 ? void 0 : _a.x) || 0, ((_b = transform === null || transform === void 0 ? void 0 : transform.position) === null || _b === void 0 ? void 0 : _b.y) || 0, ((_c = transform === null || transform === void 0 ? void 0 : transform.position) === null || _c === void 0 ? void 0 : _c.z) || 0));
114
+ .setOrigin(new Ammo.btVector3(((_a = transform === null || transform === void 0 ? void 0 : transform.position) === null || _a === void 0 ? void 0 : _a.x) || 0, ((_b = transform === null || transform === void 0 ? void 0 : transform.position) === null || _b === void 0 ? void 0 : _b.y) || 0, ((_c = transform === null || transform === void 0 ? void 0 : transform.position) === null || _c === void 0 ? void 0 : _c.z) || 0));
103
115
  ghostObject
104
116
  .getWorldTransform()
105
- .setRotation(new this.world.ammo.btQuaternion(((_d = transform === null || transform === void 0 ? void 0 : transform.rotation) === null || _d === void 0 ? void 0 : _d.x) || 0, ((_e = transform === null || transform === void 0 ? void 0 : transform.rotation) === null || _e === void 0 ? void 0 : _e.y) || 0, ((_f = transform === null || transform === void 0 ? void 0 : transform.rotation) === null || _f === void 0 ? void 0 : _f.z) || 0, ((_g = transform === null || transform === void 0 ? void 0 : transform.rotation) === null || _g === void 0 ? void 0 : _g.w) || 1));
117
+ .setRotation(new Ammo.btQuaternion(((_d = transform === null || transform === void 0 ? void 0 : transform.rotation) === null || _d === void 0 ? void 0 : _d.x) || 0, ((_e = transform === null || transform === void 0 ? void 0 : transform.rotation) === null || _e === void 0 ? void 0 : _e.y) || 0, ((_f = transform === null || transform === void 0 ? void 0 : transform.rotation) === null || _f === void 0 ? void 0 : _f.z) || 0, ((_g = transform === null || transform === void 0 ? void 0 : transform.rotation) === null || _g === void 0 ? void 0 : _g.w) || 1));
106
118
  return new AmmoTriggerComponent(this.world, ghostObject);
107
119
  }
108
120
  }
@@ -1,6 +1,7 @@
1
1
  import { IPhysicsBody3dComponentLoader } from '@gg-web-engine/core';
2
2
  import { AmmoWorldComponent } from './components/ammo-world.component';
3
- export declare class AmmoLoader extends IPhysicsBody3dComponentLoader {
3
+ import { AmmoPhysicsTypeDocRepo } from './types';
4
+ export declare class AmmoLoader extends IPhysicsBody3dComponentLoader<AmmoPhysicsTypeDocRepo> {
4
5
  protected readonly world: AmmoWorldComponent;
5
6
  constructor(world: AmmoWorldComponent);
6
7
  }
@@ -1,22 +1,30 @@
1
- import { Gg3dWorld, IEntity, IVisualScene3dComponent, Point3, Point4 } from '@gg-web-engine/core';
1
+ import { CollisionGroup, Gg3dWorld, IEntity, Point3, Point4, VisualTypeDocRepo3D } from '@gg-web-engine/core';
2
2
  import { AmmoWorldComponent } from './ammo-world.component';
3
3
  import Ammo from 'ammojs-typed';
4
+ import { AmmoPhysicsTypeDocRepo } from '../types';
4
5
  export declare abstract class AmmoBodyComponent<T extends Ammo.btCollisionObject> {
5
6
  protected readonly world: AmmoWorldComponent;
6
7
  protected _nativeBody: T;
7
8
  protected static nativeBodyReverseMap: Map<number, AmmoBodyComponent<any>>;
8
- protected get ammo(): typeof Ammo;
9
9
  get position(): Point3;
10
10
  set position(value: Point3);
11
11
  get rotation(): Point4;
12
12
  set rotation(value: Point4);
13
- get nativeBody(): T;
14
- set nativeBody(value: T);
15
13
  name: string;
16
14
  abstract entity: IEntity | null;
15
+ get nativeBody(): T;
16
+ set nativeBody(value: T);
17
+ protected addedToWorld: boolean;
18
+ protected _interactWithCGsMask: number;
19
+ protected _ownCGsMask: number;
20
+ get interactWithCollisionGroups(): CollisionGroup[];
21
+ abstract refreshCG(): void;
22
+ set interactWithCollisionGroups(value: CollisionGroup[] | 'all');
23
+ get ownCollisionGroups(): CollisionGroup[];
24
+ set ownCollisionGroups(value: CollisionGroup[] | 'all');
17
25
  protected constructor(world: AmmoWorldComponent, _nativeBody: T);
18
26
  abstract clone(): AmmoBodyComponent<T>;
19
- abstract addToWorld(world: Gg3dWorld<IVisualScene3dComponent, AmmoWorldComponent>): void;
20
- abstract removeFromWorld(world: Gg3dWorld<IVisualScene3dComponent, AmmoWorldComponent>): void;
27
+ addToWorld(world: Gg3dWorld<VisualTypeDocRepo3D, AmmoPhysicsTypeDocRepo>): void;
28
+ removeFromWorld(world: Gg3dWorld<VisualTypeDocRepo3D, AmmoPhysicsTypeDocRepo>): void;
21
29
  dispose(): void;
22
30
  }
@@ -1,21 +1,23 @@
1
+ import { BitMask } from '@gg-web-engine/core';
2
+ import Ammo from 'ammojs-typed';
1
3
  import { ammoId } from '../ammo-utils';
2
4
  export class AmmoBodyComponent {
3
5
  constructor(world, _nativeBody) {
4
6
  this.world = world;
5
7
  this._nativeBody = _nativeBody;
6
8
  this.name = '';
9
+ this.addedToWorld = false;
10
+ this._interactWithCGsMask = BitMask.full(16);
11
+ this._ownCGsMask = BitMask.full(16);
7
12
  AmmoBodyComponent.nativeBodyReverseMap.set(ammoId(this.nativeBody), this);
8
13
  }
9
- get ammo() {
10
- return this.world.ammo;
11
- }
12
14
  get position() {
13
15
  const origin = this.nativeBody.getWorldTransform().getOrigin();
14
16
  return { x: origin.x(), y: origin.y(), z: origin.z() };
15
17
  }
16
18
  set position(value) {
17
19
  const transform = this.nativeBody.getWorldTransform();
18
- transform.setOrigin(new this.ammo.btVector3(value.x, value.y, value.z));
20
+ transform.setOrigin(new Ammo.btVector3(value.x, value.y, value.z));
19
21
  this.nativeBody.setWorldTransform(transform);
20
22
  }
21
23
  get rotation() {
@@ -24,7 +26,7 @@ export class AmmoBodyComponent {
24
26
  }
25
27
  set rotation(value) {
26
28
  const transform = this.nativeBody.getWorldTransform();
27
- transform.setRotation(new this.ammo.btQuaternion(value.x, value.y, value.z, value.w));
29
+ transform.setRotation(new Ammo.btQuaternion(value.x, value.y, value.z, value.w));
28
30
  this.nativeBody.setWorldTransform(transform);
29
31
  }
30
32
  get nativeBody() {
@@ -38,9 +40,57 @@ export class AmmoBodyComponent {
38
40
  this._nativeBody = value;
39
41
  AmmoBodyComponent.nativeBodyReverseMap.set(ammoId(value), this);
40
42
  }
43
+ get interactWithCollisionGroups() {
44
+ return BitMask.unpack(this._interactWithCGsMask, 16);
45
+ }
46
+ set interactWithCollisionGroups(value) {
47
+ let mask;
48
+ if (value === 'all') {
49
+ mask = BitMask.full(16);
50
+ }
51
+ else {
52
+ mask = BitMask.pack(value, 16);
53
+ }
54
+ if (this._interactWithCGsMask !== mask) {
55
+ this._interactWithCGsMask = mask;
56
+ if (this.addedToWorld) {
57
+ this.refreshCG();
58
+ }
59
+ }
60
+ }
61
+ get ownCollisionGroups() {
62
+ return BitMask.unpack(this._ownCGsMask, 16);
63
+ }
64
+ set ownCollisionGroups(value) {
65
+ let mask;
66
+ if (value === 'all') {
67
+ mask = BitMask.full(16);
68
+ }
69
+ else {
70
+ mask = BitMask.pack(value, 16);
71
+ }
72
+ if (this._ownCGsMask !== mask) {
73
+ this._ownCGsMask = mask;
74
+ if (this.addedToWorld) {
75
+ this.refreshCG();
76
+ }
77
+ }
78
+ }
79
+ addToWorld(world) {
80
+ if (world.physicsWorld != this.world) {
81
+ throw new Error('Ammo bodies cannot be shared between different worlds');
82
+ }
83
+ this.addedToWorld = true;
84
+ }
85
+ removeFromWorld(world) {
86
+ if (world.physicsWorld != this.world) {
87
+ throw new Error('Ammo bodies cannot be shared between different worlds');
88
+ }
89
+ this.addedToWorld = false;
90
+ }
41
91
  dispose() {
42
92
  try {
43
- this.ammo.destroy(this.nativeBody);
93
+ Ammo.destroy(this.nativeBody);
44
94
  }
45
95
  catch (_a) {
46
96
  // pass
@@ -1,8 +1,9 @@
1
- import { Gg3dWorld, IRaycastVehicleComponent, IVisualScene3dComponent, Point3, Point4, RaycastVehicle3dEntity, WheelOptions, SuspensionOptions } from '@gg-web-engine/core';
1
+ import { Gg3dWorld, IRaycastVehicleComponent, Point3, Point4, RaycastVehicle3dEntity, SuspensionOptions, VisualTypeDocRepo3D, WheelOptions } from '@gg-web-engine/core';
2
2
  import Ammo from 'ammojs-typed';
3
3
  import { AmmoRigidBodyComponent } from './ammo-rigid-body.component';
4
4
  import { AmmoWorldComponent } from './ammo-world.component';
5
- export declare class AmmoRaycastVehicleComponent extends AmmoRigidBodyComponent implements IRaycastVehicleComponent<AmmoWorldComponent> {
5
+ import { AmmoPhysicsTypeDocRepo } from '../types';
6
+ export declare class AmmoRaycastVehicleComponent extends AmmoRigidBodyComponent implements IRaycastVehicleComponent<AmmoPhysicsTypeDocRepo> {
6
7
  protected readonly world: AmmoWorldComponent;
7
8
  chassisBody: AmmoRigidBodyComponent;
8
9
  readonly nativeVehicle: Ammo.btRaycastVehicle;
@@ -12,7 +13,7 @@ export declare class AmmoRaycastVehicleComponent extends AmmoRigidBodyComponent
12
13
  entity: RaycastVehicle3dEntity | null;
13
14
  constructor(world: AmmoWorldComponent, chassisBody: AmmoRigidBodyComponent);
14
15
  get wheelSpeed(): number;
15
- addToWorld(world: Gg3dWorld<IVisualScene3dComponent, AmmoWorldComponent>): void;
16
+ addToWorld(world: Gg3dWorld<VisualTypeDocRepo3D, AmmoPhysicsTypeDocRepo>): void;
16
17
  addWheel(options: WheelOptions, suspensionOptions: SuspensionOptions): void;
17
18
  setSteering(wheelIndex: number, steering: number): void;
18
19
  applyEngineForce(wheelIndex: number, force: number): void;
@@ -23,4 +24,5 @@ export declare class AmmoRaycastVehicleComponent extends AmmoRigidBodyComponent
23
24
  rotation: Point4;
24
25
  };
25
26
  resetSuspension(): void;
27
+ clone(): AmmoRaycastVehicleComponent;
26
28
  }
@@ -1,14 +1,15 @@
1
+ import Ammo from 'ammojs-typed';
1
2
  import { AmmoRigidBodyComponent } from './ammo-rigid-body.component';
2
3
  export class AmmoRaycastVehicleComponent extends AmmoRigidBodyComponent {
3
4
  constructor(world, chassisBody) {
4
5
  super(world, chassisBody.nativeBody);
5
6
  this.world = world;
6
7
  this.chassisBody = chassisBody;
7
- this.vehicleTuning = new this.ammo.btVehicleTuning();
8
- this.wheelDirectionCS0 = new this.ammo.btVector3(0, 0, -1);
9
- this.wheelAxleCS = new this.ammo.btVector3(1, 0, 0);
8
+ this.vehicleTuning = new Ammo.btVehicleTuning();
9
+ this.wheelDirectionCS0 = new Ammo.btVector3(0, 0, -1);
10
+ this.wheelAxleCS = new Ammo.btVector3(1, 0, 0);
10
11
  this.entity = null;
11
- this.nativeVehicle = new this.ammo.btRaycastVehicle(this.vehicleTuning, this.chassisBody.nativeBody, new this.ammo.btDefaultVehicleRaycaster(world.dynamicAmmoWorld));
12
+ this.nativeVehicle = new Ammo.btRaycastVehicle(this.vehicleTuning, this.chassisBody.nativeBody, new Ammo.btDefaultVehicleRaycaster(world.dynamicAmmoWorld));
12
13
  this.nativeVehicle.setCoordinateSystem(0, 2, 1);
13
14
  }
14
15
  get wheelSpeed() {
@@ -26,7 +27,7 @@ export class AmmoRaycastVehicleComponent extends AmmoRigidBodyComponent {
26
27
  this.world.dynamicAmmoWorld.addAction(this.nativeVehicle);
27
28
  }
28
29
  addWheel(options, suspensionOptions) {
29
- const wheelInfo = this.nativeVehicle.addWheel(new this.ammo.btVector3(options.position.x, options.position.y, options.position.z), this.wheelDirectionCS0, this.wheelAxleCS, suspensionOptions.restLength, options.tyreRadius, this.vehicleTuning, options.isFront);
30
+ 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);
30
31
  wheelInfo.set_m_suspensionStiffness(suspensionOptions.stiffness);
31
32
  wheelInfo.set_m_wheelsDampingRelaxation(suspensionOptions.damping);
32
33
  wheelInfo.set_m_wheelsDampingCompression(suspensionOptions.compression);
@@ -47,7 +48,7 @@ export class AmmoRaycastVehicleComponent extends AmmoRigidBodyComponent {
47
48
  return this.nativeVehicle.getWheelInfo(wheelIndex).get_m_raycastInfo().get_m_groundObject() > 0;
48
49
  }
49
50
  getWheelTransform(wheelIndex) {
50
- // FIXME when set to `true`, wheels are jittering, but it was not the case in old sandbox app. Check why
51
+ // when interpolated transform set to `true`, wheels are jittering relatively to car on high speeds
51
52
  this.nativeVehicle.updateWheelTransform(wheelIndex, false);
52
53
  const transform = this.nativeVehicle.getWheelTransformWS(wheelIndex);
53
54
  const origin = transform.getOrigin();
@@ -63,4 +64,7 @@ export class AmmoRaycastVehicleComponent extends AmmoRigidBodyComponent {
63
64
  this.nativeVehicle.updateWheelTransform(i, true);
64
65
  }
65
66
  }
67
+ clone() {
68
+ return new AmmoRaycastVehicleComponent(this.world, this.chassisBody.clone());
69
+ }
66
70
  }
@@ -1,8 +1,9 @@
1
1
  import { AmmoWorldComponent } from './ammo-world.component';
2
2
  import Ammo from 'ammojs-typed';
3
3
  import { AmmoBodyComponent } from './ammo-body.component';
4
- import { Entity3d, Gg3dWorld, IRigidBody3dComponent, IVisualScene3dComponent, Point3 } from '@gg-web-engine/core';
5
- export declare class AmmoRigidBodyComponent extends AmmoBodyComponent<Ammo.btRigidBody> implements IRigidBody3dComponent<AmmoWorldComponent> {
4
+ import { Entity3d, Gg3dWorld, IRigidBody3dComponent, Point3, VisualTypeDocRepo3D } from '@gg-web-engine/core';
5
+ import { AmmoPhysicsTypeDocRepo } from '../types';
6
+ export declare class AmmoRigidBodyComponent extends AmmoBodyComponent<Ammo.btRigidBody> implements IRigidBody3dComponent<AmmoPhysicsTypeDocRepo> {
6
7
  protected readonly world: AmmoWorldComponent;
7
8
  protected _nativeBody: Ammo.btRigidBody;
8
9
  entity: Entity3d | null;
@@ -12,7 +13,8 @@ export declare class AmmoRigidBodyComponent extends AmmoBodyComponent<Ammo.btRig
12
13
  set angularVelocity(value: Point3);
13
14
  constructor(world: AmmoWorldComponent, _nativeBody: Ammo.btRigidBody);
14
15
  clone(): AmmoRigidBodyComponent;
15
- addToWorld(world: Gg3dWorld<IVisualScene3dComponent, AmmoWorldComponent>): void;
16
- removeFromWorld(world: Gg3dWorld<IVisualScene3dComponent, AmmoWorldComponent>): void;
16
+ addToWorld(world: Gg3dWorld<VisualTypeDocRepo3D, AmmoPhysicsTypeDocRepo>): void;
17
+ removeFromWorld(world: Gg3dWorld<VisualTypeDocRepo3D, AmmoPhysicsTypeDocRepo>): void;
18
+ refreshCG(): void;
17
19
  resetMotion(): void;
18
20
  }
@@ -1,3 +1,4 @@
1
+ import Ammo from 'ammojs-typed';
1
2
  import { AmmoBodyComponent } from './ammo-body.component';
2
3
  export class AmmoRigidBodyComponent extends AmmoBodyComponent {
3
4
  constructor(world, _nativeBody) {
@@ -11,14 +12,14 @@ export class AmmoRigidBodyComponent extends AmmoBodyComponent {
11
12
  return { x: v.x(), y: v.y(), z: v.z() };
12
13
  }
13
14
  set linearVelocity(value) {
14
- this.nativeBody.setLinearVelocity(new this.ammo.btVector3(value.x, value.y, value.z));
15
+ this.nativeBody.setLinearVelocity(new Ammo.btVector3(value.x, value.y, value.z));
15
16
  }
16
17
  get angularVelocity() {
17
18
  const v = this.nativeBody.getAngularVelocity();
18
19
  return { x: v.x(), y: v.y(), z: v.z() };
19
20
  }
20
21
  set angularVelocity(value) {
21
- this.nativeBody.setAngularVelocity(new this.ammo.btVector3(value.x, value.y, value.z));
22
+ this.nativeBody.setAngularVelocity(new Ammo.btVector3(value.x, value.y, value.z));
22
23
  }
23
24
  clone() {
24
25
  return this.world.factory.createRigidBodyFromShape(this._nativeBody.getCollisionShape(), {
@@ -33,24 +34,25 @@ export class AmmoRigidBodyComponent extends AmmoBodyComponent {
33
34
  }
34
35
  addToWorld(world) {
35
36
  var _a;
36
- if (world.physicsWorld != this.world) {
37
- throw new Error('Ammo bodies cannot be shared between different worlds');
38
- }
39
- (_a = this.world.dynamicAmmoWorld) === null || _a === void 0 ? void 0 : _a.addRigidBody(this.nativeBody);
37
+ super.addToWorld(world);
38
+ (_a = this.world.dynamicAmmoWorld) === null || _a === void 0 ? void 0 : _a.addRigidBody(this.nativeBody, this._ownCGsMask, this._interactWithCGsMask);
40
39
  }
41
40
  removeFromWorld(world) {
42
41
  var _a;
43
- if (world.physicsWorld != this.world) {
44
- throw new Error('Ammo bodies cannot be shared between different worlds');
45
- }
42
+ super.removeFromWorld(world);
46
43
  (_a = this.world.dynamicAmmoWorld) === null || _a === void 0 ? void 0 : _a.removeRigidBody(this.nativeBody);
47
44
  }
45
+ refreshCG() {
46
+ var _a, _b;
47
+ (_a = this.world.dynamicAmmoWorld) === null || _a === void 0 ? void 0 : _a.removeRigidBody(this.nativeBody);
48
+ (_b = this.world.dynamicAmmoWorld) === null || _b === void 0 ? void 0 : _b.addRigidBody(this.nativeBody, this._ownCGsMask, this._interactWithCGsMask);
49
+ }
48
50
  resetMotion() {
49
- const emptyVector = new this.ammo.btVector3();
51
+ const emptyVector = new Ammo.btVector3();
50
52
  this.nativeBody.setLinearVelocity(emptyVector);
51
53
  this.nativeBody.setAngularVelocity(emptyVector);
52
54
  this.nativeBody.clearForces();
53
55
  this.nativeBody.updateInertiaTensor();
54
- this.ammo.destroy(emptyVector);
56
+ Ammo.destroy(emptyVector);
55
57
  }
56
58
  }
@@ -1,10 +1,11 @@
1
- import { Gg3dWorld, IEntity, ITrigger3dComponent, IVisualScene3dComponent } from '@gg-web-engine/core';
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
4
  import Ammo from 'ammojs-typed';
5
5
  import { AmmoBodyComponent } from './ammo-body.component';
6
6
  import { AmmoRigidBodyComponent } from './ammo-rigid-body.component';
7
- export declare class AmmoTriggerComponent extends AmmoBodyComponent<Ammo.btPairCachingGhostObject> implements ITrigger3dComponent<AmmoWorldComponent> {
7
+ import { AmmoPhysicsTypeDocRepo } from '../types';
8
+ export declare class AmmoTriggerComponent extends AmmoBodyComponent<Ammo.btPairCachingGhostObject> implements ITrigger3dComponent<AmmoPhysicsTypeDocRepo> {
8
9
  protected readonly world: AmmoWorldComponent;
9
10
  protected _nativeBody: Ammo.btPairCachingGhostObject;
10
11
  entity: IEntity | null;
@@ -16,7 +17,8 @@ export declare class AmmoTriggerComponent extends AmmoBodyComponent<Ammo.btPairC
16
17
  protected readonly overlaps: Set<Ammo.btCollisionObject>;
17
18
  checkOverlaps(): void;
18
19
  clone(): AmmoTriggerComponent;
19
- addToWorld(world: Gg3dWorld<IVisualScene3dComponent, AmmoWorldComponent>): void;
20
- removeFromWorld(world: Gg3dWorld<IVisualScene3dComponent, AmmoWorldComponent>): void;
20
+ addToWorld(world: Gg3dWorld<VisualTypeDocRepo3D, AmmoPhysicsTypeDocRepo>): void;
21
+ removeFromWorld(world: Gg3dWorld<VisualTypeDocRepo3D, AmmoPhysicsTypeDocRepo>): void;
22
+ refreshCG(): void;
21
23
  dispose(): void;
22
24
  }
@@ -42,23 +42,24 @@ export class AmmoTriggerComponent extends AmmoBodyComponent {
42
42
  }
43
43
  addToWorld(world) {
44
44
  var _a;
45
- if (world.physicsWorld != this.world) {
46
- throw new Error('Ammo triggers cannot be shared between different worlds');
47
- }
48
- (_a = this.world.dynamicAmmoWorld) === null || _a === void 0 ? void 0 : _a.addCollisionObject(this.nativeBody);
45
+ super.addToWorld(world);
46
+ (_a = this.world.dynamicAmmoWorld) === null || _a === void 0 ? void 0 : _a.addCollisionObject(this.nativeBody, this._ownCGsMask, this._interactWithCGsMask);
49
47
  this.overlaps.clear();
50
48
  }
51
49
  removeFromWorld(world) {
52
50
  var _a;
53
- if (world.physicsWorld != this.world) {
54
- throw new Error('Ammo triggers cannot be shared between different worlds');
55
- }
51
+ super.removeFromWorld(world);
56
52
  for (const body of this.overlaps) {
57
53
  this.onLeft$.next(ammoId(body));
58
54
  }
59
55
  this.overlaps.clear();
60
56
  (_a = this.world.dynamicAmmoWorld) === null || _a === void 0 ? void 0 : _a.removeCollisionObject(this.nativeBody);
61
57
  }
58
+ refreshCG() {
59
+ var _a, _b;
60
+ (_a = this.world.dynamicAmmoWorld) === null || _a === void 0 ? void 0 : _a.removeCollisionObject(this.nativeBody);
61
+ (_b = this.world.dynamicAmmoWorld) === null || _b === void 0 ? void 0 : _b.addCollisionObject(this.nativeBody, this._ownCGsMask, this._interactWithCGsMask);
62
+ }
62
63
  dispose() {
63
64
  super.dispose();
64
65
  this.overlaps.clear();
@@ -1,8 +1,9 @@
1
- import { Gg3dWorld, IDebugPhysicsDrawer, IPhysicsWorld3dComponent, IVisualScene3dComponent, Point3, Point4 } from '@gg-web-engine/core';
1
+ import { CollisionGroup, Gg3dWorld, IDebugPhysicsDrawer, IPhysicsWorld3dComponent, Point3, Point4, VisualTypeDocRepo3D } from '@gg-web-engine/core';
2
2
  import Ammo from 'ammojs-typed';
3
3
  import { AmmoFactory } from '../ammo-factory';
4
4
  import { AmmoLoader } from '../ammo-loader';
5
- export declare class AmmoWorldComponent implements IPhysicsWorld3dComponent {
5
+ import { AmmoPhysicsTypeDocRepo } from '../types';
6
+ export declare class AmmoWorldComponent implements IPhysicsWorld3dComponent<AmmoPhysicsTypeDocRepo> {
6
7
  private _factory;
7
8
  get factory(): AmmoFactory;
8
9
  private _loader;
@@ -16,8 +17,6 @@ export declare class AmmoWorldComponent implements IPhysicsWorld3dComponent {
16
17
  private _debugger;
17
18
  private _debugDrawer;
18
19
  get physicsDebugViewActive(): boolean;
19
- private ammoInstance;
20
- get ammo(): typeof Ammo;
21
20
  get dynamicAmmoWorld(): Ammo.btDiscreteDynamicsWorld | undefined;
22
21
  private collisionConfiguration;
23
22
  private dispatcher;
@@ -28,7 +27,10 @@ export declare class AmmoWorldComponent implements IPhysicsWorld3dComponent {
28
27
  protected _dynamicAmmoWorld: Ammo.btDiscreteDynamicsWorld | undefined;
29
28
  init(): Promise<void>;
30
29
  simulate(delta: number): void;
31
- startDebugger(world: Gg3dWorld<IVisualScene3dComponent, AmmoWorldComponent>, drawer: IDebugPhysicsDrawer<Point3, Point4>): void;
32
- stopDebugger(world: Gg3dWorld<IVisualScene3dComponent, AmmoWorldComponent>): void;
30
+ protected lockedCollisionGroups: number[];
31
+ registerCollisionGroup(): CollisionGroup;
32
+ deregisterCollisionGroup(group: CollisionGroup): void;
33
+ startDebugger(world: Gg3dWorld<VisualTypeDocRepo3D, AmmoPhysicsTypeDocRepo>, drawer: IDebugPhysicsDrawer<Point3, Point4>): void;
34
+ stopDebugger(world: Gg3dWorld<VisualTypeDocRepo3D, AmmoPhysicsTypeDocRepo>): void;
33
35
  dispose(): void;
34
36
  }
@@ -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 * as AmmoModule from 'ammojs-typed';
10
+ import Ammo from 'ammojs-typed';
11
11
  import { AmmoFactory } from '../ammo-factory';
12
12
  import { AmmoLoader } from '../ammo-loader';
13
13
  import { AmmoDebugger, AmmoDebugMode } from '../ammo-debugger';
@@ -19,6 +19,7 @@ export class AmmoWorldComponent {
19
19
  this._timeScale = 1;
20
20
  this._debugger = null;
21
21
  this._debugDrawer = null;
22
+ this.lockedCollisionGroups = [];
22
23
  }
23
24
  get factory() {
24
25
  if (!this._factory) {
@@ -52,25 +53,19 @@ export class AmmoWorldComponent {
52
53
  get physicsDebugViewActive() {
53
54
  return !!this._debugger;
54
55
  }
55
- get ammo() {
56
- if (this.ammoInstance) {
57
- return this.ammoInstance;
58
- }
59
- throw 'Physics world not initialized!';
60
- }
61
56
  get dynamicAmmoWorld() {
62
57
  return this._dynamicAmmoWorld;
63
58
  }
64
59
  init() {
65
60
  return __awaiter(this, void 0, void 0, function* () {
66
- this.ammoInstance = yield AmmoModule.default.bind(AmmoModule)();
67
- this.collisionConfiguration = new this.ammo.btDefaultCollisionConfiguration();
68
- this.dispatcher = new this.ammo.btCollisionDispatcher(this.collisionConfiguration);
69
- this.broadphase = new this.ammo.btDbvtBroadphase();
70
- this.ghostPairCallback = new this.ammo.btGhostPairCallback();
71
- this.solver = new this.ammo.btSequentialImpulseConstraintSolver();
72
- this.gravityVector = new this.ammo.btVector3(this._gravity.x, this._gravity.y, this._gravity.z);
73
- this._dynamicAmmoWorld = new this.ammo.btDiscreteDynamicsWorld(this.dispatcher, this.broadphase, this.solver, this.collisionConfiguration);
61
+ yield Ammo.bind(Ammo)(Ammo);
62
+ this.collisionConfiguration = new Ammo.btDefaultCollisionConfiguration();
63
+ this.dispatcher = new Ammo.btCollisionDispatcher(this.collisionConfiguration);
64
+ this.broadphase = new Ammo.btDbvtBroadphase();
65
+ this.ghostPairCallback = new Ammo.btGhostPairCallback();
66
+ this.solver = new Ammo.btSequentialImpulseConstraintSolver();
67
+ this.gravityVector = new Ammo.btVector3(this._gravity.x, this._gravity.y, this._gravity.z);
68
+ this._dynamicAmmoWorld = new Ammo.btDiscreteDynamicsWorld(this.dispatcher, this.broadphase, this.solver, this.collisionConfiguration);
74
69
  this._dynamicAmmoWorld.getPairCache().setInternalGhostPairCallback(this.ghostPairCallback);
75
70
  this._dynamicAmmoWorld.setGravity(this.gravityVector);
76
71
  this._factory = new AmmoFactory(this);
@@ -84,6 +79,18 @@ export class AmmoWorldComponent {
84
79
  this._debugger.update();
85
80
  }
86
81
  }
82
+ registerCollisionGroup() {
83
+ for (let i = 0; i < 16; i++) {
84
+ if (!this.lockedCollisionGroups.includes(i)) {
85
+ this.lockedCollisionGroups.push(i);
86
+ return i;
87
+ }
88
+ }
89
+ throw new Error('App tries to register 17th collision group, but ammo.js supports only 16');
90
+ }
91
+ deregisterCollisionGroup(group) {
92
+ this.lockedCollisionGroups = this.lockedCollisionGroups.filter(x => x !== group);
93
+ }
87
94
  startDebugger(world, drawer) {
88
95
  var _a;
89
96
  if (!this._debugger) {
@@ -98,7 +105,7 @@ export class AmmoWorldComponent {
98
105
  var _a;
99
106
  if (this._debugger) {
100
107
  (_a = this.dynamicAmmoWorld) === null || _a === void 0 ? void 0 : _a.setDebugDrawer(null);
101
- this.ammo.destroy(this._debugger.ammoInstance);
108
+ Ammo.destroy(this._debugger.ammoInstance);
102
109
  this._debugger = null;
103
110
  }
104
111
  if (this._debugDrawer) {
@@ -108,20 +115,14 @@ export class AmmoWorldComponent {
108
115
  }
109
116
  }
110
117
  dispose() {
111
- this.ammo.destroy(this._dynamicAmmoWorld);
112
- this.ammo.destroy(this.solver);
113
- this.ammo.destroy(this.broadphase);
114
- this.ammo.destroy(this.dispatcher);
115
- this.ammo.destroy(this.collisionConfiguration);
118
+ Ammo.destroy(this._dynamicAmmoWorld);
119
+ Ammo.destroy(this.solver);
120
+ Ammo.destroy(this.broadphase);
121
+ Ammo.destroy(this.dispatcher);
122
+ Ammo.destroy(this.collisionConfiguration);
116
123
  if (this._debugger) {
117
- this.ammo.destroy(this._debugger.ammoInstance);
124
+ Ammo.destroy(this._debugger.ammoInstance);
118
125
  }
119
- this._dynamicAmmoWorld =
120
- this.solver =
121
- this.broadphase =
122
- this.dispatcher =
123
- this.collisionConfiguration =
124
- this.ammoInstance =
125
- undefined;
126
+ this._dynamicAmmoWorld = this.solver = this.broadphase = this.dispatcher = this.collisionConfiguration = undefined;
126
127
  }
127
128
  }
package/dist/index.d.ts CHANGED
@@ -4,3 +4,4 @@ export * from './components/ammo-raycast-vehicle.component';
4
4
  export * from './components/ammo-world.component';
5
5
  export * from './ammo-factory';
6
6
  export * from './ammo-loader';
7
+ export * from './types';
package/dist/index.js CHANGED
@@ -4,3 +4,4 @@ export * from './components/ammo-raycast-vehicle.component';
4
4
  export * from './components/ammo-world.component';
5
5
  export * from './ammo-factory';
6
6
  export * from './ammo-loader';
7
+ export * from './types';
@@ -0,0 +1,12 @@
1
+ import { AmmoRigidBodyComponent } from './components/ammo-rigid-body.component';
2
+ import { AmmoTriggerComponent } from './components/ammo-trigger.component';
3
+ import { AmmoRaycastVehicleComponent } from './components/ammo-raycast-vehicle.component';
4
+ import { AmmoFactory } from './ammo-factory';
5
+ import { AmmoLoader } from './ammo-loader';
6
+ export declare type AmmoPhysicsTypeDocRepo = {
7
+ factory: AmmoFactory;
8
+ loader: AmmoLoader;
9
+ rigidBody: AmmoRigidBodyComponent;
10
+ trigger: AmmoTriggerComponent;
11
+ raycastVehicle: AmmoRaycastVehicleComponent;
12
+ };
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gg-web-engine/ammo",
3
- "version": "0.0.28",
3
+ "version": "0.0.30",
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",
@@ -34,14 +34,14 @@
34
34
  "dependencies": {
35
35
  },
36
36
  "devDependencies": {
37
- "@gg-web-engine/core": "0.0.28",
37
+ "@gg-web-engine/core": "0.0.30",
38
38
  "ammojs-typed": "1.0.6",
39
39
  "mini-signals": "2.0.0",
40
40
  "prettier": "^2.8.6",
41
41
  "typescript": "~4.7.2"
42
42
  },
43
43
  "peerDependencies": {
44
- "@gg-web-engine/core": "0.0.28",
44
+ "@gg-web-engine/core": "0.0.30",
45
45
  "ammojs-typed": "1.0.6",
46
46
  "mini-signals": "2.0.0"
47
47
  }