11#include " NativeRopeContext.hpp"
2+ #include " godot_cpp/classes/physics_direct_space_state2d.hpp"
3+ #include " godot_cpp/classes/physics_server2d.hpp"
4+ #include " godot_cpp/classes/physics_shape_query_parameters2d.hpp"
5+ #include " godot_cpp/classes/world2d.hpp"
6+ #include < godot_cpp/classes/window.hpp>
7+ #include < godot_cpp/variant/utility_functions.hpp>
28
39using namespace godot ;
410
@@ -16,6 +22,19 @@ static Vector2 damp_vec(Vector2 value, float damping_factor, double delta)
1622 return value.lerp (VECTOR_ZERO, (float )(1.0 - exp (-damping_factor * delta)));
1723}
1824
25+ NativeRopeContext::NativeRopeContext () :
26+ shape_query(memnew(PhysicsShapeQueryParameters2D))
27+ {
28+ PhysicsServer2D* physics_server = PhysicsServer2D::get_singleton ();
29+ cast_shape_rid = physics_server->circle_shape_create ();
30+ shape_query->set_shape_rid (cast_shape_rid);
31+ }
32+
33+ NativeRopeContext::~NativeRopeContext ()
34+ {
35+ PhysicsServer2D* physics_server = PhysicsServer2D::get_singleton ();
36+ physics_server->free_rid (cast_shape_rid);
37+ }
1938
2039bool NativeRopeContext::validate () const
2140{
@@ -42,6 +61,11 @@ void NativeRopeContext::load_context(Node2D* rope)
4261 fixate_begin = rope->get (" fixate_begin" );
4362 resolve_to_begin = rope->get (" resolve_to_begin" );
4463 resolve_to_end = rope->get (" resolve_to_end" );
64+ enable_collisions = rope->get (" enable_collisions" );
65+ collision_radius = rope->get (" collision_radius" );
66+ collision_mask = rope->get (" collision_mask" );
67+ collision_damping = rope->get (" collision_damping" );
68+ resolve_collisions_while_constraining = rope->get (" resolve_collisions_while_constraining" );
4569}
4670
4771void NativeRopeContext::simulate (double delta)
@@ -58,7 +82,10 @@ void NativeRopeContext::simulate(double delta)
5882 }
5983
6084 _simulate_velocities (delta);
61- _constraint ();
85+ _constraint (delta);
86+
87+ if (!resolve_collisions_while_constraining)
88+ _resolve_collisions (delta);
6289
6390 if (fixate_begin)
6491 simulation_weights[0 ] = backup_multiplier_begin;
@@ -168,7 +195,7 @@ static void constraint_segment(Vector2* point_a, Vector2* point_b, float weight_
168195 *point_b += (weight_b + weight_b * (1.0 - weight_a)) * dir;
169196}
170197
171- void NativeRopeContext::_constraint ()
198+ void NativeRopeContext::_constraint (double delta )
172199{
173200 const bool use_euclid_constraint = max_endpoint_distance > 0 ;
174201
@@ -205,10 +232,44 @@ void NativeRopeContext::_constraint()
205232 }
206233 }
207234
208-
209235 for (int _ = 0 ; _ < num_constraint_iterations; ++_)
210236 {
211237 for (int i = 0 ; i < points.size () - 1 ; ++i)
212238 constraint_segment (&points[i], &points[i + 1 ], simulation_weights[i], simulation_weights[i + 1 ], seg_lengths[i]);
239+
240+ if (resolve_collisions_while_constraining)
241+ _resolve_collisions (delta);
213242 }
214243}
244+
245+ void NativeRopeContext::_resolve_collisions (double delta)
246+ {
247+ if (!enable_collisions)
248+ return ;
249+
250+ PhysicsDirectSpaceState2D* space = rope->get_world_2d ()->get_direct_space_state ();
251+ PhysicsServer2D* physics_server = PhysicsServer2D::get_singleton ();
252+ Transform2D transform;
253+
254+ physics_server->shape_set_data (cast_shape_rid, collision_radius);
255+ shape_query->set_collision_mask (collision_mask);
256+
257+ for (int i = 0 ; i < points.size (); ++i)
258+ {
259+ transform.set_origin (points[i]);
260+ shape_query->set_transform (transform);
261+ const Dictionary rest_info = space->get_rest_info (shape_query);
262+
263+ if (rest_info.is_empty ())
264+ continue ;
265+
266+ const Vector2 intersect_point = rest_info[" point" ];
267+ const Vector2 intersect_normal = rest_info[" normal" ];
268+ const Vector2 safe_point = intersect_point + intersect_normal * (collision_radius + CMP_EPSILON);
269+ const Vector2 safe_motion = (safe_point - points[i]) * simulation_weights[i];
270+ const Vector2 new_point = points[i] + safe_motion;
271+
272+ points[i] = oldpoints[i] + damp_vec (new_point - oldpoints[i], collision_damping, delta);
273+ }
274+ }
275+
0 commit comments