├── .gitignore
├── README.md
├── ammo
├── ammo.js
├── ammo.wasm.js
└── ammo.wasm.wasm
├── example
└── index.html
├── package-lock.json
├── package.json
├── src
├── ammoPhysics.ts
├── common.ts
├── debugDrawer.ts
├── index.ts
├── physics.ts
├── physics.worker.ts
├── requestAnimationFramePolyfill.ts
└── wasmSupported.ts
├── tsconfig.json
├── typings
├── ammo.d.ts
└── custom.d.ts
├── webpack.bundle.js
└── webpack.worker.js
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## How to test
2 |
3 | ```console
4 | # Install
5 | $ npm i
6 |
7 | # Run
8 | $ npm run dev
9 | ```
10 |
11 | Xa = "http://localhost:8080/lib/ammo.wasm.wasm"
12 |
--------------------------------------------------------------------------------
/ammo/ammo.wasm.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yandeu/ammo-worker-test/c91e3ffc26e5a15789f84f70cdc2b59a52940125/ammo/ammo.wasm.wasm
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
17 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ammo-worker-test",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "npm run dev",
8 | "dev": "npm-run-all --parallel dev:*",
9 | "dev:serve": "live-server --open=example/index.html",
10 | "dev:bundle": "webpack --config webpack.bundle.js --watch",
11 | "dev:worker": "webpack --config webpack.worker.js --watch",
12 | "build": "webpack"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "devDependencies": {
18 | "copy-webpack-plugin": "^6.0.1",
19 | "file-loader": "^6.0.0",
20 | "html-webpack-plugin": "^4.3.0",
21 | "live-server": "^1.2.1",
22 | "npm-run-all": "^4.1.5",
23 | "stats.js": "^0.17.0",
24 | "ts-loader": "^7.0.5",
25 | "typescript": "^3.9.3",
26 | "webpack": "^4.43.0",
27 | "webpack-cli": "^3.3.11",
28 | "webpack-dev-server": "^3.11.0",
29 | "worker-loader": "^2.0.0",
30 | "worker-plugin": "^4.0.3"
31 | },
32 | "dependencies": {
33 | "comlink": "^4.3.0",
34 | "three": "^0.116.1",
35 | "web-threads": "^1.0.83"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/ammoPhysics.ts:
--------------------------------------------------------------------------------
1 | import * as Comlink from 'comlink'
2 |
3 | import {
4 | Quaternion,
5 | BufferGeometry,
6 | BufferAttribute,
7 | LineBasicMaterial,
8 | VertexColors,
9 | LineSegments,
10 | Scene,
11 | DynamicDrawUsage,
12 | StaticDrawUsage
13 | } from 'three'
14 | import { DefaultBufferSize } from './debugDrawer'
15 | import { Physics } from './physics'
16 |
17 | export class PhysicsBody {
18 | constructor(public uuid: string, private physics: Physics) {}
19 |
20 | public setLinearVelocity(x: number = 0, y: number = 0, z: number = 0) {
21 | this.physics.body.setLinearVelocity({ uuid: this.uuid, x, y, z })
22 | }
23 |
24 | public setAngularVelocity(x: number = 0, y: number = 0, z: number = 0) {
25 | this.physics.body.setAngularVelocity({ uuid: this.uuid, x, y, z })
26 | }
27 | }
28 |
29 | export class AmmoPhysics {
30 | public objects = new Map()
31 |
32 | public physics: Physics
33 |
34 | private debugGeometry: BufferGeometry
35 |
36 | constructor(public worker: Worker) {}
37 |
38 | async init() {
39 | const com: any = Comlink.wrap(this.worker)
40 | const wrapper = await new com()
41 | await wrapper.init()
42 | this.physics = wrapper.physics
43 |
44 | this.worker.addEventListener('message', e => {
45 | const { data } = e
46 | if (data.msg === 'updates') this._onUpdates(data.updates)
47 | if (data.msg === 'debugDrawerUpdate') {
48 | const { debugVertices, debugColors, index } = data
49 | if (this.debugGeometry) {
50 | this.debugGeometry.setDrawRange(0, index)
51 | for (let i = 0; i < debugVertices.length / 2; i++) {
52 | this.debugGeometry.attributes.position.setXYZ(
53 | i,
54 | debugVertices[i * 3 + 0],
55 | debugVertices[i * 3 + 1],
56 | debugVertices[i * 3 + 2]
57 | )
58 | }
59 | for (let i = 0; i < debugColors.length / 2; i++) {
60 | this.debugGeometry.attributes.color.setXYZ(
61 | i,
62 | debugColors[i * 3 + 0],
63 | debugColors[i * 3 + 1],
64 | debugColors[i * 3 + 2]
65 | )
66 | }
67 | // @ts-ignore
68 | this.debugGeometry.attributes.position.needsUpdate = true
69 | // @ts-ignore
70 | this.debugGeometry.attributes.color.needsUpdate = true
71 | }
72 | }
73 | })
74 | }
75 |
76 | public getBody(uuid: string) {
77 | return new PhysicsBody(uuid, this.physics)
78 | }
79 |
80 | public debugDrawerInit(
81 | scene: Scene,
82 | drawOnTop: boolean = false,
83 | bufferSize: number = DefaultBufferSize
84 | ) {
85 | const debugVertices = new Float32Array(bufferSize)
86 | const debugColors = new Float32Array(bufferSize)
87 |
88 | const debugVerticesBuffer = new BufferAttribute(debugVertices, 3)
89 | const debugColorsBuffer = new BufferAttribute(debugColors, 3)
90 |
91 | this.debugGeometry = new BufferGeometry()
92 | this.debugGeometry.setAttribute(
93 | 'position',
94 | debugVerticesBuffer.setUsage(StaticDrawUsage)
95 | )
96 | this.debugGeometry.setAttribute(
97 | 'color',
98 | debugColorsBuffer.setUsage(StaticDrawUsage)
99 | )
100 |
101 | var debugMaterial = new LineBasicMaterial({
102 | vertexColors: true,
103 | // vertexColors: VertexColors,
104 | depthTest: !drawOnTop
105 | })
106 |
107 | var debugMesh = new LineSegments(this.debugGeometry, debugMaterial)
108 | debugMesh.frustumCulled = false
109 | if (drawOnTop) debugMesh.renderOrder = 999
110 |
111 | scene.add(debugMesh)
112 |
113 | this.physics.debugDrawerInit(debugVertices, debugColors)
114 | }
115 |
116 | public destroy(uuid: string) {
117 | this.physics.destroy(uuid)
118 | }
119 |
120 | private _onUpdates(updates: any) {
121 | for (let i = 0; i < updates.length; i += 8) {
122 | let uuid = updates[i + 0]
123 | let px = updates[i + 1]
124 | let py = updates[i + 2]
125 | let pz = updates[i + 3]
126 | let qx = updates[i + 4]
127 | let qy = updates[i + 5]
128 | let qz = updates[i + 6]
129 | let qw = updates[i + 7]
130 | let obj = this.objects.get(uuid)
131 | obj?.position?.set(px, py, pz)
132 | obj?.rotation?.setFromQuaternion(new Quaternion(qx, qy, qz, qw))
133 | }
134 | }
135 |
136 | public get add() {
137 | return {
138 | existing: (mesh: THREE.Mesh, params: any = {}) =>
139 | this.addExisting(mesh, params),
140 | box: (params: any) => this.physics.add.box(params),
141 | sphere: (params: any) => this.physics.add.sphere(params)
142 | }
143 | }
144 |
145 | public link(mesh: THREE.Mesh) {
146 | this.objects.set(mesh.uuid, mesh)
147 | }
148 |
149 | private addExisting(mesh: THREE.Mesh, p: any = {}) {
150 | const { position: pos, quaternion: quat, uuid } = mesh
151 | const { mass = 1, collisionFlags = 0 } = p
152 |
153 | // set default params
154 | const defaultParams = {
155 | width: 1,
156 | height: 1,
157 | depth: 1,
158 | radius: 1,
159 | radiusTop: 1, // for the cylinder
160 | radiusBottom: 1, // for the cylinder
161 | tube: 0.4, // for the torus
162 | tubularSegments: 6 // for the torus
163 | }
164 |
165 | let shape: string = 'unknown'
166 | // retrieve the shape from the geometry
167 | const type = mesh.geometry?.type || 'unknown'
168 | if (/box/i.test(type)) shape = 'box'
169 | else if (/cone/i.test(type)) shape = 'cone'
170 | else if (/cylinder/i.test(type)) shape = 'cylinder'
171 | else if (/extrude/i.test(type)) shape = 'extrude'
172 | else if (/plane/i.test(type)) shape = 'plane'
173 | else if (/sphere/i.test(type)) shape = 'sphere'
174 | else if (/torus/i.test(type)) shape = 'torus'
175 |
176 | if (shape === 'unknown') console.warn('shape unknown')
177 |
178 | // get the right params
179 | // @ts-ignore
180 | let params = { ...defaultParams, ...mesh?.geometry?.parameters, ...p }
181 |
182 | params = {
183 | ...params,
184 | uuid,
185 | pos: { x: pos.x, y: pos.y, z: pos.z },
186 | quat: { x: quat.x, y: quat.y, z: quat.z, w: quat.w }
187 | }
188 |
189 | // create rigidBody
190 | switch (shape) {
191 | case 'box':
192 | this.add.box({ ...params })
193 | break
194 | case 'sphere':
195 | this.add.sphere({ ...params })
196 | break
197 | }
198 |
199 | // link rigid body
200 | this.link(mesh)
201 |
202 | // return body
203 | return this.getBody(uuid)
204 | }
205 | }
206 |
207 | /**
208 | * KEEP THIS!!
209 | */
210 | // const s = `
211 | // var Module = { TOTAL_MEMORY: 256 * 1024 * 1024 }
212 | // const urls = 'http://localhost:8080/lib/ammo.wasm.js'
213 | // importScripts(urls)
214 | // console.log(Ammo)
215 | // Ammo().then(()=>{console.log('asdf')})
216 | // const bla = e => {
217 | // console.log('bla', e.data)
218 | // }`
219 |
220 | // const webWorker = new Worker(
221 | // URL.createObjectURL(new Blob([s], { type: 'module' }))
222 | // )
223 |
--------------------------------------------------------------------------------
/src/common.ts:
--------------------------------------------------------------------------------
1 | export const createObjects = (fnc: Function) => {
2 | // add sphere rain
3 | fnc(5)
4 | const handle = setInterval(() => {
5 | fnc(5)
6 | }, 100)
7 |
8 | setTimeout(() => {
9 | clearInterval(handle)
10 | }, 15000)
11 | }
12 |
13 | export const DPI = 1
14 |
--------------------------------------------------------------------------------
/src/debugDrawer.ts:
--------------------------------------------------------------------------------
1 | /* global Ammo */
2 |
3 | export const DefaultBufferSize = 3 * 10_000
4 |
5 | export const AmmoDebugConstants = {
6 | NoDebug: 0,
7 | DrawWireframe: 1,
8 | DrawAabb: 2,
9 | DrawFeaturesText: 4,
10 | DrawContactPoints: 8,
11 | NoDeactivation: 16,
12 | NoHelpText: 32,
13 | DrawText: 64,
14 | ProfileTimings: 128,
15 | EnableSatComparison: 256,
16 | DisableBulletLCP: 512,
17 | EnableCCD: 1024,
18 | DrawConstraints: 1 << 11, //2048
19 | DrawConstraintLimits: 1 << 12, //4096
20 | FastWireframe: 1 << 13, //8192
21 | DrawNormals: 1 << 14, //16384
22 | MAX_DEBUG_DRAW_MODE: 0xffffffff,
23 | }
24 |
25 | const setXYZ = (array: any, index: any, x: any, y: any, z: any) => {
26 | index *= 3
27 | array[index + 0] = x
28 | array[index + 1] = y
29 | array[index + 2] = z
30 | }
31 |
32 | /**
33 | * An implementation of the btIDebugDraw interface in Ammo.js, for debug rendering of Ammo shapes
34 | * @class AmmoDebugDrawer
35 | * @param {Uint32Array} indexArray
36 | * @param {Float32Array} verticesArray
37 | * @param {Float32Array} colorsArray
38 | * @param {Ammo.btCollisionWorld} world
39 | * @param {object} [options]
40 | */
41 | export class AmmoDebugDrawer {
42 | debugDrawer: any
43 | debugDrawMode: any
44 | enabled: boolean
45 |
46 | index: number
47 | warnedOnce: any
48 |
49 | constructor(
50 | private indexArray: any,
51 | public verticesArray: any,
52 | public colorsArray: any,
53 | private world: any,
54 | private options: any = {}
55 | ) {
56 | this.debugDrawMode =
57 | options.debugDrawMode || AmmoDebugConstants.DrawWireframe
58 |
59 | this.index = 0
60 | if (this.indexArray) {
61 | // @ts-ignore
62 | Atomics.store(this.indexArray, 0, this.index)
63 | }
64 |
65 | this.enabled = false
66 |
67 | this.debugDrawer = new Ammo.DebugDrawer()
68 | this.debugDrawer.drawLine = this.drawLine.bind(this)
69 | this.debugDrawer.drawContactPoint = this.drawContactPoint.bind(this)
70 | this.debugDrawer.reportErrorWarning = this.reportErrorWarning.bind(this)
71 | this.debugDrawer.draw3dText = this.draw3dText.bind(this)
72 | this.debugDrawer.setDebugMode = this.setDebugMode.bind(this)
73 | this.debugDrawer.getDebugMode = this.getDebugMode.bind(this)
74 | this.debugDrawer.enable = this.enable.bind(this)
75 | this.debugDrawer.disable = this.disable.bind(this)
76 | this.debugDrawer.update = this.update.bind(this)
77 |
78 | this.world.setDebugDrawer(this.debugDrawer)
79 | }
80 |
81 | enable() {
82 | this.enabled = true
83 | }
84 |
85 | disable() {
86 | this.enabled = false
87 | }
88 |
89 | update() {
90 | if (!this.enabled) {
91 | return
92 | }
93 |
94 | if (this.indexArray) {
95 | // @ts-ignore
96 | if (Atomics.load(this.indexArray, 0) === 0) {
97 | this.index = 0
98 | this.world.debugDrawWorld()
99 | // @ts-ignore
100 | Atomics.store(this.indexArray, 0, this.index)
101 | }
102 | } else {
103 | this.index = 0
104 | this.world.debugDrawWorld()
105 | }
106 | }
107 |
108 | drawLine(from: any, to: any, color: any) {
109 | // @ts-ignore
110 | const heap = Ammo.HEAPF32
111 | const r = heap[(color + 0) / 4]
112 | const g = heap[(color + 4) / 4]
113 | const b = heap[(color + 8) / 4]
114 |
115 | const fromX = heap[(from + 0) / 4]
116 | const fromY = heap[(from + 4) / 4]
117 | const fromZ = heap[(from + 8) / 4]
118 | setXYZ(this.verticesArray, this.index, fromX, fromY, fromZ)
119 | setXYZ(this.colorsArray, this.index++, r, g, b)
120 |
121 | const toX = heap[(to + 0) / 4]
122 | const toY = heap[(to + 4) / 4]
123 | const toZ = heap[(to + 8) / 4]
124 | setXYZ(this.verticesArray, this.index, toX, toY, toZ)
125 | setXYZ(this.colorsArray, this.index++, r, g, b)
126 | }
127 |
128 | //TODO: figure out how to make lifeTime work
129 | drawContactPoint(
130 | pointOnB: any,
131 | normalOnB: any,
132 | distance: any,
133 | lifeTime: any,
134 | color: any
135 | ) {
136 | // @ts-ignore
137 | const heap = Ammo.HEAPF32
138 | const r = heap[(color + 0) / 4]
139 | const g = heap[(color + 4) / 4]
140 | const b = heap[(color + 8) / 4]
141 |
142 | const x = heap[(pointOnB + 0) / 4]
143 | const y = heap[(pointOnB + 4) / 4]
144 | const z = heap[(pointOnB + 8) / 4]
145 | setXYZ(this.verticesArray, this.index, x, y, z)
146 | setXYZ(this.colorsArray, this.index++, r, g, b)
147 |
148 | const dx = heap[(normalOnB + 0) / 4] * distance
149 | const dy = heap[(normalOnB + 4) / 4] * distance
150 | const dz = heap[(normalOnB + 8) / 4] * distance
151 | setXYZ(this.verticesArray, this.index, x + dx, y + dy, z + dz)
152 | setXYZ(this.colorsArray, this.index++, r, g, b)
153 | }
154 |
155 | reportErrorWarning(warningString: any) {
156 | if (Ammo.hasOwnProperty('UTF8ToString')) {
157 | // @ts-ignore
158 | console.warn(Ammo.UTF8ToString(warningString))
159 | } else if (!this.warnedOnce) {
160 | this.warnedOnce = true
161 | console.warn(
162 | 'Cannot print warningString, please export UTF8ToString from Ammo.js in make.py'
163 | )
164 | }
165 | }
166 |
167 | draw3dText(location: any, textString: any) {
168 | //TODO
169 | console.warn('TODO: draw3dText')
170 | }
171 |
172 | setDebugMode(debugMode: any) {
173 | this.debugDrawMode = debugMode
174 | }
175 |
176 | getDebugMode() {
177 | return this.debugDrawMode
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export { AmmoPhysics, PhysicsBody } from './ammoPhysics'
2 |
--------------------------------------------------------------------------------
/src/physics.ts:
--------------------------------------------------------------------------------
1 | import { AmmoDebugDrawer } from './debugDrawer'
2 |
3 | export class Physics {
4 | private tmpBtTrans = new Ammo.btTransform()
5 | private tmpBtVector3 = new Ammo.btVector3()
6 | private tmpBtQuaternion = new Ammo.btQuaternion(0, 0, 0, 1)
7 |
8 | public dispatcher: Ammo.btDispatcher
9 | public physicsWorld: Ammo.btDiscreteDynamicsWorld
10 | public rigidBodies: Map = new Map()
11 |
12 | public debugDrawer: AmmoDebugDrawer
13 |
14 | constructor() {
15 | this.setupPhysicsWorld()
16 | }
17 |
18 | public get body() {
19 | return {
20 | setLinearVelocity: (p: any) => {
21 | this.tmpBtVector3.setValue(p.x, p.y, p.z)
22 | this.getRigidBody(p.uuid)?.setLinearVelocity(this.tmpBtVector3)
23 | },
24 | setAngularVelocity: (p: any) => {
25 | this.tmpBtVector3.setValue(p.x, p.y, p.z)
26 | this.getRigidBody(p.uuid)?.setAngularVelocity(this.tmpBtVector3)
27 | }
28 | }
29 | }
30 |
31 | public getRigidBody(uuid: string) {
32 | return this.rigidBodies.get(uuid)
33 | }
34 |
35 | public debugDrawerInit(debugVertices: any, debugColors: any) {
36 | this.debugDrawer = new AmmoDebugDrawer(
37 | null,
38 | debugVertices,
39 | debugColors,
40 | this.physicsWorld
41 | )
42 | this.debugDrawer.enable()
43 | }
44 |
45 | public debugDrawerUpdate() {
46 | if (!this.debugDrawer || !this.debugDrawer.enabled) return false
47 | this.debugDrawer.update()
48 | return true
49 | }
50 |
51 | public setGravity(x: number = 0, y: number = 0, z: number = 0) {
52 | this.tmpBtVector3.setValue(x, y, z)
53 | this.physicsWorld.setGravity(this.tmpBtVector3)
54 | }
55 |
56 | public update(delta: number) {
57 | let updates: any[] = []
58 |
59 | // step world
60 | const deltaTime = delta / 1000
61 | this.physicsWorld.stepSimulation(deltaTime, 4, 1 / 60)
62 |
63 | this.rigidBodies.forEach((rb, uuid) => {
64 | const ms = rb.getMotionState()
65 |
66 | if (ms) {
67 | ms.getWorldTransform(this.tmpBtTrans)
68 | let p = this.tmpBtTrans.getOrigin()
69 | let q = this.tmpBtTrans.getRotation()
70 | updates.push(uuid, p.x(), p.y(), p.z(), q.x(), q.y(), q.z(), q.w())
71 | }
72 | })
73 |
74 | return updates
75 | }
76 |
77 | public get add() {
78 | return {
79 | box: (params: any) => this.addBox(params),
80 | sphere: (params: any) => this.addSphere(params)
81 | }
82 | }
83 |
84 | public destroy(uuid: string) {
85 | const rb = this.rigidBodies.get(uuid)
86 | if (rb) this.physicsWorld.removeRigidBody(rb)
87 | }
88 |
89 | private addBox(params: any = {}) {
90 | console.log('addBox')
91 | const { width = 1, height = 1, depth = 1 } = params
92 | const boxHalfExtents = new Ammo.btVector3(width / 2, height / 2, depth / 2)
93 | const collisionShape = new Ammo.btBoxShape(boxHalfExtents)
94 | this.collisionShapeToRigidBody(collisionShape, params)
95 | }
96 |
97 | private addSphere(params: any = {}) {
98 | const { radius = 1 } = params
99 | const collisionShape = new Ammo.btSphereShape(radius / 2)
100 | this.collisionShapeToRigidBody(collisionShape, params)
101 | }
102 |
103 | public addRigidBodyToWorld(uuid: string) {
104 | const rb = this.getRigidBody(uuid)
105 | if (rb) this.physicsWorld.addRigidBody(rb)
106 | }
107 |
108 | public collisionShapeToRigidBody(
109 | collisionShape: Ammo.btCollisionShape,
110 | params: any = {}
111 | ) {
112 | // apply params
113 | const {
114 | uuid,
115 | mass = 1,
116 | collisionFlags = 0,
117 | pos = { x: 0, y: 0, z: 0 },
118 | quat = { x: 0, y: 0, z: 0, w: 1 },
119 | addToWorld = true
120 | } = params
121 |
122 | // we need a uuid!
123 | if (typeof uuid === 'undefined') {
124 | console.warn('Please provide an uuid')
125 | return
126 | }
127 |
128 | // apply position and rotation
129 | const transform = new Ammo.btTransform()
130 | transform.setIdentity()
131 | transform.setOrigin(new Ammo.btVector3(pos.x || 0, pos.y || 0, pos.z || 0))
132 | transform.setRotation(
133 | new Ammo.btQuaternion(quat.x || 0, quat.y || 0, quat.z || 0, quat.w || 1)
134 | )
135 |
136 | // create the rigid body
137 | const motionState = new Ammo.btDefaultMotionState(transform)
138 | const localInertia = new Ammo.btVector3(0, 0, 0)
139 | if (mass > 0) collisionShape.calculateLocalInertia(mass, localInertia)
140 | const rbInfo = new Ammo.btRigidBodyConstructionInfo(
141 | mass,
142 | motionState,
143 | collisionShape,
144 | localInertia
145 | )
146 | const rigidBody = new Ammo.btRigidBody(rbInfo)
147 |
148 | // rigid body properties
149 | if (mass > 0) rigidBody.setActivationState(4) // Disable deactivation
150 | rigidBody.setCollisionFlags(collisionFlags)
151 |
152 | // ad rigid body to physics world
153 | this.rigidBodies.set(uuid, rigidBody)
154 | if (addToWorld) this.addRigidBodyToWorld(uuid)
155 | }
156 |
157 | public setupPhysicsWorld() {
158 | const collisionConfiguration = new Ammo.btDefaultCollisionConfiguration()
159 | const broadphase = new Ammo.btDbvtBroadphase()
160 | const solver = new Ammo.btSequentialImpulseConstraintSolver()
161 | this.dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration)
162 | this.physicsWorld = new Ammo.btDiscreteDynamicsWorld(
163 | this.dispatcher,
164 | broadphase,
165 | solver,
166 | collisionConfiguration
167 | )
168 | this.setGravity(0, -9.81 * 2, 0)
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/src/physics.worker.ts:
--------------------------------------------------------------------------------
1 | import { Physics } from './physics'
2 | import * as Comlink from 'comlink'
3 |
4 | var Module = { TOTAL_MEMORY: 256 * 1024 * 1024 }
5 |
6 | import { wasmSupported } from './wasmSupported'
7 | const ammoPath = wasmSupported ? 'ammo.wasm.js' : 'ammo.js'
8 | importScripts(ammoPath)
9 |
10 | import './requestAnimationFramePolyfill'
11 |
12 | class Wrapper {
13 | physics: Physics
14 |
15 | async init() {
16 | return new Promise(resolve => {
17 | Ammo().then(() => {
18 | this.physics = new Physics()
19 |
20 | self.postMessage({ msg: 'ready' })
21 |
22 | let last = new Date().getTime()
23 |
24 | const loop = () => {
25 | let now = new Date().getTime()
26 | const delta = now - last
27 | last = now
28 |
29 | self.postMessage({ msg: 'preUpdate' })
30 |
31 | const updates = this.physics.update(delta)
32 |
33 | self.postMessage({ msg: 'updates', updates })
34 |
35 | const hasUpdated = this.physics.debugDrawerUpdate()
36 | // console.log(hasUpdated)
37 |
38 | if (hasUpdated) {
39 | const {
40 | verticesArray,
41 | colorsArray,
42 | index
43 | } = this.physics.debugDrawer
44 | self.postMessage({
45 | msg: 'debugDrawerUpdate',
46 | debugVertices: verticesArray,
47 | debugColors: colorsArray,
48 | index: index
49 | })
50 | }
51 |
52 | self.postMessage({ msg: 'postUpdate' })
53 |
54 | requestAnimationFrame(loop)
55 | }
56 | loop()
57 |
58 | resolve()
59 | })
60 | })
61 | }
62 | }
63 |
64 | Comlink.expose(Wrapper)
65 |
--------------------------------------------------------------------------------
/src/requestAnimationFramePolyfill.ts:
--------------------------------------------------------------------------------
1 | // https://gist.github.com/paulirish/1579671
2 |
3 | // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
4 | // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
5 |
6 | // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
7 |
8 | // MIT license
9 |
10 | ;(function() {
11 | var lastTime = 0
12 | var vendors: any = ['ms', 'moz', 'webkit', 'o']
13 | for (var x = 0; x < vendors.length && !self.requestAnimationFrame; ++x) {
14 | // @ts-ignore
15 | self.requestAnimationFrame = self[vendors[x] + 'RequestAnimationFrame']
16 | self.cancelAnimationFrame =
17 | // @ts-ignore
18 | self[vendors[x] + 'CancelAnimationFrame'] ||
19 | // @ts-ignore
20 | self[vendors[x] + 'CancelRequestAnimationFrame']
21 | }
22 |
23 | if (!self.requestAnimationFrame)
24 | // @ts-ignore
25 | self.requestAnimationFrame = function(callback, element) {
26 | var currTime = new Date().getTime()
27 | var timeToCall = Math.max(0, 16 - (currTime - lastTime))
28 | var id = self.setTimeout(function() {
29 | callback(currTime + timeToCall)
30 | }, timeToCall)
31 | lastTime = currTime + timeToCall
32 | return id
33 | }
34 |
35 | if (!self.cancelAnimationFrame)
36 | self.cancelAnimationFrame = function(id: any) {
37 | clearTimeout(id)
38 | }
39 | })()
40 |
--------------------------------------------------------------------------------
/src/wasmSupported.ts:
--------------------------------------------------------------------------------
1 | // Inspired by https://github.com/playcanvas/engine/blob/master/examples/wasm-loader.js
2 | export const wasmSupported = (() => {
3 | try {
4 | if (
5 | typeof WebAssembly === 'object' &&
6 | typeof WebAssembly.instantiate === 'function'
7 | ) {
8 | const module = new WebAssembly.Module(
9 | Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00)
10 | )
11 | if (module instanceof WebAssembly.Module)
12 | return new WebAssembly.Instance(module) instanceof WebAssembly.Instance
13 | }
14 | } catch (e) {}
15 | return false
16 | })()
17 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Basic Options */
4 | // "incremental": true, /* Enable incremental compilation */
5 | "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
6 | "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
7 | "lib": [
8 | "ES2015",
9 | "WebWorker",
10 | "DOM"
11 | ] /* Specify library files to be included in the compilation. */,
12 | // "allowJs": true, /* Allow javascript files to be compiled. */
13 | // "checkJs": true, /* Report errors in .js files. */
14 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
15 | // "declaration": true, /* Generates corresponding '.d.ts' file. */
16 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
17 | // "sourceMap": true, /* Generates corresponding '.map' file. */
18 | // "outFile": "./", /* Concatenate and emit output to single file. */
19 | // "outDir": "./", /* Redirect output structure to the directory. */
20 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
21 | // "composite": true, /* Enable project compilation */
22 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
23 | // "removeComments": true, /* Do not emit comments to output. */
24 | // "noEmit": true, /* Do not emit outputs. */
25 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */
26 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
27 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
28 |
29 | /* Strict Type-Checking Options */
30 | "strict": true /* Enable all strict type-checking options. */,
31 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
32 | // "strictNullChecks": true, /* Enable strict null checks. */
33 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */
34 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
35 | "strictPropertyInitialization": false /* Enable strict checking of property initialization in classes. */,
36 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
37 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
38 |
39 | /* Additional Checks */
40 | // "noUnusedLocals": true, /* Report errors on unused locals. */
41 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
42 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
43 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
44 |
45 | /* Module Resolution Options */
46 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
47 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
48 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
49 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
50 | "typeRoots": [
51 | "./typings"
52 | ] /* List of folders to include type definitions from. */,
53 | // "types": [], /* Type declaration files to be included in compilation. */
54 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
55 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
56 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
57 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
58 |
59 | /* Source Map Options */
60 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
61 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
62 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
63 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
64 |
65 | /* Experimental Options */
66 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
67 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
68 |
69 | /* Advanced Options */
70 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/typings/ammo.d.ts:
--------------------------------------------------------------------------------
1 | // https://raw.githubusercontent.com/giniedp/ammojs-typed/master/ammo/ambient/ammo.d.ts
2 | declare function Ammo(api?: T): Promise
3 | declare module Ammo {
4 | function destroy(obj: any): void
5 | class btIDebugDraw {
6 | drawLine(from: btVector3, to: btVector3, color: btVector3): void
7 | drawContactPoint(
8 | pointOnB: btVector3,
9 | normalOnB: btVector3,
10 | distance: number,
11 | lifeTime: number,
12 | color: btVector3
13 | ): void
14 | reportErrorWarning(warningString: string): void
15 | draw3dText(location: btVector3, textString: string): void
16 | setDebugMode(debugMode: number): void
17 | getDebugMode(): number
18 | }
19 | class DebugDrawer {
20 | constructor()
21 | drawLine(from: btVector3, to: btVector3, color: btVector3): void
22 | drawContactPoint(
23 | pointOnB: btVector3,
24 | normalOnB: btVector3,
25 | distance: number,
26 | lifeTime: number,
27 | color: btVector3
28 | ): void
29 | reportErrorWarning(warningString: string): void
30 | draw3dText(location: btVector3, textString: string): void
31 | setDebugMode(debugMode: number): void
32 | getDebugMode(): number
33 | }
34 | class btVector3 {
35 | constructor()
36 | constructor(x: number, y: number, z: number)
37 | length(): number
38 | x(): number
39 | y(): number
40 | z(): number
41 | setX(x: number): void
42 | setY(y: number): void
43 | setZ(z: number): void
44 | setValue(x: number, y: number, z: number): void
45 | normalize(): void
46 | rotate(wAxis: btVector3, angle: number): btVector3
47 | dot(v: btVector3): number
48 | op_mul(x: number): btVector3
49 | op_add(v: btVector3): btVector3
50 | op_sub(v: btVector3): btVector3
51 | }
52 | class btVector4 extends btVector3 {
53 | constructor()
54 | constructor(x: number, y: number, z: number, w: number)
55 | w(): number
56 | setValue(x: number, y: number, z: number): void
57 | setValue(x: number, y: number, z: number, w: number): void
58 | }
59 | class btQuadWord {
60 | x(): number
61 | y(): number
62 | z(): number
63 | w(): number
64 | setX(x: number): void
65 | setY(y: number): void
66 | setZ(z: number): void
67 | setW(w: number): void
68 | }
69 | class btQuaternion extends btQuadWord {
70 | constructor(x: number, y: number, z: number, w: number)
71 | setValue(x: number, y: number, z: number, w: number): void
72 | setEulerZYX(z: number, y: number, x: number): void
73 | setRotation(axis: btVector3, angle: number): void
74 | normalize(): void
75 | length2(): number
76 | length(): number
77 | dot(q: btQuaternion): number
78 | normalized(): btQuaternion
79 | getAxis(): btVector3
80 | inverse(): btQuaternion
81 | getAngle(): number
82 | getAngleShortestPath(): number
83 | angle(q: btQuaternion): number
84 | angleShortestPath(q: btQuaternion): number
85 | op_add(q: btQuaternion): btQuaternion
86 | op_sub(q: btQuaternion): btQuaternion
87 | op_mul(s: number): btQuaternion
88 | op_mulq(q: btQuaternion): btQuaternion
89 | op_div(s: number): btQuaternion
90 | }
91 | class btMatrix3x3 {
92 | setEulerZYX(ex: number, ey: number, ez: number): void
93 | getRotation(q: btQuaternion): void
94 | getRow(y: number): btVector3
95 | }
96 | class btTransform {
97 | constructor()
98 | constructor(q: btQuaternion, v: btVector3)
99 | setIdentity(): void
100 | setOrigin(origin: btVector3): void
101 | setRotation(rotation: btQuaternion): void
102 | getOrigin(): btVector3
103 | getRotation(): btQuaternion
104 | getBasis(): btMatrix3x3
105 | setFromOpenGLMatrix(m: number[]): void
106 | inverse(): btTransform
107 | op_mul(t: btTransform): btTransform
108 | }
109 | class btMotionState {
110 | getWorldTransform(worldTrans: btTransform): void
111 | setWorldTransform(worldTrans: btTransform): void
112 | }
113 | class btDefaultMotionState extends btMotionState {
114 | constructor(startTrans?: btTransform, centerOfMassOffset?: btTransform)
115 | get_m_graphicsWorldTrans(): btTransform
116 | set_m_graphicsWorldTrans(m_graphicsWorldTrans: btTransform): void
117 | }
118 | class btCollisionObject {
119 | setAnisotropicFriction(anisotropicFriction: btVector3, frictionMode: number): void
120 | getCollisionShape(): btCollisionShape
121 | setContactProcessingThreshold(contactProcessingThreshold: number): void
122 | setActivationState(newState: number): void
123 | forceActivationState(newState: number): void
124 | activate(forceActivation?: boolean): void
125 | isActive(): boolean
126 | isKinematicObject(): boolean
127 | isStaticObject(): boolean
128 | isStaticOrKinematicObject(): boolean
129 | getRestitution(): number
130 | getFriction(): number
131 | getRollingFriction(): number
132 | setRestitution(rest: number): void
133 | setFriction(frict: number): void
134 | setRollingFriction(frict: number): void
135 | getWorldTransform(): btTransform
136 | getCollisionFlags(): number
137 | setCollisionFlags(flags: number): void
138 | setWorldTransform(worldTrans: btTransform): void
139 | setCollisionShape(collisionShape: btCollisionShape): void
140 | setCcdMotionThreshold(ccdMotionThreshold: number): void
141 | setCcdSweptSphereRadius(radius: number): void
142 | getUserIndex(): number
143 | setUserIndex(index: number): void
144 | getUserPointer(): any
145 | setUserPointer(userPointer: any): void
146 | getBroadphaseHandle(): btBroadphaseProxy
147 | }
148 | class btCollisionObjectWrapper {
149 | getWorldTransform(): btTransform
150 | getCollisionObject(): btCollisionObject
151 | getCollisionShape(): btCollisionShape
152 | }
153 | class RayResultCallback {
154 | hasHit(): boolean
155 | get_m_collisionFilterGroup(): number
156 | set_m_collisionFilterGroup(m_collisionFilterGroup: number): void
157 | get_m_collisionFilterMask(): number
158 | set_m_collisionFilterMask(m_collisionFilterMask: number): void
159 | get_m_closestHitFraction(): number
160 | set_m_closestHitFraction(m_closestHitFraction: number): void
161 | get_m_collisionObject(): btCollisionObject
162 | set_m_collisionObject(m_collisionObject: btCollisionObject): void
163 | }
164 | class ClosestRayResultCallback extends RayResultCallback {
165 | constructor(from: btVector3, to: btVector3)
166 | get_m_rayFromWorld(): btVector3
167 | set_m_rayFromWorld(m_rayFromWorld: btVector3): void
168 | get_m_rayToWorld(): btVector3
169 | set_m_rayToWorld(m_rayToWorld: btVector3): void
170 | get_m_hitNormalWorld(): btVector3
171 | set_m_hitNormalWorld(m_hitNormalWorld: btVector3): void
172 | get_m_hitPointWorld(): btVector3
173 | set_m_hitPointWorld(m_hitPointWorld: btVector3): void
174 | }
175 | class btConstCollisionObjectArray {
176 | size(): number
177 | at(n: number): btCollisionObject
178 | }
179 | class btScalarArray {
180 | size(): number
181 | at(n: number): number
182 | }
183 | class AllHitsRayResultCallback extends RayResultCallback {
184 | constructor(from: btVector3, to: btVector3)
185 | get_m_collisionObjects(): btConstCollisionObjectArray
186 | set_m_collisionObjects(m_collisionObjects: btConstCollisionObjectArray): void
187 | get_m_rayFromWorld(): btVector3
188 | set_m_rayFromWorld(m_rayFromWorld: btVector3): void
189 | get_m_rayToWorld(): btVector3
190 | set_m_rayToWorld(m_rayToWorld: btVector3): void
191 | get_m_hitNormalWorld(): btVector3Array
192 | set_m_hitNormalWorld(m_hitNormalWorld: btVector3Array): void
193 | get_m_hitPointWorld(): btVector3Array
194 | set_m_hitPointWorld(m_hitPointWorld: btVector3Array): void
195 | get_m_hitFractions(): btScalarArray
196 | set_m_hitFractions(m_hitFractions: btScalarArray): void
197 | }
198 | class btManifoldPoint {
199 | getPositionWorldOnA(): btVector3
200 | getPositionWorldOnB(): btVector3
201 | getAppliedImpulse(): number
202 | getDistance(): number
203 | get_m_localPointA(): btVector3
204 | set_m_localPointA(m_localPointA: btVector3): void
205 | get_m_localPointB(): btVector3
206 | set_m_localPointB(m_localPointB: btVector3): void
207 | get_m_positionWorldOnB(): btVector3
208 | set_m_positionWorldOnB(m_positionWorldOnB: btVector3): void
209 | get_m_positionWorldOnA(): btVector3
210 | set_m_positionWorldOnA(m_positionWorldOnA: btVector3): void
211 | get_m_normalWorldOnB(): btVector3
212 | set_m_normalWorldOnB(m_normalWorldOnB: btVector3): void
213 | get_m_userPersistentData(): any
214 | set_m_userPersistentData(m_userPersistentData: any): void
215 | }
216 | class ContactResultCallback {
217 | addSingleResult(
218 | cp: btManifoldPoint,
219 | colObj0Wrap: btCollisionObjectWrapper,
220 | partId0: number,
221 | index0: number,
222 | colObj1Wrap: btCollisionObjectWrapper,
223 | partId1: number,
224 | index1: number
225 | ): number
226 | }
227 | class ConcreteContactResultCallback {
228 | constructor()
229 | addSingleResult(
230 | cp: btManifoldPoint,
231 | colObj0Wrap: btCollisionObjectWrapper,
232 | partId0: number,
233 | index0: number,
234 | colObj1Wrap: btCollisionObjectWrapper,
235 | partId1: number,
236 | index1: number
237 | ): number
238 | }
239 | class LocalShapeInfo {
240 | get_m_shapePart(): number
241 | set_m_shapePart(m_shapePart: number): void
242 | get_m_triangleIndex(): number
243 | set_m_triangleIndex(m_triangleIndex: number): void
244 | }
245 | class LocalConvexResult {
246 | constructor(
247 | hitCollisionObject: btCollisionObject,
248 | localShapeInfo: LocalShapeInfo,
249 | hitNormalLocal: btVector3,
250 | hitPointLocal: btVector3,
251 | hitFraction: number
252 | )
253 | get_m_hitCollisionObject(): btCollisionObject
254 | set_m_hitCollisionObject(m_hitCollisionObject: btCollisionObject): void
255 | get_m_localShapeInfo(): LocalShapeInfo
256 | set_m_localShapeInfo(m_localShapeInfo: LocalShapeInfo): void
257 | get_m_hitNormalLocal(): btVector3
258 | set_m_hitNormalLocal(m_hitNormalLocal: btVector3): void
259 | get_m_hitPointLocal(): btVector3
260 | set_m_hitPointLocal(m_hitPointLocal: btVector3): void
261 | get_m_hitFraction(): number
262 | set_m_hitFraction(m_hitFraction: number): void
263 | }
264 | class ConvexResultCallback {
265 | hasHit(): boolean
266 | get_m_collisionFilterGroup(): number
267 | set_m_collisionFilterGroup(m_collisionFilterGroup: number): void
268 | get_m_collisionFilterMask(): number
269 | set_m_collisionFilterMask(m_collisionFilterMask: number): void
270 | get_m_closestHitFraction(): number
271 | set_m_closestHitFraction(m_closestHitFraction: number): void
272 | }
273 | class ClosestConvexResultCallback extends ConvexResultCallback {
274 | constructor(convexFromWorld: btVector3, convexToWorld: btVector3)
275 | get_m_convexFromWorld(): btVector3
276 | set_m_convexFromWorld(m_convexFromWorld: btVector3): void
277 | get_m_convexToWorld(): btVector3
278 | set_m_convexToWorld(m_convexToWorld: btVector3): void
279 | get_m_hitNormalWorld(): btVector3
280 | set_m_hitNormalWorld(m_hitNormalWorld: btVector3): void
281 | get_m_hitPointWorld(): btVector3
282 | set_m_hitPointWorld(m_hitPointWorld: btVector3): void
283 | }
284 | class btCollisionShape {
285 | setLocalScaling(scaling: btVector3): void
286 | getLocalScaling(): btVector3
287 | calculateLocalInertia(mass: number, inertia: btVector3): void
288 | setMargin(margin: number): void
289 | getMargin(): number
290 | }
291 | class btConvexShape extends btCollisionShape {}
292 | class btConvexTriangleMeshShape extends btConvexShape {
293 | constructor(meshInterface: btStridingMeshInterface, calcAabb?: boolean)
294 | }
295 | class btBoxShape extends btCollisionShape {
296 | constructor(boxHalfExtents: btVector3)
297 | setMargin(margin: number): void
298 | getMargin(): number
299 | }
300 | class btCapsuleShape extends btCollisionShape {
301 | constructor(radius: number, height: number)
302 | setMargin(margin: number): void
303 | getMargin(): number
304 | getUpAxis(): number
305 | getRadius(): number
306 | getHalfHeight(): number
307 | }
308 | class btCapsuleShapeX extends btCapsuleShape {
309 | constructor(radius: number, height: number)
310 | setMargin(margin: number): void
311 | getMargin(): number
312 | }
313 | class btCapsuleShapeZ extends btCapsuleShape {
314 | constructor(radius: number, height: number)
315 | setMargin(margin: number): void
316 | getMargin(): number
317 | }
318 | class btCylinderShape extends btCollisionShape {
319 | constructor(halfExtents: btVector3)
320 | setMargin(margin: number): void
321 | getMargin(): number
322 | }
323 | class btCylinderShapeX extends btCylinderShape {
324 | constructor(halfExtents: btVector3)
325 | setMargin(margin: number): void
326 | getMargin(): number
327 | }
328 | class btCylinderShapeZ extends btCylinderShape {
329 | constructor(halfExtents: btVector3)
330 | setMargin(margin: number): void
331 | getMargin(): number
332 | }
333 | class btSphereShape extends btCollisionShape {
334 | constructor(radius: number)
335 | setMargin(margin: number): void
336 | getMargin(): number
337 | }
338 | class btMultiSphereShape extends btCollisionShape {
339 | constructor(positions: btVector3, radii: number[], numPoints: number)
340 | }
341 | class btConeShape extends btCollisionShape {
342 | constructor(radius: number, height: number)
343 | }
344 | class btIntArray {
345 | size(): number
346 | at(n: number): number
347 | }
348 | class btFace {
349 | get_m_indices(): btIntArray
350 | set_m_indices(m_indices: btIntArray): void
351 | }
352 | class btVector3Array {
353 | size(): number
354 | at(n: number): btVector3
355 | }
356 | class btFaceArray {
357 | size(): number
358 | at(n: number): btFace
359 | }
360 | class btConvexPolyhedron {
361 | get_m_vertices(): btVector3Array
362 | set_m_vertices(m_vertices: btVector3Array): void
363 | get_m_faces(): btFaceArray
364 | set_m_faces(m_faces: btFaceArray): void
365 | }
366 | class btConvexHullShape extends btCollisionShape {
367 | constructor(points?: number[], numPoints?: number)
368 | addPoint(point: btVector3, recalculateLocalAABB?: boolean): void
369 | setMargin(margin: number): void
370 | getMargin(): number
371 | getNumVertices(): number
372 | initializePolyhedralFeatures(shiftVerticesByMargin: number): boolean
373 | recalcLocalAabb(): void
374 | getConvexPolyhedron(): btConvexPolyhedron
375 | }
376 | class btShapeHull {
377 | constructor(shape: btConvexShape)
378 | buildHull(margin: number): boolean
379 | numVertices(): number
380 | getVertexPointer(): btVector3
381 | }
382 | class btConeShapeX extends btConeShape {
383 | constructor(radius: number, height: number)
384 | }
385 | class btConeShapeZ extends btConeShape {
386 | constructor(radius: number, height: number)
387 | }
388 | class btCompoundShape extends btCollisionShape {
389 | constructor(enableDynamicAabbTree?: boolean)
390 | addChildShape(localTransform: btTransform, shape: btCollisionShape): void
391 | removeChildShape(shape: btCollisionShape): void
392 | removeChildShapeByIndex(childShapeindex: number): void
393 | getNumChildShapes(): number
394 | getChildShape(index: number): btCollisionShape
395 | updateChildTransform(childIndex: number, newChildTransform: btTransform, shouldRecalculateLocalAabb?: boolean): void
396 | setMargin(margin: number): void
397 | getMargin(): number
398 | }
399 | class btStridingMeshInterface {
400 | setScaling(scaling: btVector3): void
401 | }
402 | class btIndexedMesh {
403 | get_m_numTriangles(): number
404 | set_m_numTriangles(m_numTriangles: number): void
405 | }
406 | class btIndexedMeshArray {
407 | size(): number
408 | at(n: number): btIndexedMesh
409 | }
410 | class btTriangleMesh extends btStridingMeshInterface {
411 | constructor(use32bitIndices?: boolean, use4componentVertices?: boolean)
412 | addTriangle(vertex0: btVector3, vertex1: btVector3, vertex2: btVector3, removeDuplicateVertices?: boolean): void
413 | findOrAddVertex(vertex: btVector3, removeDuplicateVertices: boolean): number
414 | addIndex(index: number): void
415 | getIndexedMeshArray(): btIndexedMeshArray
416 | }
417 | enum PHY_ScalarType {
418 | PHY_FLOAT,
419 | PHY_DOUBLE,
420 | PHY_INTEGER,
421 | PHY_SHORT,
422 | PHY_FIXEDPOINT88,
423 | PHY_UCHAR
424 | }
425 | class btConcaveShape extends btCollisionShape {}
426 | class btStaticPlaneShape extends btConcaveShape {
427 | constructor(planeNormal: btVector3, planeConstant: number)
428 | }
429 | class btTriangleMeshShape extends btConcaveShape {}
430 | class btBvhTriangleMeshShape extends btTriangleMeshShape {
431 | constructor(meshInterface: btStridingMeshInterface, useQuantizedAabbCompression: boolean, buildBvh?: boolean)
432 | }
433 | class btHeightfieldTerrainShape extends btConcaveShape {
434 | constructor(
435 | heightStickWidth: number,
436 | heightStickLength: number,
437 | heightfieldData: any,
438 | heightScale: number,
439 | minHeight: number,
440 | maxHeight: number,
441 | upAxis: number,
442 | hdt: PHY_ScalarType,
443 | flipQuadEdges: boolean
444 | )
445 | setMargin(margin: number): void
446 | getMargin(): number
447 | }
448 | class btDefaultCollisionConstructionInfo {
449 | constructor()
450 | }
451 | class btDefaultCollisionConfiguration {
452 | constructor(info?: btDefaultCollisionConstructionInfo)
453 | }
454 | class btPersistentManifold {
455 | constructor()
456 | getBody0(): btCollisionObject
457 | getBody1(): btCollisionObject
458 | getNumContacts(): number
459 | getContactPoint(index: number): btManifoldPoint
460 | }
461 | class btDispatcher {
462 | getNumManifolds(): number
463 | getManifoldByIndexInternal(index: number): btPersistentManifold
464 | }
465 | class btCollisionDispatcher extends btDispatcher {
466 | constructor(conf: btDefaultCollisionConfiguration)
467 | }
468 | class btOverlappingPairCallback {}
469 | class btOverlappingPairCache {
470 | setInternalGhostPairCallback(ghostPairCallback: btOverlappingPairCallback): void
471 | getNumOverlappingPairs(): number
472 | }
473 | class btAxisSweep3 {
474 | constructor(
475 | worldAabbMin: btVector3,
476 | worldAabbMax: btVector3,
477 | maxHandles?: number,
478 | pairCache?: btOverlappingPairCache,
479 | disableRaycastAccelerator?: boolean
480 | )
481 | }
482 | class btBroadphaseInterface {
483 | getOverlappingPairCache(): btOverlappingPairCache
484 | }
485 | class btCollisionConfiguration {}
486 | class btDbvtBroadphase extends btBroadphaseInterface {
487 | constructor()
488 | }
489 | class btBroadphaseProxy {
490 | get_m_collisionFilterGroup(): number
491 | set_m_collisionFilterGroup(m_collisionFilterGroup: number): void
492 | get_m_collisionFilterMask(): number
493 | set_m_collisionFilterMask(m_collisionFilterMask: number): void
494 | }
495 | class btRigidBodyConstructionInfo {
496 | constructor(mass: number, motionState: btMotionState, collisionShape: btCollisionShape, localInertia?: btVector3)
497 | get_m_linearDamping(): number
498 | set_m_linearDamping(m_linearDamping: number): void
499 | get_m_angularDamping(): number
500 | set_m_angularDamping(m_angularDamping: number): void
501 | get_m_friction(): number
502 | set_m_friction(m_friction: number): void
503 | get_m_rollingFriction(): number
504 | set_m_rollingFriction(m_rollingFriction: number): void
505 | get_m_restitution(): number
506 | set_m_restitution(m_restitution: number): void
507 | get_m_linearSleepingThreshold(): number
508 | set_m_linearSleepingThreshold(m_linearSleepingThreshold: number): void
509 | get_m_angularSleepingThreshold(): number
510 | set_m_angularSleepingThreshold(m_angularSleepingThreshold: number): void
511 | get_m_additionalDamping(): boolean
512 | set_m_additionalDamping(m_additionalDamping: boolean): void
513 | get_m_additionalDampingFactor(): number
514 | set_m_additionalDampingFactor(m_additionalDampingFactor: number): void
515 | get_m_additionalLinearDampingThresholdSqr(): number
516 | set_m_additionalLinearDampingThresholdSqr(m_additionalLinearDampingThresholdSqr: number): void
517 | get_m_additionalAngularDampingThresholdSqr(): number
518 | set_m_additionalAngularDampingThresholdSqr(m_additionalAngularDampingThresholdSqr: number): void
519 | get_m_additionalAngularDampingFactor(): number
520 | set_m_additionalAngularDampingFactor(m_additionalAngularDampingFactor: number): void
521 | }
522 | class btRigidBody extends btCollisionObject {
523 | constructor(constructionInfo: btRigidBodyConstructionInfo)
524 | getCenterOfMassTransform(): btTransform
525 | setCenterOfMassTransform(xform: btTransform): void
526 | setSleepingThresholds(linear: number, angular: number): void
527 | getLinearDamping(): number
528 | getAngularDamping(): number
529 | setDamping(lin_damping: number, ang_damping: number): void
530 | setMassProps(mass: number, inertia: btVector3): void
531 | getLinearFactor(): btVector3
532 | setLinearFactor(linearFactor: btVector3): void
533 | applyTorque(torque: btVector3): void
534 | applyLocalTorque(torque: btVector3): void
535 | applyForce(force: btVector3, rel_pos: btVector3): void
536 | applyCentralForce(force: btVector3): void
537 | applyCentralLocalForce(force: btVector3): void
538 | applyTorqueImpulse(torque: btVector3): void
539 | applyImpulse(impulse: btVector3, rel_pos: btVector3): void
540 | applyCentralImpulse(impulse: btVector3): void
541 | updateInertiaTensor(): void
542 | getLinearVelocity(): btVector3
543 | getAngularVelocity(): btVector3
544 | setLinearVelocity(lin_vel: btVector3): void
545 | setAngularVelocity(ang_vel: btVector3): void
546 | getMotionState(): btMotionState
547 | setMotionState(motionState: btMotionState): void
548 | getAngularFactor(): btVector3
549 | setAngularFactor(angularFactor: btVector3): void
550 | upcast(colObj: btCollisionObject): btRigidBody
551 | getAabb(aabbMin: btVector3, aabbMax: btVector3): void
552 | applyGravity(): void
553 | getGravity(): btVector3
554 | setGravity(acceleration: btVector3): void
555 | getBroadphaseProxy(): btBroadphaseProxy
556 | }
557 | class btConstraintSetting {
558 | constructor()
559 | get_m_tau(): number
560 | set_m_tau(m_tau: number): void
561 | get_m_damping(): number
562 | set_m_damping(m_damping: number): void
563 | get_m_impulseClamp(): number
564 | set_m_impulseClamp(m_impulseClamp: number): void
565 | }
566 | class btTypedConstraint {
567 | enableFeedback(needsFeedback: boolean): void
568 | getBreakingImpulseThreshold(): number
569 | setBreakingImpulseThreshold(threshold: number): void
570 | getParam(num: number, axis: number): number
571 | setParam(num: number, value: number, axis: number): void
572 | }
573 | enum btConstraintParams {
574 | BT_CONSTRAINT_ERP,
575 | BT_CONSTRAINT_STOP_ERP,
576 | BT_CONSTRAINT_CFM,
577 | BT_CONSTRAINT_STOP_CFM
578 | }
579 | class btPoint2PointConstraint extends btTypedConstraint {
580 | constructor(rbA: btRigidBody, rbB: btRigidBody, pivotInA: btVector3, pivotInB: btVector3)
581 | constructor(rbA: btRigidBody, pivotInA: btVector3)
582 | setPivotA(pivotA: btVector3): void
583 | setPivotB(pivotB: btVector3): void
584 | getPivotInA(): btVector3
585 | getPivotInB(): btVector3
586 | get_m_setting(): btConstraintSetting
587 | set_m_setting(m_setting: btConstraintSetting): void
588 | }
589 | class btGeneric6DofConstraint extends btTypedConstraint {
590 | constructor(
591 | rbA: btRigidBody,
592 | rbB: btRigidBody,
593 | frameInA: btTransform,
594 | frameInB: btTransform,
595 | useLinearFrameReferenceFrameA: boolean
596 | )
597 | constructor(rbB: btRigidBody, frameInB: btTransform, useLinearFrameReferenceFrameB: boolean)
598 | setLinearLowerLimit(linearLower: btVector3): void
599 | setLinearUpperLimit(linearUpper: btVector3): void
600 | setAngularLowerLimit(angularLower: btVector3): void
601 | setAngularUpperLimit(angularUpper: btVector3): void
602 | getFrameOffsetA(): btTransform
603 | }
604 | class btGeneric6DofSpringConstraint extends btGeneric6DofConstraint {
605 | constructor(
606 | rbA: btRigidBody,
607 | rbB: btRigidBody,
608 | frameInA: btTransform,
609 | frameInB: btTransform,
610 | useLinearFrameReferenceFrameA: boolean
611 | )
612 | constructor(rbB: btRigidBody, frameInB: btTransform, useLinearFrameReferenceFrameB: boolean)
613 | enableSpring(index: number, onOff: boolean): void
614 | setStiffness(index: number, stiffness: number): void
615 | setDamping(index: number, damping: number): void
616 | setEquilibriumPoint(index: number, val: number): void
617 | setEquilibriumPoint(index: number): void
618 | setEquilibriumPoint(): void
619 | }
620 | class btSequentialImpulseConstraintSolver {
621 | constructor()
622 | }
623 | class btConeTwistConstraint extends btTypedConstraint {
624 | constructor(rbA: btRigidBody, rbB: btRigidBody, rbAFrame: btTransform, rbBFrame: btTransform)
625 | constructor(rbA: btRigidBody, rbAFrame: btTransform)
626 | setLimit(limitIndex: number, limitValue: number): void
627 | setAngularOnly(angularOnly: boolean): void
628 | setDamping(damping: number): void
629 | enableMotor(b: boolean): void
630 | setMaxMotorImpulse(maxMotorImpulse: number): void
631 | setMaxMotorImpulseNormalized(maxMotorImpulse: number): void
632 | setMotorTarget(q: btQuaternion): void
633 | setMotorTargetInConstraintSpace(q: btQuaternion): void
634 | }
635 | class btHingeConstraint extends btTypedConstraint {
636 | constructor(
637 | rbA: btRigidBody,
638 | rbB: btRigidBody,
639 | pivotInA: btVector3,
640 | pivotInB: btVector3,
641 | axisInA: btVector3,
642 | axisInB: btVector3,
643 | useReferenceFrameA?: boolean
644 | )
645 | constructor(
646 | rbA: btRigidBody,
647 | rbB: btRigidBody,
648 | rbAFrame: btTransform,
649 | rbBFrame: btTransform,
650 | useReferenceFrameA?: boolean
651 | )
652 | constructor(rbA: btRigidBody, rbAFrame: btTransform, useReferenceFrameA?: boolean)
653 | setLimit(low: number, high: number, softness: number, biasFactor: number, relaxationFactor?: number): void
654 | enableAngularMotor(enableMotor: boolean, targetVelocity: number, maxMotorImpulse: number): void
655 | setAngularOnly(angularOnly: boolean): void
656 | enableMotor(enableMotor: boolean): void
657 | setMaxMotorImpulse(maxMotorImpulse: number): void
658 | setMotorTarget(targetAngle: number, dt: number): void
659 | }
660 | class btSliderConstraint extends btTypedConstraint {
661 | constructor(
662 | rbA: btRigidBody,
663 | rbB: btRigidBody,
664 | frameInA: btTransform,
665 | frameInB: btTransform,
666 | useLinearReferenceFrameA: boolean
667 | )
668 | constructor(rbB: btRigidBody, frameInB: btTransform, useLinearReferenceFrameA: boolean)
669 | setLowerLinLimit(lowerLimit: number): void
670 | setUpperLinLimit(upperLimit: number): void
671 | setLowerAngLimit(lowerAngLimit: number): void
672 | setUpperAngLimit(upperAngLimit: number): void
673 | }
674 | class btFixedConstraint extends btTypedConstraint {
675 | constructor(rbA: btRigidBody, rbB: btRigidBody, frameInA: btTransform, frameInB: btTransform)
676 | }
677 | class btConstraintSolver {}
678 | class btDispatcherInfo {
679 | get_m_timeStep(): number
680 | set_m_timeStep(m_timeStep: number): void
681 | get_m_stepCount(): number
682 | set_m_stepCount(m_stepCount: number): void
683 | get_m_dispatchFunc(): number
684 | set_m_dispatchFunc(m_dispatchFunc: number): void
685 | get_m_timeOfImpact(): number
686 | set_m_timeOfImpact(m_timeOfImpact: number): void
687 | get_m_useContinuous(): boolean
688 | set_m_useContinuous(m_useContinuous: boolean): void
689 | get_m_enableSatConvex(): boolean
690 | set_m_enableSatConvex(m_enableSatConvex: boolean): void
691 | get_m_enableSPU(): boolean
692 | set_m_enableSPU(m_enableSPU: boolean): void
693 | get_m_useEpa(): boolean
694 | set_m_useEpa(m_useEpa: boolean): void
695 | get_m_allowedCcdPenetration(): number
696 | set_m_allowedCcdPenetration(m_allowedCcdPenetration: number): void
697 | get_m_useConvexConservativeDistanceUtil(): boolean
698 | set_m_useConvexConservativeDistanceUtil(m_useConvexConservativeDistanceUtil: boolean): void
699 | get_m_convexConservativeDistanceThreshold(): number
700 | set_m_convexConservativeDistanceThreshold(m_convexConservativeDistanceThreshold: number): void
701 | }
702 | class btCollisionWorld {
703 | getDispatcher(): btDispatcher
704 | rayTest(rayFromWorld: btVector3, rayToWorld: btVector3, resultCallback: RayResultCallback): void
705 | getPairCache(): btOverlappingPairCache
706 | getDispatchInfo(): btDispatcherInfo
707 | addCollisionObject(
708 | collisionObject: btCollisionObject,
709 | collisionFilterGroup?: number,
710 | collisionFilterMask?: number
711 | ): void
712 | removeCollisionObject(collisionObject: btCollisionObject): void
713 | getBroadphase(): btBroadphaseInterface
714 | convexSweepTest(
715 | castShape: btConvexShape,
716 | from: btTransform,
717 | to: btTransform,
718 | resultCallback: ConvexResultCallback,
719 | allowedCcdPenetration: number
720 | ): void
721 | contactPairTest(colObjA: btCollisionObject, colObjB: btCollisionObject, resultCallback: ContactResultCallback): void
722 | contactTest(colObj: btCollisionObject, resultCallback: ContactResultCallback): void
723 | updateSingleAabb(colObj: btCollisionObject): void
724 | setDebugDrawer(debugDrawer: btIDebugDraw): void
725 | getDebugDrawer(): btIDebugDraw
726 | debugDrawWorld(): void
727 | debugDrawObject(worldTransform: btTransform, shape: btCollisionShape, color: btVector3): void
728 | }
729 | class btContactSolverInfo {
730 | get_m_splitImpulse(): boolean
731 | set_m_splitImpulse(m_splitImpulse: boolean): void
732 | get_m_splitImpulsePenetrationThreshold(): number
733 | set_m_splitImpulsePenetrationThreshold(m_splitImpulsePenetrationThreshold: number): void
734 | get_m_numIterations(): number
735 | set_m_numIterations(m_numIterations: number): void
736 | }
737 | class btDynamicsWorld extends btCollisionWorld {
738 | addAction(action: btActionInterface): void
739 | removeAction(action: btActionInterface): void
740 | getSolverInfo(): btContactSolverInfo
741 | }
742 | class btDiscreteDynamicsWorld extends btDynamicsWorld {
743 | constructor(
744 | dispatcher: btDispatcher,
745 | pairCache: btBroadphaseInterface,
746 | constraintSolver: btConstraintSolver,
747 | collisionConfiguration: btCollisionConfiguration
748 | )
749 | setGravity(gravity: btVector3): void
750 | getGravity(): btVector3
751 | addRigidBody(body: btRigidBody): void
752 | addRigidBody(body: btRigidBody, group: number, mask: number): void
753 | removeRigidBody(body: btRigidBody): void
754 | addConstraint(constraint: btTypedConstraint, disableCollisionsBetweenLinkedBodies?: boolean): void
755 | removeConstraint(constraint: btTypedConstraint): void
756 | stepSimulation(timeStep: number, maxSubSteps?: number, fixedTimeStep?: number): number
757 | setContactAddedCallback(funcpointer: number): void
758 | setContactProcessedCallback(funcpointer: number): void
759 | setContactDestroyedCallback(funcpointer: number): void
760 | }
761 | class btVehicleTuning {
762 | constructor()
763 | get_m_suspensionStiffness(): number
764 | set_m_suspensionStiffness(m_suspensionStiffness: number): void
765 | get_m_suspensionCompression(): number
766 | set_m_suspensionCompression(m_suspensionCompression: number): void
767 | get_m_suspensionDamping(): number
768 | set_m_suspensionDamping(m_suspensionDamping: number): void
769 | get_m_maxSuspensionTravelCm(): number
770 | set_m_maxSuspensionTravelCm(m_maxSuspensionTravelCm: number): void
771 | get_m_frictionSlip(): number
772 | set_m_frictionSlip(m_frictionSlip: number): void
773 | get_m_maxSuspensionForce(): number
774 | set_m_maxSuspensionForce(m_maxSuspensionForce: number): void
775 | }
776 | class btVehicleRaycasterResult {
777 | get_m_hitPointInWorld(): btVector3
778 | set_m_hitPointInWorld(m_hitPointInWorld: btVector3): void
779 | get_m_hitNormalInWorld(): btVector3
780 | set_m_hitNormalInWorld(m_hitNormalInWorld: btVector3): void
781 | get_m_distFraction(): number
782 | set_m_distFraction(m_distFraction: number): void
783 | }
784 | class btVehicleRaycaster {
785 | castRay(from: btVector3, to: btVector3, result: btVehicleRaycasterResult): void
786 | }
787 | class btDefaultVehicleRaycaster extends btVehicleRaycaster {
788 | constructor(world: btDynamicsWorld)
789 | }
790 | class RaycastInfo {
791 | get_m_contactNormalWS(): btVector3
792 | set_m_contactNormalWS(m_contactNormalWS: btVector3): void
793 | get_m_contactPointWS(): btVector3
794 | set_m_contactPointWS(m_contactPointWS: btVector3): void
795 | get_m_suspensionLength(): number
796 | set_m_suspensionLength(m_suspensionLength: number): void
797 | get_m_hardPointWS(): btVector3
798 | set_m_hardPointWS(m_hardPointWS: btVector3): void
799 | get_m_wheelDirectionWS(): btVector3
800 | set_m_wheelDirectionWS(m_wheelDirectionWS: btVector3): void
801 | get_m_wheelAxleWS(): btVector3
802 | set_m_wheelAxleWS(m_wheelAxleWS: btVector3): void
803 | get_m_isInContact(): boolean
804 | set_m_isInContact(m_isInContact: boolean): void
805 | get_m_groundObject(): any
806 | set_m_groundObject(m_groundObject: any): void
807 | }
808 | class btWheelInfoConstructionInfo {
809 | get_m_chassisConnectionCS(): btVector3
810 | set_m_chassisConnectionCS(m_chassisConnectionCS: btVector3): void
811 | get_m_wheelDirectionCS(): btVector3
812 | set_m_wheelDirectionCS(m_wheelDirectionCS: btVector3): void
813 | get_m_wheelAxleCS(): btVector3
814 | set_m_wheelAxleCS(m_wheelAxleCS: btVector3): void
815 | get_m_suspensionRestLength(): number
816 | set_m_suspensionRestLength(m_suspensionRestLength: number): void
817 | get_m_maxSuspensionTravelCm(): number
818 | set_m_maxSuspensionTravelCm(m_maxSuspensionTravelCm: number): void
819 | get_m_wheelRadius(): number
820 | set_m_wheelRadius(m_wheelRadius: number): void
821 | get_m_suspensionStiffness(): number
822 | set_m_suspensionStiffness(m_suspensionStiffness: number): void
823 | get_m_wheelsDampingCompression(): number
824 | set_m_wheelsDampingCompression(m_wheelsDampingCompression: number): void
825 | get_m_wheelsDampingRelaxation(): number
826 | set_m_wheelsDampingRelaxation(m_wheelsDampingRelaxation: number): void
827 | get_m_frictionSlip(): number
828 | set_m_frictionSlip(m_frictionSlip: number): void
829 | get_m_maxSuspensionForce(): number
830 | set_m_maxSuspensionForce(m_maxSuspensionForce: number): void
831 | get_m_bIsFrontWheel(): boolean
832 | set_m_bIsFrontWheel(m_bIsFrontWheel: boolean): void
833 | }
834 | class btWheelInfo {
835 | get_m_suspensionStiffness(): number
836 | set_m_suspensionStiffness(m_suspensionStiffness: number): void
837 | get_m_frictionSlip(): number
838 | set_m_frictionSlip(m_frictionSlip: number): void
839 | get_m_engineForce(): number
840 | set_m_engineForce(m_engineForce: number): void
841 | get_m_rollInfluence(): number
842 | set_m_rollInfluence(m_rollInfluence: number): void
843 | get_m_suspensionRestLength1(): number
844 | set_m_suspensionRestLength1(m_suspensionRestLength1: number): void
845 | get_m_wheelsRadius(): number
846 | set_m_wheelsRadius(m_wheelsRadius: number): void
847 | get_m_wheelsDampingCompression(): number
848 | set_m_wheelsDampingCompression(m_wheelsDampingCompression: number): void
849 | get_m_wheelsDampingRelaxation(): number
850 | set_m_wheelsDampingRelaxation(m_wheelsDampingRelaxation: number): void
851 | get_m_steering(): number
852 | set_m_steering(m_steering: number): void
853 | get_m_maxSuspensionForce(): number
854 | set_m_maxSuspensionForce(m_maxSuspensionForce: number): void
855 | get_m_maxSuspensionTravelCm(): number
856 | set_m_maxSuspensionTravelCm(m_maxSuspensionTravelCm: number): void
857 | get_m_wheelsSuspensionForce(): number
858 | set_m_wheelsSuspensionForce(m_wheelsSuspensionForce: number): void
859 | get_m_bIsFrontWheel(): boolean
860 | set_m_bIsFrontWheel(m_bIsFrontWheel: boolean): void
861 | get_m_raycastInfo(): RaycastInfo
862 | set_m_raycastInfo(m_raycastInfo: RaycastInfo): void
863 | get_m_chassisConnectionPointCS(): btVector3
864 | set_m_chassisConnectionPointCS(m_chassisConnectionPointCS: btVector3): void
865 | constructor(ci: btWheelInfoConstructionInfo)
866 | getSuspensionRestLength(): number
867 | updateWheel(chassis: btRigidBody, raycastInfo: RaycastInfo): void
868 | get_m_worldTransform(): btTransform
869 | set_m_worldTransform(m_worldTransform: btTransform): void
870 | get_m_wheelDirectionCS(): btVector3
871 | set_m_wheelDirectionCS(m_wheelDirectionCS: btVector3): void
872 | get_m_wheelAxleCS(): btVector3
873 | set_m_wheelAxleCS(m_wheelAxleCS: btVector3): void
874 | get_m_rotation(): number
875 | set_m_rotation(m_rotation: number): void
876 | get_m_deltaRotation(): number
877 | set_m_deltaRotation(m_deltaRotation: number): void
878 | get_m_brake(): number
879 | set_m_brake(m_brake: number): void
880 | get_m_clippedInvContactDotSuspension(): number
881 | set_m_clippedInvContactDotSuspension(m_clippedInvContactDotSuspension: number): void
882 | get_m_suspensionRelativeVelocity(): number
883 | set_m_suspensionRelativeVelocity(m_suspensionRelativeVelocity: number): void
884 | get_m_skidInfo(): number
885 | set_m_skidInfo(m_skidInfo: number): void
886 | }
887 | class btActionInterface {
888 | updateAction(collisionWorld: btCollisionWorld, deltaTimeStep: number): void
889 | }
890 | class btKinematicCharacterController extends btActionInterface {
891 | constructor(ghostObject: btPairCachingGhostObject, convexShape: btConvexShape, stepHeight: number, upAxis?: number)
892 | setUpAxis(axis: number): void
893 | setWalkDirection(walkDirection: btVector3): void
894 | setVelocityForTimeInterval(velocity: btVector3, timeInterval: number): void
895 | warp(origin: btVector3): void
896 | preStep(collisionWorld: btCollisionWorld): void
897 | playerStep(collisionWorld: btCollisionWorld, dt: number): void
898 | setFallSpeed(fallSpeed: number): void
899 | setJumpSpeed(jumpSpeed: number): void
900 | setMaxJumpHeight(maxJumpHeight: number): void
901 | canJump(): boolean
902 | jump(): void
903 | setGravity(gravity: number): void
904 | getGravity(): number
905 | setMaxSlope(slopeRadians: number): void
906 | getMaxSlope(): number
907 | getGhostObject(): btPairCachingGhostObject
908 | setUseGhostSweepTest(useGhostObjectSweepTest: boolean): void
909 | onGround(): boolean
910 | setUpInterpolate(value: boolean): void
911 | }
912 | class btRaycastVehicle extends btActionInterface {
913 | constructor(tuning: btVehicleTuning, chassis: btRigidBody, raycaster: btVehicleRaycaster)
914 | applyEngineForce(force: number, wheel: number): void
915 | setSteeringValue(steering: number, wheel: number): void
916 | getWheelTransformWS(wheelIndex: number): btTransform
917 | updateWheelTransform(wheelIndex: number, interpolatedTransform: boolean): void
918 | addWheel(
919 | connectionPointCS0: btVector3,
920 | wheelDirectionCS0: btVector3,
921 | wheelAxleCS: btVector3,
922 | suspensionRestLength: number,
923 | wheelRadius: number,
924 | tuning: btVehicleTuning,
925 | isFrontWheel: boolean
926 | ): btWheelInfo
927 | getNumWheels(): number
928 | getRigidBody(): btRigidBody
929 | getWheelInfo(index: number): btWheelInfo
930 | setBrake(brake: number, wheelIndex: number): void
931 | setCoordinateSystem(rightIndex: number, upIndex: number, forwardIndex: number): void
932 | getCurrentSpeedKmHour(): number
933 | getChassisWorldTransform(): btTransform
934 | rayCast(wheel: btWheelInfo): number
935 | updateVehicle(step: number): void
936 | resetSuspension(): void
937 | getSteeringValue(wheel: number): number
938 | updateWheelTransformsWS(wheel: btWheelInfo, interpolatedTransform?: boolean): void
939 | setPitchControl(pitch: number): void
940 | updateSuspension(deltaTime: number): void
941 | updateFriction(timeStep: number): void
942 | getRightAxis(): number
943 | getUpAxis(): number
944 | getForwardAxis(): number
945 | getForwardVector(): btVector3
946 | getUserConstraintType(): number
947 | setUserConstraintType(userConstraintType: number): void
948 | setUserConstraintId(uid: number): void
949 | getUserConstraintId(): number
950 | }
951 | class btGhostObject extends btCollisionObject {
952 | constructor()
953 | getNumOverlappingObjects(): number
954 | getOverlappingObject(index: number): btCollisionObject
955 | }
956 | class btPairCachingGhostObject extends btGhostObject {
957 | constructor()
958 | }
959 | class btGhostPairCallback {
960 | constructor()
961 | }
962 | class btSoftBodyWorldInfo {
963 | constructor()
964 | get_air_density(): number
965 | set_air_density(air_density: number): void
966 | get_water_density(): number
967 | set_water_density(water_density: number): void
968 | get_water_offset(): number
969 | set_water_offset(water_offset: number): void
970 | get_m_maxDisplacement(): number
971 | set_m_maxDisplacement(m_maxDisplacement: number): void
972 | get_water_normal(): btVector3
973 | set_water_normal(water_normal: btVector3): void
974 | get_m_broadphase(): btBroadphaseInterface
975 | set_m_broadphase(m_broadphase: btBroadphaseInterface): void
976 | get_m_dispatcher(): btDispatcher
977 | set_m_dispatcher(m_dispatcher: btDispatcher): void
978 | get_m_gravity(): btVector3
979 | set_m_gravity(m_gravity: btVector3): void
980 | }
981 | class Node {
982 | get_m_x(): btVector3
983 | set_m_x(m_x: btVector3): void
984 | get_m_q(): btVector3
985 | set_m_q(m_q: btVector3): void
986 | get_m_v(): btVector3
987 | set_m_v(m_v: btVector3): void
988 | get_m_f(): btVector3
989 | set_m_f(m_f: btVector3): void
990 | get_m_n(): btVector3
991 | set_m_n(m_n: btVector3): void
992 | get_m_im(): number
993 | set_m_im(m_im: number): void
994 | get_m_area(): number
995 | set_m_area(m_area: number): void
996 | }
997 | class tNodeArray {
998 | size(): number
999 | at(n: number): Node
1000 | }
1001 | class Material {
1002 | get_m_kLST(): number
1003 | set_m_kLST(m_kLST: number): void
1004 | get_m_kAST(): number
1005 | set_m_kAST(m_kAST: number): void
1006 | get_m_kVST(): number
1007 | set_m_kVST(m_kVST: number): void
1008 | get_m_flags(): number
1009 | set_m_flags(m_flags: number): void
1010 | }
1011 | class tMaterialArray {
1012 | size(): number
1013 | at(n: number): Material
1014 | }
1015 | class Anchor {
1016 | get_m_node(): Node
1017 | set_m_node(m_node: Node): void
1018 | get_m_local(): btVector3
1019 | set_m_local(m_local: btVector3): void
1020 | get_m_body(): btRigidBody
1021 | set_m_body(m_body: btRigidBody): void
1022 | get_m_influence(): number
1023 | set_m_influence(m_influence: number): void
1024 | get_m_c0(): btMatrix3x3
1025 | set_m_c0(m_c0: btMatrix3x3): void
1026 | get_m_c1(): btVector3
1027 | set_m_c1(m_c1: btVector3): void
1028 | get_m_c2(): number
1029 | set_m_c2(m_c2: number): void
1030 | }
1031 | class tAnchorArray {
1032 | size(): number
1033 | at(n: number): Anchor
1034 | clear(): void
1035 | push_back(val: Anchor): void
1036 | pop_back(): void
1037 | }
1038 | class Config {
1039 | get_kVCF(): number
1040 | set_kVCF(kVCF: number): void
1041 | get_kDP(): number
1042 | set_kDP(kDP: number): void
1043 | get_kDG(): number
1044 | set_kDG(kDG: number): void
1045 | get_kLF(): number
1046 | set_kLF(kLF: number): void
1047 | get_kPR(): number
1048 | set_kPR(kPR: number): void
1049 | get_kVC(): number
1050 | set_kVC(kVC: number): void
1051 | get_kDF(): number
1052 | set_kDF(kDF: number): void
1053 | get_kMT(): number
1054 | set_kMT(kMT: number): void
1055 | get_kCHR(): number
1056 | set_kCHR(kCHR: number): void
1057 | get_kKHR(): number
1058 | set_kKHR(kKHR: number): void
1059 | get_kSHR(): number
1060 | set_kSHR(kSHR: number): void
1061 | get_kAHR(): number
1062 | set_kAHR(kAHR: number): void
1063 | get_kSRHR_CL(): number
1064 | set_kSRHR_CL(kSRHR_CL: number): void
1065 | get_kSKHR_CL(): number
1066 | set_kSKHR_CL(kSKHR_CL: number): void
1067 | get_kSSHR_CL(): number
1068 | set_kSSHR_CL(kSSHR_CL: number): void
1069 | get_kSR_SPLT_CL(): number
1070 | set_kSR_SPLT_CL(kSR_SPLT_CL: number): void
1071 | get_kSK_SPLT_CL(): number
1072 | set_kSK_SPLT_CL(kSK_SPLT_CL: number): void
1073 | get_kSS_SPLT_CL(): number
1074 | set_kSS_SPLT_CL(kSS_SPLT_CL: number): void
1075 | get_maxvolume(): number
1076 | set_maxvolume(maxvolume: number): void
1077 | get_timescale(): number
1078 | set_timescale(timescale: number): void
1079 | get_viterations(): number
1080 | set_viterations(viterations: number): void
1081 | get_piterations(): number
1082 | set_piterations(piterations: number): void
1083 | get_diterations(): number
1084 | set_diterations(diterations: number): void
1085 | get_citerations(): number
1086 | set_citerations(citerations: number): void
1087 | get_collisions(): number
1088 | set_collisions(collisions: number): void
1089 | }
1090 | class btSoftBody extends btCollisionObject {
1091 | constructor(worldInfo: btSoftBodyWorldInfo, node_count: number, x: btVector3, m: number[])
1092 | get_m_cfg(): Config
1093 | set_m_cfg(m_cfg: Config): void
1094 | get_m_nodes(): tNodeArray
1095 | set_m_nodes(m_nodes: tNodeArray): void
1096 | get_m_materials(): tMaterialArray
1097 | set_m_materials(m_materials: tMaterialArray): void
1098 | get_m_anchors(): tAnchorArray
1099 | set_m_anchors(m_anchors: tAnchorArray): void
1100 | checkLink(node0: number, node1: number): boolean
1101 | checkFace(node0: number, node1: number, node2: number): boolean
1102 | appendMaterial(): Material
1103 | appendNode(x: btVector3, m: number): void
1104 | appendLink(node0: number, node1: number, mat: Material, bcheckexist: boolean): void
1105 | appendFace(node0: number, node1: number, node2: number, mat: Material): void
1106 | appendTetra(node0: number, node1: number, node2: number, node3: number, mat: Material): void
1107 | appendAnchor(node: number, body: btRigidBody, disableCollisionBetweenLinkedBodies: boolean, influence: number): void
1108 | addForce(force: btVector3): void
1109 | addForce(force: btVector3, node: number): void
1110 | addAeroForceToNode(windVelocity: btVector3, nodeIndex: number): void
1111 | getTotalMass(): number
1112 | setTotalMass(mass: number, fromfaces: boolean): void
1113 | setMass(node: number, mass: number): void
1114 | transform(trs: btTransform): void
1115 | translate(trs: btVector3): void
1116 | rotate(rot: btQuaternion): void
1117 | scale(scl: btVector3): void
1118 | generateClusters(k: number, maxiterations?: number): number
1119 | generateBendingConstraints(distance: number, mat: Material): number
1120 | upcast(colObj: btCollisionObject): btSoftBody
1121 | }
1122 | class btSoftBodyRigidBodyCollisionConfiguration extends btDefaultCollisionConfiguration {
1123 | constructor(info?: btDefaultCollisionConstructionInfo)
1124 | }
1125 | class btSoftBodySolver {}
1126 | class btDefaultSoftBodySolver extends btSoftBodySolver {
1127 | constructor()
1128 | }
1129 | class btSoftBodyArray {
1130 | size(): number
1131 | at(n: number): btSoftBody
1132 | }
1133 | class btSoftRigidDynamicsWorld extends btDiscreteDynamicsWorld {
1134 | constructor(
1135 | dispatcher: btDispatcher,
1136 | pairCache: btBroadphaseInterface,
1137 | constraintSolver: btConstraintSolver,
1138 | collisionConfiguration: btCollisionConfiguration,
1139 | softBodySolver: btSoftBodySolver
1140 | )
1141 | addSoftBody(body: btSoftBody, collisionFilterGroup: number, collisionFilterMask: number): void
1142 | removeSoftBody(body: btSoftBody): void
1143 | removeCollisionObject(collisionObject: btCollisionObject): void
1144 | getWorldInfo(): btSoftBodyWorldInfo
1145 | getSoftBodyArray(): btSoftBodyArray
1146 | }
1147 | class btSoftBodyHelpers {
1148 | constructor()
1149 | CreateRope(worldInfo: btSoftBodyWorldInfo, from: btVector3, to: btVector3, res: number, fixeds: number): btSoftBody
1150 | CreatePatch(
1151 | worldInfo: btSoftBodyWorldInfo,
1152 | corner00: btVector3,
1153 | corner10: btVector3,
1154 | corner01: btVector3,
1155 | corner11: btVector3,
1156 | resx: number,
1157 | resy: number,
1158 | fixeds: number,
1159 | gendiags: boolean
1160 | ): btSoftBody
1161 | CreatePatchUV(
1162 | worldInfo: btSoftBodyWorldInfo,
1163 | corner00: btVector3,
1164 | corner10: btVector3,
1165 | corner01: btVector3,
1166 | corner11: btVector3,
1167 | resx: number,
1168 | resy: number,
1169 | fixeds: number,
1170 | gendiags: boolean,
1171 | tex_coords: number[]
1172 | ): btSoftBody
1173 | CreateEllipsoid(worldInfo: btSoftBodyWorldInfo, center: btVector3, radius: btVector3, res: number): btSoftBody
1174 | CreateFromTriMesh(
1175 | worldInfo: btSoftBodyWorldInfo,
1176 | vertices: number[],
1177 | triangles: number[],
1178 | ntriangles: number,
1179 | randomizeConstraints: boolean
1180 | ): btSoftBody
1181 | CreateFromConvexHull(
1182 | worldInfo: btSoftBodyWorldInfo,
1183 | vertices: btVector3,
1184 | nvertices: number,
1185 | randomizeConstraints: boolean
1186 | ): btSoftBody
1187 | }
1188 | }
1189 |
--------------------------------------------------------------------------------
/typings/custom.d.ts:
--------------------------------------------------------------------------------
1 | // typings/custom.d.ts
2 | declare module 'worker-loader!*' {
3 | class WebpackWorker extends Worker {
4 | constructor()
5 | }
6 |
7 | export default WebpackWorker
8 | }
9 |
--------------------------------------------------------------------------------
/webpack.bundle.js:
--------------------------------------------------------------------------------
1 | const WorkerPlugin = require('worker-plugin')
2 | const HtmlWebpackPlugin = require('html-webpack-plugin')
3 | const CopyPlugin = require('copy-webpack-plugin')
4 | const path = require('path')
5 |
6 | module.exports = {
7 | mode: 'development',
8 | devtool: 'inline-source-map',
9 | entry: './src/index.ts',
10 | output: {
11 | filename: 'ammoPhysics.js',
12 | path: path.resolve(__dirname, 'dist'),
13 | library: 'ENABLE3D',
14 | libraryTarget: 'umd',
15 | },
16 | resolve: {
17 | // Add `.ts` and `.tsx` as a resolvable extension.
18 | extensions: ['.ts', '.tsx', '.js'],
19 | },
20 | module: {
21 | rules: [
22 | // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
23 | {
24 | test: /\.tsx?$/,
25 | loader: 'ts-loader',
26 | },
27 | ],
28 | },
29 | plugins: [
30 | new CopyPlugin({
31 | patterns: [{ from: 'ammo', to: '' }],
32 | }),
33 | // new HtmlWebpackPlugin({ template: 'src/index.html' }),
34 | // new WorkerPlugin({ globalObject: 'self' }),
35 | ],
36 | }
37 |
--------------------------------------------------------------------------------
/webpack.worker.js:
--------------------------------------------------------------------------------
1 | const WorkerPlugin = require('worker-plugin')
2 | const HtmlWebpackPlugin = require('html-webpack-plugin')
3 | const CopyPlugin = require('copy-webpack-plugin')
4 | const path = require('path')
5 |
6 | module.exports = {
7 | mode: 'development',
8 | devtool: 'inline-source-map',
9 | entry: './src/physics.worker.ts',
10 | output: {
11 | filename: 'ammoPhysics.worker.js',
12 | path: path.resolve(__dirname, 'dist'),
13 | },
14 | resolve: {
15 | // Add `.ts` and `.tsx` as a resolvable extension.
16 | extensions: ['.ts', '.tsx', '.js'],
17 | },
18 | module: {
19 | rules: [
20 | // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
21 | {
22 | test: /\.tsx?$/,
23 | loader: 'ts-loader',
24 | },
25 | ],
26 | },
27 | plugins: [
28 | // new CopyPlugin({
29 | // patterns: [{ from: 'src/lib', to: '' }],
30 | // }),
31 | // new HtmlWebpackPlugin({ template: 'src/index.html' }),
32 | // new WorkerPlugin({ globalObject: 'self' }),
33 | ],
34 | }
35 |
--------------------------------------------------------------------------------