dimforge / rapier.js

Official JavaScript bindings for the Rapier physics engine.
https://rapier.rs
Apache License 2.0
435 stars 58 forks source link

Serialization data is unexpectedly large, can shapes be reused? #216

Open lukashaertel opened 1 year ago

lukashaertel commented 1 year ago

When initializing a shape beforehand and using it for multiple colliders, the size of the serialized data does not differ from using a new shape for each collider. I would expect that defining a single shape beforehand would reduce the size. I have run three tests with differing methods, all leading to the same snapshot sizes. The definition is below.

On a related note, I have geometry that I can load without tapping into serialization, e.g., loading predefined static world geometry. Can this be skipped in the serialization, as it is redundant and creates unnecessarily large snapshots.

Test file:

import {describe, it, beforeAll} from "vitest"
import {ColliderDesc, ConvexPolyhedron, init, RigidBodyDesc, World} from "@dimforge/rapier3d-compat";
import {suzanneConvexHullVertices} from "./suzanne";

const fmt = (n: number) => `${n}, ${(n / 1024).toFixed(1)}kb`

describe('Initializations', () => {
    beforeAll(async () => {
        await init();
    })
    it('Data', () => {
        console.log(fmt(suzanneConvexHullVertices.length * 4))
        // > stdout | test/rapier.test.ts > Initializations > Data
        // > 792, 0.8kb

    })
    it('Shape', () => {
        const world = new World({x: 0, y: -10, z: 0});
        const shape = new ConvexPolyhedron(suzanneConvexHullVertices);

        for (let i = 0; i < 3; i++) {
            const body = world.createRigidBody(RigidBodyDesc.dynamic());
            world.createCollider(new ColliderDesc(shape), body);
            console.log(fmt(world.takeSnapshot().length));
        }

        world.free();
        // > stdout | test/rapier.test.ts > Initializations > Shape
        // > 22123, 21.6kb
        // > 43727, 42.7kb
        // > 65331, 63.8kb
    })

    it('Desc', () => {
        const world = new World({x: 0, y: -10, z: 0});
        const desc = ColliderDesc.convexHull(suzanneConvexHullVertices)!;

        for (let i = 0; i < 3; i++) {
            const body = world.createRigidBody(RigidBodyDesc.dynamic());
            world.createCollider(desc, body);

            console.log(fmt(world.takeSnapshot().length));
        }

        world.free();
        // > stdout | test/rapier.test.ts > Initializations > Desc
        // > 22123, 21.6kb
        // > 43727, 42.7kb
        // > 65331, 63.8kb

    })

    it('Inline', () => {
        const world = new World({x: 0, y: -10, z: 0});

        for (let i = 0; i < 3; i++) {
            const body = world.createRigidBody(RigidBodyDesc.dynamic());
            world.createCollider(ColliderDesc.convexHull(suzanneConvexHullVertices)!, body);

            console.log(fmt(world.takeSnapshot().length));
        }

        world.free();
        // > stdout | test/rapier.test.ts > Initializations > Inline
        // > 22123, 21.6kb
        // > 43727, 42.7kb
        // > 65331, 63.8kb

    })
})

Convex hull, precomputed:

export const suzanneConvexHullVertices = Float32Array.of(
    0.351562, 0.242188, 0.828125, -0.351562, 0.242188, 0.828125,
    0.445312, 0.156250, 0.781250, -0.445312, 0.156250, 0.781250,
    0.000000, 0.898438, -0.546875, 0.000000, 0.562500, -0.851562,
    0.000000, 0.070312, -0.828125, 0.367188, -0.890625, 0.531250,
    -0.367188, -0.890625, 0.531250, 0.328125, -0.945312, 0.523438,
    -0.328125, -0.945312, 0.523438, 0.179688, -0.968750, 0.554688,
    -0.179688, -0.968750, 0.554688, 0.000000, -0.984375, 0.578125,
    0.859375, 0.429688, 0.593750, -0.859375, 0.429688, 0.593750,
    0.320312, 0.757812, 0.734375, -0.320312, 0.757812, 0.734375,
    0.000000, -0.765625, 0.734375, 0.109375, -0.718750, 0.734375,
    -0.109375, -0.718750, 0.734375, 0.117188, -0.835938, 0.710938,
    -0.117188, -0.835938, 0.710938, 0.062500, -0.882812, 0.695312,
    -0.062500, -0.882812, 0.695312, 0.687500, 0.414062, 0.726562,
    -0.687500, 0.414062, 0.726562, 0.312500, 0.640625, 0.835938,
    -0.312500, 0.640625, 0.835938, 0.203125, 0.617188, 0.851562,
    -0.203125, 0.617188, 0.851562, 0.265625, -0.820312, 0.664062,
    -0.265625, -0.820312, 0.664062, 0.234375, -0.914062, 0.632812,
    -0.234375, -0.914062, 0.632812, 0.164062, -0.929688, 0.632812,
    -0.164062, -0.929688, 0.632812, 0.000000, -0.945312, 0.640625,
    0.109375, -0.226562, 0.828125, -0.109375, -0.226562, 0.828125,
    0.000000, 0.898438, 0.289062, 0.000000, 0.984375, -0.078125,
    0.000000, -0.195312, -0.671875, 0.000000, -0.976562, 0.460938,
    0.328125, -0.914062, 0.398438, -0.328125, -0.914062, 0.398438,
    0.453125, 0.867188, -0.382812, -0.453125, 0.867188, -0.382812,
    0.453125, 0.929688, -0.070312, -0.453125, 0.929688, -0.070312,
    0.453125, 0.851562, 0.234375, -0.453125, 0.851562, 0.234375,
    1.281250, 0.054688, -0.429688, -1.281250, 0.054688, -0.429688,
    1.351562, 0.320312, -0.421875, -1.351562, 0.320312, -0.421875,
    1.234375, 0.507812, -0.421875, -1.234375, 0.507812, -0.421875,
    1.250000, 0.468750, -0.546875, -1.250000, 0.468750, -0.546875,
    1.367188, 0.296875, -0.500000, -1.367188, 0.296875, -0.500000,
    1.312500, 0.054688, -0.531250, -1.312500, 0.054688, -0.531250,
    1.039062, -0.085938, -0.492188, -1.039062, -0.085938, -0.492188
)