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

Add deterministic base function. Fix freeze mode. Fix missing events/collisions. #258

Merged
merged 19 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ on:
branches:
- "main"

concurrency:
group: ${{ github.ref }}
cancel-in-progress: true

jobs:
static-checks:
name: 📊 Static checks
Expand Down
43 changes: 27 additions & 16 deletions .github/workflows/test_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,28 @@ on:
workflow_call:

jobs:
run-tests-2d:
name: Run Tests
run-unit-tests-2d:
name: Run Unit Tests 2D
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run Unit Tests for 2D Build
shell: sh
run: |
cargo test --all-targets --features="build2d,test" --no-default-features
run-unit-tests-3d:
name: Run Unit Tests 3D
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run Unit Tests for 3D Build
shell: sh
run: |
cargo test --all-targets --features="build3d,test" --no-default-features
run-integration-tests-2d:
name: Run Integration Tests 2D
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -15,17 +35,12 @@ jobs:
version: 4.3.0
use-dotnet: false
include-templates: true
- name: Run Unit Tests for 2D Build
shell: sh
run: |
cargo test --all-targets --features="build2d,test" --no-default-features
- name: Run Integration Tests for 2D Build
shell: sh
# Skip this for now
if: false
run: |
return
./scripts/build-dev-2d.sh
ls bin2d/addons/godot-rapier2d/bin
godot --headless --path ./bin2d test.tscn --quit-after 1000 > output.log 2>&1
echo "---------------------"
grep "ERROR:" output.log
Expand All @@ -40,8 +55,8 @@ jobs:
exit 1
fi

run-tests-3d:
name: Run Tests
run-integration-tests-3d:
name: Run Integration Tests 3D
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -51,16 +66,12 @@ jobs:
version: 4.3.0
use-dotnet: false
include-templates: true
- name: Run Unit Tests for 3D Build
shell: sh
run: |
cargo test --all-targets --features="build3d,test" --no-default-features
- name: Run Integration Tests for 3D Build
# Skip this for now
if: false
shell: sh
run: |
return
./scripts/build-dev-3d.sh
ls bin3d/addons/godot-rapier3d/bin
godot --headless --path ./bin3d test.tscn --quit-after 1000 > output.log 2>&1
echo "---------------------"
grep "ERROR:" output.log
Expand Down
4 changes: 2 additions & 2 deletions bin2d/addons/godot-rapier2d/fluid_2d_renderer.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ extends MultiMeshInstance2D

@export var fluid: Fluid2D
@export var color: Color = Color(0.8, 0.8, 0.8, 0.3)

@export var mesh_scale: Vector2 = Vector2(5,5)

func _ready():
if multimesh == null:
Expand All @@ -23,7 +23,7 @@ func _process(_delta):
var points = fluid.points
for i in points.size():
var point = points[i]
var new_transform: Transform2D = Transform2D(0, Vector2(5, 5), 0, point)
var new_transform: Transform2D = Transform2D(0, mesh_scale, 0, point)
multimesh.set_instance_transform_2d(index, new_transform)
multimesh.set_instance_color(index, color)
index += 1
2 changes: 2 additions & 0 deletions bin2d/addons/godot-rapier2d/fluid_2d_shader_renderer.gd
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ extends CanvasLayer
update_configuration_warnings()
@export var camera: Camera2D
@export var water_material: Material = load("res://addons/godot-rapier2d/water_shader.tres")
@export var mesh_scale: Vector2 = Vector2(5,5)
var fluid_renderer: Fluid2DRenderer
var inside_camera: Camera2D:
set(value):
Expand Down Expand Up @@ -46,6 +47,7 @@ func _create_fluid_renderer():
fluid_renderer = Fluid2DRenderer.new()
fluid_renderer.name = "Fluid2DRenderer"
fluid_renderer.color = Color(255,0,255)
fluid_renderer.mesh_scale = mesh_scale
fluid_renderer.fluid = fluid
sub_viewport.add_child(fluid_renderer)

Expand Down
14 changes: 13 additions & 1 deletion bin2d/test.tscn
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
[gd_scene load_steps=3 format=3 uid="uid://cn4jscixu2bmf"]
[gd_scene load_steps=4 format=3 uid="uid://cn4jscixu2bmf"]

[ext_resource type="Script" path="res://test.gd" id="1_fs1uw"]

[sub_resource type="CircleShape2D" id="CircleShape2D_01opr"]

[sub_resource type="RectangleShape2D" id="RectangleShape2D_vkitq"]
size = Vector2(365, 37)

[node name="Test2D" type="Node2D"]
script = ExtResource("1_fs1uw")

Expand All @@ -12,3 +15,12 @@ position = Vector2(-18, -4)

[node name="CollisionShape2D" type="CollisionShape2D" parent="RigidBody2D"]
shape = SubResource("CircleShape2D_01opr")

[node name="StaticBody2D" type="StaticBody2D" parent="."]

[node name="CollisionShape2D" type="CollisionShape2D" parent="StaticBody2D"]
position = Vector2(10.5, 96.5)
shape = SubResource("RectangleShape2D_vkitq")

[node name="Camera2D" type="Camera2D" parent="."]
zoom = Vector2(4, 4)
15 changes: 0 additions & 15 deletions bin3d/test.gd
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,25 @@ func _ready() -> void:
get_tree().quit()

func test_capsule_shape():
RapierCapsuleShapeTests.test_allows_one_way_collision()
RapierCapsuleShapeTests.test_create()
RapierCapsuleShapeTests.test_get_data()
RapierCapsuleShapeTests.test_get_type()
RapierCapsuleShapeTests.test_set_data_from_array()
RapierCapsuleShapeTests.test_set_data_from_dictionary()
RapierCapsuleShapeTests.test_set_data_from_vector2()

func test_circle_shape():
RapierCircleShapeTests.test_allows_one_way_collision()
RapierCircleShapeTests.test_create()
RapierCircleShapeTests.test_get_data()
RapierCircleShapeTests.test_get_type()
RapierCircleShapeTests.test_set_data()

func test_concave_polygon_shape():
RapierConcavePolygonShapeTests.test_allows_one_way_collision()
RapierConcavePolygonShapeTests.test_create()
RapierConcavePolygonShapeTests.test_get_data()
RapierConcavePolygonShapeTests.test_get_type()
RapierConcavePolygonShapeTests.test_set_data()

func test_convex_polygon_shape(): # New function for convex polygon shape
RapierConvexPolygonShapeTests.test_allows_one_way_collision()
RapierConvexPolygonShapeTests.test_create()
RapierConvexPolygonShapeTests.test_get_data()
RapierConvexPolygonShapeTests.test_get_type()
RapierConvexPolygonShapeTests.test_set_data()

func test_cylinder_shape():
RapierCylinderShape3DTests.test_create()
RapierCylinderShape3DTests.test_get_type()
RapierCylinderShape3DTests.test_allows_one_way_collision()
RapierCylinderShape3DTests.test_set_data_array()
RapierCylinderShape3DTests.test_set_data_vector2()
RapierCylinderShape3DTests.test_set_data_dictionary()
RapierCylinderShape3DTests.test_get_data()
3 changes: 2 additions & 1 deletion src/bodies/rapier_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1574,6 +1574,7 @@ impl RapierBody {
if p_mode.ord() >= BodyMode::RIGID.ord() {
self.mass_properties_changed(physics_engine, physics_spaces, physics_rids);
}
self.set_space_after(physics_engine, physics_spaces, physics_rids);
}

pub fn set_state(
Expand Down Expand Up @@ -1956,7 +1957,7 @@ impl RapierBody {
&mut self,
physics_engine: &mut PhysicsEngine,
physics_spaces: &mut PhysicsSpaces,
physics_rids: &mut PhysicsRids,
physics_rids: &PhysicsRids,
) {
if self.base.is_space_valid() && self.base.mode.ord() >= BodyMode::KINEMATIC.ord() {
if self.get_force_integration_callback().is_some() {
Expand Down
3 changes: 2 additions & 1 deletion src/rapier_wrapper/physics_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,8 @@ impl PhysicsWorld {
+ collider1.contact_skin()
+ collider2.contact_skin()
{
continue;
// TODO comment this out for now since it might miss out events
//continue;
}
let collider_pos_1 = collider1.position() * contact_point.local_p1;
let collider_pos_2 = collider2.position() * contact_point.local_p2;
Expand Down
29 changes: 18 additions & 11 deletions src/rapier_wrapper/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,23 +415,30 @@ impl PhysicsEngine {
let shared_shape2 = scale_shape(raw_shared_shape2, shape_info2);
let shape_transform1 = shape_info1.transform;
let shape_transform2 = shape_info2.transform;
if let Ok(Some(contact)) = parry::query::contact(
match parry::query::contact(
&shape_transform1,
shared_shape1.as_ref(),
&shape_transform2,
shared_shape2.as_ref(),
prediction,
) {
// the distance is negative if there is intersection
// and positive if the objects are separated by distance less than margin
result.pixel_distance = contact.dist;
result.within_margin = contact.dist > 0.0;
result.collided = true;
result.normal1 = contact.normal1.into_inner();
result.normal2 = contact.normal2.into_inner();
result.pixel_point1 = (contact.point1 + contact.normal1.mul(prediction)).coords;
result.pixel_point2 = contact.point2.coords;
return result;
Ok(None) => {}
Ok(Some(contact)) => {
// the distance is negative if there is intersection
// and positive if the objects are separated by distance less than margin
result.pixel_distance = contact.dist;
result.within_margin = contact.dist > 0.0;
result.collided = true;
result.normal1 = contact.normal1.into_inner();
result.normal2 = contact.normal2.into_inner();
result.pixel_point1 =
(contact.point1 + contact.normal1.mul(prediction)).coords;
result.pixel_point2 = contact.point2.coords;
return result;
}
Err(err) => {
godot_error!("Shape Contact Error: {:?}", err);
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/servers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use godot::prelude::*;

use crate::servers::rapier_project_settings::RapierProjectSettings;
pub mod rapier_math;
#[cfg(feature = "dim2")]
pub mod rapier_physics_server_2d;
#[cfg(feature = "dim3")]
Expand Down
97 changes: 97 additions & 0 deletions src/servers/rapier_math.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use godot::prelude::*;
use rapier::na::ComplexField;
#[derive(GodotClass)]
#[class(base=Object, init)]
/// Contains Rapier Deterministic Math functions.
pub struct RapierMath {
base: Base<Object>,
}
#[godot_api]
impl RapierMath {
#[func]
/// Deterministically compute acos.
fn acos(x: real) -> real {
ComplexField::acos(x)
}

#[func]
/// Deterministically compute acosh.
fn acosh(x: real) -> real {
ComplexField::acosh(x)
}

#[func]
/// Deterministically compute asin.
fn asin(x: real) -> real {
ComplexField::asin(x)
}

#[func]
/// Deterministically compute asinh.
fn asinh(x: real) -> real {
ComplexField::asinh(x)
}

#[func]
/// Deterministically compute atan.
fn atan(x: real) -> real {
ComplexField::atan(x)
}

#[func]
/// Deterministically compute atanh.
fn atanh(x: real) -> real {
ComplexField::atanh(x)
}

#[func]
/// Deterministically compute cos.
fn cos(x: real) -> real {
ComplexField::cos(x)
}

#[func]
/// Deterministically compute cosh.
fn cosh(x: real) -> real {
ComplexField::cosh(x)
}

#[func]
/// Deterministically compute log.
fn log(x: real) -> real {
ComplexField::ln(x)
}

#[func]
/// Deterministically compute sin.
fn sin(x: real) -> real {
ComplexField::sin(x)
}

#[func]
/// Deterministically compute sinh.
fn sinh(x: real) -> real {
ComplexField::sinh(x)
}

#[func]
/// Deterministically compute tan.
fn tan(x: real) -> real {
ComplexField::tan(x)
}

#[func]
/// Deterministically compute tanh.
fn tanh(x: real) -> real {
ComplexField::tanh(x)
}

#[func]
/// Deterministically compute sqrt.
fn sqrt(x: real) -> real {
if let Some(result) = ComplexField::try_sqrt(x) {
return result;
}
real::NAN
}
}
Loading
Loading