1/**************************************************************************/
2/* physics_server_3d_wrap_mt.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef PHYSICS_SERVER_3D_WRAP_MT_H
32#define PHYSICS_SERVER_3D_WRAP_MT_H
33
34#include "core/config/project_settings.h"
35#include "core/os/thread.h"
36#include "core/templates/command_queue_mt.h"
37#include "servers/physics_server_3d.h"
38
39#ifdef DEBUG_SYNC
40#define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__));
41#else
42#define SYNC_DEBUG
43#endif
44
45class PhysicsServer3DWrapMT : public PhysicsServer3D {
46 mutable PhysicsServer3D *physics_server_3d;
47
48 mutable CommandQueueMT command_queue;
49
50 static void _thread_callback(void *_instance);
51 void thread_loop();
52
53 Thread::ID server_thread;
54 Thread::ID main_thread;
55 volatile bool exit = false;
56 Thread thread;
57 volatile bool step_thread_up = false;
58 bool create_thread = false;
59
60 Semaphore step_sem;
61 void thread_step(real_t p_delta);
62
63 void thread_exit();
64
65 bool first_frame = true;
66
67 Mutex alloc_mutex;
68 int pool_max_size = 0;
69
70public:
71#define ServerName PhysicsServer3D
72#define ServerNameWrapMT PhysicsServer3DWrapMT
73#define server_name physics_server_3d
74#define WRITE_ACTION
75
76#include "servers/server_wrap_mt_common.h"
77
78 //FUNC1RID(shape,ShapeType); todo fix
79 FUNCRID(world_boundary_shape)
80 FUNCRID(separation_ray_shape)
81 FUNCRID(sphere_shape)
82 FUNCRID(box_shape)
83 FUNCRID(capsule_shape)
84 FUNCRID(cylinder_shape)
85 FUNCRID(convex_polygon_shape)
86 FUNCRID(concave_polygon_shape)
87 FUNCRID(heightmap_shape)
88 FUNCRID(custom_shape)
89
90 FUNC2(shape_set_data, RID, const Variant &);
91 FUNC2(shape_set_custom_solver_bias, RID, real_t);
92
93 FUNC2(shape_set_margin, RID, real_t)
94 FUNC1RC(real_t, shape_get_margin, RID)
95
96 FUNC1RC(ShapeType, shape_get_type, RID);
97 FUNC1RC(Variant, shape_get_data, RID);
98 FUNC1RC(real_t, shape_get_custom_solver_bias, RID);
99#if 0
100 //these work well, but should be used from the main thread only
101 bool shape_collide(RID p_shape_A, const Transform &p_xform_A, const Vector3 &p_motion_A, RID p_shape_B, const Transform &p_xform_B, const Vector3 &p_motion_B, Vector3 *r_results, int p_result_max, int &r_result_count) {
102 ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
103 return physics_server_3d->shape_collide(p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, r_result_count);
104 }
105#endif
106 /* SPACE API */
107
108 FUNCRID(space);
109 FUNC2(space_set_active, RID, bool);
110 FUNC1RC(bool, space_is_active, RID);
111
112 FUNC3(space_set_param, RID, SpaceParameter, real_t);
113 FUNC2RC(real_t, space_get_param, RID, SpaceParameter);
114
115 // this function only works on physics process, errors and returns null otherwise
116 PhysicsDirectSpaceState3D *space_get_direct_state(RID p_space) override {
117 ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr);
118 return physics_server_3d->space_get_direct_state(p_space);
119 }
120
121 FUNC2(space_set_debug_contacts, RID, int);
122 virtual Vector<Vector3> space_get_contacts(RID p_space) const override {
123 ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), Vector<Vector3>());
124 return physics_server_3d->space_get_contacts(p_space);
125 }
126
127 virtual int space_get_contact_count(RID p_space) const override {
128 ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), 0);
129 return physics_server_3d->space_get_contact_count(p_space);
130 }
131
132 /* AREA API */
133
134 //FUNC0RID(area);
135 FUNCRID(area);
136
137 FUNC2(area_set_space, RID, RID);
138 FUNC1RC(RID, area_get_space, RID);
139
140 FUNC4(area_add_shape, RID, RID, const Transform3D &, bool);
141 FUNC3(area_set_shape, RID, int, RID);
142 FUNC3(area_set_shape_transform, RID, int, const Transform3D &);
143 FUNC3(area_set_shape_disabled, RID, int, bool);
144
145 FUNC1RC(int, area_get_shape_count, RID);
146 FUNC2RC(RID, area_get_shape, RID, int);
147 FUNC2RC(Transform3D, area_get_shape_transform, RID, int);
148 FUNC2(area_remove_shape, RID, int);
149 FUNC1(area_clear_shapes, RID);
150
151 FUNC2(area_attach_object_instance_id, RID, ObjectID);
152 FUNC1RC(ObjectID, area_get_object_instance_id, RID);
153
154 FUNC3(area_set_param, RID, AreaParameter, const Variant &);
155 FUNC2(area_set_transform, RID, const Transform3D &);
156
157 FUNC2RC(Variant, area_get_param, RID, AreaParameter);
158 FUNC1RC(Transform3D, area_get_transform, RID);
159
160 FUNC2(area_set_collision_layer, RID, uint32_t);
161 FUNC1RC(uint32_t, area_get_collision_layer, RID);
162
163 FUNC2(area_set_collision_mask, RID, uint32_t);
164 FUNC1RC(uint32_t, area_get_collision_mask, RID);
165
166 FUNC2(area_set_monitorable, RID, bool);
167 FUNC2(area_set_ray_pickable, RID, bool);
168
169 FUNC2(area_set_monitor_callback, RID, const Callable &);
170 FUNC2(area_set_area_monitor_callback, RID, const Callable &);
171
172 /* BODY API */
173
174 //FUNC2RID(body,BodyMode,bool);
175 FUNCRID(body)
176
177 FUNC2(body_set_space, RID, RID);
178 FUNC1RC(RID, body_get_space, RID);
179
180 FUNC2(body_set_mode, RID, BodyMode);
181 FUNC1RC(BodyMode, body_get_mode, RID);
182
183 FUNC4(body_add_shape, RID, RID, const Transform3D &, bool);
184 FUNC3(body_set_shape, RID, int, RID);
185 FUNC3(body_set_shape_transform, RID, int, const Transform3D &);
186
187 FUNC1RC(int, body_get_shape_count, RID);
188 FUNC2RC(Transform3D, body_get_shape_transform, RID, int);
189 FUNC2RC(RID, body_get_shape, RID, int);
190
191 FUNC3(body_set_shape_disabled, RID, int, bool);
192
193 FUNC2(body_remove_shape, RID, int);
194 FUNC1(body_clear_shapes, RID);
195
196 FUNC2(body_attach_object_instance_id, RID, ObjectID);
197 FUNC1RC(ObjectID, body_get_object_instance_id, RID);
198
199 FUNC2(body_set_enable_continuous_collision_detection, RID, bool);
200 FUNC1RC(bool, body_is_continuous_collision_detection_enabled, RID);
201
202 FUNC2(body_set_collision_layer, RID, uint32_t);
203 FUNC1RC(uint32_t, body_get_collision_layer, RID);
204
205 FUNC2(body_set_collision_mask, RID, uint32_t);
206 FUNC1RC(uint32_t, body_get_collision_mask, RID);
207
208 FUNC2(body_set_collision_priority, RID, real_t);
209 FUNC1RC(real_t, body_get_collision_priority, RID);
210
211 FUNC2(body_set_user_flags, RID, uint32_t);
212 FUNC1RC(uint32_t, body_get_user_flags, RID);
213
214 FUNC3(body_set_param, RID, BodyParameter, const Variant &);
215 FUNC2RC(Variant, body_get_param, RID, BodyParameter);
216
217 FUNC1(body_reset_mass_properties, RID);
218
219 FUNC3(body_set_state, RID, BodyState, const Variant &);
220 FUNC2RC(Variant, body_get_state, RID, BodyState);
221
222 FUNC2(body_apply_torque_impulse, RID, const Vector3 &);
223 FUNC2(body_apply_central_impulse, RID, const Vector3 &);
224 FUNC3(body_apply_impulse, RID, const Vector3 &, const Vector3 &);
225
226 FUNC2(body_apply_central_force, RID, const Vector3 &);
227 FUNC3(body_apply_force, RID, const Vector3 &, const Vector3 &);
228 FUNC2(body_apply_torque, RID, const Vector3 &);
229
230 FUNC2(body_add_constant_central_force, RID, const Vector3 &);
231 FUNC3(body_add_constant_force, RID, const Vector3 &, const Vector3 &);
232 FUNC2(body_add_constant_torque, RID, const Vector3 &);
233
234 FUNC2(body_set_constant_force, RID, const Vector3 &);
235 FUNC1RC(Vector3, body_get_constant_force, RID);
236
237 FUNC2(body_set_constant_torque, RID, const Vector3 &);
238 FUNC1RC(Vector3, body_get_constant_torque, RID);
239
240 FUNC2(body_set_axis_velocity, RID, const Vector3 &);
241
242 FUNC3(body_set_axis_lock, RID, BodyAxis, bool);
243 FUNC2RC(bool, body_is_axis_locked, RID, BodyAxis);
244
245 FUNC2(body_add_collision_exception, RID, RID);
246 FUNC2(body_remove_collision_exception, RID, RID);
247 FUNC2S(body_get_collision_exceptions, RID, List<RID> *);
248
249 FUNC2(body_set_max_contacts_reported, RID, int);
250 FUNC1RC(int, body_get_max_contacts_reported, RID);
251
252 FUNC2(body_set_contacts_reported_depth_threshold, RID, real_t);
253 FUNC1RC(real_t, body_get_contacts_reported_depth_threshold, RID);
254
255 FUNC2(body_set_omit_force_integration, RID, bool);
256 FUNC1RC(bool, body_is_omitting_force_integration, RID);
257
258 FUNC2(body_set_state_sync_callback, RID, const Callable &);
259 FUNC3(body_set_force_integration_callback, RID, const Callable &, const Variant &);
260
261 FUNC2(body_set_ray_pickable, RID, bool);
262
263 bool body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result = nullptr) override {
264 ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
265 return physics_server_3d->body_test_motion(p_body, p_parameters, r_result);
266 }
267
268 // this function only works on physics process, errors and returns null otherwise
269 PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override {
270 ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr);
271 return physics_server_3d->body_get_direct_state(p_body);
272 }
273
274 /* SOFT BODY API */
275
276 FUNCRID(soft_body)
277
278 FUNC2(soft_body_update_rendering_server, RID, PhysicsServer3DRenderingServerHandler *)
279
280 FUNC2(soft_body_set_space, RID, RID)
281 FUNC1RC(RID, soft_body_get_space, RID)
282
283 FUNC2(soft_body_set_ray_pickable, RID, bool);
284
285 FUNC2(soft_body_set_collision_layer, RID, uint32_t)
286 FUNC1RC(uint32_t, soft_body_get_collision_layer, RID)
287
288 FUNC2(soft_body_set_collision_mask, RID, uint32_t)
289 FUNC1RC(uint32_t, soft_body_get_collision_mask, RID)
290
291 FUNC2(soft_body_add_collision_exception, RID, RID)
292 FUNC2(soft_body_remove_collision_exception, RID, RID)
293 FUNC2S(soft_body_get_collision_exceptions, RID, List<RID> *)
294
295 FUNC3(soft_body_set_state, RID, BodyState, const Variant &);
296 FUNC2RC(Variant, soft_body_get_state, RID, BodyState);
297
298 FUNC2(soft_body_set_transform, RID, const Transform3D &);
299
300 FUNC2(soft_body_set_simulation_precision, RID, int);
301 FUNC1RC(int, soft_body_get_simulation_precision, RID);
302
303 FUNC2(soft_body_set_total_mass, RID, real_t);
304 FUNC1RC(real_t, soft_body_get_total_mass, RID);
305
306 FUNC2(soft_body_set_linear_stiffness, RID, real_t);
307 FUNC1RC(real_t, soft_body_get_linear_stiffness, RID);
308
309 FUNC2(soft_body_set_pressure_coefficient, RID, real_t);
310 FUNC1RC(real_t, soft_body_get_pressure_coefficient, RID);
311
312 FUNC2(soft_body_set_damping_coefficient, RID, real_t);
313 FUNC1RC(real_t, soft_body_get_damping_coefficient, RID);
314
315 FUNC2(soft_body_set_drag_coefficient, RID, real_t);
316 FUNC1RC(real_t, soft_body_get_drag_coefficient, RID);
317
318 FUNC2(soft_body_set_mesh, RID, RID);
319
320 FUNC1RC(AABB, soft_body_get_bounds, RID);
321
322 FUNC3(soft_body_move_point, RID, int, const Vector3 &);
323 FUNC2RC(Vector3, soft_body_get_point_global_position, RID, int);
324
325 FUNC1(soft_body_remove_all_pinned_points, RID);
326 FUNC3(soft_body_pin_point, RID, int, bool);
327 FUNC2RC(bool, soft_body_is_point_pinned, RID, int);
328
329 /* JOINT API */
330
331 FUNCRID(joint)
332
333 FUNC1(joint_clear, RID)
334
335 FUNC5(joint_make_pin, RID, RID, const Vector3 &, RID, const Vector3 &)
336
337 FUNC3(pin_joint_set_param, RID, PinJointParam, real_t)
338 FUNC2RC(real_t, pin_joint_get_param, RID, PinJointParam)
339
340 FUNC2(pin_joint_set_local_a, RID, const Vector3 &)
341 FUNC1RC(Vector3, pin_joint_get_local_a, RID)
342
343 FUNC2(pin_joint_set_local_b, RID, const Vector3 &)
344 FUNC1RC(Vector3, pin_joint_get_local_b, RID)
345
346 FUNC5(joint_make_hinge, RID, RID, const Transform3D &, RID, const Transform3D &)
347 FUNC7(joint_make_hinge_simple, RID, RID, const Vector3 &, const Vector3 &, RID, const Vector3 &, const Vector3 &)
348
349 FUNC3(hinge_joint_set_param, RID, HingeJointParam, real_t)
350 FUNC2RC(real_t, hinge_joint_get_param, RID, HingeJointParam)
351
352 FUNC3(hinge_joint_set_flag, RID, HingeJointFlag, bool)
353 FUNC2RC(bool, hinge_joint_get_flag, RID, HingeJointFlag)
354
355 FUNC5(joint_make_slider, RID, RID, const Transform3D &, RID, const Transform3D &)
356
357 FUNC3(slider_joint_set_param, RID, SliderJointParam, real_t)
358 FUNC2RC(real_t, slider_joint_get_param, RID, SliderJointParam)
359
360 FUNC5(joint_make_cone_twist, RID, RID, const Transform3D &, RID, const Transform3D &)
361
362 FUNC3(cone_twist_joint_set_param, RID, ConeTwistJointParam, real_t)
363 FUNC2RC(real_t, cone_twist_joint_get_param, RID, ConeTwistJointParam)
364
365 FUNC5(joint_make_generic_6dof, RID, RID, const Transform3D &, RID, const Transform3D &)
366
367 FUNC4(generic_6dof_joint_set_param, RID, Vector3::Axis, G6DOFJointAxisParam, real_t)
368 FUNC3RC(real_t, generic_6dof_joint_get_param, RID, Vector3::Axis, G6DOFJointAxisParam)
369
370 FUNC4(generic_6dof_joint_set_flag, RID, Vector3::Axis, G6DOFJointAxisFlag, bool)
371 FUNC3RC(bool, generic_6dof_joint_get_flag, RID, Vector3::Axis, G6DOFJointAxisFlag)
372
373 FUNC1RC(JointType, joint_get_type, RID);
374
375 FUNC2(joint_set_solver_priority, RID, int);
376 FUNC1RC(int, joint_get_solver_priority, RID);
377
378 FUNC2(joint_disable_collisions_between_bodies, RID, bool);
379 FUNC1RC(bool, joint_is_disabled_collisions_between_bodies, RID);
380
381 /* MISC */
382
383 FUNC1(free, RID);
384 FUNC1(set_active, bool);
385
386 virtual void init() override;
387 virtual void step(real_t p_step) override;
388 virtual void sync() override;
389 virtual void end_sync() override;
390 virtual void flush_queries() override;
391 virtual void finish() override;
392
393 virtual bool is_flushing_queries() const override {
394 return physics_server_3d->is_flushing_queries();
395 }
396
397 int get_process_info(ProcessInfo p_info) override {
398 return physics_server_3d->get_process_info(p_info);
399 }
400
401 PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread);
402 ~PhysicsServer3DWrapMT();
403
404#undef ServerNameWrapMT
405#undef ServerName
406#undef server_name
407#undef WRITE_ACTION
408};
409
410#ifdef DEBUG_SYNC
411#undef DEBUG_SYNC
412#endif
413#undef SYNC_DEBUG
414
415#endif // PHYSICS_SERVER_3D_WRAP_MT_H
416