bullet-raub
Advanced tools
Comparing version 2.0.1 to 3.0.0
@@ -8,6 +8,6 @@ 'use strict'; | ||
const { bin } = require('addon-tools-raub'); | ||
const { getBin } = require('addon-tools-raub'); | ||
const core = require(`./${bin}/bullet`); | ||
const core = require(`./${getBin()}/bullet`); | ||
module.exports = core; |
'use strict'; | ||
const install = require('addon-tools-raub/install'); | ||
const { install } = require('addon-tools-raub'); | ||
const prefix = 'https://github.com/node-3d/bullet-raub/releases/download'; | ||
const tag = process.env.npm_package_config_install; | ||
const tag = '3.0.0'; | ||
install(`${prefix}/${tag}`); |
'use strict'; | ||
const { inspect, inherits } = require('util'); | ||
const Emitter = require('events'); | ||
const { inspect, inherits } = require('node:util'); | ||
const Emitter = require('node:events'); | ||
@@ -10,23 +10,27 @@ const { Body } = require('../core'); | ||
let nextId = 1; | ||
const genId = () => nextId++; | ||
const nonGcDict = {}; | ||
function JsBody({ scene, ...opts }) { | ||
Body.call(this, scene); | ||
Object.keys(opts).forEach(key => (this[key] = opts[key])); | ||
} | ||
JsBody.prototype = { | ||
class JsBody extends Body { | ||
constructor({ scene, ...opts }) { | ||
super(scene); | ||
Object.keys(opts).forEach((key) => (this[key] = opts[key])); | ||
// Prevent garbage collection until object is intentionally destroyed | ||
this.__nonGcId = genId(); | ||
nonGcDict[this.__nonGcId] = this; | ||
this.on('destroy', () => { | ||
delete nonGcDict[this.__nonGcId]; | ||
}); | ||
} | ||
[inspect.custom]() { return this.toString(); } | ||
[inspect.custom]() { return this.toString(); }, | ||
toString() { | ||
return `Body { type: ${this.type}, pos: [${this.pos}] }`; | ||
}, | ||
}; | ||
} | ||
} | ||
inherits(JsBody, Body); | ||
module.exports = JsBody; |
'use strict'; | ||
const Body = require('./body'); | ||
const Scene = require('./scene'); | ||
const Joint = require('./joint'); | ||
module.exports = { | ||
Scene: require('./scene'), | ||
Body: require('./body'), | ||
Joint: require('./joint'), | ||
Body, Scene, Joint, | ||
}; |
'use strict'; | ||
const { inspect, inherits } = require('util'); | ||
const Emitter = require('events'); | ||
const { inspect, inherits } = require('node:util'); | ||
const Emitter = require('node:events'); | ||
@@ -10,21 +10,27 @@ const { Joint } = require('../core'); | ||
let nextId = 1; | ||
const genId = () => nextId++; | ||
const nonGcDict = {}; | ||
function JsJoint() { | ||
Joint.call(this); | ||
} | ||
JsJoint.prototype = { | ||
class JsJoint extends Joint { | ||
constructor(opts = {}) { | ||
super(); | ||
Object.keys(opts).forEach((key) => (this[key] = opts[key])); | ||
// Prevent garbage collection until object is intentionally destroyed | ||
this.__nonGcId = genId(); | ||
nonGcDict[this.__nonGcId] = this; | ||
this.on('destroy', () => { | ||
delete nonGcDict[this.__nonGcId]; | ||
}); | ||
} | ||
[inspect.custom]() { return this.toString(); } | ||
[inspect.custom]() { return this.toString(); }, | ||
toString() { | ||
return `Joint { broken: ${this.broken} }`; | ||
}, | ||
}; | ||
} | ||
} | ||
inherits(JsJoint, Joint); | ||
module.exports = JsJoint; |
'use strict'; | ||
const { inspect, inherits } = require('util'); | ||
const Emitter = require('events'); | ||
const { inspect, inherits } = require('node:util'); | ||
const Emitter = require('node:events'); | ||
@@ -10,21 +10,27 @@ const { Scene } = require('../core'); | ||
let nextId = 1; | ||
const genId = () => nextId++; | ||
const nonGcDict = {}; | ||
function JsScene() { | ||
Scene.call(this); | ||
} | ||
JsScene.prototype = { | ||
class JsScene extends Scene { | ||
constructor(opts = {}) { | ||
super(); | ||
Object.keys(opts).forEach((key) => (this[key] = opts[key])); | ||
// Prevent garbage collection until object is intentionally destroyed | ||
this.__nonGcId = genId(); | ||
nonGcDict[this.__nonGcId] = this; | ||
this.on('destroy', () => { | ||
delete nonGcDict[this.__nonGcId]; | ||
}); | ||
} | ||
[inspect.custom]() { return this.toString(); }, | ||
[inspect.custom]() { return this.toString(); } | ||
toString() { | ||
return `Scene { gravity: [${this.gravity}] }`; | ||
}, | ||
}; | ||
} | ||
} | ||
inherits(JsScene, Scene); | ||
module.exports = JsScene; |
{ | ||
"author": "Luis Blanco <luisblanco1337@gmail.com>", | ||
"name": "bullet-raub", | ||
"version": "2.0.1", | ||
"version": "3.0.0", | ||
"description": "Bullet-driven physics API", | ||
@@ -29,10 +29,11 @@ "license": "MIT", | ||
"engines": { | ||
"node": ">=12.13.0", | ||
"npm": ">=6.12.0" | ||
"node": ">=18.16.0", | ||
"npm": ">=9.5.1" | ||
}, | ||
"config": { | ||
"install": "v2.0.0" | ||
}, | ||
"scripts": { | ||
"postinstall": "node install" | ||
"postinstall": "node install", | ||
"eslint": "eslint .", | ||
"build": "cd src && node-gyp rebuild -j max --silent && node -e \"require('addon-tools-raub').cpbin('bullet')\" && cd ..", | ||
"build-only": "cd src && node-gyp build -j max --silent && node -e \"require('addon-tools-raub').cpbin('bullet')\" && cd ..", | ||
"test": "node --test" | ||
}, | ||
@@ -44,6 +45,13 @@ "repository": { | ||
"dependencies": { | ||
"addon-tools-raub": "5.0.0", | ||
"deps-bullet-raub": "2.0.0", | ||
"segfault-raub": "1.1.0" | ||
"addon-tools-raub": "^7.4.0", | ||
"deps-bullet-raub": "^3.0.0", | ||
"segfault-raub": "^2.1.2" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^20.8.3", | ||
"eslint": "^8.51.0", | ||
"eslint-plugin-node": "^11.1.0", | ||
"node-addon-api": "^7.0.0", | ||
"typescript": "^5.2.2" | ||
} | ||
} |
261
README.md
@@ -1,20 +0,18 @@ | ||
# Physics engine for Node.js | ||
# Bullet Physics for Node.js | ||
This is a part of [Node3D](https://github.com/node-3d) project. | ||
[![NPM](https://nodei.co/npm/bullet-raub.png?compact=true)](https://www.npmjs.com/package/bullet-raub) | ||
[![NPM](https://badge.fury.io/js/bullet-raub.svg)](https://badge.fury.io/js/bullet-raub) | ||
[![ESLint](https://github.com/node-3d/bullet-raub/actions/workflows/eslint.yml/badge.svg)](https://github.com/node-3d/bullet-raub/actions/workflows/eslint.yml) | ||
[![Test](https://github.com/node-3d/bullet-raub/actions/workflows/test.yml/badge.svg)](https://github.com/node-3d/bullet-raub/actions/workflows/test.yml) | ||
[![Cpplint](https://github.com/node-3d/bullet-raub/actions/workflows/cpplint.yml/badge.svg)](https://github.com/node-3d/bullet-raub/actions/workflows/cpplint.yml) | ||
[![Build Status](https://api.travis-ci.com/node-3d/bullet-raub.svg?branch=master)](https://travis-ci.com/node-3d/bullet-raub) | ||
[![CodeFactor](https://www.codefactor.io/repository/github/node-3d/bullet-raub/badge)](https://www.codefactor.io/repository/github/node-3d/bullet-raub) | ||
```console | ||
npm i -s bullet-raub | ||
``` | ||
> npm i bullet-raub | ||
## Synopsis | ||
**Node.js** addon providing a Bullet-driven physics API. | ||
This library is not a direct mapping of | ||
[Bullet Physics API](https://github.com/bulletphysics/bullet3), | ||
rather it is more of a simplified interpretation for generic purposes. | ||
This library is a simplified interpretation of | ||
[Bullet Physics](https://github.com/bulletphysics/bullet3). | ||
Only rigid bodies and DOF-6 constraint are supported. | ||
@@ -26,239 +24,2 @@ | ||
## Usage | ||
In multiple occasions vector parameters are used. Telling that `pos` (position) | ||
is a `vec3` this doc implies you can use either `[x, y, z]` or `{ x, y, z }` values. | ||
Those are considered equal. The same way you can retrieve values as `pos[0]` or `pos.x`. | ||
There is also `quat` type, which is 4D vector, having additional `w` component. | ||
Any **set** property has an event with the same name. The event is emitted whenever | ||
this property is changed by the setter. In some cases such properties are changed | ||
not by the setters, but by the engine itself. Then there is `'update'` event, containing | ||
a limited set of info on what was updated by the engine. If getters are called within | ||
update-handler, they get the newest values as well. | ||
Each class has a `destroy` method, which can be used to free its native resources. | ||
If called, it causes the `'destroy'` event to be fired. However in case of GC | ||
the resources will be freed in the same way, but with no such event. | ||
--- | ||
### class Scene | ||
Wraps around `btPhysicsWorld`. Scene works as a container | ||
for Bodies. Bodies only interact within the same scene. There can be multiple scenes | ||
running simultaneously. | ||
``` | ||
const { Scene } = require('bullet-raub'); | ||
const scene = new Scene(); | ||
``` | ||
Constructor: | ||
* `Scene()` | ||
Properties: | ||
* `get/set vec3 gravity [0,-10,0]` - free fall acceleration speed for Bodies. | ||
Methods: | ||
* `void update(float ?delta)` - advance the scene, optional parameter `delta` is how much time have | ||
supposedly passed since last update **in seconds**. If not set, a precise internal | ||
timer is used instead. Therefore it is prefered to call `scene.update()` without arguments. | ||
* `Trace hit(vec3 from, vec3 to)` - conducts a ray trace within the scene and returns a new Trace | ||
containing the result of the first hit against body, if any. | ||
* `[Trace] trace( vec3 from, vec3 to )` - conducts a ray trace within the scene and returns a | ||
whole list of hits occuring on its way. | ||
* `void destroy()` - destroys the scene and all the contained bodies, `'destroy'` event is emitted. | ||
Events: | ||
* Basic events, as it is stated above. | ||
--- | ||
### class Body | ||
Wraps around `btRigidBody` (as if this was relevant). Bodies only interact within the same scene. | ||
A body can take different shapes, and even change them on flight. | ||
``` | ||
const { Scene, Body } = require('bullet-raub'); | ||
const scene = new Scene(); | ||
const body = new Body({ scene }); | ||
``` | ||
Constructor: | ||
* `Body({ Scene scene })` | ||
Properties: | ||
* `get/set string type 'box'` - defines body shape. NOTE: set is expensive. One of: | ||
* `'box'` - `btBoxShape` | ||
* `'ball'` - `btSphereShape` | ||
* `'roll'` - `btCylinderShape` | ||
* `'caps'` - `btCapsuleShape` | ||
* `'plane'` - `btStaticPlaneShape` | ||
* WIP: `'map'` - `btHeightfieldTerrainShape` | ||
* WIP: `'mesh'` - `btBvhTriangleMeshShape` | ||
* `get/set vec3 pos [0,0,0]` - body position. NOTE: set is expensive. | ||
* `get/set vec3 rot [0,0,0]` - body rotation, Euler angles - DEGREES. NOTE: get/set is a bit expensive. | ||
* `get/set vec3 vell [0,0,0]` - linear velosity. | ||
* `get/set vec3 vela [0,0,0]` - angular velocity. | ||
* `get/set vec3 size [1,1,1]` - size in three dimensions. NOTE: set is expensive. | ||
* `get/set vec3 factl [1,1,1]` - linear movement axis-multipliers. May be you want a 2D | ||
scene with a locked z-axis, then just set it [1,1,0]. | ||
* `get/set vec3 facta [1,1,1]` - angular movement axis-multipliers. May be you want to | ||
create a controlled dynamic character capsule which does not tilt , then just set it [0,0,0]. | ||
* `get/set {} map null` - WIP | ||
* `get/set {} mesh null` - WIP | ||
* `get/set number mass 0.0` - body mass, if 0 - body is **static**. NOTE: set is expensive. | ||
* `get/set number rest 0.0` - restitution, bounciness. | ||
* `get/set number dampl 0.1` - something like air friction and how much it is applied to | ||
the linear velocity. | ||
* `get/set number dampa 0.1` - something like air friction and how much it is applied to | ||
the angular velocity. | ||
* `get/set number frict 0.5` - surface friction on contact points between two bodies. | ||
* `get/set boolean sleepy true` - if this body tends to "fall asleep" when not moving for | ||
a while. This is a good way to optimize calculation and throughput of the scene. Only | ||
set it to `false` for specific body if its sleepiness causes issues. | ||
Methods: | ||
* `void destroy()` - destroys the body, `'destroy'` event is emitted. | ||
Events: | ||
* Basic events, as it is stated above. | ||
* `'update' { vec3 pos, quat quat, vec3 vell, vec3 vela }` - emitted for every non-sleeping | ||
Body per every `scene.update()` call. Instead of `rot` value it caries a raw quaternion. | ||
However you can get the newest `body.rot` yourself. It is done to minimize calculation, | ||
because rotation is internally quaternion and requires conversion to Euler-angles. Also | ||
visualization frameworks tend to treat quaternions way better then angles, and the main | ||
use case of this event is to update visualization. | ||
``` | ||
body.on('update', ({ pos, quat }) => { | ||
mesh.position.set(pos.x, pos.y, pos.z); | ||
mesh.quaternion.set(quat.x, quat.y, quat.z, quat.w); | ||
}); | ||
``` | ||
--- | ||
### class Joint | ||
Wraps around `btGeneric6DofSpringConstraint` (as if this was relevant). Can only connect | ||
Bodies within the same scene. A generic constraint can be turned into any other kind | ||
by a carefull setting of parameters. This is why we have a HUGE number of props here. | ||
``` | ||
const { Scene, Body } = require('bullet-raub'); | ||
const scene = new Scene(); | ||
const bodyA = new Body({ scene }); | ||
const bodyB = new Body({ scene }); | ||
const joint = new Joint(); | ||
joint.a = bodyA; | ||
joint.b = bodyB; | ||
``` | ||
Constructor: | ||
* `Joint()` | ||
Properties: | ||
* `get/set Body a null` - the first connected body | ||
* `get/set Body b null` - the second connected body | ||
* `get/set boolean broken false` - if the connection was broken. | ||
* `get/set number maximp 9001.f*9001.f` - it's over 9000! A maximum impulse that can be withstood | ||
by this joint. This value should be big: small values simply break upon spawn. | ||
* `get/set vec3 posa [0,0,0]` - joint attachment position within the first connected body. | ||
NOTE: this is not the position of the body in scene. | ||
* `get/set vec3 posb [0,0,0]` - joint attachment position within the second connected body. | ||
NOTE: this is not the position of the body in scene. | ||
* `get/set vec3 rota [0,0,0]` - joint attachment rotation within the first connected body. | ||
NOTE: this is not the rotation of the body in scene. | ||
* `get/set vec3 rotb [0,0,0]` - joint attachment rotation within the second connected body. | ||
NOTE: this is not the rotation of the body in scene. | ||
* `get/set vec3 minl [0,0,0]` - linear lower limit of the connection. | ||
* `get/set vec3 maxl [0,0,0]` - linear upper limit of the connection. | ||
* `get/set vec3 mina [0,0,0]` - angular lower limit of the connection. | ||
* `get/set vec3 maxa [0,0,0]` - angular upper limit of the connection. | ||
* `get/set vec3 dampl [1,1,1]` - linear damping. | ||
* `get/set vec3 dampa [1,1,1]` - angular damping. | ||
* `get/set vec3 stifl [0,0,0]` - linear spring stiffness. | ||
* `get/set vec3 stifa [0,0,0]` - angular spring stiffness. | ||
* `get/set vec3 springl [0,0,0]` - enable/disable linear spring behavior. | ||
* `get/set vec3 springa [0,0,0]` - enable/disable angular spring behavior. | ||
* `get/set vec3 motorl [0,0,0]` - enable/disable linear motor behavior. | ||
* `get/set vec3 motora [0,0,0]` - enable/disable angular motor behavior. | ||
* `get/set vec3 motorlf [0,0,0]` - linear motor max force. | ||
* `get/set vec3 motoraf [0,0,0]` - angular motor max force. | ||
* `get/set vec3 motorlv [0,0,0]` - linear motor target velocity. | ||
* `get/set vec3 motorav [0,0,0]` - angular motor target velocity. | ||
Methods: | ||
* `void destroy()` - destroys the joint, `'destroy'` event is emitted. | ||
Events: | ||
* Basic events, as it is stated above. | ||
* `'update' { vec3 posa, vec3 posb, boolean broken }` - emitted for every joint, connecting | ||
two bodies, at least one of which is non-sleeping, per every `scene.update()` call. | ||
Instead of `getter posa/posb`, values passed represent current positions of connected bodies. | ||
Same can be retrieved by `joint.a.pos` and `joint.b.pos`.The main use case of this event | ||
is to update visualization. | ||
``` | ||
joint.on('update', ({ posa, posb, broken }) => { | ||
line.start.set(posa.x, posa.y, posa.z) | ||
line.end.set(posb.x, posb.y, posb.z) | ||
line.color = broken ? 0xFF0000 : 0x00FF00; | ||
}); | ||
``` | ||
--- | ||
### class Trace | ||
A read-only trace result. Holds the information about a ray trace. | ||
``` | ||
const { Scene, Body } = require('bullet-raub'); | ||
const scene = new Scene(); | ||
const body = new Body({ scene }); | ||
const trace = new Trace({ scene, from: [0, 10, 0], to: [0, -10, 0] }); | ||
console.log('trace', trace); | ||
const hitRes = scene.hit([0, 10, 0], [0, -10, 0]); | ||
console.log('hitRes', hitRes); | ||
const traceRes = scene.trace([0, 10, 0], [0, -10, 0]); | ||
console.log('traceRes', traceRes); | ||
``` | ||
Constructor: | ||
* `Trace({ Scene scene, vec3 from, vec3 to })` | ||
Properties: | ||
* `get boolean hit` - if ray hit any body | ||
* `get Body body` - the body or null | ||
* `get vec3 pos` - where did it hit | ||
* `get vec3 norm` - body surface normal | ||
Events: | ||
* Basic events, as it is stated above. | ||
See [TypeScript declarations](/index.d.ts) for more details. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
97
1
6302
5
25
+ Addedaddon-tools-raub@7.4.08.0.0(transitive)
+ Addeddeps-bullet-raub@3.0.0(transitive)
+ Addedsegfault-raub@2.3.0(transitive)
- Removedaddon-tools-raub@5.0.0(transitive)
- Removedbalanced-match@1.0.2(transitive)
- Removedbig-integer@1.6.52(transitive)
- Removedbinary@0.3.0(transitive)
- Removedbluebird@3.4.7(transitive)
- Removedbrace-expansion@1.1.11(transitive)
- Removedbuffer-indexof-polyfill@1.0.2(transitive)
- Removedbuffers@0.1.1(transitive)
- Removedchainsaw@0.1.0(transitive)
- Removedconcat-map@0.0.1(transitive)
- Removedcore-util-is@1.0.3(transitive)
- Removeddeps-bullet-raub@2.0.0(transitive)
- Removedduplexer2@0.1.4(transitive)
- Removedfs.realpath@1.0.0(transitive)
- Removedfstream@1.0.12(transitive)
- Removedglob@7.2.3(transitive)
- Removedgraceful-fs@4.2.11(transitive)
- Removedinflight@1.0.6(transitive)
- Removedinherits@2.0.4(transitive)
- Removedisarray@1.0.0(transitive)
- Removedlistenercount@1.0.1(transitive)
- Removedminimatch@3.1.2(transitive)
- Removedminimist@1.2.8(transitive)
- Removedmkdirp@0.5.6(transitive)
- Removednode-addon-api@1.7.1(transitive)
- Removedonce@1.4.0(transitive)
- Removedpath-is-absolute@1.0.1(transitive)
- Removedprocess-nextick-args@2.0.1(transitive)
- Removedreadable-stream@2.3.8(transitive)
- Removedrimraf@2.7.1(transitive)
- Removedsafe-buffer@5.1.2(transitive)
- Removedsegfault-raub@1.1.0(transitive)
- Removedsetimmediate@1.0.5(transitive)
- Removedstring_decoder@1.1.1(transitive)
- Removedtraverse@0.3.9(transitive)
- Removedunzipper@0.10.5(transitive)
- Removedutil-deprecate@1.0.2(transitive)
- Removedwrappy@1.0.2(transitive)
Updatedaddon-tools-raub@^7.4.0
Updateddeps-bullet-raub@^3.0.0
Updatedsegfault-raub@^2.1.2