Giter Club home page Giter Club logo

rapier.js's People

Contributors

alexandernanberg avatar andygura avatar automatonsystems avatar chargeuk avatar dested avatar drfbwilliams avatar hmans avatar hoiast avatar isaac-mason avatar jcyuan avatar joseluis avatar lucas-schuermann avatar maun avatar sebcrozet avatar viridia avatar whaqzhzd avatar willheslam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rapier.js's Issues

[rapier2D-compat] undefined 'document' in web-worker

I would like to use rapier inside a web-worker through the rapier2d-compatmodule, for an easy setup.

I am blocked by a problem in the file node_modules/@dimforge/rapier2d-compat/rapier.js at the very last line of the file.

A=A.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),g.p=A})(),g.b=document.baseURI||self.location.href,g(123)})()}));

I do not know what the source code is because I have only access to the minified version, but the use of document makes the library unusable inside a web-worker.

Here is the error:

rapier.js?28fd:1 Uncaught ReferenceError: document is not defined
    at eval (rapier.js?28fd:1)
    at eval (rapier.js?28fd:1)
    at eval (rapier.js?28fd:1)
    at eval (rapier.js?28fd:1)
    at Object../node_modules/@dimforge/rapier2d-compat/rapier.js (src_simulation_worker_ts.js:18)

ReferenceError: Buffer is not defined in init.ts

In 0.7.1 (3d-compat), I'm seeing this error:

Uncaught (in promise) ReferenceError: Buffer is not defined

While awaiting Rapier.init().

Buffer seems undefined in this commit, but not sure if there's some global definition somewhere: https://github.com/viridia/rapier.js/blob/40ef3dc75208f1936ac3b41520e99d8dec20d805/rapier-compat/src3d/init.ts#L10

Seems like it's gone in master: https://github.com/viridia/rapier.js/blob/master/rapier-compat/src3d/init.ts

So maybe it just needs a new version pushed? Or maybe I'm importing incorrectly - neither of the following work for me:

import * as Rapier from "@dimforge/rapier3d-compat";

async function main() {
    await Rapier.init();
}
import Rapier from "@dimforge/rapier3d-compat";

async function main() {
    await Rapier.init();
}

The first one worked in 0.7.0. Thanks for any help!

[bug] 0.8.0-alpha, failed to create a impulse joint.

    const staticCenterBody = context.createBody(RigidBodyType.Static);

    const tumblerBox = context.createBody(RigidBodyType.Dynamic);

    const ballJointParam = JointData.revolute(VectorOps.new(cx, cy), VectorOps.new(cx, cy));
    const ballJoint = context.world.createImpulseJoint(ballJointParam, staticCenterBody, tumblerBox) as RevoluteImpulseJoint;
    ballJoint.configureMotorVelocity(cfg.angularVelocity, cfg.angularVelocity);

image

An example that creates ColliderDesc from THREE.js mesh

Hi, it should be good to have an example that creates a ColliderDesc.trimesh from a THREE.js mesh. It will make it easier for those who want to apply rapier.js to an existing three.js project.
Here is my try, but it's not easy to know whether it's correct or not since I can't visualize the trimesh.

let vertices = threeMesh.geometry.getAttribute('position');
let indices = threeMesh.geometry.index;
if (indices == null) {
    // unindexed bufferedgeometry
    indices = [...Array(vertices.count).keys()]
}
let colliderDesc = RAPIER.ColliderDesc.trimesh(vertices, indices);

Comparison still exist with ammo.js and others?

I found this old reddit thread: https://www.reddit.com/r/javascript/comments/hn0vd2/i_started_writing_a_testbed_to_compare/
from (presumably) @sebcrozet which states that you were putting together a comparison with "Ammo.js/Cannon.js/Oimo.js/PhysX-js". The link now 404s. Is this comparison still around?

I'm currently evaluating .js physics engines for use in a beginner-friendly online game maker, and this is exactly the sort of comparison I was hoping to find.

world.createImpuselJoint() returns undefined if the joint is revolute.

This is when using 0.8.0-alpha.1 @dimforge/rapier2d
Previously it has worked as intended and returned the created joint.

If taking the example from the docs:

let params = RAPIER.JointData.revolute({ x: 0.0, y: 1.0 }, { x: 0.0, y: -3.0 });
let joint = world.createImpulseJoint(params, body1, body2);

joint would be undefined if trying to create a revolute joint. It works fine when using fixed or prismatic. The joint is created and can be found in the world using world.impulseJoints.forEachJointHandle or world.impulseJoints.forEachJoint, but world.impulseJoints.get() will return undefined.

[feature request] simd version

after some research i found that some libs from c++ has their wasm released with simd supported.
i think this is a good feature which can improve the effeicency when running on web.
hope this can be adopted, thank you very much.

Collider.setShape throws exception: null pointer passed to rust

Calls to change the shape of a collider cause the engine to crash.

You can check it with this simple instruciton:

collider.setShape(new RAPIER.Ball(2));

vendors-physics.js:67 Uncaught Error: null pointer passed to rust
at C.wbg.__wbindgen_throw (vendors-physics.js:67)
at 0032afe2:0xbf704
at 0032afe2:0xbf711
at 0032afe2:0xbab75
at u.free (vendors-physics.js:67)
at A.setShape (vendors-physics.js:67)

vendors-physics.js is just the Webpack chunk I created to load RAPIER dynamically.

[feature request] add user data to collider / rigidbody

usually we will attach some user data to a collider / rigidbody, for example my sprite / my entity etc.

body.userData = a;
collider.userData = b;

so this will be a very convenient attribute. and it exists in a lot of physics engines already too.
so hope you can add it for us please.
thank you very much.

Use joint motors without TypeScript

Hi, I have been trying to build a robot simulator with Rapier.js. Thanks for the great tool.

I was trying to use joint motors. Here is how to use them in the documentation:

let joint = world.createImpulseJoint(params, body1, body2);
(joint as RAPIER.PrismaticImpulseJoint).configureMotorVelocity(1.0, 0.5);

(joint as RAPIER.PrismaticImpulseJoint) seems like a TypeScript grammar, but my project is in vanilla JavaScript, so the webpack complains about the grammar.

I wonder whether there is way to use joint motors without TypeScript?

I tried to use joint.rawSet.jointConfigureMotorPosition, but I couldn't find RawJointAxis, which is the second parameter of that function.

ColliderDesc.polyline(vs, indices), indices can be null

1, i have tested and it seems i can pass indices as null to ColliderDesc.polyline and it works normally.
so should be just a mistake in the TS declration file?

2, dynamic polyline does not fall
i guess because it does not have density so no mass so not falling. please just ignore this if it's expected so.

Invalid Collider.activeHooks return type

I noticed when using @dimforge/rapier2d that the Collider.activeHooks() return type was void when it should be ActiveHooks. I'm not familiar with the Rapier build process, so I hope this is the correct repo to propose a fix.

@dimforge/rapier2d/geometry/collider.d.ts:

107     /**
108      * Get the physics hooks active for this collider.
109      */
110     activeHooks(): void;

Patch:

diff --git a/src.ts/geometry/collider.ts b/src.ts/geometry/collider.ts
index 5f0220e..b2e1642 100644
--- a/src.ts/geometry/collider.ts
+++ b/src.ts/geometry/collider.ts
@@ -192,7 +192,7 @@ export class Collider {
     /**
      * Get the physics hooks active for this collider.
      */
-    public activeHooks() {
+    public activeHooks(): ActiveHooks {
         return this.rawSet.coActiveHooks(this.handle);
     }

Adjust local anchors of a ball joint

Hi,
I was wondering if it would be possible to adjust the local_anchor1 and local_anchor2 values of a ball joint after the joint had been created?
I have been digging through the code, but do not know the rust language. It seems that the anchors are simply defined within the ball joint class, but I do see that other classes take copies (or references?) to their values. If a method to change the anchors was added to the ball joint, would the changed value be used throughout the system? And then could this method be exposed via the JavaScript interface?
Many thanks, Rapier looks like an awesome physics engine.

recursive use of an object detected which would lead to unsafe aliasing in rust

Using rapier2d-compat version 0.7.6

// World contains some static and dynamic body
world.forEachRigidBody(body =>{
  const collidersLength = body.numColliders();

  for (let i = 0; i < collidersLength; i++) {
    const collider = world.getCollider(body.collider(i));
    drawBody(ctx, collider, body);
  }

  if (body.bodyType() === RAPIER.RigidBodyType.Static) {
    return
  }

  const bodyPosition = body.translation();

  const bodyMass = body.mass();

  world.forEachRigidBody(otherBody => {
    if (body.handle === otherBody.handle) {
      return
    }

    const otherBodyMass = otherBody.mass();

    const otherBodyPosition = otherBody.translation();

    const distance = getDistance(otherBodyPosition, bodyPosition);

    const forceDirection = getDirection(
      otherBodyPosition,
      bodyPosition
    );
    const forceMagnitude = getGravitationalForce(
      otherBodyMass,
      bodyMass,
      distance
    );
    try {
      body.applyForce(
        new RAPIER.Vector2(
          (Math.sin(forceDirection) * forceMagnitude) /
            Math.sqrt(bodyMass),
          (Math.cos(forceDirection) * forceMagnitude) /
            Math.sqrt(bodyMass)
        ),
        true
      );
    } catch (error) {
      console.error(error);
    }
  })
})

This code always throws as soon as I have 2 bodies (1 static & 1 dynamic, 2 statics, 2 dynamics, whatever) with the error recursive use of an object detected which would lead to unsafe aliasing in rust.

image

The error also happens with forEachRigidBodyHandle

The same code using forEachCollider works (but I wanna use forEachRigidBody because some bodies have multiple colliders)

world.forEachCollider((collider) => {
  const body = world.getRigidBody(collider.parent());

  drawBody(ctx, collider, body);

  if (body.bodyType() === RAPIER.RigidBodyType.Static) {
    return;
  }

  const bodyPosition = body.translation();

  const bodyMass = body.mass();

  world.forEachCollider((otherCollider) => {
    const otherBody = world.getRigidBody(otherCollider.parent());

    if (body.handle === otherBody.handle) {
      return;
    }

    const otherBodyMass = otherBody.mass();

    const otherBodyPosition = otherBody.translation();

    const distance = getDistance(otherBodyPosition, bodyPosition);

    const forceDirection = getDirection(
      otherBodyPosition,
      bodyPosition
    );
    const forceMagnitude = getGravitationalForce(
      otherBodyMass,
      bodyMass,
      distance
    );
    try {
      body.applyForce(
        new RAPIER.Vector2(
          (Math.sin(forceDirection) * forceMagnitude) /
            Math.sqrt(bodyMass),
          (Math.cos(forceDirection) * forceMagnitude) /
            Math.sqrt(bodyMass)
        ),
        true
      );
    } catch (error) {
      console.error(error);
    }
  });
});

`RAPIER.BodyStatus` needs to be updated to `RAPIER.RigidBodyType` in the "getting started" codepen example

The example codepen linked from this "getting started" page of the docs errors due to RAPIER.BodyStatus not existing. Per the v0.7.0 changelog it needs to be updated to RAPIER.RigidBodyType, or use the shorthand .newStatic()/.newDynamic().

I'm not able to submit a pull request to fix this because the code is on CodeMirror rather than Github. I wonder if there's some way to move the example code to Github but also keep them interactive/editable like on codepen? It would be handy if codepen had a URL-based import like https://codepen.io/?js=https://github.com/dimforge/rapier.js/path/to/example.js

Allow asynchronous initialization of Rapier

Right now there are two ways to initialize rapier.js: The 'rapier-compat' package, or (for lack of a better name) the 'vanilla' version.

The reason that rapier-compat exists is to allow use with bundlers that have trouble loading .wasm resources. However, this compatibility comes at a price: the entire .wasm resource is encoded as text. While this works, it is not ideal.

Right now the only bundler (that I know of) that can handle the 'vanilla' version of rapier.js is Webpack 4. Webpack 5 will not work, nor will Snowpack. Rollup uses a strategy similar to rapier-compat, encoding the resource as text. I have not tried Parcel, Vite, or any of the other bundlers, but I imagine they have similar issues.

However, there is a third option, which is to not depend on a bundler encoding at all. This is in fact the recommended option for snowpack, as shown in this guide. This technique loads the .wasm resource directly using the browser fetch API, and then once the promise resolves, it manually bootstraps the JavaScript wrappers around the WASM resource.

However, doing it this way means that the .wasm resource will not be available until after the fetch promise resolves. Unfortunately, the current rapier.js TypeScript code imports the raw bundle as a static resource - that is, it assume that the WASM code is already ready at the time that the JavaScript code is imported. So this option will not work with the current rapier.js code.

To support this use case, it would be necessary to change the way that the rapier.js World object, and the objects within it, are constructed. Instead of statically importing all of the references to WASM classes, these would need to be passed in as part of the constructor call. Possibly it would make sense to define a TypeScript interface which has the same shape to "import * from 'raw'" and pass that object around to each class that is constructed.

Also, a lot of the import { symbol } statements would be changed to import type { symbol } to let the TypeScript compiler know that we're only interested in the type definitions, not the values of the imports. "import type" statements are always removed from the output JavaScript, so this prevents the .wasm resources from being accidentally dereferenced too early.

This is not a huge change, but unfortunately it is a backwards-incompatible one. The strategy proposed here is not that different from the way JavaScript clients use Rapier already - you have to have a handle to the rapier object before you can create a world, rb, collider, or anything else other than the basic math types.

Importing wasm, compat with Vite?

Hello, I'm trying to try out rapier with Vite as my bundler. Vite supports direct wasm imports, so I'm wondering if some of its magic isn't working with how rapier is bundled.

When I try to import it (either as async or a standard ESM format) I can see types in my IDE, but my code doesn't run in the browser, with this error:
The requested module '/@fs/GitHub/test/@dimforge/rapier2d/rapier_wasm2d_bg.wasm?import' does not provide an export named '__wbg_rawbroadphase_free'

I'm happy to do some legwork to figure this out, but I'm not sure what else to try, are there any clues in there?

Edit: using the compat package works as expected, so I'll do that in the meantime

[bug] error when multiple substeps calling

Env: PC, Win10
Version: TS / JS

error when call multiple substeps

code snippet:

const fixedTimeStep = 1000 / 60;
this._world.timestep = fixedTimeStep;

private stepPhysicsWorld(delta: number) {
    this._accumulator += delta;
    let substepIndex = 0;

    while (substepIndex++ < this._maxSubSteps && this._accumulator > fixedTimeStep) {
        this._world.step();
        this._accumulator -= fixedTimeStep;
    }
}

if the delta always small enough, then while will always loop just for 1 times, which works fine.
but once the _accumulator has enough lagged time value, then the while will call twice or more world.step times, and then it will throw error:

image

error in wasm and call stack:
image
image

this means i can't call step immedately after a step call? otherwise how to implement fixed time step on web? because even use webworker in web, you actually can't implement a real fixed time interval calling still...
hmmm, with wasm this is the obvious disadvantage, i can do nothing when find a bug.... 😅

thank you.

rapier3d-compat package has incorrect raw.d.ts output

In the rapier3d-compat build the raw.d.ts file contains export * from "../pkg3d/rapier_wasm3d"; which does not exist in the distributed package. In the rapier3d build, this file is export * from "./rapier_wasm3d"; which would work just fine in the compat build.

This line is added for the rapier3d build here but I don't see a corresponding line for the compat build.

This results in typescript errors when building projects against the compat build such as:

node_modules/@dimforge/rapier3d-compat/dynamics/ccd_solver.d.ts:1:10 - error TS2305: Module '"../raw"' has no exported member 'RawCCDSolver'.

1 import { RawCCDSolver } from "../raw";

intersectionsWithRay on empty ColliderSet causes RuntimeError

When I query for intersectionsWithRay on an empty ColliderSet, I get the following RuntimeError:

cb4a7832f88eb109b422.module.wasm:0x109724 Uncaught RuntimeError: unreachable
    at http://localhost:8080/build/cb4a7832f88eb109b422.module.wasm:wasm-function[803]:0x109724
    at http://localhost:8080/build/cb4a7832f88eb109b422.module.wasm:wasm-function[901]:0x10d9ac
    at http://localhost:8080/build/cb4a7832f88eb109b422.module.wasm:wasm-function[1248]:0x115602
    at http://localhost:8080/build/cb4a7832f88eb109b422.module.wasm:wasm-function[1181]:0x1148e8
    at http://localhost:8080/build/cb4a7832f88eb109b422.module.wasm:wasm-function[1250]:0x115666
    at http://localhost:8080/build/cb4a7832f88eb109b422.module.wasm:wasm-function[1011]:0x110f3e
    at http://localhost:8080/build/cb4a7832f88eb109b422.module.wasm:wasm-function[115]:0xa2fcc
    at rawquerypipeline_intersectionsWithRay (http://localhost:8080/build/cb4a7832f88eb109b422.module.wasm:wasm-function[734]:0x1055fd)
    at RawQueryPipeline.intersectionsWithRay (http://localhost:8080/build/0.0.js:5740:105)
    at QueryPipeline.push.../node_modules/@dimforge/rapier3d/pipeline/query_pipeline.js.QueryPipeline.intersectionsWithRay (http://localhost:8080/build/0.0.js:3244:18)

In my world loop, I need to check that colliders.len() > 0 to proceed:

    const colliders = this.physics.world.colliders;
    if (colliders.len() > 0) {
      this.physics.world.intersectionsWithRay(
        colliders,
        rayDown,
        MAX_GROUND_TOI,
        true,
        AVATAR_INTERACTION,
        (isect) => {
          // ... callback code ...
          return true;
        }
      );
    }

[bug] Segment does not return start / end point

image

1, here if i want to retrieve the start point / end point of a segment (the c)
it returns undefined.

c.a, c.b, c.vertices() all returns undefined

2, triangle shape does not return a,b,c too
c.a, c.b, c.c, c.vertices(), all returns undefined

3, all rounded shape, if you want to retrieve its round radius, all undefined
for example roundCuboid.roundRadius() will return undefined

Undefined methods for limits

@dimforge/rapier2d 0.8.0-alpha.1

I was having problems getting limits to work properly with a prismatic joint, while trying to figure it out it seems that the following methods: limitsEnabled, limitesMax and LimitsMin are undefined.

According to the typescript these should be there. The same is true for the Revolute joint, typescript says they should be there, but they appear to be undefined.

Build script should not require global typescript installation

Currently the build script requires the user to have previously installed the TypeScript compiler. This is a recipe for trouble - there is no guarantee that the version of TypeScript that the user has installed is one that will work with the current version of rapier.js.

The standard practice in the npm world is to declare "typescript" as a dependency in package.json. This allows the compiler version to be explicitly specified. You can then call "npx tsc" in your shell script (after running "npm install") to invoke the version of tsc that has been installed with the project.

Even better would be to eliminate the shell scripts entirely and just make the build commands npm scripts in package.json, so that "npm run build" builds the project.

This will of course require adding a package.json file to the rapier.js repo. That can either live at the top level or in the individual directories for rapier2d and rapier3d.

failed to compile

Env: Win10 PC

execute cargo build --release in folder rapier.js\rapier2d gives this:

image

same error for both 2d & 3d.

am i doing something wrong?

Include Typescript source in npm package

When using webpack's source-map-loader in development mode, the plugin is unable to see Rapier's source files and provides many warnings:

./node_modules/@dimforge/rapier3d/dynamics/index.js
Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from '/Users/duane/Projects/relm5/node_modules/@dimforge/rapier3d/dynamics/index.ts' file: Error: ENOENT: no such file or directory, open '/Users/duane/Projects/relm5/node_modules/@dimforge/rapier3d/dynamics/index.ts' client:135
./node_modules/@dimforge/rapier3d/dynamics/integration_parameters.js
Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from '/Users/duane/Projects/relm5/node_modules/@dimforge/rapier3d/dynamics/integration_parameters.ts' file: Error: ENOENT: no such file or directory, open '/Users/duane/Projects/relm5/node_modules/@dimforge/rapier3d/dynamics/integration_parameters.ts'
...

Could these files be included in the npm package in order to help with stack trace debugging?

How to draw cuboid ?

I'm using rapier2d-compat version 0.7.6.

I'm creating a radial gravity based platform game.

I had no issue creating and rendering 2d ball object => I create a body, attach it to a Ball shaped collider, then in the game loop, I iterate over all collider and draw them according to their ShapeType. In case of ball ShapeType, I use the body translation property and the collider radius property.

Then I tried to create a simple square with cuboid() with the following code

const heroBodyDesc = RAPIER.RigidBodyDesc.newDynamic().setTranslation(
  100,
  100
);
const heroColliderDesc = RAPIER.ColliderDesc.cuboid(10, 10).setDensity(
  1
);
let heroBody = world.createRigidBody(heroBodyDesc);
let heroCollider = world.createCollider(
  heroColliderDesc,
  heroBody.handle
);
console.log(heroCollider.vertices(), heroBody.mass());
// logs : undefined 400

I do not understand how to retrieve the shape infos, there is no width or height nor vertices on the collider. Could someone give me a hand ?

Support for compound shapes

I need to create a 2d body made by a circle and a rectangle. According to the documentation on the website I should use a compound collider for this, correct?

I've been looking into how to use a compound shape with rapier2d, but couldn't find much: the "Compound = 8" definition in the typescript source is commented out and there's no constructor or function to handle them.

Would it be possible to port support to compound shapes?

Otherwise what's the recommended way to create my shape?

Exposing contact information

As someone interested in building games for the web platform and XR, I'm really excited to find this library! Existing solutions are either feature-complete and fast (Ammo) or easy to use (Cannon) - but not both, it seems. Rapier is looking delightful in all respects.

I understand it's relatively early in the project, but are there plans yet to expose contact position and normal? I noticed this information has been provided recently in the Rust project, and I'm curious if there's any way I could help bring it into the JS bindings as well. I'm not so familiar with Rust but I know my way around TS and would love to learn how that bridge works.

[bug] lockRotations will lock its translation

when you call lockRotations on an existing created dynamic rigidBody on the fly, the body will no longer move.
but call lockRotations from the creation desc when creating it, later the created body will be locked and can be moved which works fine.

a clue if it will help:
1, lock rotation from creation rigidbodyDesc.lockRotations() will work fine (but can't unlock later by calling lockRotations(false)).

2, call lockRotations on the fly, it will lock both rotation & translation, but can unlock later.

[bug] error throws when kinematic body collide with polygonline

image

1, colliding error when touches polygonline
kinematic body (no matter positionbased or velocitybased)
as the pic shows, the ball moving from right to left, error will throw out when it touches the polygonline.

error:
image
image
image

it seems the same position in the step. not sure what happened. it seems almost all the errors are thrown from here.

2, kinematic does not collide with heightfield (static, the green line in the image)
it will just go through the heightfield line (same as the last bug report: #61)
image

kinematic body collides normally with other dynamic shapes.
image

"Getting Started" docs won't get you started

So, the docs leave a lot out - in particular, simply importing the rapier3d from npm isn't going to work without configuring your bundler (webpack, rollup, etc.) to handle wasm files. I've spent a couple hours trying to get it to work with snowpack - it kept complaining that the .wasm file was not a JavaScript file; switched over to webpack and got a similar error. Then I tried installing wasm-loader, but that doesn't work either - I get _rapier_wasm3d_bg_wasm__WEBPACK_IMPORTED_MODULE_0__.rawintegrationparameters_new is not a function. I'm guessing that I need to find a different loader, but I have no idea which loader I should use.

"RuntimeError: unreachable" error with heightfields

I'm trying to create a 2D heightfield but it throws a unreachable error at runtime for no apparent reason.

image

...

const rigidBody = this.world.createRigidBody(rigidBodyDesc);
const colliderDesc = RAPIER.ColliderDesc.heightfield(new Float32Array([ 2, 3 ]), { x: 50.0, y: 1.0 });
const collider = this.world.createCollider(colliderDesc, rigidBody.handle);

...

Also, on the testbed heightfield.js example it passes an array to the heights parameters, but on Typescript it requires a Float32Array. Anyway, the testbed example also doesn't work:

let ground_size = {x: 50.0, y: 1.0};
let nsubdivs = 100;
let heights = [];

heights.push(40.0);

for (let i = 1; i < nsubdivs; ++i) {
    heights.push(Math.cos(i * ground_size.x / (nsubdivs)) * 2.0);
}

heights.push(40.0);

...

const colliderDesc = RAPIER.ColliderDesc.heightfield(new Float32Array(heights), ground_size);
const collider = this.world.createCollider(colliderDesc, rigidBody.handle);

...

I'm using the latest version of Rapier2D (0.7.6).

"unreachable" error when using heightmap

I'm getting the following error:

Uncaught RuntimeError: unreachable
    at std::panicking::rust_panic_with_hook::h9d91fa0fae16500f (http://localhost:3000/0c0ef481b8428110185b.module.wasm:wasm-function[788]:0x108529)
    at std::panicking::begin_panic_handler::{{closure}}::h2d82b5b2db976f3f (http://localhost:3000/0c0ef481b8428110185b.module.wasm:wasm-function[897]:0x10d32a)
    at std::sys_common::backtrace::__rust_end_short_backtrace::h24539600b7e2452c (http://localhost:3000/0c0ef481b8428110185b.module.wasm:wasm-function[1245]:0x114d35)
    at rust_begin_unwind (http://localhost:3000/0c0ef481b8428110185b.module.wasm:wasm-function[1161]:0x113c87)
    at core::panicking::panic_fmt::h91d2023e5afe1929 (http://localhost:3000/0c0ef481b8428110185b.module.wasm:wasm-function[1247]:0x114d99)
    at core::panicking::panic::h5da66f104e83c46a (http://localhost:3000/0c0ef481b8428110185b.module.wasm:wasm-function[1111]:0x112e78)
    at rapier3d::geometry::broad_phase_multi_sap::sap_axis::SAPAxis::batch_insert::h22440a950023a6c1 (http://localhost:3000/0c0ef481b8428110185b.module.wasm:wasm-function[58]:0x6e464)
    at rapier3d::geometry::broad_phase_multi_sap::broad_phase::BroadPhase::update::hcb9a53f41ef84931 (http://localhost:3000/0c0ef481b8428110185b.module.wasm:wasm-function[46]:0x5b78c)
    at rapier3d::pipeline::physics_pipeline::PhysicsPipeline::detect_collisions::he6a99ba9c9b1190f (http://localhost:3000/0c0ef481b8428110185b.module.wasm:wasm-function[321]:0xdbb17)
    at rapier3d::pipeline::physics_pipeline::PhysicsPipeline::step::h0bcdada6b45b091e (http://localhost:3000/0c0ef481b8428110185b.module.wasm:wasm-function[45]:0x59992)

What is interesting is that if I fill the heightmap with all zeroes, I don't get this error. If I pass in real terrain data I do.

Even more strangely, if I multiply the data by a small constant (.01) the error goes away, but I multiply by (.99) it happens. So basically it is as if the magnitude of what is in the array matters. I've tried a bunch of other combinations, it's completely consistent but I can't figure out the pattern.

Note: it took me a few hours to even get this stack dump, as I had to build the library locally in order to turn on debug symbols, and I had to fuss with it to get it to build on my system.

The way I am building the height map isn't very interesting either:

/** Physics object representing a height field such as terrain. */
export class PhysicsHeightField {
  #body: RigidBody;
  #collider: Collider | null = null;

  constructor(private rapier3d: R, private world: World, position: Vector2) {
    // TODO: Add friction and such.
    const rbDesc = rapier3d.RigidBodyDesc.newDynamic().setTranslation(position.x, 0, position.y);
    this.#body = this.world.createRigidBody(rbDesc);
  }

  public dispose() {
    if (this.#collider) {
      this.world.removeCollider(this.#collider);
      this.#collider = null;
    }
    this.world.removeRigidBody(this.#body);
  }

  public setHeights(heights: Float32Array) {
    // Remove previous collider, if any.
    if (this.#collider) {
      this.world.removeCollider(this.#collider);
    }
    // Generate new height map from data.
    const clDesc = this.rapier3d.ColliderDesc.heightfield(
      PLOT_LENGTH,
      PLOT_LENGTH,
      heights,
      terrainScale
    );
    this.#collider = this.world.createCollider(clDesc, this.#body.handle);
  }
}

Event handlers are not called

Hi guys, first of all, thanks for the great library you are working on.
I'm using 0.8.0-alpha.0 version of rapier.js.
I have a ground as a static body and two dynamic bodies. I've added colliders of these bodies to one collision group and set active contact events on them with the code below:

collider.setCollisionGroups(0x00010001)
collider.setActiveEvents(
  RAPIER.ActiveEvents.CONTACT_EVENTS
)

I've created an event queue and added one dummy contact event handler:

const eventQueue = new RAPIER.EventQueue(true)

eventQueue.drainContactEvents((handle1, handle2, started) => {
  /* Handle the contact event. */
  console.log(handle1, handle2, started)
})

in a render loop I pass eventQueue as a parameter to the step method:

world.step(eventQueue)

One of the dynamic bodies is a character controlled by a keyboard/mouse.
The problem is, that regardless of the way I collide these bodies the contact events handler with console.log is not called.

Do I do something wrong, or is it something missing in the alpha version of the library? Thanks.

user_data isn’t exposed by the JS bindings

I only see the user-data API in the Rust section of the docs, and I can't find any mention of it in TypeScript types. It looks like it's not exposed in the JS version of the library yet, and would be very useful to have. Is it possible to add it to the JS lib? Thank you!

Allow changing velocity scaling factor on each axis individually

A feature request to add linear and angular velocity scaling factor on a rigidbody, which would allow to control each axis individually:

For example, in Bullet engine:

void btRigidBody::setLinearFactor(const btVector3 &linearFactor);
void btRigidBody::setAngularFactor(const btVector3 &angFac);

JS Bindings Demo (2D & 3D) Playback Speed Issues

Hello, the 2D Demos and 3D Demos seem to run fine at first glance, but selecting a different "demo" from the dropdown seems to double the speed of the simulation.

I noticed that the speed seems to be reset when selecting the "keva tower" 3D demo and then switching to another demo.

Also you can quickly reproduce this issue by pressing "restart" multiple times.

Crashes iOS Safari and iOS Chrome

I notice that the rapier.rs 3d demo crashes iOS Safari (14.0.1) and iOS Chrome (87).

Unfortunately, it crashes the browser (no console logs, no crash traces), so it's difficult to say what's causing the problem.

The error message in Safari is "A problem repeatedly occurred on [url]". In Chrome the error message is "Can't open this page" with an "aww snap" crash icon ().

Raycasting before step returns undefined

I'm struggling with kind of an insane bug right now, or perhaps it's just undefined behavior, but i am not receiving any results of a raycast if step has not been called at least once.

The use case is I am restoring a snapshot and immediately casting and getting null.

    const world = new World({x: 0.0, y: -9.81, z: 0.0});
    const colliderDesc = ColliderDesc.cuboid(10, 10, 10);
    const body = world.createRigidBody(RigidBodyDesc.newStatic());
    const collider = world.createCollider(colliderDesc, body.handle);

    world.step();

    const result = world.castRay(new Ray(new Vector3(0, 20, 0), new Vector3(0, -1, 0)), 100, true, 0xfffffffff);
    console.log(!!result); /*true, but would be false if I commented out step*/


    const world2 = World.restoreSnapshot(world.takeSnapshot());
    const result2 = world2.castRay(new Ray(new Vector3(0, 20, 0), new Vector3(0, -1, 0)), 100, true, 0xfffffffff);
    console.log(!!result2); /*false*/

If this is the intended behavior, is there any thoughts on a way to "pump the gas" without explicitly calling step and pushing the simulation forward?

[Feature Request] castShape between shapes

to do sweep test between two shapes, this method is missing from collider (or a static method like castShape(p0, r0, shape0, p1, r1, shape1, vel, maxToi))
just like last update, collider.castRay/intersectsXXXX has been done for intersection test.
this method is for the similar purpose: move my character, which is a key feature.
thank you very much.

RoundCuboid has null halfExtents

I'm trying to draw all the colliders in the world but I'm having trouble getting the properties of some of the shapes.

 world.forEachCollider(c => {
    switch (c.shapeType()) {
      case ShapeType.Cuboid:
        console.log("Cuboid", c.halfExtents())
        break
      case ShapeType.RoundCuboid:
        console.log("RoundCuboid", c.halfExtents())
        break

For cuboids it works fine, ir prints: Cuboid AA {x: 100, y: 0.25}
but for round cuboids it prints RoundCuboid null

Here is a small reproduction https://codesandbox.io/s/stupefied-galileo-9zz4f?file=/src/index.ts

The same happens for the 2D version.

Make the API more idiomatic and as flexible as the Rust API

Problems with the current bindings

The current JS bindings need to be reworked to address the following problems:

  1. The JS bindings generated by wasm-bindgen are great, but they require the end-user to do manual memory management for any struct returned from rust. For example rigidBody.linvel() will return a Vector which has to be explicitly freed by the end-user with vector.free(). This is very bad because it is very easy to forget to free something, which will ultimately lead to leaks.
  2. The API exposed through JS is very different from the Rust API. Some differences are justified, but others are not. In particular, JS bindings expose a monolithic World structure which is convenient but will become quite limited in the future once rapier exposes more pipelines than the physics pipeline.
  3. The fact that the JS API is very different from the Rust API makes it more difficult to design. Two different APIs imply twice as much design work.

New design

In order to address these problems, we should modify our bindings by splitting them into two elements:

  • Low-level bindings as close as the Rust API as possible. The bindings will suffer from the manual-memory management mentioned in 1, but won't suffer from 2 and 3.
  • High-level bindings that will basically wrap the low-level bindings in order to automatically perform all the relevant memory management, except for long-lived objects. Long-lived objects are the objects that are supposed to be kept alive during the whole simulation, e.g., the RigidBodySet, ColliderSet, PhysicsPipeline, etc. but not the colliders and rigidbodies for example. This will solve the manual-memory management mentioned in 1 because it will automatically free transient objects that could have been easily forgotten by the end-user.

Another bonus of the high-level bindings is that they will allow us to design a more JS-idomatic API by defining, e.g., builder patterns.

About backward compatibility

This change will necessarily be a breaking change. However we should attempt to limit as much as possible the amount of breaking changes. To do so we will:

  • Define a World structure in the high-level bindings. This structure will work like the current monolithic World so that existing code wont suffer too much from this binding rewrite. At some point in the future we may end up making World as deprecated.
  • Update the user-guide and examples accordingly at the same time as we publish the new bindings.
  • The new binding version should be 0.2.0 to show that a breaking change happened.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.