Skip to content

Commit

Permalink
Fix impulse local center. Also implement one way direction for rigidb…
Browse files Browse the repository at this point in the history
…odies. (#9)

- Fixes #8
- Fixes #1
  • Loading branch information
Ughuuu authored Oct 26, 2023
1 parent 778aa6b commit 97f291d
Show file tree
Hide file tree
Showing 20 changed files with 139 additions and 35 deletions.
10 changes: 10 additions & 0 deletions .github/actions/build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ runs:
${{ github.workspace }}/.scons-cache/
${{ github.workspace }}/godot-cpp/.scons-cache/
key: ${{ inputs.platform }}_${{ inputs.arch }}_${{ inputs.target }}_cache
- uses: paulhatch/[email protected]
id: version
with:
bump_each_commit: true
tag_prefix: "v"
debug: true
- name: Print version
shell: sh
run:
echo ${{ steps.version.outputs.version }} > bin/addons/godot-rapier2d/VERSION.txt
- name: Setup python and scons
uses: ./.github/actions/deps
- name: Lint
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/android_builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0
- name: Set up Java 11
uses: actions/setup-java@v3
with:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ios_builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0
- name: Build ${{ matrix.target }} ${{ matrix.arch }} ${{ matrix.precision }} ${{ matrix.features }}
uses: ./.github/actions/build
with:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/linux_builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0

- name: Build ${{ matrix.target }} ${{ matrix.arch }} ${{ matrix.precision }} ${{ matrix.features }}
uses: ./.github/actions/build
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/macos_builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0

- name: Build ${{ matrix.target }} ${{ matrix.arch }} ${{ matrix.precision }} ${{ matrix.features }}
uses: ./.github/actions/build
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/web_builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0

- name: Set up Emscripten latest
uses: mymindstorm/setup-emsdk@v12
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/windows_builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0
- name: Setup MSVC problem matcher
uses: ammaraskar/msvc-problem-matcher@master

Expand Down
11 changes: 11 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"rust-analyzer.linkedProjects": [
"./src/rapier2d-wrapper/Cargo.toml"
],
"files.associations": {
"__locale": "cpp",
"string": "cpp",
"string_view": "cpp"
},
"rust-analyzer.showUnlinkedFileNotification": false
}
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@
</div>

<p align="center">
<a href="https://github.com/fabriceci/godot-rapier2d/actions/workflows/runner.yml">
<img src="https://github.com/fabriceci/godot-rapier2d/actions/workflows/runner.yml/badge.svg?branch=main"
<a href="https://github.com/appsinacup/godot-rapier2d/actions/workflows/runner.yml">
<img src="https://github.com/appsinacup/godot-rapier2d/actions/workflows/runner.yml/badge.svg?branch=main"
alt="Godot Rapier2D Build"></a>
<a href="https://github.com/dimforge/rapier/releases/tag/v0.17.2" alt="Rapier2D Version">
<img src="https://img.shields.io/badge/Rapier2D-v0.17.2-%23478cbf?logoColor=white" /></a>
<a href="https://github.com/godotengine/godot-cpp" alt="Godot Version">
<img src="https://img.shields.io/badge/Godot-v4.1-%23478cbf?logo=godot-engine&logoColor=white" /></a>
<a href="https://github.com/fabriceci/godot-rapier2d/graphs/contributors" alt="Contributors">
<img src="https://img.shields.io/github/contributors/fabriceci/godot-rapier2d" /></a>
<a href="https://github.com/fabriceci/godot-rapier2d/pulse" alt="Activity">
<img src="https://img.shields.io/github/commit-activity/m/fabriceci/godot-rapier2d" /></a>
<a href="https://github.com/appsinacup/godot-rapier2d/graphs/contributors" alt="Contributors">
<img src="https://img.shields.io/github/contributors/appsinacup/godot-rapier2d" /></a>
<a href="https://github.com/appsinacup/godot-rapier2d/pulse" alt="Activity">
<img src="https://img.shields.io/github/commit-activity/m/appsinacup/godot-rapier2d" /></a>
<a href="https://discord.gg/56dMud8HYn">
<img src="https://img.shields.io/discord/1138836561102897172?logo=discord"
alt="Chat on Discord"></a>
</p>

<img src="https://github.com/fabriceci/godot-rapier2d/blob/main/logo.jpg?raw=true"/>
<img src="https://github.com/appsinacup/godot-rapier2d/blob/main/logo.jpg?raw=true"/>

A 2d [rapier](https://github.com/dimforge/rapier) physics server for [Godot Engine](https://github.com/godotengine/godot), implemented as a GDExtension.

Expand Down
4 changes: 2 additions & 2 deletions bin/addons/godot-rapier2d/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

<a href="https://github.com/godotengine/godot/releases/tag/4.1-stable"><img src="https://img.shields.io/badge/Godot-v4.1-%23478cbf?logo=godot-engine&logoColor=white"/></a>
<a href="https://github.com/dimforge/rapier/releases/tag/v0.17.2"><img src="https://img.shields.io/badge/Rapier2D-v0.17.2-%23478cbf?logoColor=white"/></a>
<a href="https://github.com/fabriceci/godot-rapier2d/actions/workflows/runner.yml?branch=main">![🔗 Build Status](https://github.com/fabriceci/godot-rapier2d/actions/workflows/runner.yml/badge.svg?branch=main)</a>
<a href="https://github.com/appsinacup/godot-rapier2d/actions/workflows/runner.yml?branch=main">![🔗 Build Status](https://github.com/appsinacup/godot-rapier2d/actions/workflows/runner.yml/badge.svg?branch=main)</a>
</div>

<img src="https://github.com/fabriceci/godot-rapier2d/blob/main/logo.jpg?raw=true"/>
<img src="https://github.com/appsinacup/godot-rapier2d/blob/main/logo.jpg?raw=true"/>

## Build the Rapier 2D Extension

Expand Down
3 changes: 3 additions & 0 deletions scripts/build-rapier.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cd src/rapier2d-wrapper
cargo build --release --features="single,simd-stable"
cd ../..
4 changes: 4 additions & 0 deletions scripts/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
scons arch=arm64
rm -rf Godot-Physics-Tests/addons
cp -rf bin/addons Godot-Physics-Tests/addons

4 changes: 4 additions & 0 deletions scripts/generate-api.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cd src/rapier2d-wrapper
cargo install cbindgen
cbindgen --config cbindgen.toml --crate rapier2d-wrapper --output includes/rapier2d_wrapper.h
cd ../..
11 changes: 11 additions & 0 deletions src/rapier2d-wrapper/includes/rapier2d_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,14 @@ using ContactPointCallback = bool (*)(Handle world_handle,
const ContactPointInfo *contact_info,
const ContactForceEventInfo *event_info);

struct OneWayDirection {
bool body1;
bool body2;
};

using CollisionModifyContactsCallback = OneWayDirection (*)(Handle world_handle,
const CollisionFilterInfo *filter_info);

struct SimulationSettings {
/// The timestep length (default: `1.0 / 60.0`)
Real dt;
Expand Down Expand Up @@ -472,6 +480,9 @@ void world_set_contact_force_event_callback(Handle world_handle,

void world_set_contact_point_callback(Handle world_handle, ContactPointCallback callback);

void world_set_modify_contacts_callback(Handle world_handle,
CollisionModifyContactsCallback callback);

void world_set_sensor_collision_filter_callback(Handle world_handle,
CollisionFilterCallback callback);

Expand Down
10 changes: 8 additions & 2 deletions src/rapier2d-wrapper/src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,10 @@ pub extern "C" fn body_add_force_at_point(world_handle : Handle, body_handle : H
let rigid_body_handle = handle_to_rigid_body_handle(body_handle);
let body = physics_world.rigid_body_set.get_mut(rigid_body_handle);
assert!(body.is_some());
body.unwrap().add_force_at_point(vector!(force.x, force.y),point![point.x, point.y] , true);
let mut local_point = point![point.x, point.y];
let body = body.unwrap();
local_point += body.center_of_mass().coords;
body.add_force_at_point(vector!(force.x, force.y), local_point, true);
}

#[no_mangle]
Expand Down Expand Up @@ -270,7 +273,10 @@ pub extern "C" fn body_apply_impulse_at_point(world_handle : Handle, body_handle
let rigid_body_handle = handle_to_rigid_body_handle(body_handle);
let body = physics_world.rigid_body_set.get_mut(rigid_body_handle);
assert!(body.is_some());
body.unwrap().apply_impulse_at_point(vector!(impulse.x, impulse.y),point![point.x, point.y] , true);
let mut local_point = point![point.x, point.y];
let body = body.unwrap();
local_point += body.center_of_mass().coords;
body.apply_impulse_at_point(vector!(impulse.x, impulse.y), local_point, true);
}

#[no_mangle]
Expand Down
2 changes: 1 addition & 1 deletion src/rapier2d-wrapper/src/collider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub extern "C" fn collider_create_solid(world_handle : Handle, shape_handle : Ha
collider.set_restitution_combine_rule(CoefficientCombineRule::Max);
collider.set_density(0.0);
collider.user_data = user_data.get_data();
collider.set_active_hooks(ActiveHooks::FILTER_CONTACT_PAIRS | ActiveHooks::FILTER_INTERSECTION_PAIR | ActiveHooks::MODIFY_SOLVER_CONTACTS);
collider.set_active_hooks(ActiveHooks::FILTER_CONTACT_PAIRS | ActiveHooks::MODIFY_SOLVER_CONTACTS);
let physics_world = physics_engine.get_world(world_handle);
return physics_world.insert_collider(collider, body_handle);
}
Expand Down
54 changes: 31 additions & 23 deletions src/rapier2d-wrapper/src/physics_hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ use rapier2d::prelude::*;
use crate::handle::*;
use crate::user_data::*;

#[repr(C)]
pub struct OneWayDirection {
pub body1 : bool,
pub body2 : bool,
}

pub type CollisionFilterCallback = Option<extern "C" fn(world_handle : Handle, filter_info : &CollisionFilterInfo) -> bool>;
pub type CollisionModifyContactsCallback = Option<extern "C" fn(world_handle : Handle, filter_info : &CollisionFilterInfo) -> OneWayDirection>;

#[repr(C)]
pub struct CollisionFilterInfo {
Expand All @@ -23,6 +30,7 @@ pub struct PhysicsHooksCollisionFilter<'a> {
pub world_handle : Handle,
pub collision_filter_body_callback : &'a CollisionFilterCallback,
pub collision_filter_sensor_callback : &'a CollisionFilterCallback,
pub collision_modify_contacts_callback : &'a CollisionModifyContactsCallback,
}

impl<'a> PhysicsHooks for PhysicsHooksCollisionFilter<'a> {
Expand Down Expand Up @@ -64,30 +72,30 @@ impl<'a> PhysicsHooks for PhysicsHooksCollisionFilter<'a> {
return true;
}

fn modify_solver_contacts(&self, _context: &mut ContactModificationContext) {
// TODO implement conveyer belt
// for this we need to store the static object constant speed somewhere
/*
if context.rigid_body1.is_none() || context.rigid_body2.is_none() {
return;
}
let rigid_body1 = context.bodies.get(context.rigid_body1.unwrap());
let rigid_body2 = context.bodies.get(context.rigid_body1.unwrap());
if rigid_body1.is_none() || rigid_body2.is_none() {
return;
}
let mut rigid_body1 = rigid_body1.unwrap();
let mut rigid_body2 = rigid_body2.unwrap();
fn modify_solver_contacts(&self, context: &mut ContactModificationContext) {
if self.collision_modify_contacts_callback.is_some() {
let callback = self.collision_modify_contacts_callback.unwrap();

let collider_1 = &context.colliders[context.collider1];
let collider_2 = &context.colliders[context.collider2];
let body1 = &context.bodies[context.rigid_body1.unwrap()];
let body2 = &context.bodies[context.rigid_body2.unwrap()];

if rigid_body2.is_fixed() && !rigid_body1.is_fixed() {
(rigid_body2, rigid_body1) = (rigid_body1, rigid_body2);
let mut filter_info = CollisionFilterInfo::new();
filter_info.user_data1 = UserData::new(collider_1.user_data);
filter_info.user_data2 = UserData::new(collider_2.user_data);
let allowed_local_n1 = collider_1.position().rotation * Vector::y();
let allowed_local_n2 = collider_2.position().rotation * Vector::y();
let one_way_direction = callback(self.world_handle, &filter_info);
let mut contact_is_pass_through = false;
if one_way_direction.body1 {
contact_is_pass_through = body2.linvel().normalize().dot(&allowed_local_n1) <= -DEFAULT_EPSILON * 10.0;
} else if one_way_direction.body2 {
contact_is_pass_through = body1.linvel().normalize().dot(&allowed_local_n2) <= -DEFAULT_EPSILON * 10.0;
}
if contact_is_pass_through {
context.solver_contacts.clear();
}
}
*/
// static and non static
//if rigid_body1.is_fixed() && !rigid_body2.is_fixed() {
//for solver_contact in &mut *context.solver_contacts {
//solver_contact.tangent_velocity.x = 100.0;
//}
//}
}
}
10 changes: 10 additions & 0 deletions src/rapier2d-wrapper/src/physics_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ pub struct PhysicsWorld {
pub active_body_callback : ActiveBodyCallback,
pub collision_filter_body_callback : CollisionFilterCallback,
pub collision_filter_sensor_callback : CollisionFilterCallback,
pub collision_modify_contacts_callback : CollisionModifyContactsCallback,

pub collision_event_callback : CollisionEventCallback,
pub contact_force_event_callback : ContactForceEventCallback,
Expand Down Expand Up @@ -153,6 +154,7 @@ impl PhysicsWorld {
active_body_callback : None,
collision_filter_body_callback : None,
collision_filter_sensor_callback : None,
collision_modify_contacts_callback: None,

collision_event_callback : None,
contact_force_event_callback : None,
Expand Down Expand Up @@ -191,6 +193,7 @@ impl PhysicsWorld {
world_handle : self.handle,
collision_filter_body_callback : &self.collision_filter_body_callback,
collision_filter_sensor_callback : &self.collision_filter_sensor_callback,
collision_modify_contacts_callback: &self.collision_modify_contacts_callback,
};

// Initialize the event collector.
Expand Down Expand Up @@ -501,6 +504,13 @@ pub extern "C" fn world_set_sensor_collision_filter_callback(world_handle : Hand
physics_world.collision_filter_sensor_callback = callback;
}

#[no_mangle]
pub extern "C" fn world_set_modify_contacts_callback(world_handle : Handle, callback : CollisionModifyContactsCallback) {
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
physics_world.collision_modify_contacts_callback = callback;
}

#[no_mangle]
pub extern "C" fn world_set_collision_event_callback(world_handle : Handle, callback : CollisionEventCallback) {
let mut physics_engine = SINGLETON.lock().unwrap();
Expand Down
30 changes: 30 additions & 0 deletions src/spaces/rapier_space_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,35 @@ bool RapierSpace2D::collision_filter_sensor_callback(rapier2d::Handle world_hand
return collision_filter_common_callback(world_handle, filter_info, colliders_info);
}

rapier2d::OneWayDirection RapierSpace2D::collision_modify_contacts_callback(rapier2d::Handle world_handle, const rapier2d::CollisionFilterInfo *filter_info) {
rapier2d::OneWayDirection result;
result.body1 = false;
result.body2 = false;

RapierSpace2D *space = RapierPhysicsServer2D::singleton->get_active_space(world_handle);
ERR_FAIL_COND_V(!space, result);

RapierCollisionObject2D *body1;
RapierCollisionObject2D *body2;
uint32_t shape1;
uint32_t shape2;
if (rapier2d::is_user_data_valid(filter_info->user_data1)) {
body1 = RapierCollisionObject2D::get_collider_user_data(filter_info->user_data1, shape1);
}

if (rapier2d::is_user_data_valid(filter_info->user_data2)) {
body2 = RapierCollisionObject2D::get_collider_user_data(filter_info->user_data2, shape2);
}
ERR_FAIL_COND_V(!body1, result);
ERR_FAIL_COND_V(!body2, result);
if (body1->interacts_with(body2)) {
result.body1 = body1->is_shape_set_as_one_way_collision(shape1);
result.body2 = body2->is_shape_set_as_one_way_collision(shape2);
}

return result;
}

void RapierSpace2D::collision_event_callback(rapier2d::Handle world_handle, const rapier2d::CollisionEventInfo *event_info) {
RapierSpace2D *space = RapierPhysicsServer2D::singleton->get_active_space(world_handle);
ERR_FAIL_COND(!space);
Expand Down Expand Up @@ -606,6 +635,7 @@ RapierSpace2D::RapierSpace2D() {
rapier2d::world_set_active_body_callback(handle, active_body_callback);
rapier2d::world_set_body_collision_filter_callback(handle, collision_filter_body_callback);
rapier2d::world_set_sensor_collision_filter_callback(handle, collision_filter_sensor_callback);
rapier2d::world_set_modify_contacts_callback(handle, collision_modify_contacts_callback);
rapier2d::world_set_collision_event_callback(handle, collision_event_callback);
rapier2d::world_set_contact_force_event_callback(handle, contact_force_event_callback);
rapier2d::world_set_contact_point_callback(handle, contact_point_callback);
Expand Down
1 change: 1 addition & 0 deletions src/spaces/rapier_space_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class RapierSpace2D {
static bool collision_filter_common_callback(rapier2d::Handle world_handle, const rapier2d::CollisionFilterInfo *filter_info, CollidersInfo &r_colliders_info);
static bool collision_filter_body_callback(rapier2d::Handle world_handle, const rapier2d::CollisionFilterInfo *filter_info);
static bool collision_filter_sensor_callback(rapier2d::Handle world_handle, const rapier2d::CollisionFilterInfo *filter_info);
static rapier2d::OneWayDirection collision_modify_contacts_callback(rapier2d::Handle world_handle, const rapier2d::CollisionFilterInfo *filter_info);

static void collision_event_callback(rapier2d::Handle world_handle, const rapier2d::CollisionEventInfo *event_info);

Expand Down

0 comments on commit 97f291d

Please sign in to comment.