Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mass Setting Issue in Rapier3D JavaScript #761

Closed
jojocello opened this issue Nov 21, 2024 · 1 comment
Closed

Mass Setting Issue in Rapier3D JavaScript #761

jojocello opened this issue Nov 21, 2024 · 1 comment

Comments

@jojocello
Copy link

Description

I'm trying to create a physics demo to demonstrate how objects with different masses behave differently when sliding down a tilted floor. The demo consists of three spheres of identical size but different masses placed at the top of a tilted floor. However, despite trying multiple approaches to set different masses for the spheres, they all behave identically in the simulation, suggesting that the mass differences are not being properly applied.

I reused the same model than the existing testbed3d demos of the rapier-js repository:

import type { Testbed } from "../Testbed";

type RAPIER_API = typeof import("@dimforge/rapier3d");

// Create a tilted floor with three spheres of different masses
// in order to observe the effect of mass on the gliding motion

export function initWorld(RAPIER: RAPIER_API, testbed: Testbed) {
    let gravity = new RAPIER.Vector3(0.0, -9.81, 0.0);
    let world = new RAPIER.World(gravity);

    // Create tilted ground 
    let groundDesc = RAPIER.RigidBodyDesc.fixed()
          .setTranslation(0, -5, 0)
          .setRotation({
            w: Math.cos(Math.PI / 20),
            x: Math.sin(Math.PI / 20),
            y: 0,
            z: 0,
    });
    let groundBody = world.createRigidBody(groundDesc);
    let groundColliderDesc = RAPIER.ColliderDesc.cuboid(25.0, 0.1, 125.0);
    groundColliderDesc.setFriction(0.001);
    world.createCollider(groundColliderDesc, groundBody);

    // Common properties for all spheres
    const sphereRadius = 2.0;
    const startHeight = 35.0;
    const startZ = -110.0;
    const spacing = 15.0; // Space between spheres on x-axis

    // Create three spheres with different masses
    const sphereConfigs = [
        { mass: 10.0, x: -spacing, color: 0x00FF00  },    // Green sphere (light)
        { mass: 500.0, x: 0, color: 0x0000FF },          // Blue sphere (medium)
        { mass: 3000.0, x: spacing, color:0xFF0000 }    // Red sphere (heavy)
    ];

    sphereConfigs.forEach(config => {
        // Create rigid body without mass first
        let sphereDesc = RAPIER.RigidBodyDesc.dynamic()
            .setTranslation(config.x, startHeight, startZ);
        let sphereBody = world.createRigidBody(sphereDesc);
        
        // Create collider with zero density
        let sphereColliderDesc = RAPIER.ColliderDesc.ball(sphereRadius)
            .setDensity(0.0)
            .setFriction(0.001);
        let sphereCollider = world.createCollider(sphereColliderDesc, sphereBody);

        // Set mass object after creation
        // sphereBody.setAdditionalMass(config.mass, true);
        // sphereCollider.setMass(config.mass);

        // For a sphere, the principal inertia is the same in all directions
        const centerOfMassTranslation = new RAPIER.Vector3(0.0, 0.0, 0.0);
        const principalInertia = {x: config.mass * sphereRadius * sphereRadius * 2/5,
                                 y: config.mass * sphereRadius * sphereRadius * 2/5,
                                 z: config.mass * sphereRadius * sphereRadius * 2/5};
        const angularInertia = {x: 0.0, y: 0.0, z: 0.0, w: 1.0};
        // sphereBody.setAdditionalMassProperties(
        //     config.mass,      
        //     centerOfMassTranslation,             
        //     principalInertia, 
        //     angularInertia, 
        //     true            // wake up the body
        // );
        sphereCollider.setMassProperties(
          config.mass,      
          centerOfMassTranslation,             
          principalInertia, 
          angularInertia
      );

        // Set the color
        sphereCollider.setActiveHooks(config.color);
    });

    testbed.setWorld(world);

    let cameraPosition = {
        eye: { x: -180.0, y: 180.0, z: 150.0 },
        target: { x: 0.0, y: 0.0, z: 0.0 },
    };
    testbed.lookAt(cameraPosition);
}

Attempted Solutions

  • Using setAdditionalMass on RigidBody
  • Using setMass on Collider
  • Using setAdditionalMassProperties on RigidBody
  • Using setMassProperties on Collider

Expected Behavior

  • The spheres should roll down the tilted floor at different speeds due to their different masses
  • The heavier spheres should have more momentum and be less affected by friction
  • Each sphere should demonstrate distinct behavior based on its mass
  • The mass differences are significant (10 vs 500 vs 3000) so the behavior differences should be clearly visible

Actual Behavior

All spheres move identically down the ramp, suggesting that either:

  1. The mass settings are not being properly applied
  2. The mass differences are not being taken into account in the physics calculations
  3. The physics engine might be normalizing masses internally

Would appreciate any insights into:

  1. Which is the correct method to set different masses for rigid bodies in Rapier3D
  2. Whether there are any known limitations or considerations when working with different masses
  3. If there are any specific physics engine settings that need to be adjusted for mass differences to take effect
@Vrixyz
Copy link
Contributor

Vrixyz commented Nov 25, 2024

Hello,

Thanks for the details included in this report!

Friction won’t slow down down a rolling ball (friction is what makes the ball roll in the first place).

What you're observing is an "expected" behaviour of rapier. What you are looking for is rolling friction which isn’t implemented in Rapier.

Common workarounds for this are:

  • The most popular approach is setting some angular damping to your sphere.
  • You can also constraint your (physical) ball from rotating at all, so you can control its slowing down with friction, and adapt its visual rendering (rolling or what you need)

@Vrixyz Vrixyz closed this as completed Nov 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants