diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml
index 4945ee83..db00aa7d 100644
--- a/.github/actions/build/action.yml
+++ b/.github/actions/build/action.yml
@@ -16,7 +16,7 @@ inputs:
rust_env_flags:
required: false
default: ''
- descriptio: RUSTFLAGS env var.
+ description: RUSTFLAGS env var.
arch:
default: ''
description: Target architecture.
@@ -49,11 +49,6 @@ runs:
echo v${{ steps.version.outputs.version }} > bin/addons/godot-rapier2d/VERSION.txt
- name: Setup python and scons
uses: ./.github/actions/deps
- - name: Lint
- shell: sh
- run:
- ./scripts/clang-format.sh
- ./scripts/clang-tidy.sh
- name: Build Godot Cpp
shell: sh
env:
diff --git a/README.md b/README.md
index 3effaa51..f0c25d01 100644
--- a/README.md
+++ b/README.md
@@ -3,17 +3,17 @@
-
-
+
-
-
+
+
-
-
-
-
+
+
+
+
@@ -40,8 +40,8 @@ A 2d [rapier](https://github.com/dimforge/rapier) physics server for [Godot Engi
# Limitations
- SeparationRay2D missing.
-- DampedSpringJoint2D missing.
- Shape skew missing.
+- Web exports not working [issues/23](https://github.com/appsinacup/godot-rapier-2d/issues/23)
# Supported Platforms
@@ -50,7 +50,7 @@ A 2d [rapier](https://github.com/dimforge/rapier) physics server for [Godot Engi
- Linux (x86_64)
- Android (x86_64, arm64)
- iOS (arm64)
-- Web (wasm32)
+- Web (wasm32) * Not working
# Installation
diff --git a/scripts/build.sh b/scripts/build.sh
index d37f9898..0f514713 100755
--- a/scripts/build.sh
+++ b/scripts/build.sh
@@ -1,4 +1,4 @@
-scons arch=arm64
+scons arch=arm64 target=template_debug
rm -rf Godot-Physics-Tests/addons
cp -rf bin/addons Godot-Physics-Tests/addons
diff --git a/src/bodies/rapier_body_2d.cpp b/src/bodies/rapier_body_2d.cpp
index 12e496ea..11437966 100644
--- a/src/bodies/rapier_body_2d.cpp
+++ b/src/bodies/rapier_body_2d.cpp
@@ -41,8 +41,9 @@ void RapierBody2D::_apply_mass_properties(bool force_update) {
void RapierBody2D::update_mass_properties(bool force_update) {
mass_properties_update_list.remove_from_list();
-
- ERR_FAIL_COND(mode < PhysicsServer2D::BODY_MODE_RIGID);
+ if (mode < PhysicsServer2D::BODY_MODE_RIGID) {
+ return;
+ }
real_t total_area = 0;
for (int i = 0; i < get_shape_count(); i++) {
@@ -64,7 +65,7 @@ void RapierBody2D::update_mass_properties(bool force_update) {
const RapierShape2D *shape = get_shape(i);
real_t shape_area = shape->get_aabb().get_area();
- if (shape_area == 0.0) {
+ if (shape_area == 0.0 || mass == 0.0) {
continue;
}
@@ -90,7 +91,7 @@ void RapierBody2D::update_mass_properties(bool force_update) {
const RapierShape2D *shape = get_shape(i);
real_t shape_area = shape->get_aabb().get_area();
- if (shape_area == 0.0) {
+ if (shape_area == 0.0 || mass == 0.0) {
continue;
}
diff --git a/src/bodies/rapier_body_2d.h b/src/bodies/rapier_body_2d.h
index 78390bc5..c04f16c3 100644
--- a/src/bodies/rapier_body_2d.h
+++ b/src/bodies/rapier_body_2d.h
@@ -152,6 +152,9 @@ class RapierBody2D : public RapierCollisionObject2D {
contacts.resize(p_size);
contact_count = 0;
}
+ _FORCE_INLINE_ void reset_contact_count() {
+ contact_count = 0;
+ }
_FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); }
_FORCE_INLINE_ bool can_report_contacts() const { return !contacts.is_empty(); }
_FORCE_INLINE_ void add_contact(const Vector2 &p_local_pos, const Vector2 &p_local_normal, real_t p_depth, int p_local_shape, const Vector2 &p_collider_pos, int p_collider_shape, ObjectID p_collider_instance_id, const RID &p_collider, const Vector2 &p_collider_velocity_at_pos, const Vector2 &p_impulse);
diff --git a/src/joints/rapier_damped_spring_joint_2d.cpp b/src/joints/rapier_damped_spring_joint_2d.cpp
index df9c239e..9d74609a 100644
--- a/src/joints/rapier_damped_spring_joint_2d.cpp
+++ b/src/joints/rapier_damped_spring_joint_2d.cpp
@@ -1,4 +1,5 @@
#include "rapier_damped_spring_joint_2d.h"
+#include "../spaces/rapier_space_2d.h"
void RapierDampedSpringJoint2D::set_param(PhysicsServer2D::DampedSpringParam p_param, real_t p_value) {
switch (p_param) {
@@ -12,6 +13,7 @@ void RapierDampedSpringJoint2D::set_param(PhysicsServer2D::DampedSpringParam p_p
stiffness = p_value;
} break;
}
+ rapier2d::joint_change_sprint_params(space_handle, handle, rest_length, damping, stiffness);
}
real_t RapierDampedSpringJoint2D::get_param(PhysicsServer2D::DampedSpringParam p_param) const {
@@ -37,10 +39,14 @@ RapierDampedSpringJoint2D::RapierDampedSpringJoint2D(const Vector2 &p_anchor_a,
rest_length = p_anchor_a.distance_to(p_anchor_b);
- // TODO: create rapier joint when available
- // See https://github.com/dimforge/rapier/issues/241
- ERR_FAIL_MSG("Spring joints not supported for now");
+ rapier2d::Vector rapier_anchor_A = { anchor_A.x, anchor_A.y };
+ rapier2d::Vector rapier_anchor_B = { anchor_B.x, anchor_B.y };
- //A->add_constraint(this, 0);
- //B->add_constraint(this, 1);
+ ERR_FAIL_COND(!p_body_a->get_space());
+ ERR_FAIL_COND(p_body_a->get_space() != p_body_b->get_space());
+ space_handle = p_body_a->get_space()->get_handle();
+ ERR_FAIL_COND(!rapier2d::is_handle_valid(space_handle));
+
+ handle = rapier2d::joint_create_spring(space_handle, p_body_a->get_body_handle(), p_body_b->get_body_handle(), &rapier_anchor_A, &rapier_anchor_B, stiffness, damping, rest_length, is_disabled_collisions_between_bodies());
+ ERR_FAIL_COND(!rapier2d::is_handle_valid(handle));
}
diff --git a/src/joints/rapier_groove_joint_2d.cpp b/src/joints/rapier_groove_joint_2d.cpp
index a8520b7c..daa9d682 100644
--- a/src/joints/rapier_groove_joint_2d.cpp
+++ b/src/joints/rapier_groove_joint_2d.cpp
@@ -22,7 +22,7 @@ RapierGrooveJoint2D::RapierGrooveJoint2D(const Vector2 &p_a_groove1, const Vecto
space_handle = p_body_a->get_space()->get_handle();
ERR_FAIL_COND(!rapier2d::is_handle_valid(space_handle));
- handle = rapier2d::joint_create_prismatic(space_handle, p_body_a->get_body_handle(), p_body_b->get_body_handle(), &rapier_axis, &rapier_anchor_A, &rapier_anchor_B, &rapier_limits);
+ handle = rapier2d::joint_create_prismatic(space_handle, p_body_a->get_body_handle(), p_body_b->get_body_handle(), &rapier_axis, &rapier_anchor_A, &rapier_anchor_B, &rapier_limits, is_disabled_collisions_between_bodies());
ERR_FAIL_COND(!rapier2d::is_handle_valid(handle));
//A->add_constraint(this, 0);
diff --git a/src/joints/rapier_joint_2d.cpp b/src/joints/rapier_joint_2d.cpp
index 696a7dab..e0e5f53d 100644
--- a/src/joints/rapier_joint_2d.cpp
+++ b/src/joints/rapier_joint_2d.cpp
@@ -14,6 +14,14 @@ void RapierJoint2D::copy_settings_from(RapierJoint2D *p_joint) {
disable_collisions_between_bodies(p_joint->is_disabled_collisions_between_bodies());
}
+void RapierJoint2D::disable_collisions_between_bodies(const bool p_disabled) {
+ disabled_collisions_between_bodies = p_disabled;
+ if (rapier2d::is_handle_valid(handle)) {
+ // Joint not yet created, when it will be created it will have disable collision flag set
+ rapier2d::joint_change_disable_collision(space_handle, handle, is_disabled_collisions_between_bodies());
+ }
+}
+
RapierJoint2D::~RapierJoint2D() {
if (rapier2d::is_handle_valid(handle)) {
ERR_FAIL_COND(!rapier2d::is_handle_valid(space_handle));
diff --git a/src/joints/rapier_joint_2d.h b/src/joints/rapier_joint_2d.h
index d3b62c2e..b37db0a9 100644
--- a/src/joints/rapier_joint_2d.h
+++ b/src/joints/rapier_joint_2d.h
@@ -24,7 +24,7 @@ class RapierJoint2D {
_FORCE_INLINE_ void set_rid(const RID &p_rid) { rid = p_rid; }
_FORCE_INLINE_ RID get_rid() const { return rid; }
- _FORCE_INLINE_ void disable_collisions_between_bodies(const bool p_disabled) { disabled_collisions_between_bodies = p_disabled; }
+ void disable_collisions_between_bodies(const bool p_disabled);
_FORCE_INLINE_ bool is_disabled_collisions_between_bodies() const { return disabled_collisions_between_bodies; }
_FORCE_INLINE_ void set_max_force(real_t p_force) { max_force = p_force; }
diff --git a/src/joints/rapier_pin_joint_2d.cpp b/src/joints/rapier_pin_joint_2d.cpp
index e5eaca6a..b8d7c527 100644
--- a/src/joints/rapier_pin_joint_2d.cpp
+++ b/src/joints/rapier_pin_joint_2d.cpp
@@ -79,6 +79,6 @@ RapierPinJoint2D::RapierPinJoint2D(const Vector2 &p_pos, RapierBody2D *p_body_a,
ERR_FAIL_COND(p_body_a->get_space() != p_body_b->get_space());
space_handle = p_body_a->get_space()->get_handle();
ERR_FAIL_COND(!rapier2d::is_handle_valid(space_handle));
- handle = rapier2d::joint_create_revolute(space_handle, p_body_a->get_body_handle(), p_body_b->get_body_handle(), &rapier_anchor_A, &rapier_anchor_B, angular_limit_lower, angular_limit_upper, angular_limit_enabled, motor_target_velocity, motor_enabled);
+ handle = rapier2d::joint_create_revolute(space_handle, p_body_a->get_body_handle(), p_body_b->get_body_handle(), &rapier_anchor_A, &rapier_anchor_B, angular_limit_lower, angular_limit_upper, angular_limit_enabled, motor_target_velocity, motor_enabled, is_disabled_collisions_between_bodies());
ERR_FAIL_COND(!rapier2d::is_handle_valid(handle));
}
diff --git a/src/rapier2d-wrapper/Cargo.toml b/src/rapier2d-wrapper/Cargo.toml
index 4f594b74..0caf1980 100644
--- a/src/rapier2d-wrapper/Cargo.toml
+++ b/src/rapier2d-wrapper/Cargo.toml
@@ -23,8 +23,8 @@ parallel = ["rapier2d/parallel", "rapier2d-f64/parallel"]
# rapier2d = { features = [ "simd-stable"] }
# This changes the parry contacts to work even in some weird cases where in main branch it would return None
-rapier2d = {git = "https://github.com/appsinacup/rapier", branch = "possible-fix-for-contacts"}
-rapier2d-f64 = {git = "https://github.com/appsinacup/rapier", branch = "possible-fix-for-contacts"}
+rapier2d = {git = "https://github.com/appsinacup/rapier", branch = "master"}
+rapier2d-f64 = {git = "https://github.com/appsinacup/rapier", branch = "master"}
lazy_static = "1.4.0"
[profile.release]
diff --git a/src/rapier2d-wrapper/includes/rapier2d_wrapper.h b/src/rapier2d-wrapper/includes/rapier2d_wrapper.h
index 41e27b67..301c4f3f 100644
--- a/src/rapier2d-wrapper/includes/rapier2d_wrapper.h
+++ b/src/rapier2d-wrapper/includes/rapier2d_wrapper.h
@@ -66,7 +66,7 @@ struct Material {
struct ShapeInfo {
Handle handle;
- Vector position;
+ Vector pixel_position;
Real rotation;
Vector scale;
};
@@ -97,7 +97,7 @@ using QueryHandleExcludedCallback = bool (*)(Handle world_handle,
const QueryExcludedInfo *handle_excluded_info);
struct RayHitInfo {
- Vector position;
+ Vector pixel_position;
Vector normal;
Handle collider;
UserData user_data;
@@ -106,8 +106,8 @@ struct RayHitInfo {
struct ShapeCastResult {
bool collided;
Real toi;
- Vector witness1;
- Vector witness2;
+ Vector pixel_witness1;
+ Vector pixel_witness2;
Vector normal1;
Vector normal2;
Handle collider;
@@ -117,9 +117,9 @@ struct ShapeCastResult {
struct ContactResult {
bool collided;
bool within_margin;
- Real distance;
- Vector point1;
- Vector point2;
+ Real pixel_distance;
+ Vector pixel_point1;
+ Vector pixel_point2;
Vector normal1;
Vector normal2;
};
@@ -161,14 +161,14 @@ using ContactForceEventCallback = bool (*)(Handle world_handle,
const ContactForceEventInfo *event_info);
struct ContactPointInfo {
- Vector local_pos_1;
- Vector local_pos_2;
- Vector velocity_pos_1;
- Vector velocity_pos_2;
+ Vector pixel_local_pos_1;
+ Vector pixel_local_pos_2;
+ Vector pixel_velocity_pos_1;
+ Vector pixel_velocity_pos_2;
Vector normal;
- Real distance;
- Real impulse;
- Real tangent_impulse;
+ Real pixel_distance;
+ Real pixel_impulse;
+ Real pixel_tangent_impulse;
};
using ContactPointCallback = bool (*)(Handle world_handle,
@@ -178,8 +178,8 @@ using ContactPointCallback = bool (*)(Handle world_handle,
struct OneWayDirection {
bool body1;
bool body2;
- Real body1_margin;
- Real body2_margin;
+ Real pixel_body1_margin;
+ Real pixel_body2_margin;
Real last_timestep;
};
@@ -189,17 +189,6 @@ using CollisionModifyContactsCallback = OneWayDirection (*)(Handle world_handle,
struct SimulationSettings {
/// The timestep length (default: `1.0 / 60.0`)
Real dt;
- /// Minimum timestep size when using CCD with multiple substeps (default `1.0 / 60.0 / 100.0`)
- ///
- /// When CCD with multiple substeps is enabled, the timestep is subdivided
- /// into smaller pieces. This timestep subdivision won't generate timestep
- /// lengths smaller than `min_ccd_dt`.
- ///
- /// Setting this to a large value will reduce the opportunity to performing
- /// CCD substepping, resulting in potentially more time dropped by the
- /// motion-clamping mechanism. Setting this to an very small value may lead
- /// to numerical instabilities.
- Real min_ccd_dt;
/// 0-1: multiplier for how much of the constraint violation (e.g. contact penetration)
/// will be compensated for during the velocity solve.
/// (default `0.8`).
@@ -218,52 +207,43 @@ struct SimulationSettings {
Real joint_damping_ratio;
/// Amount of penetration the engine wont attempt to correct (default: `0.001m`).
Real allowed_linear_error;
- /// Maximum amount of penetration the solver will attempt to resolve in one timestep.
- Real max_penetration_correction;
/// The maximal distance separating two objects that will generate predictive contacts (default: `0.002`).
Real prediction_distance;
- /// Maximum number of iterations performed to solve non-penetration and joint constraints (default: `4`).
- size_t max_velocity_iterations;
- /// Maximum number of iterations performed to solve friction constraints (default: `8`).
- size_t max_velocity_friction_iterations;
- /// Maximum number of iterations performed to remove the energy introduced by penetration corrections (default: `1`).
- size_t max_stabilization_iterations;
- /// If `false`, friction and non-penetration constraints will be solved in the same loop. Otherwise,
- /// non-penetration constraints are solved first, and friction constraints are solved after (default: `true`).
- bool interleave_restitution_and_friction_resolution;
- /// Minimum number of dynamic bodies in each active island (default: `128`).
- size_t min_island_size;
- /// Maximum number of substeps performed by the solver (default: `1`).
- size_t max_ccd_substeps;
- Vector gravity;
+ /// The number of solver iterations run by the constraints solver for calculating forces (default: `4`).
+ size_t num_solver_iterations;
+ /// Number of addition friction resolution iteration run during the last solver sub-step (default: `4`).
+ size_t num_additional_friction_iterations;
+ /// Number of internal Project Gauss Seidel (PGS) iterations run at each solver iteration (default: `1`).
+ size_t num_internal_pgs_iterations;
+ Vector pixel_gravity;
};
extern "C" {
bool are_handles_equal(Handle handle1, Handle handle2);
-void body_add_force(Handle world_handle, Handle body_handle, const Vector *force);
+void body_add_force(Handle world_handle, Handle body_handle, const Vector *pixel_force);
void body_add_force_at_point(Handle world_handle,
Handle body_handle,
- const Vector *force,
- const Vector *point);
+ const Vector *pixel_force,
+ const Vector *pixel_point);
void body_add_torque(Handle world_handle, Handle body_handle, Real torque);
-void body_apply_impulse(Handle world_handle, Handle body_handle, const Vector *impulse);
+void body_apply_impulse(Handle world_handle, Handle body_handle, const Vector *pixel_impulse);
void body_apply_impulse_at_point(Handle world_handle,
Handle body_handle,
- const Vector *impulse,
- const Vector *point);
+ const Vector *pixel_impulse,
+ const Vector *pixel_point);
void body_apply_torque_impulse(Handle world_handle, Handle body_handle, Real torque_impulse);
void body_change_mode(Handle world_handle, Handle body_handle, BodyType body_type, bool wakeup);
Handle body_create(Handle world_handle,
- const Vector *pos,
+ const Vector *pixel_pos,
Real rot,
const UserData *user_data,
BodyType body_type);
@@ -305,19 +285,19 @@ void body_set_gravity_scale(Handle world_handle,
void body_set_linear_damping(Handle world_handle, Handle body_handle, Real linear_damping);
-void body_set_linear_velocity(Handle world_handle, Handle body_handle, const Vector *vel);
+void body_set_linear_velocity(Handle world_handle, Handle body_handle, const Vector *pixel_vel);
void body_set_mass_properties(Handle world_handle,
Handle body_handle,
Real mass,
- Real inertia,
- const Vector *local_com,
+ Real pixel_inertia,
+ const Vector *pixel_local_com,
bool wake_up,
bool force_update);
void body_set_transform(Handle world_handle,
Handle body_handle,
- const Vector *pos,
+ const Vector *pixel_pos,
Real rot,
bool wake_up);
@@ -355,8 +335,8 @@ QueryExcludedInfo default_query_excluded_info();
WorldSettings default_world_settings();
size_t intersect_aabb(Handle world_handle,
- const Vector *aabb_min,
- const Vector *aabb_max,
+ const Vector *pixel_aabb_min,
+ const Vector *pixel_aabb_max,
bool collide_with_body,
bool collide_with_area,
PointHitInfo *hit_info_array,
@@ -365,7 +345,7 @@ size_t intersect_aabb(Handle world_handle,
const QueryExcludedInfo *handle_excluded_info);
size_t intersect_point(Handle world_handle,
- const Vector *position,
+ const Vector *pixel_position,
bool collide_with_body,
bool collide_with_area,
PointHitInfo *hit_info_array,
@@ -374,9 +354,9 @@ size_t intersect_point(Handle world_handle,
const QueryExcludedInfo *handle_excluded_info);
bool intersect_ray(Handle world_handle,
- const Vector *from,
+ const Vector *pixel_from,
const Vector *dir,
- Real length,
+ Real pixel_length,
bool collide_with_body,
bool collide_with_area,
bool hit_from_inside,
@@ -401,66 +381,88 @@ bool is_handle_valid(Handle handle);
bool is_user_data_valid(UserData user_data);
+void joint_change_disable_collision(Handle world_handle,
+ Handle joint_handle,
+ bool disable_collision);
+
void joint_change_revolute_params(Handle world_handle,
Handle joint_handle,
Real angular_limit_lower,
Real angular_limit_upper,
bool angular_limit_enabled,
- Real motor_target_velocity,
+ Real pixel_motor_target_velocity,
bool motor_enabled);
+void joint_change_sprint_params(Handle world_handle,
+ Handle joint_handle,
+ Real stiffness,
+ Real damping,
+ Real pixel_rest_length);
+
Handle joint_create_prismatic(Handle world_handle,
Handle body_handle_1,
Handle body_handle_2,
const Vector *axis,
- const Vector *anchor_1,
- const Vector *anchor_2,
- const Vector *limits);
+ const Vector *pixel_anchor_1,
+ const Vector *pixel_anchor_2,
+ const Vector *pixel_limits,
+ bool disable_collision);
Handle joint_create_revolute(Handle world_handle,
Handle body_handle_1,
Handle body_handle_2,
- const Vector *anchor_1,
- const Vector *anchor_2,
+ const Vector *pixel_anchor_1,
+ const Vector *pixel_anchor_2,
Real angular_limit_lower,
Real angular_limit_upper,
bool angular_limit_enabled,
- Real motor_target_velocity,
- bool motor_enabled);
+ Real pixel_motor_target_velocity,
+ bool motor_enabled,
+ bool disable_collision);
+
+Handle joint_create_spring(Handle world_handle,
+ Handle body_handle_1,
+ Handle body_handle_2,
+ const Vector *pixel_anchor_1,
+ const Vector *pixel_anchor_2,
+ Real stiffness,
+ Real damping,
+ Real pixel_rest_length,
+ bool disable_collision);
void joint_destroy(Handle world_handle, Handle joint_handle);
ShapeCastResult shape_casting(Handle world_handle,
- const Vector *motion,
+ const Vector *pixel_motion,
ShapeInfo shape_info,
bool collide_with_body,
bool collide_with_area,
QueryHandleExcludedCallback handle_excluded_callback,
const QueryExcludedInfo *handle_excluded_info);
-ShapeCastResult shape_collide(const Vector *motion1,
+ShapeCastResult shape_collide(const Vector *pixel_motion1,
ShapeInfo shape_info1,
- const Vector *motion2,
+ const Vector *pixel_motion2,
ShapeInfo shape_info2);
-Handle shape_create_box(const Vector *size);
+Handle shape_create_box(const Vector *pixel_size);
-Handle shape_create_capsule(Real half_height, Real radius);
+Handle shape_create_capsule(Real pixel_half_height, Real pixel_radius);
-Handle shape_create_circle(Real radius);
+Handle shape_create_circle(Real pixel_radius);
-Handle shape_create_convave_polyline(const Vector *points, size_t point_count);
+Handle shape_create_convave_polyline(const Vector *pixel_points, size_t point_count);
-Handle shape_create_convex_polyline(const Vector *points, size_t point_count);
+Handle shape_create_convex_polyline(const Vector *pixel_points, size_t point_count);
-Handle shape_create_halfspace(const Vector *normal);
+Handle shape_create_halfspace(const Vector *normal, Real pixel_distance);
void shape_destroy(Handle shape_handle);
ContactResult shapes_contact(Handle world_handle,
ShapeInfo shape_info1,
ShapeInfo shape_info2,
- Real margin);
+ Real pixel_margin);
Handle world_create(const WorldSettings *settings);
diff --git a/src/rapier2d-wrapper/src/body.rs b/src/rapier2d-wrapper/src/body.rs
index 2d1fa6d3..47c88652 100644
--- a/src/rapier2d-wrapper/src/body.rs
+++ b/src/rapier2d-wrapper/src/body.rs
@@ -1,4 +1,5 @@
use rapier2d::prelude::*;
+use crate::convert::*;
use crate::handle::*;
use crate::vector::Vector;
use crate::user_data::UserData;
@@ -12,7 +13,9 @@ pub enum BodyType {
Static,
}
-fn set_rigid_body_properties_internal(rigid_body : &mut RigidBody, pos : &Vector, rot : Real, wake_up : bool) {
+fn set_rigid_body_properties_internal(rigid_body : &mut RigidBody, pixel_pos : &Vector, rot : Real, wake_up : bool) {
+ let pos = &vector_pixels_to_meters(pixel_pos);
+
if !rigid_body.is_kinematic() {
rigid_body.set_position(Isometry::new(vector![pos.x, pos.y], rot), wake_up);
} else {
@@ -21,7 +24,7 @@ fn set_rigid_body_properties_internal(rigid_body : &mut RigidBody, pos : &Vector
}
#[no_mangle]
-pub extern "C" fn body_create(world_handle : Handle, pos : &Vector, rot : Real, user_data : &UserData, body_type: BodyType) -> Handle {
+pub extern "C" fn body_create(world_handle : Handle, pixel_pos : &Vector, rot : Real, user_data : &UserData, body_type: BodyType) -> Handle {
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
let mut rigid_body : RigidBody;
@@ -36,11 +39,12 @@ pub extern "C" fn body_create(world_handle : Handle, pos : &Vector, rot : Real,
rigid_body = RigidBodyBuilder::fixed().build();
}
}
- let activation = rigid_body.activation_mut();
- activation.time_until_sleep = physics_world.sleep_time_until_sleep;
- activation.linear_threshold = physics_world.sleep_linear_threshold;
- activation.angular_threshold = physics_world.sleep_angular_threshold;
- set_rigid_body_properties_internal(&mut rigid_body, pos, rot, true);
+ // let default values better
+ //let activation = rigid_body.activation_mut();
+ //activation.time_until_sleep = physics_world.sleep_time_until_sleep;
+ //activation.linear_threshold = physics_world.sleep_linear_threshold;
+ //activation.angular_threshold = physics_world.sleep_angular_threshold;
+ set_rigid_body_properties_internal(&mut rigid_body, pixel_pos, rot, true);
rigid_body.user_data = user_data.get_data();
let body_handle = physics_world.rigid_body_set.insert(rigid_body);
return rigid_body_handle_to_handle(body_handle);
@@ -82,7 +86,7 @@ pub extern "C" fn body_get_position(world_handle : Handle, body_handle : Handle)
let body = physics_world.rigid_body_set.get(rigid_body_handle);
assert!(body.is_some());
let body_vector = body.unwrap().translation();
- return Vector { x : body_vector.x, y : body_vector.y };
+ return vector_meters_to_pixels(&Vector { x : body_vector.x, y : body_vector.y });
}
#[no_mangle]
@@ -96,14 +100,14 @@ pub extern "C" fn body_get_angle(world_handle : Handle, body_handle : Handle) ->
}
#[no_mangle]
-pub extern "C" fn body_set_transform(world_handle : Handle, body_handle : Handle, pos : &Vector, rot : Real, wake_up : bool) {
+pub extern "C" fn body_set_transform(world_handle : Handle, body_handle : Handle, pixel_pos : &Vector, rot : Real, wake_up : bool) {
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_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());
let body = body.unwrap();
- set_rigid_body_properties_internal(body, pos, rot, wake_up);
+ set_rigid_body_properties_internal(body, pixel_pos, rot, wake_up);
}
#[no_mangle]
@@ -115,11 +119,13 @@ pub extern "C" fn body_get_linear_velocity(world_handle : Handle, body_handle :
assert!(body.is_some());
let body = body.unwrap();
let body_vel = body.linvel();
- return Vector { x : body_vel.x, y : body_vel.y };
+ return vector_meters_to_pixels(&Vector { x : body_vel.x, y : body_vel.y });
}
#[no_mangle]
-pub extern "C" fn body_set_linear_velocity(world_handle : Handle, body_handle : Handle, vel : &Vector) {
+pub extern "C" fn body_set_linear_velocity(world_handle : Handle, body_handle : Handle, pixel_vel : &Vector) {
+ let vel = &vector_pixels_to_meters(pixel_vel);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
let rigid_body_handle = handle_to_rigid_body_handle(body_handle);
@@ -138,7 +144,7 @@ pub extern "C" fn body_update_material(world_handle : Handle, body_handle : Hand
for collider in body.unwrap().colliders() {
if let Some(col) = physics_world.collider_set.get_mut(*collider) {
col.set_friction(mat.friction);
- col.set_restitution(mat.restitution)
+ col.set_restitution(mat.restitution);
}
}
}
@@ -239,7 +245,14 @@ pub extern "C" fn body_set_ccd_enabled(world_handle : Handle, body_handle : Hand
}
#[no_mangle]
-pub extern "C" fn body_set_mass_properties(world_handle : Handle, body_handle : Handle, mass : Real, inertia : Real, local_com : &Vector, wake_up : bool, force_update : bool) {
+pub extern "C" fn body_set_mass_properties(world_handle : Handle, body_handle : Handle, mass : Real, pixel_inertia : Real, pixel_local_com : &Vector, wake_up : bool, force_update : bool) {
+ let local_com = &vector_pixels_to_meters(pixel_local_com);
+ let inertia = pixels_to_meters(pixels_to_meters(pixel_inertia));
+ let mass = mass;
+ if inertia == 0.0 || mass == 0.0{
+ return
+ }
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
let rigid_body_handle = handle_to_rigid_body_handle(body_handle);
@@ -253,7 +266,9 @@ pub extern "C" fn body_set_mass_properties(world_handle : Handle, body_handle :
}
#[no_mangle]
-pub extern "C" fn body_add_force(world_handle : Handle, body_handle : Handle, force : &Vector) {
+pub extern "C" fn body_add_force(world_handle : Handle, body_handle : Handle, pixel_force : &Vector) {
+ let force = &vector_pixels_to_meters(pixel_force);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
let rigid_body_handle = handle_to_rigid_body_handle(body_handle);
@@ -263,7 +278,10 @@ pub extern "C" fn body_add_force(world_handle : Handle, body_handle : Handle, fo
}
#[no_mangle]
-pub extern "C" fn body_add_force_at_point(world_handle : Handle, body_handle : Handle, force : &Vector, point : &Vector) {
+pub extern "C" fn body_add_force_at_point(world_handle : Handle, body_handle : Handle, pixel_force : &Vector, pixel_point : &Vector) {
+ let force = &vector_pixels_to_meters(pixel_force);
+ let point = &vector_pixels_to_meters(pixel_point);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
let rigid_body_handle = handle_to_rigid_body_handle(body_handle);
@@ -276,7 +294,8 @@ pub extern "C" fn body_add_force_at_point(world_handle : Handle, body_handle : H
}
#[no_mangle]
-pub extern "C" fn body_add_torque(world_handle : Handle, body_handle : Handle, torque: Real) {
+pub extern "C" fn body_add_torque(world_handle : Handle, body_handle : Handle, pixel_torque: Real) {
+ let torque = pixels_to_meters(pixels_to_meters(pixel_torque));
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
let rigid_body_handle = handle_to_rigid_body_handle(body_handle);
@@ -286,7 +305,9 @@ pub extern "C" fn body_add_torque(world_handle : Handle, body_handle : Handle, t
}
#[no_mangle]
-pub extern "C" fn body_apply_impulse(world_handle : Handle, body_handle : Handle, impulse : &Vector) {
+pub extern "C" fn body_apply_impulse(world_handle : Handle, body_handle : Handle, pixel_impulse : &Vector) {
+ let impulse = &vector_pixels_to_meters(pixel_impulse);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
let rigid_body_handle = handle_to_rigid_body_handle(body_handle);
@@ -296,7 +317,10 @@ pub extern "C" fn body_apply_impulse(world_handle : Handle, body_handle : Handle
}
#[no_mangle]
-pub extern "C" fn body_apply_impulse_at_point(world_handle : Handle, body_handle : Handle, impulse : &Vector, point : &Vector) {
+pub extern "C" fn body_apply_impulse_at_point(world_handle : Handle, body_handle : Handle, pixel_impulse : &Vector, pixel_point : &Vector) {
+ let impulse = &vector_pixels_to_meters(pixel_impulse);
+ let point = &vector_pixels_to_meters(pixel_point);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
let rigid_body_handle = handle_to_rigid_body_handle(body_handle);
@@ -316,7 +340,7 @@ pub extern "C" fn body_get_constant_force(world_handle : Handle, body_handle : H
let body = physics_world.rigid_body_set.get_mut(rigid_body_handle);
assert!(body.is_some());
let constant_force = body.unwrap().user_force();
- return Vector { x : constant_force.x, y : constant_force.y };
+ return vector_meters_to_pixels(&Vector { x : constant_force.x, y : constant_force.y });
}
#[no_mangle]
@@ -326,11 +350,13 @@ pub extern "C" fn body_get_constant_torque(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().user_torque()
+ meters_to_pixels(meters_to_pixels(body.unwrap().user_torque()))
}
#[no_mangle]
-pub extern "C" fn body_apply_torque_impulse(world_handle : Handle, body_handle : Handle, torque_impulse : Real) {
+pub extern "C" fn body_apply_torque_impulse(world_handle : Handle, body_handle : Handle, pixel_torque_impulse : Real) {
+ let torque_impulse = pixels_to_meters(pixels_to_meters(pixel_torque_impulse));
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
let rigid_body_handle = handle_to_rigid_body_handle(body_handle);
diff --git a/src/rapier2d-wrapper/src/collider.rs b/src/rapier2d-wrapper/src/collider.rs
index 6504df29..2c910e7b 100644
--- a/src/rapier2d-wrapper/src/collider.rs
+++ b/src/rapier2d-wrapper/src/collider.rs
@@ -5,6 +5,7 @@ use crate::shape::ShapeInfo;
use crate::user_data::*;
use crate::vector::Vector;
use crate::physics_world::*;
+use crate::convert::*;
pub fn scale_shape(shape: &SharedShape, scale: &Vector) -> Option {
let shape_type = shape.shape_type();
@@ -112,7 +113,7 @@ pub extern "C" fn collider_get_position(world_handle : Handle, handle : Handle)
let collider = physics_world.collider_set.get(collider_handle);
assert!(collider.is_some());
let collider_vector = collider.unwrap().translation();
- return Vector { x : collider_vector.x, y : collider_vector.y };
+ return vector_meters_to_pixels(&Vector { x : collider_vector.x, y : collider_vector.y });
}
#[no_mangle]
@@ -127,14 +128,16 @@ pub extern "C" fn collider_get_angle(world_handle : Handle, handle : Handle) ->
#[no_mangle]
pub extern "C" fn collider_set_transform(world_handle : Handle, handle : Handle, shape_info: ShapeInfo) {
- {
+ {
+ let position = &vector_pixels_to_meters(&shape_info.pixel_position);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
let collider_handle = handle_to_collider_handle(handle);
let collider = physics_world.collider_set.get_mut(collider_handle);
assert!(collider.is_some());
let collider = collider.unwrap();
- collider.set_position_wrt_parent(Isometry::new(vector![shape_info.position.x, shape_info.position.y], shape_info.rotation));
+ collider.set_position_wrt_parent(Isometry::new(vector![position.x, position.y], shape_info.rotation));
}
{
let new_shape:SharedShape;
@@ -144,6 +147,7 @@ pub extern "C" fn collider_set_transform(world_handle : Handle, handle : Handle,
if let Some(extracted_shape) = scale_shape(shape, &shape_info.scale) {
new_shape = extracted_shape;
} else {
+ //assert!(false);
// investigate why it failed
return;
}
diff --git a/src/rapier2d-wrapper/src/convert.rs b/src/rapier2d-wrapper/src/convert.rs
new file mode 100644
index 00000000..8f85ee40
--- /dev/null
+++ b/src/rapier2d-wrapper/src/convert.rs
@@ -0,0 +1,20 @@
+use rapier2d::prelude::*;
+use crate::vector::Vector;
+
+const PIXELS_PER_METER : Real = 100.0;
+
+pub fn pixels_to_meters(x : Real) -> Real {
+ if x == 0.0 { 0.0 } else { x / PIXELS_PER_METER }
+}
+
+pub fn vector_pixels_to_meters(v : &Vector) -> Vector {
+ Vector{x: pixels_to_meters(v.x), y: pixels_to_meters(v.y)}
+}
+
+pub fn meters_to_pixels(x : Real) -> Real {
+ x * PIXELS_PER_METER
+}
+
+pub fn vector_meters_to_pixels(v : &Vector) -> Vector {
+ Vector{x: meters_to_pixels(v.x), y: meters_to_pixels(v.y)}
+}
diff --git a/src/rapier2d-wrapper/src/joint.rs b/src/rapier2d-wrapper/src/joint.rs
index 15714352..dbd34c31 100644
--- a/src/rapier2d-wrapper/src/joint.rs
+++ b/src/rapier2d-wrapper/src/joint.rs
@@ -1,17 +1,24 @@
use rapier2d::prelude::*;
+use crate::convert::*;
use crate::handle::*;
use crate::physics_world::*;
use crate::vector::Vector;
#[no_mangle]
-pub extern "C" fn joint_create_revolute(world_handle : Handle, body_handle_1 : Handle, body_handle_2 : Handle, anchor_1 : &Vector, anchor_2 : &Vector, angular_limit_lower: Real, angular_limit_upper: Real, angular_limit_enabled: bool, motor_target_velocity: Real, motor_enabled: bool) -> Handle {
+pub extern "C" fn joint_create_revolute(world_handle : Handle, body_handle_1 : Handle, body_handle_2 : Handle, pixel_anchor_1 : &Vector, pixel_anchor_2 : &Vector, angular_limit_lower: Real, angular_limit_upper: Real, angular_limit_enabled: bool, pixel_motor_target_velocity: Real, motor_enabled: bool, disable_collision: bool) -> Handle {
+ let anchor_1 = &vector_pixels_to_meters(pixel_anchor_1);
+ let anchor_2 = &vector_pixels_to_meters(pixel_anchor_2);
+
+ let motor_target_velocity = pixels_to_meters(pixel_motor_target_velocity);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
let mut joint = RevoluteJointBuilder::new()
.local_anchor1(point!(anchor_1.x, anchor_1.y))
.local_anchor2(point!(anchor_2.x, anchor_2.y))
- .motor_model(MotorModel::AccelerationBased);
+ .motor_model(MotorModel::AccelerationBased)
+ .contacts_enabled(!disable_collision);
if angular_limit_enabled {
joint = joint.limits([angular_limit_lower, angular_limit_upper]);
}
@@ -24,7 +31,9 @@ pub extern "C" fn joint_create_revolute(world_handle : Handle, body_handle_1 : H
#[no_mangle]
-pub extern "C" fn joint_change_revolute_params(world_handle : Handle, joint_handle: Handle , angular_limit_lower: Real, angular_limit_upper: Real, angular_limit_enabled: bool, motor_target_velocity: Real, motor_enabled: bool){
+pub extern "C" fn joint_change_revolute_params(world_handle : Handle, joint_handle: Handle , angular_limit_lower: Real, angular_limit_upper: Real, angular_limit_enabled: bool, pixel_motor_target_velocity: Real, motor_enabled: bool){
+ let motor_target_velocity = pixels_to_meters(pixel_motor_target_velocity);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
@@ -42,18 +51,53 @@ pub extern "C" fn joint_change_revolute_params(world_handle : Handle, joint_hand
}
#[no_mangle]
-pub extern "C" fn joint_create_prismatic(world_handle : Handle, body_handle_1 : Handle, body_handle_2 : Handle, axis : &Vector, anchor_1 : &Vector, anchor_2 : &Vector, limits : &Vector) -> Handle {
+pub extern "C" fn joint_create_prismatic(world_handle : Handle, body_handle_1 : Handle, body_handle_2 : Handle, axis : &Vector, pixel_anchor_1 : &Vector, pixel_anchor_2 : &Vector, pixel_limits : &Vector, disable_collision: bool) -> Handle {
+ let anchor_1 = &vector_pixels_to_meters(pixel_anchor_1);
+ let anchor_2 = &vector_pixels_to_meters(pixel_anchor_2);
+ let limits = &vector_pixels_to_meters(pixel_limits);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
let joint = PrismaticJointBuilder::new(UnitVector::new_normalize(vector![axis.x, axis.y]))
.local_anchor1(point!(anchor_1.x, anchor_1.y))
.local_anchor2(point!(anchor_2.x, anchor_2.y))
- .limits([limits.x, limits.y]);
+ .limits([limits.x, limits.y])
+ .contacts_enabled(!disable_collision);
+
+ return physics_world.insert_joint(body_handle_1, body_handle_2, joint);
+}
+
+#[no_mangle]
+pub extern "C" fn joint_create_spring(world_handle : Handle, body_handle_1 : Handle, body_handle_2 : Handle, pixel_anchor_1 : &Vector, pixel_anchor_2 : &Vector, stiffness: Real, damping: Real, pixel_rest_length: Real, disable_collision: bool) -> Handle {
+ let anchor_1 = &vector_pixels_to_meters(pixel_anchor_1);
+ let anchor_2 = &vector_pixels_to_meters(pixel_anchor_2);
+ let rest_length = pixels_to_meters(pixel_rest_length);
+
+ let mut physics_engine = SINGLETON.lock().unwrap();
+ let physics_world = physics_engine.get_world(world_handle);
+
+ let joint = SpringJointBuilder::new(rest_length, stiffness, damping)
+ .local_anchor1(point!(anchor_1.x, anchor_1.y))
+ .local_anchor2(point!(anchor_2.x, anchor_2.y))
+ .contacts_enabled(!disable_collision);
return physics_world.insert_joint(body_handle_1, body_handle_2, joint);
}
+#[no_mangle]
+pub extern "C" fn joint_change_sprint_params(world_handle : Handle, joint_handle: Handle , stiffness: Real, damping: Real, pixel_rest_length: Real){
+ let rest_length = pixels_to_meters(pixel_rest_length);
+
+ let mut physics_engine = SINGLETON.lock().unwrap();
+ let physics_world = physics_engine.get_world(world_handle);
+
+ let joint = physics_world.impulse_joint_set.get_mut(handle_to_joint_handle(joint_handle));
+ assert!(joint.is_some());
+ let mut joint = joint.unwrap().data;
+ joint.set_motor_position(JointAxis::X, rest_length, stiffness, damping);
+}
+
#[no_mangle]
pub extern "C" fn joint_destroy(world_handle : Handle, joint_handle : Handle) {
let mut physics_engine = SINGLETON.lock().unwrap();
@@ -61,3 +105,13 @@ pub extern "C" fn joint_destroy(world_handle : Handle, joint_handle : Handle) {
return physics_world.remove_joint(joint_handle);
}
+
+#[no_mangle]
+pub extern "C" fn joint_change_disable_collision(world_handle : Handle, joint_handle: Handle , disable_collision: bool){
+ let mut physics_engine = SINGLETON.lock().unwrap();
+ let physics_world = physics_engine.get_world(world_handle);
+
+ let joint = physics_world.impulse_joint_set.get_mut(handle_to_joint_handle(joint_handle));
+ assert!(joint.is_some());
+ joint.unwrap().data.set_contacts_enabled(!disable_collision);
+}
\ No newline at end of file
diff --git a/src/rapier2d-wrapper/src/lib.rs b/src/rapier2d-wrapper/src/lib.rs
index 17c57f6e..9b99f19f 100644
--- a/src/rapier2d-wrapper/src/lib.rs
+++ b/src/rapier2d-wrapper/src/lib.rs
@@ -2,6 +2,7 @@
extern crate rapier2d_f64 as rapier2d;
mod body;
mod collider;
+mod convert;
mod handle;
mod joint;
mod physics_hooks;
diff --git a/src/rapier2d-wrapper/src/physics_hooks.rs b/src/rapier2d-wrapper/src/physics_hooks.rs
index 3cd0933b..4b352cb7 100644
--- a/src/rapier2d-wrapper/src/physics_hooks.rs
+++ b/src/rapier2d-wrapper/src/physics_hooks.rs
@@ -1,6 +1,5 @@
-use std::borrow::BorrowMut;
-
use rapier2d::prelude::*;
+use crate::convert::*;
use crate::handle::*;
use crate::user_data::*;
@@ -8,8 +7,8 @@ use crate::user_data::*;
pub struct OneWayDirection {
pub body1 : bool,
pub body2 : bool,
- pub body1_margin : Real,
- pub body2_margin : Real,
+ pub pixel_body1_margin : Real,
+ pub pixel_body2_margin : Real,
pub last_timestep: Real,
}
@@ -99,11 +98,13 @@ impl<'a> PhysicsHooks for PhysicsHooksCollisionFilter<'a> {
if one_way_direction.body1 {
let motion_len = body2.linvel().magnitude();
- let max_allowed = motion_len * Real::max(body2.linvel().normalize().dot(&allowed_local_n1), 0.0) + one_way_direction.body1_margin;
+ let body_margin1 = pixels_to_meters(one_way_direction.pixel_body1_margin);
+ let max_allowed = motion_len * Real::max(body2.linvel().normalize().dot(&allowed_local_n1), 0.0) + body_margin1;
contact_is_pass_through = body2.linvel().dot(&allowed_local_n1) <= DEFAULT_EPSILON * 10.0 || dist < -max_allowed;
} else if one_way_direction.body2 {
let motion_len = body1.linvel().magnitude();
- let max_allowed = motion_len * Real::max(body1.linvel().normalize().dot(&allowed_local_n2), 0.0) + one_way_direction.body2_margin;
+ let body_margin2 = pixels_to_meters(one_way_direction.pixel_body2_margin);
+ let max_allowed = motion_len * Real::max(body1.linvel().normalize().dot(&allowed_local_n2), 0.0) + body_margin2;
contact_is_pass_through = body1.linvel().dot(&allowed_local_n2) <= DEFAULT_EPSILON * 10.0 || dist < -max_allowed;
}
if contact_is_pass_through {
diff --git a/src/rapier2d-wrapper/src/physics_world.rs b/src/rapier2d-wrapper/src/physics_world.rs
index 3baabb24..75f45626 100644
--- a/src/rapier2d-wrapper/src/physics_world.rs
+++ b/src/rapier2d-wrapper/src/physics_world.rs
@@ -2,7 +2,11 @@ use rapier2d::crossbeam;
use rapier2d::data::Arena;
use rapier2d::prelude::*;
use std::sync::Mutex;
+use std::num::NonZeroUsize;
use lazy_static::lazy_static;
+use crate::convert::meters_to_pixels;
+use crate::convert::vector_meters_to_pixels;
+use crate::convert::vector_pixels_to_meters;
use crate::handle::*;
use crate::user_data::*;
use crate::settings::*;
@@ -27,27 +31,27 @@ impl ActiveBodyInfo {
#[repr(C)]
pub struct ContactPointInfo {
- local_pos_1: Vector,
- local_pos_2: Vector,
- velocity_pos_1: Vector,
- velocity_pos_2: Vector,
+ pixel_local_pos_1: Vector,
+ pixel_local_pos_2: Vector,
+ pixel_velocity_pos_1: Vector,
+ pixel_velocity_pos_2: Vector,
normal: Vector,
- distance: Real,
- impulse: Real,
- tangent_impulse: Real,
+ pixel_distance: Real,
+ pixel_impulse: Real,
+ pixel_tangent_impulse: Real,
}
impl ContactPointInfo {
fn new() -> ContactPointInfo {
ContactPointInfo {
- local_pos_1: Vector { x : 0.0, y : 0.0 },
- local_pos_2: Vector { x : 0.0, y : 0.0 },
- velocity_pos_1: Vector { x : 0.0, y : 0.0 },
- velocity_pos_2: Vector { x : 0.0, y : 0.0 },
+ pixel_local_pos_1: Vector { x : 0.0, y : 0.0 },
+ pixel_local_pos_2: Vector { x : 0.0, y : 0.0 },
+ pixel_velocity_pos_1: Vector { x : 0.0, y : 0.0 },
+ pixel_velocity_pos_2: Vector { x : 0.0, y : 0.0 },
normal: Vector { x : 0.0, y : 0.0 },
- distance: 0.0,
- impulse: 0.0,
- tangent_impulse: 0.0,
+ pixel_distance: 0.0,
+ pixel_impulse: 0.0,
+ pixel_tangent_impulse: 0.0,
}
}
}
@@ -107,7 +111,7 @@ pub struct PhysicsWorld {
pub query_pipeline: QueryPipeline,
pub physics_pipeline : PhysicsPipeline,
pub island_manager : IslandManager,
- pub broad_phase : BroadPhase,
+ pub broad_phase : BroadPhaseMultiSap,
pub narrow_phase : NarrowPhase,
pub impulse_joint_set : ImpulseJointSet,
pub multibody_joint_set : MultibodyJointSet,
@@ -140,7 +144,7 @@ impl PhysicsWorld {
query_pipeline : QueryPipeline::new(),
physics_pipeline : PhysicsPipeline::new(),
island_manager : IslandManager::new(),
- broad_phase : BroadPhase::new(),
+ broad_phase : DefaultBroadPhase::new(),
narrow_phase : NarrowPhase::new(),
impulse_joint_set : ImpulseJointSet::new(),
multibody_joint_set : MultibodyJointSet::new(),
@@ -172,22 +176,19 @@ impl PhysicsWorld {
let mut integration_parameters = IntegrationParameters::default();
integration_parameters.dt = settings.dt;
- integration_parameters.min_ccd_dt = settings.min_ccd_dt;
integration_parameters.erp = settings.erp;
integration_parameters.damping_ratio = settings.damping_ratio;
integration_parameters.joint_erp = settings.joint_erp;
integration_parameters.joint_damping_ratio = settings.joint_damping_ratio;
integration_parameters.allowed_linear_error = settings.allowed_linear_error;
- integration_parameters.max_penetration_correction = settings.max_penetration_correction;
integration_parameters.prediction_distance = settings.prediction_distance;
- integration_parameters.max_velocity_iterations = settings.max_velocity_iterations;
- integration_parameters.max_velocity_friction_iterations = settings.max_velocity_friction_iterations;
- integration_parameters.max_stabilization_iterations = settings.max_stabilization_iterations;
- integration_parameters.interleave_restitution_and_friction_resolution = settings.interleave_restitution_and_friction_resolution;
- integration_parameters.min_island_size = settings.min_island_size;
- integration_parameters.max_ccd_substeps = settings.max_ccd_substeps;
-
- let gravity = vector![settings.gravity.x, settings.gravity.y];
+ if settings.num_solver_iterations > 0 {
+ integration_parameters.num_solver_iterations = NonZeroUsize::new(settings.num_solver_iterations).unwrap();
+ }
+ integration_parameters.num_additional_friction_iterations = settings.num_additional_friction_iterations;
+ integration_parameters.num_internal_pgs_iterations = settings.num_internal_pgs_iterations;
+ let gravity_vector = vector_pixels_to_meters(&settings.pixel_gravity);
+ let gravity = vector![gravity_vector.x, gravity_vector.y];
let physics_hooks = PhysicsHooksCollisionFilter {
world_handle : self.handle,
@@ -304,19 +305,19 @@ impl PhysicsWorld {
let point_velocity_2 = body2.velocity_at_point(&collider_pos_2);
if swap {
- contact_info.local_pos_1 = Vector { x : collider_pos_2.x, y : collider_pos_2.y };
- contact_info.local_pos_2 = Vector { x : collider_pos_1.x, y : collider_pos_1.y };
- contact_info.velocity_pos_1 = Vector { x : point_velocity_2.x, y : point_velocity_2.y };
- contact_info.velocity_pos_2 = Vector { x : point_velocity_1.x, y : point_velocity_1.y };
+ contact_info.pixel_local_pos_1 = vector_meters_to_pixels(&Vector { x : collider_pos_2.x, y : collider_pos_2.y });
+ contact_info.pixel_local_pos_2 = vector_meters_to_pixels(&Vector { x : collider_pos_1.x, y : collider_pos_1.y });
+ contact_info.pixel_velocity_pos_1 = vector_meters_to_pixels(&Vector { x : point_velocity_2.x, y : point_velocity_2.y });
+ contact_info.pixel_velocity_pos_2 = vector_meters_to_pixels(&Vector { x : point_velocity_1.x, y : point_velocity_1.y });
} else {
- contact_info.local_pos_1 = Vector { x : collider_pos_1.x, y : collider_pos_1.y };
- contact_info.local_pos_2 = Vector { x : collider_pos_2.x, y : collider_pos_2.y };
- contact_info.velocity_pos_1 = Vector { x : point_velocity_1.x, y : point_velocity_1.y };
- contact_info.velocity_pos_2 = Vector { x : point_velocity_2.x, y : point_velocity_2.y };
+ contact_info.pixel_local_pos_1 = vector_meters_to_pixels(&Vector { x : collider_pos_1.x, y : collider_pos_1.y });
+ contact_info.pixel_local_pos_2 = vector_meters_to_pixels(&Vector { x : collider_pos_2.x, y : collider_pos_2.y });
+ contact_info.pixel_velocity_pos_1 = vector_meters_to_pixels(&Vector { x : point_velocity_1.x, y : point_velocity_1.y });
+ contact_info.pixel_velocity_pos_2 = vector_meters_to_pixels(&Vector { x : point_velocity_2.x, y : point_velocity_2.y });
}
- contact_info.distance = contact_point.dist;
- contact_info.impulse = contact_point.data.impulse;
- contact_info.tangent_impulse = contact_point.data.tangent_impulse;
+ contact_info.pixel_distance = meters_to_pixels(contact_point.dist);
+ contact_info.pixel_impulse = meters_to_pixels(contact_point.data.impulse);
+ contact_info.pixel_tangent_impulse = meters_to_pixels(contact_point.data.tangent_impulse);
send_contact_points = contact_callback(self.handle, &contact_info, &event_info);
if !send_contact_points {
@@ -540,4 +541,4 @@ pub extern "C" fn world_get_active_objects_count(world_handle : Handle) -> usize
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
return physics_world.island_manager.active_dynamic_bodies().len();
-}
+}
\ No newline at end of file
diff --git a/src/rapier2d-wrapper/src/query.rs b/src/rapier2d-wrapper/src/query.rs
index c0d1e54f..eab77afa 100644
--- a/src/rapier2d-wrapper/src/query.rs
+++ b/src/rapier2d-wrapper/src/query.rs
@@ -1,8 +1,12 @@
use rapier2d::parry;
use rapier2d::parry::query::NonlinearRigidMotion;
-use parry::query::{DefaultQueryDispatcher};
+use parry::query::DefaultQueryDispatcher;
use rapier2d::parry::query::QueryDispatcher;
use rapier2d::prelude::*;
+use crate::convert::meters_to_pixels;
+use crate::convert::pixels_to_meters;
+use crate::convert::vector_meters_to_pixels;
+use crate::convert::vector_pixels_to_meters;
use crate::handle::*;
use crate::user_data::*;
use crate::physics_world::*;
@@ -12,7 +16,7 @@ use crate::shape::*;
#[repr(C)]
pub struct RayHitInfo {
- position: Vector,
+ pixel_position: Vector,
normal: Vector,
collider: Handle,
user_data: UserData,
@@ -28,8 +32,8 @@ pub struct PointHitInfo {
pub struct ShapeCastResult {
collided: bool,
toi : Real,
- witness1 : Vector,
- witness2 : Vector,
+ pixel_witness1 : Vector,
+ pixel_witness2 : Vector,
normal1 : Vector,
normal2 : Vector,
collider: Handle,
@@ -42,8 +46,8 @@ impl ShapeCastResult {
collided : false,
toi : 1.0,
collider : invalid_handle(),
- witness1 : Vector{ x: 0.0, y: 0.0 },
- witness2 : Vector{ x: 0.0, y: 0.0 },
+ pixel_witness1 : Vector{ x: 0.0, y: 0.0 },
+ pixel_witness2 : Vector{ x: 0.0, y: 0.0 },
normal1 : Vector{ x: 0.0, y: 0.0 },
normal2 : Vector{ x: 0.0, y: 0.0 },
user_data: UserData { part1: 0, part2: 0 }
@@ -55,9 +59,9 @@ impl ShapeCastResult {
pub struct ContactResult {
collided: bool,
within_margin: bool,
- distance: Real,
- point1 : Vector,
- point2 : Vector,
+ pixel_distance: Real,
+ pixel_point1 : Vector,
+ pixel_point2 : Vector,
normal1 : Vector,
normal2 : Vector
}
@@ -67,9 +71,9 @@ impl ContactResult {
ContactResult {
collided : false,
within_margin: false,
- distance : 0.0,
- point1 : Vector{ x: 0.0, y: 0.0 },
- point2 : Vector{ x: 0.0, y: 0.0 },
+ pixel_distance : 0.0,
+ pixel_point1 : Vector{ x: 0.0, y: 0.0 },
+ pixel_point2 : Vector{ x: 0.0, y: 0.0 },
normal1 : Vector{ x: 0.0, y: 0.0 },
normal2 : Vector{ x: 0.0, y: 0.0 }
}
@@ -101,7 +105,10 @@ pub extern "C" fn default_query_excluded_info() -> QueryExcludedInfo {
type QueryHandleExcludedCallback = Option bool>;
#[no_mangle]
-pub extern "C" fn intersect_ray(world_handle : Handle, from : &Vector, dir : &Vector, length: Real, collide_with_body: bool, collide_with_area: bool, hit_from_inside: bool, hit_info : &mut RayHitInfo, handle_excluded_callback: QueryHandleExcludedCallback, handle_excluded_info: &QueryExcludedInfo) -> bool {
+pub extern "C" fn intersect_ray(world_handle : Handle, pixel_from : &Vector, dir : &Vector, pixel_length: Real, collide_with_body: bool, collide_with_area: bool, hit_from_inside: bool, hit_info : &mut RayHitInfo, handle_excluded_callback: QueryHandleExcludedCallback, handle_excluded_info: &QueryExcludedInfo) -> bool {
+ let from = vector_pixels_to_meters(&pixel_from);
+ let length = pixels_to_meters(pixel_length);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
@@ -135,10 +142,10 @@ pub extern "C" fn intersect_ray(world_handle : Handle, from : &Vector, dir : &Ve
let hit_point = ray.point_at(intersection.toi);
let hit_normal = intersection.normal;
- hit_info.position = Vector {
+ hit_info.pixel_position = vector_meters_to_pixels(&Vector {
x: hit_point.x,
y: hit_point.y,
- };
+ });
hit_info.normal = Vector {
x: hit_normal.x,
y: hit_normal.y,
@@ -155,10 +162,10 @@ pub extern "C" fn intersect_ray(world_handle : Handle, from : &Vector, dir : &Ve
}
#[no_mangle]
-pub extern "C" fn intersect_point(world_handle : Handle, position : &Vector, collide_with_body: bool, collide_with_area: bool, hit_info_array : *mut PointHitInfo, hit_info_length : usize, handle_excluded_callback: QueryHandleExcludedCallback, handle_excluded_info: &QueryExcludedInfo) -> usize {
+pub extern "C" fn intersect_point(world_handle : Handle, pixel_position : &Vector, collide_with_body: bool, collide_with_area: bool, hit_info_array : *mut PointHitInfo, hit_info_length : usize, handle_excluded_callback: QueryHandleExcludedCallback, handle_excluded_info: &QueryExcludedInfo) -> usize {
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
-
+ let position = vector_pixels_to_meters(&pixel_position);
let point = Point::new(position.x, position.y);
let mut filter = QueryFilter::new();
@@ -201,7 +208,12 @@ pub extern "C" fn intersect_point(world_handle : Handle, position : &Vector, co
}
#[no_mangle]
-pub extern "C" fn shape_collide(motion1 : &Vector, shape_info1: ShapeInfo, motion2 : &Vector, shape_info2: ShapeInfo) -> ShapeCastResult {
+pub extern "C" fn shape_collide(pixel_motion1 : &Vector, shape_info1: ShapeInfo, pixel_motion2 : &Vector, shape_info2: ShapeInfo) -> ShapeCastResult {
+ let motion1 = vector_pixels_to_meters(&pixel_motion1);
+ let motion2 = vector_pixels_to_meters(&pixel_motion2);
+ let position1 = vector_pixels_to_meters(&shape_info1.pixel_position);
+ let position2 = vector_pixels_to_meters(&shape_info2.pixel_position);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let mut shared_shape1 = physics_engine.get_shape(shape_info1.handle).clone();
@@ -215,8 +227,8 @@ pub extern "C" fn shape_collide(motion1 : &Vector, shape_info1: ShapeInfo, motio
let shape_vel1 = vector![motion1.x, motion1.y];
let shape_vel2 = vector![motion2.x, motion2.y];
- let shape_transform1 = Isometry::new(vector![shape_info1.position.x, shape_info1.position.y], shape_info1.rotation);
- let shape_transform2 = Isometry::new(vector![shape_info2.position.x, shape_info2.position.y], shape_info2.rotation);
+ let shape_transform1 = Isometry::new(vector![position1.x, position1.y], shape_info1.rotation);
+ let shape_transform2 = Isometry::new(vector![position2.x, position2.y], shape_info2.rotation);
let shape_nonlin1 = NonlinearRigidMotion::new(shape_transform1, Point::default(), shape_vel1, 0.0);
let shape_nonlin2 = NonlinearRigidMotion::new(shape_transform2, Point::default(), shape_vel2, 0.0);
let mut result = ShapeCastResult::new();
@@ -226,8 +238,8 @@ pub extern "C" fn shape_collide(motion1 : &Vector, shape_info1: ShapeInfo, motio
if let Some(hit) = toi_result.unwrap() {
result.collided = true;
result.toi = hit.toi;
- result.witness1 = Vector{ x: hit.witness1.x, y: hit.witness1.y };
- result.witness2 = Vector{ x: hit.witness2.x, y: hit.witness2.y };
+ result.pixel_witness1 = vector_meters_to_pixels(&Vector{ x: hit.witness1.x, y: hit.witness1.y });
+ result.pixel_witness2 = vector_meters_to_pixels(&Vector{ x: hit.witness2.x, y: hit.witness2.y });
result.normal1 = Vector{ x: hit.normal1.x, y: hit.normal1.y };
result.normal2 = Vector{ x: hit.normal2.x, y: hit.normal2.y };
return result;
@@ -236,7 +248,10 @@ pub extern "C" fn shape_collide(motion1 : &Vector, shape_info1: ShapeInfo, motio
}
#[no_mangle]
-pub extern "C" fn shape_casting(world_handle : Handle, motion : &Vector, shape_info: ShapeInfo, collide_with_body: bool, collide_with_area: bool, handle_excluded_callback: QueryHandleExcludedCallback, handle_excluded_info: &QueryExcludedInfo) -> ShapeCastResult {
+pub extern "C" fn shape_casting(world_handle : Handle, pixel_motion : &Vector, shape_info: ShapeInfo, collide_with_body: bool, collide_with_area: bool, handle_excluded_callback: QueryHandleExcludedCallback, handle_excluded_info: &QueryExcludedInfo) -> ShapeCastResult {
+ let motion = vector_pixels_to_meters(&pixel_motion);
+ let position = vector_pixels_to_meters(&shape_info.pixel_position);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let mut shared_shape = physics_engine.get_shape(shape_info.handle).clone();
@@ -247,7 +262,7 @@ pub extern "C" fn shape_casting(world_handle : Handle, motion : &Vector, shape_i
let physics_world = physics_engine.get_world(world_handle);
let shape_vel = vector![motion.x, motion.y];
- let shape_transform = Isometry::new(vector![shape_info.position.x, shape_info.position.y], shape_info.rotation);
+ let shape_transform = Isometry::new(vector![position.x, position.y], shape_info.rotation);
let mut filter = QueryFilter::new();
@@ -274,8 +289,8 @@ pub extern "C" fn shape_casting(world_handle : Handle, motion : &Vector, shape_i
) {
result.collided = true;
result.toi = hit.toi;
- result.witness1 = Vector{ x: hit.witness1.x, y: hit.witness1.y };
- result.witness2 = Vector{ x: hit.witness2.x, y: hit.witness2.y };
+ result.pixel_witness1 = vector_meters_to_pixels(&Vector{ x: hit.witness1.x, y: hit.witness1.y });
+ result.pixel_witness2 = vector_meters_to_pixels(&Vector{ x: hit.witness2.x, y: hit.witness2.y });
result.normal1 = Vector{ x: hit.normal1.x, y: hit.normal1.y };
result.normal2 = Vector{ x: hit.normal2.x, y: hit.normal2.y };
result.collider = collider_handle_to_handle(collider_handle);
@@ -287,6 +302,7 @@ pub extern "C" fn shape_casting(world_handle : Handle, motion : &Vector, shape_i
#[no_mangle]
pub extern "C" fn intersect_shape(world_handle : Handle, shape_info: ShapeInfo, collide_with_body: bool, collide_with_area: bool, hit_info_array : *mut PointHitInfo, hit_info_length : usize, handle_excluded_callback: QueryHandleExcludedCallback, handle_excluded_info: &QueryExcludedInfo) -> usize {
+ let position = vector_pixels_to_meters(&shape_info.pixel_position);
let mut physics_engine = SINGLETON.lock().unwrap();
let mut shared_shape = physics_engine.get_shape(shape_info.handle).clone();
@@ -295,7 +311,7 @@ pub extern "C" fn intersect_shape(world_handle : Handle, shape_info: ShapeInfo,
}
let physics_world = physics_engine.get_world(world_handle);
- let shape_transform = Isometry::new(vector![shape_info.position.x, shape_info.position.y], shape_info.rotation);
+ let shape_transform = Isometry::new(vector![position.x, position.y], shape_info.rotation);
let mut filter = QueryFilter::new();
@@ -340,7 +356,10 @@ pub extern "C" fn intersect_shape(world_handle : Handle, shape_info: ShapeInfo,
}
#[no_mangle]
-pub extern "C" fn intersect_aabb(world_handle : Handle, aabb_min : &Vector, aabb_max : &Vector, collide_with_body: bool, collide_with_area: bool, hit_info_array : *mut PointHitInfo, hit_info_length : usize, handle_excluded_callback: QueryHandleExcludedCallback, handle_excluded_info: &QueryExcludedInfo) -> usize {
+pub extern "C" fn intersect_aabb(world_handle : Handle, pixel_aabb_min : &Vector, pixel_aabb_max : &Vector, collide_with_body: bool, collide_with_area: bool, hit_info_array : *mut PointHitInfo, hit_info_length : usize, handle_excluded_callback: QueryHandleExcludedCallback, handle_excluded_info: &QueryExcludedInfo) -> usize {
+ let aabb_min = vector_pixels_to_meters(&pixel_aabb_min);
+ let aabb_max = vector_pixels_to_meters(&pixel_aabb_max);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
@@ -400,7 +419,11 @@ pub extern "C" fn intersect_aabb(world_handle : Handle, aabb_min : &Vector, aabb
}
#[no_mangle]
-pub extern "C" fn shapes_contact(world_handle : Handle, shape_info1 : ShapeInfo, shape_info2 : ShapeInfo, margin: Real) -> ContactResult {
+pub extern "C" fn shapes_contact(world_handle : Handle, shape_info1 : ShapeInfo, shape_info2 : ShapeInfo, pixel_margin: Real) -> ContactResult {
+ let position1 = vector_pixels_to_meters(&shape_info1.pixel_position);
+ let position2 = vector_pixels_to_meters(&shape_info2.pixel_position);
+ let margin = pixels_to_meters(pixel_margin);
+
let mut physics_engine = SINGLETON.lock().unwrap();
let physics_world = physics_engine.get_world(world_handle);
@@ -416,8 +439,8 @@ pub extern "C" fn shapes_contact(world_handle : Handle, shape_info1 : ShapeInfo,
shared_shape2 = new_shape;
}
- let shape_transform1 = Isometry::new(vector![shape_info1.position.x, shape_info1.position.y], shape_info1.rotation);
- let shape_transform2 = Isometry::new(vector![shape_info2.position.x, shape_info2.position.y], shape_info2.rotation);
+ let shape_transform1 = Isometry::new(vector![position1.x, position1.y], shape_info1.rotation);
+ let shape_transform2 = Isometry::new(vector![position2.x, position2.y], shape_info2.rotation);
let mut result = ContactResult::new();
if let Ok(Some(contact)) = parry::query::contact(
@@ -425,15 +448,15 @@ pub extern "C" fn shapes_contact(world_handle : Handle, shape_info1 : ShapeInfo,
) {
// the distance is negative if there is intersection
// and positive if the objects are separated by distance less than margin
- result.distance = contact.dist;
+ result.pixel_distance = meters_to_pixels(contact.dist);
if contact.dist <= 0.0 {
result.within_margin = false;
} else {
result.within_margin = true;
}
result.collided = true;
- result.point1 = Vector{ x: contact.point1.x + prediction * contact.normal1.x, y: contact.point1.y + prediction * contact.normal1.y };
- result.point2 = Vector{ x: contact.point2.x, y: contact.point2.y };
+ result.pixel_point1 = vector_meters_to_pixels(&Vector{ x: contact.point1.x + prediction * contact.normal1.x, y: contact.point1.y + prediction * contact.normal1.y });
+ result.pixel_point2 = vector_meters_to_pixels(&Vector{ x: contact.point2.x, y: contact.point2.y });
result.normal1 = Vector{ x: contact.normal1.x, y: contact.normal1.y };
result.normal2 = Vector{ x: contact.normal2.x, y: contact.normal2.y };
return result;
diff --git a/src/rapier2d-wrapper/src/settings.rs b/src/rapier2d-wrapper/src/settings.rs
index 57827826..1467d1c7 100644
--- a/src/rapier2d-wrapper/src/settings.rs
+++ b/src/rapier2d-wrapper/src/settings.rs
@@ -23,17 +23,6 @@ pub extern "C" fn default_world_settings() -> WorldSettings {
pub struct SimulationSettings {
/// The timestep length (default: `1.0 / 60.0`)
pub dt: Real,
- /// Minimum timestep size when using CCD with multiple substeps (default `1.0 / 60.0 / 100.0`)
- ///
- /// When CCD with multiple substeps is enabled, the timestep is subdivided
- /// into smaller pieces. This timestep subdivision won't generate timestep
- /// lengths smaller than `min_ccd_dt`.
- ///
- /// Setting this to a large value will reduce the opportunity to performing
- /// CCD substepping, resulting in potentially more time dropped by the
- /// motion-clamping mechanism. Setting this to an very small value may lead
- /// to numerical instabilities.
- pub min_ccd_dt: Real,
/// 0-1: multiplier for how much of the constraint violation (e.g. contact penetration)
/// will be compensated for during the velocity solve.
@@ -56,23 +45,13 @@ pub struct SimulationSettings {
/// Amount of penetration the engine wont attempt to correct (default: `0.001m`).
pub allowed_linear_error: Real,
- /// Maximum amount of penetration the solver will attempt to resolve in one timestep.
- pub max_penetration_correction: Real,
/// The maximal distance separating two objects that will generate predictive contacts (default: `0.002`).
pub prediction_distance: Real,
- /// Maximum number of iterations performed to solve non-penetration and joint constraints (default: `4`).
- pub max_velocity_iterations: usize,
- /// Maximum number of iterations performed to solve friction constraints (default: `8`).
- pub max_velocity_friction_iterations: usize,
- /// Maximum number of iterations performed to remove the energy introduced by penetration corrections (default: `1`).
- pub max_stabilization_iterations: usize,
- /// If `false`, friction and non-penetration constraints will be solved in the same loop. Otherwise,
- /// non-penetration constraints are solved first, and friction constraints are solved after (default: `true`).
- pub interleave_restitution_and_friction_resolution: bool,
- /// Minimum number of dynamic bodies in each active island (default: `128`).
- pub min_island_size: usize,
- /// Maximum number of substeps performed by the solver (default: `1`).
- pub max_ccd_substeps: usize,
-
- pub gravity : Vector,
+ /// The number of solver iterations run by the constraints solver for calculating forces (default: `4`).
+ pub num_solver_iterations: usize,
+ /// Number of addition friction resolution iteration run during the last solver sub-step (default: `4`).
+ pub num_additional_friction_iterations: usize,
+ /// Number of internal Project Gauss Seidel (PGS) iterations run at each solver iteration (default: `1`).
+ pub num_internal_pgs_iterations: usize,
+ pub pixel_gravity : Vector,
}
diff --git a/src/rapier2d-wrapper/src/shape.rs b/src/rapier2d-wrapper/src/shape.rs
index 4c5afbed..18ed36a7 100644
--- a/src/rapier2d-wrapper/src/shape.rs
+++ b/src/rapier2d-wrapper/src/shape.rs
@@ -1,13 +1,15 @@
use rapier2d::prelude::*;
+use crate::convert::*;
use crate::handle::*;
use crate::vector::Vector;
use crate::physics_world::*;
-pub fn point_array_to_vec(data : &Vector, data_count : usize) -> Vec::> {
+fn pixel_point_array_to_vec(pixel_data : &Vector, data_count : usize) -> Vec::> {
let mut vec = Vec::>::with_capacity(data_count);
unsafe {
- let data_raw = std::slice::from_raw_parts(data, data_count);
- for point in data_raw {
+ let data_raw = std::slice::from_raw_parts(pixel_data, data_count);
+ for pixel_point in data_raw {
+ let point = &vector_pixels_to_meters(pixel_point);
vec.push(Point:: { coords : vector![point.x, point.y] });
}
}
@@ -17,57 +19,69 @@ pub fn point_array_to_vec(data : &Vector, data_count : usize) -> Vec:: Handle {
+pub extern "C" fn shape_create_box(pixel_size : &Vector) -> Handle {
+ let size = &vector_pixels_to_meters(pixel_size);
let shape = SharedShape::cuboid(0.5 * size.x, 0.5 * size.y);
let mut physics_engine = SINGLETON.lock().unwrap();
return physics_engine.insert_shape(shape);
}
#[no_mangle]
-pub extern "C" fn shape_create_halfspace(normal : &Vector) -> Handle {
- let shape = SharedShape::halfspace(UnitVector::new_normalize(vector![normal.x, normal.y]));
+pub extern "C" fn shape_create_halfspace(normal : &Vector, pixel_distance: Real) -> Handle {
+ let distance = pixels_to_meters(pixel_distance);
+
+ let shape = SharedShape::halfspace(UnitVector::new_normalize(vector![normal.x, -normal.y]));
+ let shape_position = Isometry::new(vector![normal.x * distance, normal.y * distance], 0.0);
+ let mut shapes_vec = Vec::<(Isometry, SharedShape)>::new();
+ shapes_vec.push((shape_position, shape));
+ let shape_compound = SharedShape::compound(shapes_vec);
let mut physics_engine = SINGLETON.lock().unwrap();
- return physics_engine.insert_shape(shape);
+ return physics_engine.insert_shape(shape_compound);
}
#[no_mangle]
-pub extern "C" fn shape_create_circle(radius : Real) -> Handle {
+pub extern "C" fn shape_create_circle(pixel_radius : Real) -> Handle {
+ let radius = pixels_to_meters(pixel_radius);
let shape = SharedShape::ball(radius);
let mut physics_engine = SINGLETON.lock().unwrap();
return physics_engine.insert_shape(shape);
}
#[no_mangle]
-pub extern "C" fn shape_create_capsule(half_height : Real, radius : Real) -> Handle {
- let top_circle = SharedShape::ball(radius);
- let top_circle_position = Isometry::new(vector![0.0, -half_height], 0.0);
- let bottom_circle = SharedShape::ball(radius);
- let bottom_circle_position = Isometry::new(vector![0.0, half_height], 0.0);
- let square = SharedShape::cuboid(0.5 * radius, 0.5 * (half_height - radius));
- let square_pos = Isometry::new(vector![0.0, 0.0], 0.0);
- let mut shapes_vec = Vec::<(Isometry, SharedShape)>::new();
- shapes_vec.push((top_circle_position, top_circle));
- shapes_vec.push((bottom_circle_position, bottom_circle));
- shapes_vec.push((square_pos, square));
- let shape = SharedShape::compound(shapes_vec);
+pub extern "C" fn shape_create_capsule(pixel_half_height : Real, pixel_radius : Real) -> Handle {
+ let half_height = pixels_to_meters(pixel_half_height);
+ let radius = pixels_to_meters(pixel_radius);
+
+ //let top_circle = SharedShape::ball(radius);
+ //let top_circle_position = Isometry::new(vector![0.0, -half_height], 0.0);
+ //let bottom_circle = SharedShape::ball(radius);
+ //let bottom_circle_position = Isometry::new(vector![0.0, half_height], 0.0);
+ //let square = SharedShape::cuboid(0.5 * radius, 0.5 * (half_height - radius));
+ //let square_pos = Isometry::default();
+ //let mut shapes_vec = Vec::<(Isometry, SharedShape)>::new();
+ //shapes_vec.push((top_circle_position, top_circle));
+ //shapes_vec.push((bottom_circle_position, bottom_circle));
+ //shapes_vec.push((square_pos, square));
+ //let shape = SharedShape::compound(shapes_vec);
// For now create the shape using circles and squares as the default capsule is buggy
// in case of distance checking(returns invalid distances when close to the ends)
// overall results in a 1.33x decrease in performance
// TODO only do this in case of static objects?
- //let shape = SharedShape::capsule_y(half_height, radius);
+ let shape = SharedShape::capsule_y(half_height, radius);
let mut physics_engine = SINGLETON.lock().unwrap();
return physics_engine.insert_shape(shape);
}
#[no_mangle]
-pub extern "C" fn shape_create_convex_polyline(points : &Vector, point_count : usize) -> Handle {
- let points_vec = point_array_to_vec(points, point_count);
+pub extern "C" fn shape_create_convex_polyline(pixel_points : &Vector, point_count : usize) -> Handle {
+
+ let points_vec = pixel_point_array_to_vec(pixel_points, point_count);
let shape_data = SharedShape::convex_polyline(points_vec);
if shape_data.is_none() {
return Handle::default();
@@ -78,8 +92,8 @@ pub extern "C" fn shape_create_convex_polyline(points : &Vector, point_count : u
}
#[no_mangle]
-pub extern "C" fn shape_create_convave_polyline(points : &Vector, point_count : usize) -> Handle {
- let points_vec = point_array_to_vec(points, point_count);
+pub extern "C" fn shape_create_convave_polyline(pixel_points : &Vector, point_count : usize) -> Handle {
+ let points_vec = pixel_point_array_to_vec(pixel_points, point_count);
let shape = SharedShape::polyline(points_vec, None);
let mut physics_engine = SINGLETON.lock().unwrap();
return physics_engine.insert_shape(shape);
diff --git a/src/servers/rapier_body_utils_2d.cpp b/src/servers/rapier_body_utils_2d.cpp
index e231c541..faa8bd61 100644
--- a/src/servers/rapier_body_utils_2d.cpp
+++ b/src/servers/rapier_body_utils_2d.cpp
@@ -9,7 +9,7 @@
#define BODY_MOTION_RECOVER_RATIO 0.4
bool should_skip_collision_one_dir(rapier2d::ContactResult contact, RapierShape2D *body_shape, RapierBody2D *collision_body, int shape_index, const Transform2D &col_shape_transform, real_t p_margin, real_t last_step, Vector2 p_motion) {
- real_t dist = contact.distance;
+ real_t dist = contact.pixel_distance;
if (!contact.within_margin && body_shape->allows_one_way_collision() && collision_body->is_shape_set_as_one_way_collision(shape_index)) {
real_t valid_depth = 10e20;
Vector2 valid_dir = col_shape_transform.columns[1].normalized();
@@ -33,7 +33,7 @@ bool should_skip_collision_one_dir(rapier2d::ContactResult contact, RapierShape2
Vector2 motion = p_motion;
real_t motion_len = motion.length();
valid_depth += motion_len * MAX(motion.normalized().dot(valid_dir), 0.0);
- if ((dist < -valid_depth) || (p_motion.normalized().dot(valid_dir) < CMP_EPSILON * 10.0)) {
+ if ((dist < -valid_depth) || (p_motion.normalized().dot(valid_dir) < CMP_EPSILON)) {
return true;
}
}
@@ -98,8 +98,8 @@ bool RapierBodyUtils2D::body_motion_recover(
if (should_skip_collision_one_dir(contact, body_shape, collision_body, shape_index, col_shape_transform, p_margin, p_space.get_last_step(), p_motion)) {
continue;
}
- Vector2 a(contact.point1.x, contact.point1.y);
- Vector2 b(contact.point2.x, contact.point2.y);
+ Vector2 a(contact.pixel_point1.x, contact.pixel_point1.y);
+ Vector2 b(contact.pixel_point2.x, contact.pixel_point2.y);
recovered = true;
@@ -186,7 +186,7 @@ void RapierBodyUtils2D::cast_motion(const RapierSpace2D &p_space, RapierBody2D &
Transform2D const &col_shape_transform = collision_body->get_transform() * collision_body->get_shape_transform(shape_index);
rapier2d::ShapeInfo col_shape_info = rapier2d::shape_info_from_body_shape(col_shape->get_rapier_shape(), col_shape_transform);
// stuck logic, check if body collides in place
- body_shape_info.position = { (body_shape_transform.get_origin()).x, (body_shape_transform.get_origin()).y };
+ body_shape_info.pixel_position = { (body_shape_transform.get_origin()).x, (body_shape_transform.get_origin()).y };
rapier2d::ContactResult step_contact = rapier2d::shapes_contact(p_space.get_handle(), body_shape_info, col_shape_info, 0.0);
if (step_contact.collided && !step_contact.within_margin) {
if (body_shape->allows_one_way_collision() && collision_body->is_shape_set_as_one_way_collision(shape_index)) {
@@ -209,7 +209,7 @@ void RapierBodyUtils2D::cast_motion(const RapierSpace2D &p_space, RapierBody2D &
for (int k = 0; k < 8; k++) {
real_t fraction = low + (hi - low) * fraction_coeff;
- body_shape_info.position = rapier2d::Vector{ (body_shape_transform.get_origin() + p_motion * fraction).x,
+ body_shape_info.pixel_position = rapier2d::Vector{ (body_shape_transform.get_origin() + p_motion * fraction).x,
(body_shape_transform.get_origin() + p_motion * fraction).y };
rapier2d::ContactResult step_contact = rapier2d::shapes_contact(p_space.get_handle(), body_shape_info, col_shape_info, 0.0);
if (step_contact.collided && !step_contact.within_margin) {
@@ -236,7 +236,7 @@ void RapierBodyUtils2D::cast_motion(const RapierSpace2D &p_space, RapierBody2D &
}
}
}
- body_shape_info.position =
+ body_shape_info.pixel_position =
rapier2d::Vector{ (body_shape_transform.get_origin() + p_motion * (hi + contact_max_allowed_penetration)).x,
(body_shape_transform.get_origin() + p_motion * (hi + contact_max_allowed_penetration)).y };
rapier2d::ContactResult contact = rapier2d::shapes_contact(p_space.get_handle(), body_shape_info, col_shape_info, 0.0);
@@ -318,14 +318,14 @@ bool RapierBodyUtils2D::body_motion_collide(const RapierSpace2D &p_space, Rapier
continue;
}
- Vector2 a(contact.point1.x, contact.point1.y);
- Vector2 b(contact.point2.x, contact.point2.y);
+ Vector2 a(contact.pixel_point1.x, contact.pixel_point1.y);
+ Vector2 b(contact.pixel_point2.x, contact.pixel_point2.y);
if (should_skip_collision_one_dir(contact, body_shape, collision_body, shape_index, col_shape_transform, p_margin, p_space.get_last_step(), p_motion)) {
continue;
}
- if (contact.distance < min_distance) {
- min_distance = contact.distance;
+ if (contact.pixel_distance < min_distance) {
+ min_distance = contact.pixel_distance;
best_collision_body = collision_body;
best_collision_shape_index = shape_index;
best_body_shape_index = body_shape_idx;
@@ -344,11 +344,11 @@ bool RapierBodyUtils2D::body_motion_collide(const RapierSpace2D &p_space, Rapier
p_result->collider_shape = best_collision_shape_index;
p_result->collision_local_shape = best_body_shape_index;
// World position from the moving body to get the contact point
- p_result->collision_point = Vector2(best_contact.point1.x, best_contact.point1.y);
+ p_result->collision_point = Vector2(best_contact.pixel_point1.x, best_contact.pixel_point1.y);
// Normal from the collided object to get the contact normal
p_result->collision_normal = Vector2(best_contact.normal2.x, best_contact.normal2.y);
// compute distance without sign
- p_result->collision_depth = p_margin - best_contact.distance;
+ p_result->collision_depth = p_margin - best_contact.pixel_distance;
Vector2 local_position = p_result->collision_point - best_collision_body->get_transform().get_origin();
p_result->collider_velocity = best_collision_body->get_velocity_at_local_point(local_position);
diff --git a/src/servers/rapier_physics_server_2d.cpp b/src/servers/rapier_physics_server_2d.cpp
index d1bd5aaa..e7aedc51 100644
--- a/src/servers/rapier_physics_server_2d.cpp
+++ b/src/servers/rapier_physics_server_2d.cpp
@@ -148,8 +148,8 @@ bool RapierPhysicsServer2D::_shape_collide(const RID &p_shape_A, const Transform
}
(*p_result_count)++;
- results_out[array_idx++] = Vector2(result.witness1.x, result.witness1.y);
- results_out[array_idx++] = Vector2(result.witness2.x, result.witness2.y);
+ results_out[array_idx++] = Vector2(result.pixel_witness1.x, result.pixel_witness1.y);
+ results_out[array_idx++] = Vector2(result.pixel_witness2.x, result.pixel_witness2.y);
return array_idx > 0;
}
diff --git a/src/servers/rapier_project_settings.cpp b/src/servers/rapier_project_settings.cpp
index a99b1927..68acba9f 100644
--- a/src/servers/rapier_project_settings.cpp
+++ b/src/servers/rapier_project_settings.cpp
@@ -6,20 +6,15 @@ using namespace godot;
constexpr char RUN_ON_SEPARATE_THREAD[] = "physics/2d/run_on_separate_thread";
constexpr char MAX_THREADS[] = "threading/worker_pool/max_threads";
-constexpr char SOLVER_MIN_CCD_DT[] = "physics/rapier_2d/solver/min_ccd_dt";
constexpr char SOLVER_ERP[] = "physics/rapier_2d/solver/erp";
constexpr char SOLVER_DAMPING_RATIO[] = "physics/rapier_2d/solver/damping_ratio";
constexpr char SOLVER_JOINT_ERP[] = "physics/rapier_2d/solver/joint_erp";
constexpr char SOLVER_JOINT_DAMPING_RATIO[] = "physics/rapier_2d/solver/joint_damping_ratio";
constexpr char SOLVER_ALLOWED_LINEAR_ERROR[] = "physics/rapier_2d/solver/allowed_linear_error";
-constexpr char SOLVER_MAX_PENETRATION_CORRECTION[] = "physics/rapier_2d/solver/max_penetration_correction";
constexpr char SOLVER_PREDICTION_DISTANCE[] = "physics/rapier_2d/solver/prediction_distance";
-constexpr char SOLVER_MAX_VELOCITY_ITERATIONS[] = "physics/rapier_2d/solver/max_velocity_iterations";
-constexpr char SOLVER_MAX_VELOCITY_FRICTION_ITERATIONS[] = "physics/rapier_2d/solver/max_velocity_friction_iterations";
-constexpr char SOLVER_MAX_STABILIZATION_ITERATIONS[] = "physics/rapier_2d/solver/max_stabilization_iterations";
-constexpr char SOLVER_INTERLEAVE_RESTITUTION_AND_FRICTION_RESOLUTION[] = "physics/rapier_2d/solver/interleave_restitution_and_friction_resolution";
-constexpr char SOLVER_MIN_ISLAND_SIZE[] = "physics/rapier_2d/solver/min_island_size";
-constexpr char SOLVER_MAX_CCD_SUBSTEPS[] = "physics/rapier_2d/solver/max_ccd_substeps";
+constexpr char SOLVER_NUM_ITERATIONS[] = "physics/rapier_2d/solver/num_iterations";
+constexpr char SOLVER_NUM_ADDITIONAL_FRICTION_ITERATIONS[] = "physics/rapier_2d/solver/num_additional_friction_iterations";
+constexpr char SOLVER_NUM_INTERNAL_PGS_ITERATIONS[] = "physics/rapier_2d/solver/num_internal_pgs_iterations";
void register_setting(
const String &p_name,
@@ -76,20 +71,15 @@ void register_setting_ranged(
}
void RapierProjectSettings::register_settings() {
- register_setting_ranged(SOLVER_MIN_CCD_DT, 1.0 / 60.0 / 100.0, U"0.0000001,1,0.0000001,suffix:1/s");
- register_setting_ranged(SOLVER_ERP, 0.85, U"0.00001,1,0.00001,suffix:%");
- register_setting_ranged(SOLVER_DAMPING_RATIO, 0.35, U"0.00001,1,0.00001,suffix:%");
+ register_setting_ranged(SOLVER_ERP, 0.6, U"0.00001,1,0.00001,suffix:%");
+ register_setting_ranged(SOLVER_DAMPING_RATIO, 1.0, U"0.00001,1,0.00001,suffix:%");
register_setting_ranged(SOLVER_JOINT_ERP, 1.0, U"0.00001,1,0.00001,suffix:%");
- register_setting_ranged(SOLVER_JOINT_DAMPING_RATIO, 0.25, U"0.0001,1,0.00001,suffix:%");
+ register_setting_ranged(SOLVER_JOINT_DAMPING_RATIO, 1.0, U"0.0001,1,0.00001,suffix:%");
register_setting_ranged(SOLVER_ALLOWED_LINEAR_ERROR, 0.001, U"0,1,0.00001,suffix:m");
- register_setting_ranged(SOLVER_MAX_PENETRATION_CORRECTION, 3.40282e+38, U"0, 3.40282e+38f,1,suffix:m");
register_setting_ranged(SOLVER_PREDICTION_DISTANCE, 0.002, U"0,1,0.00001,suffix:m");
- register_setting_ranged(SOLVER_MAX_VELOCITY_ITERATIONS, 19, U"1,16,or_greater");
- register_setting_ranged(SOLVER_MAX_VELOCITY_FRICTION_ITERATIONS, 27, U"1,16,or_greater");
- register_setting_ranged(SOLVER_MAX_STABILIZATION_ITERATIONS, 1, U"1,16,or_greater");
- register_setting_plain(SOLVER_INTERLEAVE_RESTITUTION_AND_FRICTION_RESOLUTION, true);
- register_setting_plain(SOLVER_MIN_ISLAND_SIZE, 128);
- register_setting_plain(SOLVER_MAX_CCD_SUBSTEPS, 1);
+ register_setting_ranged(SOLVER_NUM_INTERNAL_PGS_ITERATIONS, 1, U"1,4,or_greater");
+ register_setting_ranged(SOLVER_NUM_ADDITIONAL_FRICTION_ITERATIONS, 4, U"1,16,or_greater");
+ register_setting_ranged(SOLVER_NUM_ITERATIONS, 4, U"1,16,or_greater");
}
template
@@ -111,10 +101,6 @@ bool RapierProjectSettings::should_run_on_separate_thread() {
int RapierProjectSettings::get_max_threads() {
return get_setting(MAX_THREADS);
}
-
-double RapierProjectSettings::get_solver_min_ccd_dt() {
- return get_setting(SOLVER_MIN_CCD_DT);
-}
double RapierProjectSettings::get_solver_erp() {
return get_setting(SOLVER_ERP);
}
@@ -130,27 +116,15 @@ double RapierProjectSettings::get_solver_joint_damping_ratio() {
double RapierProjectSettings::get_solver_allowed_linear_error() {
return get_setting(SOLVER_ALLOWED_LINEAR_ERROR);
}
-double RapierProjectSettings::get_solver_max_penetration_correction() {
- return get_setting(SOLVER_MAX_PENETRATION_CORRECTION);
-}
double RapierProjectSettings::get_solver_prediction_distance() {
return get_setting(SOLVER_PREDICTION_DISTANCE);
}
-int RapierProjectSettings::get_solver_max_velocity_iterations() {
- return get_setting(SOLVER_MAX_VELOCITY_ITERATIONS);
-}
-int RapierProjectSettings::get_solver_max_velocity_friction_iterations() {
- return get_setting(SOLVER_MAX_VELOCITY_FRICTION_ITERATIONS);
-}
-int RapierProjectSettings::get_solver_max_stabilization_iterations() {
- return get_setting(SOLVER_MAX_STABILIZATION_ITERATIONS);
-}
-bool RapierProjectSettings::get_solver_interleave_restitution_and_friction_resolution() {
- return get_setting(SOLVER_INTERLEAVE_RESTITUTION_AND_FRICTION_RESOLUTION);
-}
-int RapierProjectSettings::get_solver_min_island_size() {
- return get_setting(SOLVER_MIN_ISLAND_SIZE);
+int RapierProjectSettings::get_solver_num_solver_iterations() {
+ return get_setting(SOLVER_NUM_ITERATIONS);
}
-int RapierProjectSettings::get_solver_max_ccd_substeps() {
- return get_setting(SOLVER_MAX_CCD_SUBSTEPS);
+int RapierProjectSettings::get_solver_num_additional_friction_iterations() {
+ return get_setting(SOLVER_NUM_ADDITIONAL_FRICTION_ITERATIONS);
}
+int RapierProjectSettings::get_solver_num_internal_pgs_iterations() {
+ return get_setting(SOLVER_NUM_INTERNAL_PGS_ITERATIONS);
+}
\ No newline at end of file
diff --git a/src/servers/rapier_project_settings.h b/src/servers/rapier_project_settings.h
index 28dc5abb..56bcdb1f 100644
--- a/src/servers/rapier_project_settings.h
+++ b/src/servers/rapier_project_settings.h
@@ -8,7 +8,6 @@ class RapierProjectSettings {
static bool should_run_on_separate_thread();
static int get_max_threads();
- static double get_solver_min_ccd_dt();
static double get_solver_erp();
static double get_solver_damping_ratio();
static double get_solver_joint_erp();
@@ -16,12 +15,9 @@ class RapierProjectSettings {
static double get_solver_allowed_linear_error();
static double get_solver_max_penetration_correction();
static double get_solver_prediction_distance();
- static int get_solver_max_velocity_iterations();
- static int get_solver_max_velocity_friction_iterations();
- static int get_solver_max_stabilization_iterations();
- static bool get_solver_interleave_restitution_and_friction_resolution();
- static int get_solver_min_island_size();
- static int get_solver_max_ccd_substeps();
+ static int get_solver_num_solver_iterations();
+ static int get_solver_num_additional_friction_iterations();
+ static int get_solver_num_internal_pgs_iterations();
};
#endif // RAPIER_PROJECT_SETTINGS_H
diff --git a/src/shapes/rapier_concave_polygon_shape_2d.cpp b/src/shapes/rapier_concave_polygon_shape_2d.cpp
index 50edd7bf..5086309a 100644
--- a/src/shapes/rapier_concave_polygon_shape_2d.cpp
+++ b/src/shapes/rapier_concave_polygon_shape_2d.cpp
@@ -3,11 +3,13 @@
rapier2d::Handle RapierConcavePolygonShape2D::create_rapier_shape() const {
int point_count = points.size();
ERR_FAIL_COND_V(point_count < 3, rapier2d::invalid_handle());
- rapier2d::Vector *rapier_points = (rapier2d::Vector *)alloca(point_count * sizeof(rapier2d::Vector));
+ rapier2d::Vector *rapier_points = (rapier2d::Vector *)alloca((point_count + 1) * sizeof(rapier2d::Vector));
for (int i = 0; i < point_count; i++) {
rapier_points[i] = rapier2d::Vector{ (points[i].x), (points[i].y) };
}
- return rapier2d::shape_create_convave_polyline(rapier_points, point_count);
+ // In order to close the polyline shape
+ rapier_points[point_count] = rapier_points[0];
+ return rapier2d::shape_create_convave_polyline(rapier_points, point_count + 1);
}
void RapierConcavePolygonShape2D::set_data(const Variant &p_data) {
diff --git a/src/shapes/rapier_separation_ray_shape_2d.h b/src/shapes/rapier_separation_ray_shape_2d.h
index bf602044..8a876916 100644
--- a/src/shapes/rapier_separation_ray_shape_2d.h
+++ b/src/shapes/rapier_separation_ray_shape_2d.h
@@ -13,8 +13,6 @@ class RapierSeparationRayShape2D : public RapierSegmentShape2D {
public:
virtual PhysicsServer2D::ShapeType get_type() const override { return PhysicsServer2D::SHAPE_SEPARATION_RAY; }
- //virtual void apply_rapier_transform(rapier2d::Vector &position, real_t &angle) const override;
-
_FORCE_INLINE_ bool get_slide_on_slope() const { return slide_on_slope; }
virtual bool allows_one_way_collision() const override { return false; }
diff --git a/src/shapes/rapier_shape_2d.h b/src/shapes/rapier_shape_2d.h
index d0a6aca3..54f1ea5b 100644
--- a/src/shapes/rapier_shape_2d.h
+++ b/src/shapes/rapier_shape_2d.h
@@ -40,8 +40,6 @@ class RapierShape2D {
virtual PhysicsServer2D::ShapeType get_type() const = 0;
- virtual void apply_rapier_transform(rapier2d::Vector &position, real_t &angle) const {}
-
virtual bool allows_one_way_collision() const { return true; }
rapier2d::Handle get_rapier_shape();
diff --git a/src/shapes/rapier_world_boundary_shape_2d.cpp b/src/shapes/rapier_world_boundary_shape_2d.cpp
index f1b35706..1e1d4383 100644
--- a/src/shapes/rapier_world_boundary_shape_2d.cpp
+++ b/src/shapes/rapier_world_boundary_shape_2d.cpp
@@ -1,13 +1,8 @@
#include "rapier_world_boundary_shape_2d.h"
rapier2d::Handle RapierWorldBoundaryShape2D::create_rapier_shape() const {
- rapier2d::Vector v = { normal.x, normal.y };
- return rapier2d::shape_create_halfspace(&v);
-}
-
-void RapierWorldBoundaryShape2D::apply_rapier_transform(rapier2d::Vector &position, real_t &angle) const {
- position.x += normal.x * d;
- position.y += normal.y * d;
+ rapier2d::Vector v = { normal.x, -normal.y };
+ return rapier2d::shape_create_halfspace(&v, -d);
}
void RapierWorldBoundaryShape2D::set_data(const Variant &p_data) {
diff --git a/src/shapes/rapier_world_boundary_shape_2d.h b/src/shapes/rapier_world_boundary_shape_2d.h
index 4441ae07..b7fd54e4 100644
--- a/src/shapes/rapier_world_boundary_shape_2d.h
+++ b/src/shapes/rapier_world_boundary_shape_2d.h
@@ -13,8 +13,6 @@ class RapierWorldBoundaryShape2D : public RapierShape2D {
public:
virtual PhysicsServer2D::ShapeType get_type() const override { return PhysicsServer2D::SHAPE_WORLD_BOUNDARY; }
- virtual void apply_rapier_transform(rapier2d::Vector &position, real_t &angle) const override;
-
virtual void set_data(const Variant &p_data) override;
virtual Variant get_data() const override;
diff --git a/src/spaces/rapier_direct_space_state_2d.cpp b/src/spaces/rapier_direct_space_state_2d.cpp
index c4293618..81dd3759 100644
--- a/src/spaces/rapier_direct_space_state_2d.cpp
+++ b/src/spaces/rapier_direct_space_state_2d.cpp
@@ -67,7 +67,7 @@ bool RapierDirectSpaceState2D::_intersect_ray(const Vector2 &from, const Vector2
&query_excluded_info);
if (collide) {
- r_result->position = Vector2(hit_info.position.x, hit_info.position.y);
+ r_result->position = Vector2(hit_info.pixel_position.x, hit_info.pixel_position.y);
r_result->normal = Vector2(hit_info.normal.x, hit_info.normal.y);
ERR_FAIL_COND_V(!rapier2d::is_user_data_valid(hit_info.user_data), false);
@@ -131,8 +131,8 @@ bool RapierDirectSpaceState2D::_collide_shape(const RID &shape_rid, const Transf
(*result_count)++;
query_excluded_info.query_exclude[query_excluded_info.query_exclude_size++] = result.collider;
- results_out[array_idx++] = Vector2(result.witness1.x, result.witness1.y);
- results_out[array_idx++] = Vector2(result.witness2.x, result.witness2.y);
+ results_out[array_idx++] = Vector2(result.pixel_witness1.x, result.pixel_witness1.y);
+ results_out[array_idx++] = Vector2(result.pixel_witness2.x, result.pixel_witness2.y);
cpt++;
} while (cpt < max_results);
diff --git a/src/spaces/rapier_space_2d.cpp b/src/spaces/rapier_space_2d.cpp
index ccd4372f..abac92c2 100644
--- a/src/spaces/rapier_space_2d.cpp
+++ b/src/spaces/rapier_space_2d.cpp
@@ -138,9 +138,9 @@ rapier2d::OneWayDirection RapierSpace2D::collision_modify_contacts_callback(rapi
ERR_FAIL_COND_V(collision_object_1->is_shape_disabled(shape1), result);
ERR_FAIL_COND_V(collision_object_2->is_shape_disabled(shape2), result);
result.body1 = collision_object_1->is_shape_set_as_one_way_collision(shape1);
- result.body1_margin = collision_object_1->get_shape_one_way_collision_margin(shape1);
+ result.pixel_body1_margin = collision_object_1->get_shape_one_way_collision_margin(shape1);
result.body2 = collision_object_2->is_shape_set_as_one_way_collision(shape2);
- result.body2_margin = collision_object_2->get_shape_one_way_collision_margin(shape2);
+ result.pixel_body2_margin = collision_object_2->get_shape_one_way_collision_margin(shape2);
if (collision_object_1->get_type() == RapierCollisionObject2D::TYPE_BODY && collision_object_2->get_type() == RapierCollisionObject2D::TYPE_BODY) {
RapierBody2D *body1 = static_cast(collision_object_1);
RapierBody2D *body2 = static_cast(collision_object_2);
@@ -216,7 +216,7 @@ void RapierSpace2D::collision_event_callback(rapier2d::Handle world_handle, cons
if (event_info->is_sensor) {
if (!instanceId1.is_valid()) {
- ERR_FAIL_COND_MSG(pObject2, "Should be able to get info about a removed object if the other one is still valid.");
+ ERR_FAIL_COND_MSG(pObject1, "Should be able to get info about a removed object if the other one is still valid.");
return;
}
if (!instanceId2.is_valid()) {
@@ -235,36 +235,32 @@ void RapierSpace2D::collision_event_callback(rapier2d::Handle world_handle, cons
}
RapierArea2D *pArea = static_cast(pObject1);
- uint32_t area_shape = shape1;
- uint32_t other_shape = shape2;
- RID other_rid = rid2;
- ObjectID other_instance_id = instanceId2;
if (type2 == RapierCollisionObject2D::TYPE_AREA) {
RapierArea2D *pArea2 = static_cast(pObject2);
if (event_info->is_started) {
ERR_FAIL_COND(!pArea);
ERR_FAIL_COND(!pArea2);
- pArea->on_area_enter(collider_handle2, pArea2, other_shape, other_rid, other_instance_id, collider_handle1, area_shape);
- pArea2->on_area_enter(collider_handle1, pArea, area_shape, other_rid, other_instance_id, collider_handle2, other_shape);
+ pArea->on_area_enter(collider_handle2, pArea2, shape2, rid2, instanceId2, collider_handle1, shape1);
+ pArea2->on_area_enter(collider_handle1, pArea, shape1, rid1, instanceId1, collider_handle2, shape2);
} else {
if (pArea) {
- pArea->on_area_exit(collider_handle2, pArea2, other_shape, other_rid, other_instance_id, collider_handle1, area_shape);
+ pArea->on_area_exit(collider_handle2, pArea2, shape2, rid2, instanceId2, collider_handle1, shape1);
} else {
// Try to retrieve area if not destroyed yet
pArea = space->get_area_from_rid(rid1);
if (pArea) {
// Use invalid area case to keep counters consistent for already removed collider
- pArea->on_area_exit(collider_handle2, nullptr, other_shape, other_rid, other_instance_id, collider_handle1, area_shape);
+ pArea->on_area_exit(collider_handle2, nullptr, shape2, rid2, instanceId2, collider_handle1, shape1);
}
}
if (pArea2) {
- pArea2->on_area_exit(collider_handle1, pArea, area_shape, other_rid, other_instance_id, collider_handle2, other_shape);
+ pArea2->on_area_exit(collider_handle1, pArea, shape1, rid1, instanceId1, collider_handle2, shape2);
} else {
// Try to retrieve area if not destroyed yet
pArea2 = space->get_area_from_rid(rid2);
if (pArea2) {
// Use invalid area case to keep counters consistent for already removed collider
- pArea2->on_area_exit(collider_handle1, nullptr, area_shape, other_rid, other_instance_id, collider_handle2, other_shape);
+ pArea2->on_area_exit(collider_handle1, nullptr, shape1, rid1, instanceId1, collider_handle2, shape2);
}
}
}
@@ -272,15 +268,15 @@ void RapierSpace2D::collision_event_callback(rapier2d::Handle world_handle, cons
RapierBody2D *pBody = static_cast(pObject2);
if (event_info->is_started) {
ERR_FAIL_COND(!pArea);
- pArea->on_body_enter(collider_handle2, pBody, other_shape, other_rid, other_instance_id, collider_handle1, area_shape);
+ pArea->on_body_enter(collider_handle2, pBody, shape2, rid2, instanceId2, collider_handle1, shape1);
} else if (pArea) {
- pArea->on_body_exit(collider_handle2, pBody, other_shape, other_rid, other_instance_id, collider_handle1, area_shape);
+ pArea->on_body_exit(collider_handle2, pBody, shape2, rid2, instanceId2, collider_handle1, shape1);
} else {
// Try to retrieve area if not destroyed yet
pArea = space->get_area_from_rid(rid1);
if (pArea) {
// Use invalid body case to keep counters consistent for already removed collider
- pArea->on_body_exit(collider_handle2, nullptr, other_shape, other_rid, other_instance_id, collider_handle1, area_shape, false);
+ pArea->on_body_exit(collider_handle2, nullptr, shape2, rid2, instanceId2, collider_handle1, shape1, false);
}
}
}
@@ -334,8 +330,8 @@ bool RapierSpace2D::contact_point_callback(rapier2d::Handle world_handle, const
ERR_FAIL_COND_V(!space, false);
ERR_FAIL_COND_V(space->get_handle().id != world_handle.id, false);
- Vector2 pos1(contact_info->local_pos_1.x, contact_info->local_pos_1.y);
- Vector2 pos2(contact_info->local_pos_2.x, contact_info->local_pos_2.y);
+ Vector2 pos1(contact_info->pixel_local_pos_1.x, contact_info->pixel_local_pos_1.y);
+ Vector2 pos2(contact_info->pixel_local_pos_2.x, contact_info->pixel_local_pos_2.y);
bool keep_sending_contacts = false;
@@ -354,7 +350,6 @@ bool RapierSpace2D::contact_point_callback(rapier2d::Handle world_handle, const
}
ERR_FAIL_COND_V(!pObject1, false);
ERR_FAIL_COND_V(pObject1->get_type() != RapierCollisionObject2D::TYPE_BODY, false);
- ERR_FAIL_COND_V(!pObject1, false);
RapierBody2D *body1 = static_cast(pObject1);
// body and shape 2
uint32_t shape2 = 0;
@@ -364,24 +359,23 @@ bool RapierSpace2D::contact_point_callback(rapier2d::Handle world_handle, const
}
ERR_FAIL_COND_V(!pObject2, false);
ERR_FAIL_COND_V(pObject2->get_type() != RapierCollisionObject2D::TYPE_BODY, false);
- ERR_FAIL_COND_V(!pObject2, false);
RapierBody2D *body2 = static_cast(pObject2);
- real_t depth = MAX(0.0, -contact_info->distance); // negative distance means penetration
+ real_t depth = MAX(0.0, -contact_info->pixel_distance); // negative distance means penetration
Vector2 normal(contact_info->normal.x, contact_info->normal.y);
Vector2 tangent = normal.orthogonal();
- Vector2 impulse = contact_info->impulse * normal + contact_info->tangent_impulse * tangent;
+ Vector2 impulse = contact_info->pixel_impulse * normal + contact_info->pixel_tangent_impulse * tangent;
if (body1->can_report_contacts()) {
keep_sending_contacts = true;
- Vector2 vel_pos2(contact_info->velocity_pos_2.x, contact_info->velocity_pos_2.y);
+ Vector2 vel_pos2(contact_info->pixel_velocity_pos_2.x, contact_info->pixel_velocity_pos_2.y);
body1->add_contact(pos1, -normal, depth, (int)shape1, pos2, (int)shape2, body2->get_instance_id(), body2->get_rid(), vel_pos2, impulse);
}
if (body2->can_report_contacts()) {
keep_sending_contacts = true;
- Vector2 vel_pos1(contact_info->velocity_pos_1.x, contact_info->velocity_pos_1.y);
+ Vector2 vel_pos1(contact_info->pixel_velocity_pos_1.x, contact_info->pixel_velocity_pos_1.y);
body2->add_contact(pos2, normal, depth, (int)shape2, pos1, (int)shape1, body1->get_instance_id(), body1->get_rid(), vel_pos1, impulse);
}
@@ -390,6 +384,11 @@ bool RapierSpace2D::contact_point_callback(rapier2d::Handle world_handle, const
void RapierSpace2D::step(real_t p_step) {
last_step = p_step;
+ for (SelfList *body_iterator = active_list.first(); body_iterator;) {
+ RapierBody2D *body = body_iterator->self();
+ body_iterator = body_iterator->next();
+ body->reset_contact_count();
+ }
contact_debug_count = 0;
ProjectSettings *project_settings = ProjectSettings::get_singleton();
@@ -426,22 +425,17 @@ void RapierSpace2D::step(real_t p_step) {
rapier2d::SimulationSettings settings;
settings.dt = p_step;
- settings.gravity.x = default_gravity_dir.x * default_gravity_value;
- settings.gravity.y = default_gravity_dir.y * default_gravity_value;
+ settings.pixel_gravity.x = default_gravity_dir.x * default_gravity_value;
+ settings.pixel_gravity.y = default_gravity_dir.y * default_gravity_value;
settings.allowed_linear_error = RapierProjectSettings::get_solver_allowed_linear_error();
settings.damping_ratio = RapierProjectSettings::get_solver_damping_ratio();
settings.erp = RapierProjectSettings::get_solver_erp();
- settings.interleave_restitution_and_friction_resolution = RapierProjectSettings::get_solver_interleave_restitution_and_friction_resolution();
settings.joint_damping_ratio = RapierProjectSettings::get_solver_joint_damping_ratio();
settings.joint_erp = RapierProjectSettings::get_solver_joint_erp();
- settings.max_ccd_substeps = RapierProjectSettings::get_solver_max_ccd_substeps();
- settings.max_penetration_correction = RapierProjectSettings::get_solver_max_penetration_correction();
- settings.max_stabilization_iterations = RapierProjectSettings::get_solver_max_stabilization_iterations();
- settings.max_velocity_friction_iterations = RapierProjectSettings::get_solver_max_velocity_friction_iterations();
- settings.max_velocity_iterations = RapierProjectSettings::get_solver_max_velocity_iterations();
- settings.min_ccd_dt = RapierProjectSettings::get_solver_min_ccd_dt();
- settings.min_island_size = RapierProjectSettings::get_solver_min_island_size();
settings.prediction_distance = RapierProjectSettings::get_solver_prediction_distance();
+ settings.num_additional_friction_iterations = RapierProjectSettings::get_solver_num_additional_friction_iterations();
+ settings.num_internal_pgs_iterations = RapierProjectSettings::get_solver_num_internal_pgs_iterations();
+ settings.num_solver_iterations = RapierProjectSettings::get_solver_num_solver_iterations();
ERR_FAIL_COND(!is_handle_valid(handle));
rapier2d::world_step(handle, &settings);