summaryrefslogtreecommitdiff
path: root/servers/physics
diff options
context:
space:
mode:
Diffstat (limited to 'servers/physics')
-rw-r--r--servers/physics/body_pair_sw.cpp42
-rw-r--r--servers/physics/body_sw.cpp16
-rw-r--r--servers/physics/body_sw.h22
-rw-r--r--servers/physics/collision_object_sw.cpp18
-rw-r--r--servers/physics/collision_object_sw.h2
-rw-r--r--servers/physics/collision_solver_sat.cpp3
-rw-r--r--servers/physics/physics_server_sw.cpp54
-rw-r--r--servers/physics/physics_server_sw.h75
-rw-r--r--servers/physics/space_sw.h2
9 files changed, 215 insertions, 19 deletions
diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp
index 2a6a9e08ae..5a41b621eb 100644
--- a/servers/physics/body_pair_sw.cpp
+++ b/servers/physics/body_pair_sw.cpp
@@ -211,6 +211,44 @@ bool BodyPairSW::_test_ccd(real_t p_step, BodySW *p_A, int p_shape_A, const Tran
return true;
}
+real_t combine_bounce(BodySW *A, BodySW *B) {
+ const PhysicsServer::CombineMode cm = A->get_bounce_combine_mode();
+
+ switch (cm) {
+ case PhysicsServer::COMBINE_MODE_INHERIT:
+ if (B->get_bounce_combine_mode() != PhysicsServer::COMBINE_MODE_INHERIT)
+ return combine_bounce(B, A);
+ // else use MAX [This is used when the two bodies doesn't use physical material]
+ case PhysicsServer::COMBINE_MODE_MAX:
+ return MAX(A->get_bounce(), B->get_bounce());
+ case PhysicsServer::COMBINE_MODE_MIN:
+ return MIN(A->get_bounce(), B->get_bounce());
+ case PhysicsServer::COMBINE_MODE_MULTIPLY:
+ return A->get_bounce() * B->get_bounce();
+ default: // Is always PhysicsServer::COMBINE_MODE_AVERAGE:
+ return (A->get_bounce() + B->get_bounce()) / 2;
+ }
+}
+
+real_t combine_friction(BodySW *A, BodySW *B) {
+ const PhysicsServer::CombineMode cm = A->get_friction_combine_mode();
+
+ switch (cm) {
+ case PhysicsServer::COMBINE_MODE_INHERIT:
+ if (B->get_friction_combine_mode() != PhysicsServer::COMBINE_MODE_INHERIT)
+ return combine_friction(B, A);
+ // else use Multiply [This is used when the two bodies doesn't use physical material]
+ case PhysicsServer::COMBINE_MODE_MULTIPLY:
+ return A->get_friction() * B->get_friction();
+ case PhysicsServer::COMBINE_MODE_MAX:
+ return MAX(A->get_friction(), B->get_friction());
+ case PhysicsServer::COMBINE_MODE_MIN:
+ return MIN(A->get_friction(), B->get_friction());
+ default: // Is always PhysicsServer::COMBINE_MODE_AVERAGE:
+ return (A->get_friction() + B->get_friction()) / 2;
+ }
+}
+
bool BodyPairSW::setup(real_t p_step) {
//cannot collide
@@ -331,7 +369,7 @@ bool BodyPairSW::setup(real_t p_step) {
c.acc_bias_impulse = 0;
c.acc_bias_impulse_center_of_mass = 0;
- c.bounce = MAX(A->get_bounce(), B->get_bounce());
+ c.bounce = combine_bounce(A, B);
if (c.bounce) {
Vector3 crA = A->get_angular_velocity().cross(c.rA);
@@ -421,7 +459,7 @@ void BodyPairSW::solve(real_t p_step) {
//friction impulse
- real_t friction = A->get_friction() * B->get_friction();
+ real_t friction = combine_friction(A, B);
Vector3 lvA = A->get_linear_velocity() + A->get_angular_velocity().cross(c.rA);
Vector3 lvB = B->get_linear_velocity() + B->get_angular_velocity().cross(c.rB);
diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp
index cc9681193c..59f987fc17 100644
--- a/servers/physics/body_sw.cpp
+++ b/servers/physics/body_sw.cpp
@@ -423,6 +423,22 @@ void BodySW::_compute_area_gravity_and_dampenings(const AreaSW *p_area) {
area_angular_damp += p_area->get_angular_damp();
}
+void BodySW::set_combine_mode(PhysicsServer::BodyParameter p_param, PhysicsServer::CombineMode p_mode) {
+ if (p_param == PhysicsServer::BODY_PARAM_BOUNCE) {
+ bounce_combine_mode = p_mode;
+ } else {
+ friction_combine_mode = p_mode;
+ }
+}
+
+PhysicsServer::CombineMode BodySW::get_combine_mode(PhysicsServer::BodyParameter p_param) const {
+ if (p_param == PhysicsServer::BODY_PARAM_BOUNCE) {
+ return bounce_combine_mode;
+ } else {
+ return friction_combine_mode;
+ }
+}
+
void BodySW::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock) {
if (lock) {
locked_axis |= p_axis;
diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h
index fd2ab16b84..5df270f679 100644
--- a/servers/physics/body_sw.h
+++ b/servers/physics/body_sw.h
@@ -49,6 +49,8 @@ class BodySW : public CollisionObjectSW {
real_t mass;
real_t bounce;
real_t friction;
+ PhysicsServer::CombineMode bounce_combine_mode;
+ PhysicsServer::CombineMode friction_combine_mode;
real_t linear_damp;
real_t angular_damp;
@@ -157,7 +159,7 @@ public:
_FORCE_INLINE_ void add_area(AreaSW *p_area) {
int index = areas.find(AreaCMP(p_area));
if (index > -1) {
- areas[index].refCount += 1;
+ areas.write[index].refCount += 1;
} else {
areas.ordered_insert(AreaCMP(p_area));
}
@@ -166,7 +168,7 @@ public:
_FORCE_INLINE_ void remove_area(AreaSW *p_area) {
int index = areas.find(AreaCMP(p_area));
if (index > -1) {
- areas[index].refCount -= 1;
+ areas.write[index].refCount -= 1;
if (areas[index].refCount < 1)
areas.remove(index);
}
@@ -217,6 +219,10 @@ public:
_FORCE_INLINE_ const Vector3 &get_biased_linear_velocity() const { return biased_linear_velocity; }
_FORCE_INLINE_ const Vector3 &get_biased_angular_velocity() const { return biased_angular_velocity; }
+ _FORCE_INLINE_ void apply_central_impulse(const Vector3 &p_j) {
+ linear_velocity += p_j * _inv_mass;
+ }
+
_FORCE_INLINE_ void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) {
linear_velocity += p_j * _inv_mass;
@@ -298,6 +304,12 @@ public:
_FORCE_INLINE_ Vector3 get_gravity() const { return gravity; }
_FORCE_INLINE_ real_t get_bounce() const { return bounce; }
+ void set_combine_mode(PhysicsServer::BodyParameter p_param, PhysicsServer::CombineMode p_mode);
+ PhysicsServer::CombineMode get_combine_mode(PhysicsServer::BodyParameter p_param) const;
+
+ _FORCE_INLINE_ PhysicsServer::CombineMode get_bounce_combine_mode() const { return bounce_combine_mode; }
+ _FORCE_INLINE_ PhysicsServer::CombineMode get_friction_combine_mode() const { return friction_combine_mode; }
+
void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock);
bool is_axis_locked(PhysicsServer::BodyAxis p_axis) const;
@@ -344,7 +356,7 @@ void BodySW::add_contact(const Vector3 &p_local_pos, const Vector3 &p_local_norm
if (c_max == 0)
return;
- Contact *c = &contacts[0];
+ Contact *c = contacts.ptrw();
int idx = -1;
@@ -413,6 +425,7 @@ public:
virtual void add_central_force(const Vector3 &p_force) { body->add_central_force(p_force); }
virtual void add_force(const Vector3 &p_force, const Vector3 &p_pos) { body->add_force(p_force, p_pos); }
virtual void add_torque(const Vector3 &p_torque) { body->add_torque(p_torque); }
+ virtual void apply_central_impulse(const Vector3 &p_j) { body->apply_central_impulse(p_j); }
virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) { body->apply_impulse(p_pos, p_j); }
virtual void apply_torque_impulse(const Vector3 &p_j) { body->apply_torque_impulse(p_j); }
@@ -429,6 +442,9 @@ public:
ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Vector3());
return body->contacts[p_contact_idx].local_normal;
}
+ virtual float get_contact_impulse(int p_contact_idx) const {
+ return 0.0f; // Only implemented for bullet
+ }
virtual int get_contact_local_shape(int p_contact_idx) const {
ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, -1);
return body->contacts[p_contact_idx].local_shape;
diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp
index f7a58a9cf2..09f72ff39b 100644
--- a/servers/physics/collision_object_sw.cpp
+++ b/servers/physics/collision_object_sw.cpp
@@ -53,7 +53,7 @@ void CollisionObjectSW::set_shape(int p_index, ShapeSW *p_shape) {
ERR_FAIL_INDEX(p_index, shapes.size());
shapes[p_index].shape->remove_owner(this);
- shapes[p_index].shape = p_shape;
+ shapes.write[p_index].shape = p_shape;
p_shape->add_owner(this);
if (!pending_shape_update_list.in_list()) {
@@ -66,8 +66,8 @@ void CollisionObjectSW::set_shape_transform(int p_index, const Transform &p_tran
ERR_FAIL_INDEX(p_index, shapes.size());
- shapes[p_index].xform = p_transform;
- shapes[p_index].xform_inv = p_transform.affine_inverse();
+ shapes.write[p_index].xform = p_transform;
+ shapes.write[p_index].xform_inv = p_transform.affine_inverse();
if (!pending_shape_update_list.in_list()) {
PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
}
@@ -97,7 +97,7 @@ void CollisionObjectSW::remove_shape(int p_index) {
continue;
//should never get here with a null owner
space->get_broadphase()->remove(shapes[i].bpid);
- shapes[i].bpid = 0;
+ shapes.write[i].bpid = 0;
}
shapes[p_index].shape->remove_owner(this);
shapes.remove(p_index);
@@ -117,7 +117,7 @@ void CollisionObjectSW::_set_static(bool p_static) {
if (!space)
return;
for (int i = 0; i < get_shape_count(); i++) {
- Shape &s = shapes[i];
+ const Shape &s = shapes[i];
if (s.bpid > 0) {
space->get_broadphase()->set_static(s.bpid, _static);
}
@@ -128,7 +128,7 @@ void CollisionObjectSW::_unregister_shapes() {
for (int i = 0; i < shapes.size(); i++) {
- Shape &s = shapes[i];
+ Shape &s = shapes.write[i];
if (s.bpid > 0) {
space->get_broadphase()->remove(s.bpid);
s.bpid = 0;
@@ -143,7 +143,7 @@ void CollisionObjectSW::_update_shapes() {
for (int i = 0; i < shapes.size(); i++) {
- Shape &s = shapes[i];
+ Shape &s = shapes.write[i];
if (s.bpid == 0) {
s.bpid = space->get_broadphase()->create(this, i);
space->get_broadphase()->set_static(s.bpid, _static);
@@ -170,7 +170,7 @@ void CollisionObjectSW::_update_shapes_with_motion(const Vector3 &p_motion) {
for (int i = 0; i < shapes.size(); i++) {
- Shape &s = shapes[i];
+ Shape &s = shapes.write[i];
if (s.bpid == 0) {
s.bpid = space->get_broadphase()->create(this, i);
space->get_broadphase()->set_static(s.bpid, _static);
@@ -195,7 +195,7 @@ void CollisionObjectSW::_set_space(SpaceSW *p_space) {
for (int i = 0; i < shapes.size(); i++) {
- Shape &s = shapes[i];
+ Shape &s = shapes.write[i];
if (s.bpid) {
space->get_broadphase()->remove(s.bpid);
s.bpid = 0;
diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h
index dee28bb6df..b6430b38dc 100644
--- a/servers/physics/collision_object_sw.h
+++ b/servers/physics/collision_object_sw.h
@@ -135,7 +135,7 @@ public:
_FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable = p_enable; }
_FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; }
- _FORCE_INLINE_ void set_shape_as_disabled(int p_idx, bool p_enable) { shapes[p_idx].disabled = p_enable; }
+ _FORCE_INLINE_ void set_shape_as_disabled(int p_idx, bool p_enable) { shapes.write[p_idx].disabled = p_enable; }
_FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const { return shapes[p_idx].disabled; }
_FORCE_INLINE_ void set_collision_layer(uint32_t p_layer) { collision_layer = p_layer; }
diff --git a/servers/physics/collision_solver_sat.cpp b/servers/physics/collision_solver_sat.cpp
index e587485fcb..44b7c9ac34 100644
--- a/servers/physics/collision_solver_sat.cpp
+++ b/servers/physics/collision_solver_sat.cpp
@@ -217,8 +217,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_
// generate contacts
//Plane plane_A(p_points_A[0],p_points_A[1],p_points_A[2]);
- int added = 0;
-
for (int i = 0; i < clipbuf_len; i++) {
real_t d = plane_B.distance_to(clipbuf_src[i]);
@@ -233,7 +231,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_
continue;
p_callback->call(clipbuf_src[i], closest_B);
- added++;
}
}
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 6c25ad43f9..a06942cb2a 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -701,6 +701,20 @@ real_t PhysicsServerSW::body_get_param(RID p_body, BodyParameter p_param) const
return body->get_param(p_param);
};
+void PhysicsServerSW::body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode) {
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_combine_mode(p_param, p_mode);
+}
+
+PhysicsServer::CombineMode PhysicsServerSW::body_get_combine_mode(RID p_body, BodyParameter p_param) const {
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, COMBINE_MODE_INHERIT);
+
+ return body->get_combine_mode(p_param);
+}
+
void PhysicsServerSW::body_set_kinematic_safe_margin(RID p_body, real_t p_margin) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
@@ -763,6 +777,40 @@ Vector3 PhysicsServerSW::body_get_applied_torque(RID p_body) const {
return body->get_applied_torque();
};
+void PhysicsServerSW::body_add_central_force(RID p_body, const Vector3 &p_force) {
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->add_central_force(p_force);
+ body->wakeup();
+}
+
+void PhysicsServerSW::body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_pos) {
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->add_force(p_force, p_pos);
+ body->wakeup();
+};
+
+void PhysicsServerSW::body_add_torque(RID p_body, const Vector3 &p_torque) {
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->add_torque(p_torque);
+ body->wakeup();
+};
+
+void PhysicsServerSW::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) {
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ _update_shapes();
+
+ body->apply_central_impulse(p_impulse);
+ body->wakeup();
+}
+
void PhysicsServerSW::body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse) {
BodySW *body = body_owner.get(p_body);
@@ -1367,6 +1415,8 @@ void PhysicsServerSW::init() {
void PhysicsServerSW::step(real_t p_step) {
+#ifndef _3D_DISABLED
+
if (!active)
return;
@@ -1387,6 +1437,7 @@ void PhysicsServerSW::step(real_t p_step) {
active_objects += E->get()->get_active_objects();
collision_pairs += E->get()->get_collision_pairs();
}
+#endif
}
void PhysicsServerSW::sync(){
@@ -1395,6 +1446,8 @@ void PhysicsServerSW::sync(){
void PhysicsServerSW::flush_queries() {
+#ifndef _3D_DISABLED
+
if (!active)
return;
@@ -1441,6 +1494,7 @@ void PhysicsServerSW::flush_queries() {
ScriptDebugger::get_singleton()->add_profiling_frame_data("physics", values);
}
+#endif
};
void PhysicsServerSW::finish() {
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index 3f56ba26d0..57037fb325 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -188,6 +188,10 @@ public:
virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value);
virtual real_t body_get_param(RID p_body, BodyParameter p_param) const;
+ /// p_param accept only Bounce and Friction
+ virtual void body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode);
+ virtual CombineMode body_get_combine_mode(RID p_body, BodyParameter p_param) const;
+
virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin);
virtual real_t body_get_kinematic_safe_margin(RID p_body) const;
@@ -200,6 +204,11 @@ public:
virtual void body_set_applied_torque(RID p_body, const Vector3 &p_torque);
virtual Vector3 body_get_applied_torque(RID p_body) const;
+ virtual void body_add_central_force(RID p_body, const Vector3 &p_force);
+ virtual void body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_pos);
+ virtual void body_add_torque(RID p_body, const Vector3 &p_torque);
+
+ virtual void body_apply_central_impulse(RID p_body, const Vector3 &p_impulse);
virtual void body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse);
virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse);
virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity);
@@ -230,6 +239,72 @@ public:
// this function only works on physics process, errors and returns null otherwise
virtual PhysicsDirectBodyState *body_get_direct_state(RID p_body);
+ /* SOFT BODY */
+
+ virtual RID soft_body_create(bool p_init_sleeping = false) { return RID(); }
+
+ virtual void soft_body_update_visual_server(RID p_body, class SoftBodyVisualServerHandler *p_visual_server_handler) {}
+
+ virtual void soft_body_set_space(RID p_body, RID p_space) {}
+ virtual RID soft_body_get_space(RID p_body) const { return RID(); }
+
+ virtual void soft_body_set_collision_layer(RID p_body, uint32_t p_layer) {}
+ virtual uint32_t soft_body_get_collision_layer(RID p_body) const { return 0; }
+
+ virtual void soft_body_set_collision_mask(RID p_body, uint32_t p_mask) {}
+ virtual uint32_t soft_body_get_collision_mask(RID p_body) const { return 0; }
+
+ virtual void soft_body_add_collision_exception(RID p_body, RID p_body_b) {}
+ virtual void soft_body_remove_collision_exception(RID p_body, RID p_body_b) {}
+ virtual void soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {}
+
+ virtual void soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {}
+ virtual Variant soft_body_get_state(RID p_body, BodyState p_state) const { return Variant(); }
+
+ virtual void soft_body_set_transform(RID p_body, const Transform &p_transform) {}
+ virtual Vector3 soft_body_get_vertex_position(RID p_body, int vertex_index) const { return Vector3(); }
+
+ virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) {}
+ virtual bool soft_body_is_ray_pickable(RID p_body) const { return false; }
+
+ virtual void soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) {}
+ virtual int soft_body_get_simulation_precision(RID p_body) { return 0; }
+
+ virtual void soft_body_set_total_mass(RID p_body, real_t p_total_mass) {}
+ virtual real_t soft_body_get_total_mass(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) {}
+ virtual real_t soft_body_get_linear_stiffness(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) {}
+ virtual real_t soft_body_get_areaAngular_stiffness(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) {}
+ virtual real_t soft_body_get_volume_stiffness(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) {}
+ virtual real_t soft_body_get_pressure_coefficient(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_pose_matching_coefficient(RID p_body, real_t p_pose_matching_coefficient) {}
+ virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) {}
+ virtual real_t soft_body_get_damping_coefficient(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) {}
+ virtual real_t soft_body_get_drag_coefficient(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_mesh(RID p_body, const REF &p_mesh) {}
+
+ virtual void soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) {}
+ virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) { return Vector3(); }
+
+ virtual Vector3 soft_body_get_point_offset(RID p_body, int p_point_index) const { return Vector3(); }
+
+ virtual void soft_body_remove_all_pinned_points(RID p_body) {}
+ virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) {}
+ virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) { return 0; }
+
/* JOINT API */
virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B);
diff --git a/servers/physics/space_sw.h b/servers/physics/space_sw.h
index 2452d6a187..4d864e9a51 100644
--- a/servers/physics/space_sw.h
+++ b/servers/physics/space_sw.h
@@ -186,7 +186,7 @@ public:
void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); }
_FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.empty(); }
_FORCE_INLINE_ void add_debug_contact(const Vector3 &p_contact) {
- if (contact_debug_count < contact_debug.size()) contact_debug[contact_debug_count++] = p_contact;
+ if (contact_debug_count < contact_debug.size()) contact_debug.write[contact_debug_count++] = p_contact;
}
_FORCE_INLINE_ Vector<Vector3> get_debug_contacts() { return contact_debug; }
_FORCE_INLINE_ int get_debug_contact_count() { return contact_debug_count; }