Skip to content

Latest commit

 

History

History
162 lines (119 loc) · 8.6 KB

CONTRIBUTING.md

File metadata and controls

162 lines (119 loc) · 8.6 KB

Contributing

  1. Extending Godot Physics
  2. How the Physics Server works with Godot Nodes
  3. Rapier Physics Server Serialization
  4. Rapier Physics Server Fluids
  5. How to build
  6. How to debug

Extending Godot Physics

Godot let's any GDExtension create a new Physics Server if they call register_server on the PhysicsServer2DManager or PhysicsServer3DManager and on the callback return a new instance of their custom Physics Server that extends either PhysicsServer2DExtension or PhysicsServer3DExtension.

A physics server has to implement 3 classes:

Note that these functions all have underscore in begining of function name. The flow for how Godot calls them is the function without underscore calls into th one with underscore, eg.:

body_create()
|
v
_body_create()

Godot can register multiple Physics Servers, and can decide at runtime which one to use.

Godot Rapier Physics implements these under the name like this:

Code is reused as much as possible, by having each of these classes call into a generic class that does the implementation, and a few configuration flags to select dimensions, precision, etc.

The code written here is based on the Physics Server from Godot.

How the Physics Server works with Godot Nodes

The Physics Server is a singleton with a set of API's for bodies, areas, shapes and spaces. An example of this is body_create function. This function creates a body, and returns an RID. These RID's are resource id's for objects that are handled by the Physics Server.

Normally you wouldn't call these functions directly, but instead you would create a node that would call these functions. Eg. when you create a RigidBody2D node, this calls the following:

body_rid = body_create()
body_set_space(body_rid, space_rid)
body_set_state(body_rid, BODY_STATE_TRANSFORM, Transform2D())
...

Also, aside from communication from Godot -> Physics Server, there is also the reverse, where the Physics Server notifies Godot of updates (eg. collision events, etc.). For this, Godot first calls into the Physics Server's method, eg.:

These functions send a Callable to the Physics Server that it uses to call back into Godot and notify of certain changes.

Rapier Physics Server Serialization

The Rapier Physics Server, which is our custom implementation of Physics Server, hands out RID's for objects it has internally, similar to how Godot Physics Server does. The classes are named similar to how Godot naming works, but with Rapier instead of Godot, eg.:

  • RapierArea
  • RapierBody
  • RapierCollisionObjectBase
  • ...

The difference from Godot Physics Server is that resources are not using pointers, and as such are safe to be serialized.

However, there are some things that need to be reconstructed after saving and loading the state, namely:

  • Callable
  • RID
  • instance_id
  • canvas_instance_id

As described in the chapter above, the Physics Server creates some resources and gives Godot RID's that can be used to access them. Godot also gives some resources to the Physics Server, eg. Callable, that are used to notify Godot of updates (eg. collision events, etc.). Godot also gives to objects from Physics Server instance_id's and canvas_instance_id's in order to identify a node corresponds to a resource.

As such, when saving and loading, first one must recreate the Godot scene and make sure all the dependencies are created, and only later load the Physics Server state. Even if some of the things the Physics Server loads won't be the exact same, eg. RID's, Callable, etc. The simulation will work deterministic as internally it uses Rapier which is itself deterministic. Also the update order isn't based on these resources that Godot hands over.

Rapier Physics Server Fluids

Godot Rapier Physics also exposes new nodes, Fluid2D and Fluid3D. These nodes can set and get position, velocity and acceleration of particles used for fluid simulation. Internally it uses salva to create them.

How to build

  1. Prerequisites:
  1. Update dependencies to latest:
cargo update
  1. Build the project
# for 2d
cargo build --release --features="build2d" --no-default-features
# for 3d
cargo build --release --features="build3d" --no-default-features
  1. Copy the output to bin folder of the addon:

Eg. macOS

cp target/release/libgodot_rapier.dylib bin2d/addons/godot-rapier2d/bin/libgodot_rapier.macos.framework/libgodot_rapier.macos.dylib

Eg. Windows

cp target/release/godot_rapier.dll bin2d/addons/godot-rapier2d/bin/godot_rapier.windows.x86_64-pc-windows-msvc.dll

For the correct path to use inside the bin folder, look inside the bin2d/addons/godot-rapier2d.gdextension or the bin3d/addons/godot-rapier3d.gdextension.

Available features

For features, the following are available:

  • single-dim2
  • single-dim3
  • double-dim2
  • double-dim3
  • parallel
  • simd-stable
  • enhanced-determinism
  • serde-serialize

The single and double refer to the precision used in Godot.

The dim2 or dim3 refers to the rapier and salva versions used, and to what classes will be implemented for Godot and what Physics Server will be replaced(2d or 3d).

The parallel version doesn't work on web.

The enhanced-determinism usually slows down the simulation.

The serde-serialize feature enabled serialization methods for physics server.

How to debug

Run Godot from debugger inside VSCode

Click Run and Debug in VSCode on the left. Add a configuration to the launch.configurations similar to this (eg. below one is for macOS):

{
    "name": "Launch",
    "program": "path/to/godot/bin/godot.macos.editor.dev.arm64",
    "type": "cppdbg",
    "request": "launch",
    "cwd": "${workspaceFolder:godot-rapier-2d}",
    "osx": {
        "MIMode": "lldb"
    },
    "args": [
        "--path",
        "path/to/project/folder",
        "--debug-collisions",
        "scene-name.tscn"
    ]
},

More on godot cli usage here.