├── .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 | --------------------------------------------------------------------------------