diff options
-rw-r--r-- | core/debugger/engine_debugger.h | 2 | ||||
-rw-r--r-- | core/debugger/local_debugger.cpp | 2 | ||||
-rw-r--r-- | core/debugger/local_debugger.h | 2 | ||||
-rw-r--r-- | core/debugger/remote_debugger.cpp | 6 | ||||
-rw-r--r-- | core/debugger/remote_debugger.h | 4 | ||||
-rw-r--r-- | core/debugger/script_debugger.cpp | 4 | ||||
-rw-r--r-- | core/debugger/script_debugger.h | 2 | ||||
-rw-r--r-- | core/error/error_macros.cpp | 36 | ||||
-rw-r--r-- | core/error/error_macros.h | 251 | ||||
-rw-r--r-- | core/extension/gdnative_interface.cpp | 6 | ||||
-rw-r--r-- | core/io/logger.cpp | 10 | ||||
-rw-r--r-- | core/io/logger.h | 4 | ||||
-rw-r--r-- | core/io/resource.cpp | 1 | ||||
-rw-r--r-- | core/os/os.cpp | 4 | ||||
-rw-r--r-- | core/os/os.h | 2 | ||||
-rw-r--r-- | doc/classes/XRAnchor3D.xml | 33 | ||||
-rw-r--r-- | doc/classes/XRController3D.xml | 68 | ||||
-rw-r--r-- | doc/classes/XRInterface.xml | 79 | ||||
-rw-r--r-- | doc/classes/XRInterfaceExtension.xml | 49 | ||||
-rw-r--r-- | doc/classes/XRNode3D.xml | 53 | ||||
-rw-r--r-- | doc/classes/XRPose.xml | 41 | ||||
-rw-r--r-- | doc/classes/XRPositionalTracker.xml | 121 | ||||
-rw-r--r-- | doc/classes/XRServer.xml | 31 | ||||
-rw-r--r-- | drivers/unix/os_unix.cpp | 2 | ||||
-rw-r--r-- | drivers/unix/os_unix.h | 2 | ||||
-rw-r--r-- | editor/editor_log.cpp | 6 | ||||
-rw-r--r-- | editor/editor_log.h | 2 | ||||
-rw-r--r-- | editor/editor_node.cpp | 4 | ||||
-rw-r--r-- | editor/editor_node.h | 2 | ||||
-rw-r--r-- | editor/editor_settings.cpp | 1 | ||||
-rw-r--r-- | editor/editor_toaster.cpp | 511 | ||||
-rw-r--r-- | editor/editor_toaster.h | 116 | ||||
-rw-r--r-- | editor/icons/Notification.svg | 1 | ||||
-rw-r--r-- | editor/icons/NotificationDisabled.svg | 1 | ||||
-rw-r--r-- | editor/plugins/tiles/atlas_merging_dialog.cpp | 1 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_map_editor.cpp | 19 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_set_atlas_source_editor.cpp | 23 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_set_editor.cpp | 19 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp | 28 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_set_scenes_collection_source_editor.h | 1 | ||||
-rw-r--r-- | editor/rename_dialog.cpp | 2 | ||||
-rw-r--r-- | editor/rename_dialog.h | 2 | ||||
-rw-r--r-- | main/main.cpp | 3 | ||||
-rw-r--r-- | modules/gdnative/gdnative/gdnative.cpp | 6 | ||||
-rw-r--r-- | modules/gdscript/gdscript.cpp | 8 | ||||
-rw-r--r-- | modules/gdscript/gdscript_vm.cpp | 2 | ||||
-rw-r--r-- | modules/gdscript/tests/gdscript_test_runner.cpp | 2 | ||||
-rw-r--r-- | modules/gdscript/tests/gdscript_test_runner.h | 2 | ||||
-rw-r--r-- | modules/gltf/gltf_document.cpp | 4 | ||||
-rw-r--r-- | modules/mobile_vr/doc_classes/MobileVRInterface.xml | 1 | ||||
-rw-r--r-- | modules/mobile_vr/mobile_vr_interface.cpp | 69 | ||||
-rw-r--r-- | modules/mobile_vr/mobile_vr_interface.h | 9 | ||||
-rw-r--r-- | modules/mono/csharp_script.cpp | 2 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_property.cpp | 30 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_property.h | 5 | ||||
-rw-r--r-- | modules/visual_script/visual_script.cpp | 2 | ||||
-rw-r--r-- | modules/webxr/doc_classes/WebXRInterface.xml | 2 | ||||
-rw-r--r-- | modules/webxr/webxr_interface_js.cpp | 86 | ||||
-rw-r--r-- | modules/webxr/webxr_interface_js.h | 3 | ||||
-rw-r--r-- | platform/osx/os_osx.mm | 2 | ||||
-rw-r--r-- | scene/3d/xr_nodes.cpp | 627 | ||||
-rw-r--r-- | scene/3d/xr_nodes.h | 110 | ||||
-rw-r--r-- | scene/register_scene_types.cpp | 3 | ||||
-rw-r--r-- | servers/audio_server.cpp | 6 | ||||
-rw-r--r-- | servers/physics_2d/godot_area_2d.cpp (renamed from servers/physics_2d/area_2d_sw.cpp) | 42 | ||||
-rw-r--r-- | servers/physics_2d/godot_area_2d.h (renamed from servers/physics_2d/area_2d_sw.h) | 57 | ||||
-rw-r--r-- | servers/physics_2d/godot_area_pair_2d.cpp (renamed from servers/physics_2d/area_pair_2d_sw.cpp) | 30 | ||||
-rw-r--r-- | servers/physics_2d/godot_area_pair_2d.h (renamed from servers/physics_2d/area_pair_2d_sw.h) | 34 | ||||
-rw-r--r-- | servers/physics_2d/godot_body_2d.cpp (renamed from servers/physics_2d/body_2d_sw.cpp) | 74 | ||||
-rw-r--r-- | servers/physics_2d/godot_body_2d.h (renamed from servers/physics_2d/body_2d_sw.h) | 57 | ||||
-rw-r--r-- | servers/physics_2d/godot_body_direct_state_2d.cpp (renamed from servers/physics_2d/body_direct_state_2d_sw.cpp) | 74 | ||||
-rw-r--r-- | servers/physics_2d/godot_body_direct_state_2d.h (renamed from servers/physics_2d/body_direct_state_2d_sw.h) | 16 | ||||
-rw-r--r-- | servers/physics_2d/godot_body_pair_2d.cpp (renamed from servers/physics_2d/body_pair_2d_sw.cpp) | 44 | ||||
-rw-r--r-- | servers/physics_2d/godot_body_pair_2d.h (renamed from servers/physics_2d/body_pair_2d_sw.h) | 28 | ||||
-rw-r--r-- | servers/physics_2d/godot_broad_phase_2d.cpp (renamed from servers/physics_2d/broad_phase_2d_sw.cpp) | 8 | ||||
-rw-r--r-- | servers/physics_2d/godot_broad_phase_2d.h (renamed from servers/physics_2d/broad_phase_2d_sw.h) | 28 | ||||
-rw-r--r-- | servers/physics_2d/godot_broad_phase_2d_bvh.cpp (renamed from servers/physics_2d/broad_phase_2d_bvh.cpp) | 48 | ||||
-rw-r--r-- | servers/physics_2d/godot_broad_phase_2d_bvh.h (renamed from servers/physics_2d/broad_phase_2d_bvh.h) | 31 | ||||
-rw-r--r-- | servers/physics_2d/godot_collision_object_2d.cpp (renamed from servers/physics_2d/collision_object_2d_sw.cpp) | 48 | ||||
-rw-r--r-- | servers/physics_2d/godot_collision_object_2d.h (renamed from servers/physics_2d/collision_object_2d_sw.h) | 47 | ||||
-rw-r--r-- | servers/physics_2d/godot_collision_solver_2d.cpp (renamed from servers/physics_2d/collision_solver_2d_sw.cpp) | 26 | ||||
-rw-r--r-- | servers/physics_2d/godot_collision_solver_2d.h (renamed from servers/physics_2d/collision_solver_2d_sw.h) | 22 | ||||
-rw-r--r-- | servers/physics_2d/godot_collision_solver_2d_sat.cpp (renamed from servers/physics_2d/collision_solver_2d_sat.cpp) | 134 | ||||
-rw-r--r-- | servers/physics_2d/godot_collision_solver_2d_sat.h (renamed from servers/physics_2d/collision_solver_2d_sat.h) | 12 | ||||
-rw-r--r-- | servers/physics_2d/godot_constraint_2d.h (renamed from servers/physics_2d/constraint_2d_sw.h) | 20 | ||||
-rw-r--r-- | servers/physics_2d/godot_joints_2d.cpp (renamed from servers/physics_2d/joints_2d_sw.cpp) | 58 | ||||
-rw-r--r-- | servers/physics_2d/godot_joints_2d.h (renamed from servers/physics_2d/joints_2d_sw.h) | 54 | ||||
-rw-r--r-- | servers/physics_2d/godot_physics_server_2d.cpp | 1350 | ||||
-rw-r--r-- | servers/physics_2d/godot_physics_server_2d.h (renamed from servers/physics_2d/physics_server_2d_sw.h) | 50 | ||||
-rw-r--r-- | servers/physics_2d/godot_shape_2d.cpp (renamed from servers/physics_2d/shape_2d_sw.cpp) | 128 | ||||
-rw-r--r-- | servers/physics_2d/godot_shape_2d.h (renamed from servers/physics_2d/shape_2d_sw.h) | 70 | ||||
-rw-r--r-- | servers/physics_2d/godot_space_2d.cpp (renamed from servers/physics_2d/space_2d_sw.cpp) | 247 | ||||
-rw-r--r-- | servers/physics_2d/godot_space_2d.h (renamed from servers/physics_2d/space_2d_sw.h) | 107 | ||||
-rw-r--r-- | servers/physics_2d/godot_step_2d.cpp (renamed from servers/physics_2d/step_2d_sw.cpp) | 72 | ||||
-rw-r--r-- | servers/physics_2d/godot_step_2d.h (renamed from servers/physics_2d/step_2d_sw.h) | 30 | ||||
-rw-r--r-- | servers/physics_2d/physics_server_2d_sw.cpp | 1349 | ||||
-rw-r--r-- | servers/physics_3d/gjk_epa.cpp | 28 | ||||
-rw-r--r-- | servers/physics_3d/gjk_epa.h | 8 | ||||
-rw-r--r-- | servers/physics_3d/godot_area_3d.cpp (renamed from servers/physics_3d/area_3d_sw.cpp) | 47 | ||||
-rw-r--r-- | servers/physics_3d/godot_area_3d.h (renamed from servers/physics_3d/area_3d_sw.h) | 73 | ||||
-rw-r--r-- | servers/physics_3d/godot_area_pair_3d.cpp (renamed from servers/physics_3d/area_pair_3d_sw.cpp) | 43 | ||||
-rw-r--r-- | servers/physics_3d/godot_area_pair_3d.h (renamed from servers/physics_3d/area_pair_3d_sw.h) | 46 | ||||
-rw-r--r-- | servers/physics_3d/godot_body_3d.cpp (renamed from servers/physics_3d/body_3d_sw.cpp) | 111 | ||||
-rw-r--r-- | servers/physics_3d/godot_body_3d.h (renamed from servers/physics_3d/body_3d_sw.h) | 53 | ||||
-rw-r--r-- | servers/physics_3d/godot_body_direct_state_3d.cpp (renamed from servers/physics_3d/body_direct_state_3d_sw.cpp) | 78 | ||||
-rw-r--r-- | servers/physics_3d/godot_body_direct_state_3d.h (renamed from servers/physics_3d/body_direct_state_3d_sw.h) | 16 | ||||
-rw-r--r-- | servers/physics_3d/godot_body_pair_3d.cpp (renamed from servers/physics_3d/body_pair_3d_sw.cpp) | 73 | ||||
-rw-r--r-- | servers/physics_3d/godot_body_pair_3d.h (renamed from servers/physics_3d/body_pair_3d_sw.h) | 49 | ||||
-rw-r--r-- | servers/physics_3d/godot_broad_phase_3d.cpp (renamed from servers/physics_3d/broad_phase_3d_sw.cpp) | 8 | ||||
-rw-r--r-- | servers/physics_3d/godot_broad_phase_3d.h (renamed from servers/physics_3d/broad_phase_3d_sw.h) | 30 | ||||
-rw-r--r-- | servers/physics_3d/godot_broad_phase_3d_bvh.cpp (renamed from servers/physics_3d/broad_phase_3d_bvh.cpp) | 51 | ||||
-rw-r--r-- | servers/physics_3d/godot_broad_phase_3d_bvh.h (renamed from servers/physics_3d/broad_phase_3d_bvh.h) | 33 | ||||
-rw-r--r-- | servers/physics_3d/godot_collision_object_3d.cpp (renamed from servers/physics_3d/collision_object_3d_sw.cpp) | 49 | ||||
-rw-r--r-- | servers/physics_3d/godot_collision_object_3d.h (renamed from servers/physics_3d/collision_object_3d_sw.h) | 47 | ||||
-rw-r--r-- | servers/physics_3d/godot_collision_solver_3d.cpp (renamed from servers/physics_3d/collision_solver_3d_sw.cpp) | 70 | ||||
-rw-r--r-- | servers/physics_3d/godot_collision_solver_3d.h (renamed from servers/physics_3d/collision_solver_3d_sw.h) | 32 | ||||
-rw-r--r-- | servers/physics_3d/godot_collision_solver_3d_sat.cpp (renamed from servers/physics_3d/collision_solver_3d_sat.cpp) | 189 | ||||
-rw-r--r-- | servers/physics_3d/godot_collision_solver_3d_sat.h (renamed from servers/physics_3d/collision_solver_3d_sat.h) | 12 | ||||
-rw-r--r-- | servers/physics_3d/godot_constraint_3d.h (renamed from servers/physics_3d/constraint_3d_sw.h) | 24 | ||||
-rw-r--r-- | servers/physics_3d/godot_joint_3d.h (renamed from servers/physics_3d/joints_3d_sw.h) | 24 | ||||
-rw-r--r-- | servers/physics_3d/godot_physics_server_3d.cpp | 1749 | ||||
-rw-r--r-- | servers/physics_3d/godot_physics_server_3d.h (renamed from servers/physics_3d/physics_server_3d_sw.h) | 49 | ||||
-rw-r--r-- | servers/physics_3d/godot_shape_3d.cpp (renamed from servers/physics_3d/shape_3d_sw.cpp) | 332 | ||||
-rw-r--r-- | servers/physics_3d/godot_shape_3d.h (renamed from servers/physics_3d/shape_3d_sw.h) | 94 | ||||
-rw-r--r-- | servers/physics_3d/godot_soft_body_3d.cpp (renamed from servers/physics_3d/soft_body_3d_sw.cpp) | 149 | ||||
-rw-r--r-- | servers/physics_3d/godot_soft_body_3d.h (renamed from servers/physics_3d/soft_body_3d_sw.h) | 48 | ||||
-rw-r--r-- | servers/physics_3d/godot_space_3d.cpp (renamed from servers/physics_3d/space_3d_sw.cpp) | 263 | ||||
-rw-r--r-- | servers/physics_3d/godot_space_3d.h (renamed from servers/physics_3d/space_3d_sw.h) | 113 | ||||
-rw-r--r-- | servers/physics_3d/godot_step_3d.cpp (renamed from servers/physics_3d/step_3d_sw.cpp) | 97 | ||||
-rw-r--r-- | servers/physics_3d/godot_step_3d.h (renamed from servers/physics_3d/step_3d_sw.h) | 32 | ||||
-rw-r--r-- | servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp (renamed from servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp) | 18 | ||||
-rw-r--r-- | servers/physics_3d/joints/godot_cone_twist_joint_3d.h (renamed from servers/physics_3d/joints/cone_twist_joint_3d_sw.h) | 28 | ||||
-rw-r--r-- | servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp (renamed from servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp) | 69 | ||||
-rw-r--r-- | servers/physics_3d/joints/godot_generic_6dof_joint_3d.h (renamed from servers/physics_3d/joints/generic_6dof_joint_3d_sw.h) | 111 | ||||
-rw-r--r-- | servers/physics_3d/joints/godot_hinge_joint_3d.cpp (renamed from servers/physics_3d/joints/hinge_joint_3d_sw.cpp) | 34 | ||||
-rw-r--r-- | servers/physics_3d/joints/godot_hinge_joint_3d.h (renamed from servers/physics_3d/joints/hinge_joint_3d_sw.h) | 28 | ||||
-rw-r--r-- | servers/physics_3d/joints/godot_jacobian_entry_3d.h (renamed from servers/physics_3d/joints/jacobian_entry_3d_sw.h) | 28 | ||||
-rw-r--r-- | servers/physics_3d/joints/godot_pin_joint_3d.cpp (renamed from servers/physics_3d/joints/pin_joint_3d_sw.cpp) | 20 | ||||
-rw-r--r-- | servers/physics_3d/joints/godot_pin_joint_3d.h (renamed from servers/physics_3d/joints/pin_joint_3d_sw.h) | 26 | ||||
-rw-r--r-- | servers/physics_3d/joints/godot_slider_joint_3d.cpp (renamed from servers/physics_3d/joints/slider_joint_3d_sw.cpp) | 48 | ||||
-rw-r--r-- | servers/physics_3d/joints/godot_slider_joint_3d.h (renamed from servers/physics_3d/joints/slider_joint_3d_sw.h) | 30 | ||||
-rw-r--r-- | servers/physics_3d/physics_server_3d_sw.cpp | 1748 | ||||
-rw-r--r-- | servers/physics_server_2d.h | 6 | ||||
-rw-r--r-- | servers/physics_server_2d_wrap_mt.cpp (renamed from servers/physics_2d/physics_server_2d_wrap_mt.cpp) | 0 | ||||
-rw-r--r-- | servers/physics_server_2d_wrap_mt.h (renamed from servers/physics_2d/physics_server_2d_wrap_mt.h) | 6 | ||||
-rw-r--r-- | servers/physics_server_3d.h | 6 | ||||
-rw-r--r-- | servers/physics_server_3d_wrap_mt.cpp (renamed from servers/physics_3d/physics_server_3d_wrap_mt.cpp) | 0 | ||||
-rw-r--r-- | servers/physics_server_3d_wrap_mt.h (renamed from servers/physics_3d/physics_server_3d_wrap_mt.h) | 6 | ||||
-rw-r--r-- | servers/register_server_types.cpp | 13 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/shader_compiler_rd.cpp | 2 | ||||
-rw-r--r-- | servers/rendering/renderer_viewport.cpp | 3 | ||||
-rw-r--r-- | servers/xr/xr_interface.cpp | 67 | ||||
-rw-r--r-- | servers/xr/xr_interface.h | 33 | ||||
-rw-r--r-- | servers/xr/xr_interface_extension.cpp | 70 | ||||
-rw-r--r-- | servers/xr/xr_interface_extension.h | 19 | ||||
-rw-r--r-- | servers/xr/xr_pose.cpp | 110 | ||||
-rw-r--r-- | servers/xr/xr_pose.h | 68 | ||||
-rw-r--r-- | servers/xr/xr_positional_tracker.cpp | 247 | ||||
-rw-r--r-- | servers/xr/xr_positional_tracker.h | 42 | ||||
-rw-r--r-- | servers/xr_server.cpp | 227 | ||||
-rw-r--r-- | servers/xr_server.h | 23 | ||||
-rw-r--r-- | tests/test_tools.h | 2 |
162 files changed, 7902 insertions, 6289 deletions
diff --git a/core/debugger/engine_debugger.h b/core/debugger/engine_debugger.h index 22c6ef943e..41142bf305 100644 --- a/core/debugger/engine_debugger.h +++ b/core/debugger/engine_debugger.h @@ -128,7 +128,7 @@ public: virtual void poll_events(bool p_is_idle) {} virtual void send_message(const String &p_msg, const Array &p_data) = 0; - virtual void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type) = 0; + virtual void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type) = 0; virtual void debug(bool p_can_continue = true, bool p_is_error_breakpoint = false) = 0; virtual ~EngineDebugger(); diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp index f7e56351b0..60aa3e6be7 100644 --- a/core/debugger/local_debugger.cpp +++ b/core/debugger/local_debugger.cpp @@ -358,7 +358,7 @@ void LocalDebugger::send_message(const String &p_message, const Array &p_args) { // print_line("MESSAGE: '" + p_message + "' - " + String(Variant(p_args))); } -void LocalDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type) { +void LocalDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type) { print_line("ERROR: '" + (p_descr.is_empty() ? p_err : p_descr) + "'"); } diff --git a/core/debugger/local_debugger.h b/core/debugger/local_debugger.h index e793b2a859..cb59eb82e9 100644 --- a/core/debugger/local_debugger.h +++ b/core/debugger/local_debugger.h @@ -50,7 +50,7 @@ private: public: void debug(bool p_can_continue, bool p_is_error_breakpoint); void send_message(const String &p_message, const Array &p_args); - void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type); + void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type); LocalDebugger(); ~LocalDebugger(); diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index 032c7d55c0..9967d1e361 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -455,7 +455,7 @@ Error RemoteDebugger::_put_msg(String p_message, Array p_data) { return err; } -void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, ErrorHandlerType p_type) { +void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, bool p_editor_notify, ErrorHandlerType p_type) { if (p_type == ERR_HANDLER_SCRIPT) { return; //ignore script errors, those go through debugger } @@ -475,7 +475,7 @@ void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char * } // send_error will lock internally. - rd->script_debugger->send_error(p_func, p_file, p_line, p_err, p_descr, p_type, si); + rd->script_debugger->send_error(p_func, p_file, p_line, p_err, p_descr, p_editor_notify, p_type, si); } void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p_error) { @@ -605,7 +605,7 @@ void RemoteDebugger::send_message(const String &p_message, const Array &p_args) } } -void RemoteDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type) { +void RemoteDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type) { ErrorMessage oe; oe.error = p_err; oe.error_descr = p_descr; diff --git a/core/debugger/remote_debugger.h b/core/debugger/remote_debugger.h index 28e670747e..73799e3f81 100644 --- a/core/debugger/remote_debugger.h +++ b/core/debugger/remote_debugger.h @@ -89,7 +89,7 @@ private: PrintHandlerList phl; static void _print_handler(void *p_this, const String &p_string, bool p_error); ErrorHandlerList eh; - static void _err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, ErrorHandlerType p_type); + static void _err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, bool p_editor_notify, ErrorHandlerType p_type); ErrorMessage _create_overflow_error(const String &p_what, const String &p_descr); Error _put_msg(String p_message, Array p_data); @@ -111,7 +111,7 @@ public: // Overrides void poll_events(bool p_is_idle); void send_message(const String &p_message, const Array &p_args); - void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type); + void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type); void debug(bool p_can_continue = true, bool p_is_error_breakpoint = false); RemoteDebugger(Ref<RemoteDebuggerPeer> p_peer); diff --git a/core/debugger/script_debugger.cpp b/core/debugger/script_debugger.cpp index 6d1e4ed101..70ec101a03 100644 --- a/core/debugger/script_debugger.cpp +++ b/core/debugger/script_debugger.cpp @@ -100,10 +100,10 @@ void ScriptDebugger::debug(ScriptLanguage *p_lang, bool p_can_continue, bool p_i break_lang = prev; } -void ScriptDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<StackInfo> &p_stack_info) { +void ScriptDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type, const Vector<StackInfo> &p_stack_info) { // Store stack info, this is ugly, but allows us to separate EngineDebugger and ScriptDebugger. There might be a better way. error_stack_info.append_array(p_stack_info); - EngineDebugger::get_singleton()->send_error(p_func, p_file, p_line, p_err, p_descr, p_type); + EngineDebugger::get_singleton()->send_error(p_func, p_file, p_line, p_err, p_descr, p_editor_notify, p_type); error_stack_info.resize(0); } diff --git a/core/debugger/script_debugger.h b/core/debugger/script_debugger.h index 9f034a5e5d..c1d0170334 100644 --- a/core/debugger/script_debugger.h +++ b/core/debugger/script_debugger.h @@ -71,7 +71,7 @@ public: void debug(ScriptLanguage *p_lang, bool p_can_continue = true, bool p_is_error_breakpoint = false); ScriptLanguage *get_break_language() const; - void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<StackInfo> &p_stack_info); + void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type, const Vector<StackInfo> &p_stack_info); Vector<StackInfo> get_error_stack_info() const; ScriptDebugger() {} }; diff --git a/core/error/error_macros.cpp b/core/error/error_macros.cpp index 272dda97d8..719ea8afb5 100644 --- a/core/error/error_macros.cpp +++ b/core/error/error_macros.cpp @@ -65,45 +65,49 @@ void remove_error_handler(ErrorHandlerList *p_handler) { _global_unlock(); } -void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type) { - _err_print_error(p_function, p_file, p_line, p_error, "", p_type); +// Errors without messages. +void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_editor_notify, ErrorHandlerType p_type) { + _err_print_error(p_function, p_file, p_line, p_error, "", p_editor_notify, p_type); } -void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, ErrorHandlerType p_type) { - _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), "", p_type); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, bool p_editor_notify, ErrorHandlerType p_type) { + _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), "", p_editor_notify, p_type); } -void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, ErrorHandlerType p_type) { +// Main error printing function. +void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify, ErrorHandlerType p_type) { OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, p_message, (Logger::ErrorType)p_type); _global_lock(); ErrorHandlerList *l = error_handler_list; while (l) { - l->errfunc(l->userdata, p_function, p_file, p_line, p_error, p_message, p_type); + l->errfunc(l->userdata, p_function, p_file, p_line, p_error, p_message, p_editor_notify, p_type); l = l->next; } _global_unlock(); } -void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, ErrorHandlerType p_type) { - _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_message, p_type); +// Errors with message. (All combinations of p_error and p_message as String or char*.) +void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, bool p_editor_notify, ErrorHandlerType p_type) { + _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_message, p_editor_notify, p_type); } -void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, ErrorHandlerType p_type) { - _err_print_error(p_function, p_file, p_line, p_error, p_message.utf8().get_data(), p_type); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, bool p_editor_notify, ErrorHandlerType p_type) { + _err_print_error(p_function, p_file, p_line, p_error, p_message.utf8().get_data(), p_editor_notify, p_type); } -void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, ErrorHandlerType p_type) { - _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_message.utf8().get_data(), p_type); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, bool p_editor_notify, ErrorHandlerType p_type) { + _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_message.utf8().get_data(), p_editor_notify, p_type); } -void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message, bool fatal) { - String fstr(fatal ? "FATAL: " : ""); +// Index errors. (All combinations of p_message as String or char*.) +void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message, bool p_editor_notify, bool p_fatal) { + String fstr(p_fatal ? "FATAL: " : ""); String err(fstr + "Index " + p_index_str + " = " + itos(p_index) + " is out of bounds (" + p_size_str + " = " + itos(p_size) + ")."); _err_print_error(p_function, p_file, p_line, err.utf8().get_data(), p_message); } -void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool fatal) { - _err_print_index_error(p_function, p_file, p_line, p_index, p_size, p_index_str, p_size_str, p_message.utf8().get_data(), fatal); +void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool p_editor_notify, bool p_fatal) { + _err_print_index_error(p_function, p_file, p_line, p_index, p_size, p_index_str, p_size_str, p_message.utf8().get_data(), p_fatal); } diff --git a/core/error/error_macros.h b/core/error/error_macros.h index 1bed8d366b..4eb862dce2 100644 --- a/core/error/error_macros.h +++ b/core/error/error_macros.h @@ -46,7 +46,7 @@ enum ErrorHandlerType { // Pointer to the error handler printing function. Reassign to any function to have errors printed. // Parameters: userdata, function, file, line, error, explanation, type. -typedef void (*ErrorHandlerFunc)(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type); +typedef void (*ErrorHandlerFunc)(void *, const char *, const char *, int p_line, const char *, const char *, bool p_editor_notify, ErrorHandlerType p_type); struct ErrorHandlerList { ErrorHandlerFunc errfunc = nullptr; @@ -61,14 +61,14 @@ void add_error_handler(ErrorHandlerList *p_handler); void remove_error_handler(ErrorHandlerList *p_handler); // Functions used by the error macros. -void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool fatal = false); -void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool fatal = false); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool p_editor_notify = false, bool fatal = false); +void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool p_editor_notify = false, bool fatal = false); #ifdef __GNUC__ //#define FUNCTION_STR __PRETTY_FUNCTION__ - too annoying @@ -136,6 +136,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li ((void)0) /** + * Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0. + * If not, prints `m_msg`, notifies in the editor, and the current function returns. + */ +#define ERR_FAIL_INDEX_EDMSG(m_index, m_size, m_msg) \ + if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \ + return; \ + } else \ + ((void)0) + +/** * Try using `ERR_FAIL_INDEX_V_MSG`. * Only use this macro if there is no sensible error message. * @@ -161,6 +172,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li ((void)0) /** + * Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0. + * If not, prints `m_msg`, notifies in the editor, and the current function returns `m_retval`. + */ +#define ERR_FAIL_INDEX_V_EDMSG(m_index, m_size, m_retval, m_msg) \ + if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \ + return m_retval; \ + } else \ + ((void)0) + +/** * Try using `ERR_FAIL_INDEX_MSG` or `ERR_FAIL_INDEX_V_MSG`. * Only use this macro if there is no sensible fallback i.e. the error is unrecoverable, and * there is no sensible error message. @@ -215,6 +237,16 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li return; \ } else \ ((void)0) +/** + * Ensures an unsigned integer index `m_index` is less than `m_size`. + * If not, prints `m_msg`, notifies in the editor, and the current function returns. + */ +#define ERR_FAIL_UNSIGNED_INDEX_EDMSG(m_index, m_size, m_msg) \ + if (unlikely((m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \ + return; \ + } else \ + ((void)0) /** * Try using `ERR_FAIL_UNSIGNED_INDEX_V_MSG`. @@ -242,6 +274,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li ((void)0) /** + * Ensures an unsigned integer index `m_index` is less than `m_size`. + * If not, prints `m_msg`, notifies in the editor, and the current function returns `m_retval`. + */ +#define ERR_FAIL_UNSIGNED_INDEX_V_EDMSG(m_index, m_size, m_retval, m_msg) \ + if (unlikely((m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \ + return m_retval; \ + } else \ + ((void)0) + +/** * Try using `ERR_FAIL_UNSIGNED_INDEX_MSG` or `ERR_FAIL_UNSIGNED_INDEX_V_MSG`. * Only use this macro if there is no sensible fallback i.e. the error is unrecoverable, and * there is no sensible error message. @@ -298,6 +341,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li ((void)0) /** + * Ensures a pointer `m_param` is not null. + * If it is null, prints `m_msg`, notifies in the editor, and the current function returns. + */ +#define ERR_FAIL_NULL_EDMSG(m_param, m_msg) \ + if (unlikely(m_param == nullptr)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", m_msg, true); \ + return; \ + } else \ + ((void)0) + +/** * Try using `ERR_FAIL_NULL_V_MSG`. * Only use this macro if there is no sensible error message. * @@ -323,6 +377,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li ((void)0) /** + * Ensures a pointer `m_param` is not null. + * If it is null, prints `m_msg`, notifies in the editor, and the current function returns `m_retval`. + */ +#define ERR_FAIL_NULL_V_EDMSG(m_param, m_retval, m_msg) \ + if (unlikely(m_param == nullptr)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", m_msg, true); \ + return m_retval; \ + } else \ + ((void)0) + +/** * Try using `ERR_FAIL_COND_MSG`. * Only use this macro if there is no sensible error message. * If checking for null use ERR_FAIL_NULL_MSG instead. @@ -353,6 +418,20 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li ((void)0) /** + * Ensures `m_cond` is false. + * If `m_cond` is true, prints `m_msg`, notifies in the editor, and the current function returns. + * + * If checking for null use ERR_FAIL_NULL_MSG instead. + * If checking index bounds use ERR_FAIL_INDEX_MSG instead. + */ +#define ERR_FAIL_COND_EDMSG(m_cond, m_msg) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true.", m_msg, true); \ + return; \ + } else \ + ((void)0) + +/** * Try using `ERR_FAIL_COND_V_MSG`. * Only use this macro if there is no sensible error message. * If checking for null use ERR_FAIL_NULL_V_MSG instead. @@ -383,6 +462,20 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li ((void)0) /** + * Ensures `m_cond` is false. + * If `m_cond` is true, prints `m_msg`, notifies in the editor, and the current function returns `m_retval`. + * + * If checking for null use ERR_FAIL_NULL_V_MSG instead. + * If checking index bounds use ERR_FAIL_INDEX_V_MSG instead. + */ +#define ERR_FAIL_COND_V_EDMSG(m_cond, m_retval, m_msg) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returning: " _STR(m_retval), m_msg, true); \ + return m_retval; \ + } else \ + ((void)0) + +/** * Try using `ERR_CONTINUE_MSG`. * Only use this macro if there is no sensible error message. * @@ -408,6 +501,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li ((void)0) /** + * Ensures `m_cond` is false. + * If `m_cond` is true, prints `m_msg`, notifies in the editor, and the current loop continues. + */ +#define ERR_CONTINUE_EDMSG(m_cond, m_msg) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Continuing.", m_msg, true); \ + continue; \ + } else \ + ((void)0) + +/** * Try using `ERR_BREAK_MSG`. * Only use this macro if there is no sensible error message. * @@ -433,6 +537,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li ((void)0) /** + * Ensures `m_cond` is false. + * If `m_cond` is true, prints `m_msg`, notifies in the editor, and the current loop breaks. + */ +#define ERR_BREAK_EDMSG(m_cond, m_msg) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Breaking.", m_msg, true); \ + break; \ + } else \ + ((void)0) + +/** * Try using `ERR_FAIL_COND_MSG` or `ERR_FAIL_COND_V_MSG`. * Only use this macro if there is no sensible fallback i.e. the error is unrecoverable, and * there is no sensible error message. @@ -491,6 +606,19 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li ((void)0) /** + * Try using `ERR_FAIL_COND_MSG`. + * Only use this macro if more complex error detection or recovery is required. + * + * Prints `m_msg`, notifies in the editor, and the current function returns. + */ +#define ERR_FAIL_EDMSG(m_msg) \ + if (true) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed.", m_msg, true); \ + return; \ + } else \ + ((void)0) + +/** * Try using `ERR_FAIL_COND_V_MSG` or `ERR_FAIL_V_MSG`. * Only use this macro if more complex error detection or recovery is required, and * there is no sensible error message. @@ -518,6 +646,19 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li ((void)0) /** + * Try using `ERR_FAIL_COND_V_MSG`. + * Only use this macro if more complex error detection or recovery is required. + * + * Prints `m_msg`, notifies in the editor, and the current function returns `m_retval`. + */ +#define ERR_FAIL_V_EDMSG(m_retval, m_msg) \ + if (true) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed. Returning: " _STR(m_retval), m_msg, true); \ + return m_retval; \ + } else \ + ((void)0) + +/** * Try using `ERR_FAIL_COND_MSG`, `ERR_FAIL_COND_V_MSG`, `ERR_CONTINUE_MSG` or ERR_BREAK_MSG. * Only use this macro at the start of a function that has not been implemented yet, or * if more complex error detection or recovery is required. @@ -528,6 +669,16 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg) /** + * Try using `ERR_FAIL_COND_MSG`, `ERR_FAIL_COND_V_MSG`, `ERR_CONTINUE_MSG` or ERR_BREAK_MSG. + * Only use this macro at the start of a function that has not been implemented yet, or + * if more complex error detection or recovery is required. + * + * Prints `m_msg` and notifies the editor. + */ +#define ERR_PRINT_ED(m_msg) \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, ) + +/** * Prints `m_msg` once during the application lifetime. */ #define ERR_PRINT_ONCE(m_msg) \ @@ -540,6 +691,19 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li } else \ ((void)0) +/** + * Prints `m_msg` and notifies the editor once during the application lifetime. + */ +#define ERR_PRINT_ONCE_ED(m_msg) \ + if (true) { \ + static bool first_print = true; \ + if (first_print) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, true); \ + first_print = false; \ + } \ + } else \ + ((void)0) + // Print warning message macros. /** @@ -548,52 +712,75 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li * If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead. */ #define WARN_PRINT(m_msg) \ - _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, ERR_HANDLER_WARNING) + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, false, ERR_HANDLER_WARNING) + +/** + * Prints `m_msg` and notifies the editor. + * + * If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead. + */ +#define WARN_PRINT_ED(m_msg) \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, true, ERR_HANDLER_WARNING) /** * Prints `m_msg` once during the application lifetime. * * If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead. */ -#define WARN_PRINT_ONCE(m_msg) \ - if (true) { \ - static bool first_print = true; \ - if (first_print) { \ - _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, ERR_HANDLER_WARNING); \ - first_print = false; \ - } \ - } else \ +#define WARN_PRINT_ONCE(m_msg) \ + if (true) { \ + static bool first_print = true; \ + if (first_print) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, false, ERR_HANDLER_WARNING); \ + first_print = false; \ + } \ + } else \ ((void)0) -// Print deprecated warning message macros. - /** - * Warns that the current function is deprecated. + * Prints `m_msg` and notifies the editor once during the application lifetime. + * + * If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead. */ -#define WARN_DEPRECATED \ - if (true) { \ - static SafeFlag warning_shown; \ - if (!warning_shown.is_set()) { \ - _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", ERR_HANDLER_WARNING); \ - warning_shown.set(); \ - } \ - } else \ +#define WARN_PRINT_ONCE_ED(m_msg) \ + if (true) { \ + static bool first_print = true; \ + if (first_print) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, true, ERR_HANDLER_WARNING); \ + first_print = false; \ + } \ + } else \ ((void)0) +// Print deprecated warning message macros. + /** - * Warns that the current function is deprecated and prints `m_msg`. + * Warns that the current function is deprecated. */ -#define WARN_DEPRECATED_MSG(m_msg) \ +#define WARN_DEPRECATED \ if (true) { \ static SafeFlag warning_shown; \ if (!warning_shown.is_set()) { \ - _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", m_msg, ERR_HANDLER_WARNING); \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", false, ERR_HANDLER_WARNING); \ warning_shown.set(); \ } \ } else \ ((void)0) /** + * Warns that the current function is deprecated and prints `m_msg`. + */ +#define WARN_DEPRECATED_MSG(m_msg) \ + if (true) { \ + static SafeFlag warning_shown; \ + if (!warning_shown.is_set()) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", m_msg, false, ERR_HANDLER_WARNING); \ + warning_shown.set(); \ + } \ + } else \ + ((void)0) + +/** * Do not use. * If the application should never reach this point use CRASH_NOW_MSG(m_msg) to explain why. * diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp index ff09b0b86c..4770c9c65f 100644 --- a/core/extension/gdnative_interface.cpp +++ b/core/extension/gdnative_interface.cpp @@ -51,13 +51,13 @@ static void gdnative_free(void *p_mem) { // Helper print functions. static void gdnative_print_error(const char *p_description, const char *p_function, const char *p_file, int32_t p_line) { - _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_ERROR); + _err_print_error(p_function, p_file, p_line, p_description, false, ERR_HANDLER_ERROR); } static void gdnative_print_warning(const char *p_description, const char *p_function, const char *p_file, int32_t p_line) { - _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_WARNING); + _err_print_error(p_function, p_file, p_line, p_description, false, ERR_HANDLER_WARNING); } static void gdnative_print_script_error(const char *p_description, const char *p_function, const char *p_file, int32_t p_line) { - _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_SCRIPT); + _err_print_error(p_function, p_file, p_line, p_description, false, ERR_HANDLER_SCRIPT); } // Variant functions diff --git a/core/io/logger.cpp b/core/io/logger.cpp index 09539f716c..b68a8b20a5 100644 --- a/core/io/logger.cpp +++ b/core/io/logger.cpp @@ -50,7 +50,7 @@ void Logger::set_flush_stdout_on_print(bool value) { _flush_stdout_on_print = value; } -void Logger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) { +void Logger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) { if (!should_log(true)) { return; } @@ -81,7 +81,11 @@ void Logger::log_error(const char *p_function, const char *p_file, int p_line, c err_details = p_code; } - logf_error("%s: %s\n", err_type, err_details); + if (p_editor_notify) { + logf_error("%s: %s\n", err_type, err_details); + } else { + logf_error("USER %s: %s\n", err_type, err_details); + } logf_error(" at: %s (%s:%i) - %s\n", p_function, p_file, p_line, p_code); } @@ -256,7 +260,7 @@ void CompositeLogger::logv(const char *p_format, va_list p_list, bool p_err) { } } -void CompositeLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) { +void CompositeLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) { if (!should_log(true)) { return; } diff --git a/core/io/logger.h b/core/io/logger.h index ccf68562d6..f244f70e7e 100644 --- a/core/io/logger.h +++ b/core/io/logger.h @@ -54,7 +54,7 @@ public: static void set_flush_stdout_on_print(bool value); virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0 = 0; - virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR); + virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR); void logf(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3; void logf_error(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3; @@ -103,7 +103,7 @@ public: CompositeLogger(Vector<Logger *> p_loggers); virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0; - virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR); + virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type = ERR_ERROR); void add_logger(Logger *p_logger); diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 1cefa52d69..972076e397 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -136,6 +136,7 @@ String Resource::get_scene_unique_id() const { void Resource::set_name(const String &p_name) { name = p_name; + emit_changed(); } String Resource::get_name() const { diff --git a/core/os/os.cpp b/core/os/os.cpp index 12f85858c3..7404ffdcd5 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -75,12 +75,12 @@ void OS::add_logger(Logger *p_logger) { } } -void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type) { +void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, Logger::ErrorType p_type) { if (!_stderr_enabled) { return; } - _logger->log_error(p_function, p_file, p_line, p_code, p_rationale, p_type); + _logger->log_error(p_function, p_file, p_line, p_code, p_rationale, p_editor_notify, p_type); } void OS::print(const char *p_format, ...) { diff --git a/core/os/os.h b/core/os/os.h index 29d33ce4f0..6d7bc47407 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -110,7 +110,7 @@ public: static OS *get_singleton(); - void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type = Logger::ERR_ERROR); + void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, Logger::ErrorType p_type = Logger::ERR_ERROR); void print(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3; void printerr(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3; diff --git a/doc/classes/XRAnchor3D.xml b/doc/classes/XRAnchor3D.xml index 94fc8fc13d..2c54c728ed 100644 --- a/doc/classes/XRAnchor3D.xml +++ b/doc/classes/XRAnchor3D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="XRAnchor3D" inherits="Node3D" version="4.0"> +<class name="XRAnchor3D" inherits="XRNode3D" version="4.0"> <brief_description> An anchor point in AR space. </brief_description> @@ -11,24 +11,6 @@ <tutorials> </tutorials> <methods> - <method name="get_anchor_name" qualifiers="const"> - <return type="String" /> - <description> - Returns the name given to this anchor. - </description> - </method> - <method name="get_is_active" qualifiers="const"> - <return type="bool" /> - <description> - Returns [code]true[/code] if the anchor is being tracked and [code]false[/code] if no anchor with this ID is currently known. - </description> - </method> - <method name="get_mesh" qualifiers="const"> - <return type="Mesh" /> - <description> - If provided by the [XRInterface], this returns a mesh object for the anchor. For an anchor, this can be a shape related to the object being tracked or it can be a mesh that provides topology related to the anchor and can be used to create shadows/reflections on surfaces or for generating collision shapes. - </description> - </method> <method name="get_plane" qualifiers="const"> <return type="Plane" /> <description> @@ -42,17 +24,4 @@ </description> </method> </methods> - <members> - <member name="anchor_id" type="int" setter="set_anchor_id" getter="get_anchor_id" default="1"> - The anchor's ID. You can set this before the anchor itself exists. The first anchor gets an ID of [code]1[/code], the second an ID of [code]2[/code], etc. When anchors get removed, the engine can then assign the corresponding ID to new anchors. The most common situation where anchors "disappear" is when the AR server identifies that two anchors represent different parts of the same plane and merges them. - </member> - </members> - <signals> - <signal name="mesh_updated"> - <argument index="0" name="mesh" type="Mesh" /> - <description> - Emitted when the mesh associated with the anchor changes or when one becomes available. This is especially important for topology that is constantly being [code]mesh_updated[/code]. - </description> - </signal> - </signals> </class> diff --git a/doc/classes/XRController3D.xml b/doc/classes/XRController3D.xml index 35edf5c2b2..eb91196e00 100644 --- a/doc/classes/XRController3D.xml +++ b/doc/classes/XRController3D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="XRController3D" inherits="Node3D" version="4.0"> +<class name="XRController3D" inherits="XRNode3D" version="4.0"> <brief_description> A spatial node representing a spatially-tracked controller. </brief_description> @@ -7,63 +7,41 @@ This is a helper spatial node that is linked to the tracking of controllers. It also offers several handy passthroughs to the state of buttons and such on the controllers. Controllers are linked by their ID. You can create controller nodes before the controllers are available. If your game always uses two controllers (one for each hand), you can predefine the controllers with ID 1 and 2; they will become active as soon as the controllers are identified. If you expect additional controllers to be used, you should react to the signals and add XRController3D nodes to your scene. The position of the controller node is automatically updated by the [XRServer]. This makes this node ideal to add child nodes to visualize the controller. + As many XR runtimes now use a configurable action map all inputs are named. </description> <tutorials> <link title="VR documentation index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link> </tutorials> <methods> - <method name="get_controller_name" qualifiers="const"> - <return type="String" /> + <method name="get_axis" qualifiers="const"> + <return type="Vector2" /> + <argument index="0" name="name" type="StringName" /> <description> - If active, returns the name of the associated controller if provided by the AR/VR SDK used. + Returns a [Vector2] for the input with the given [code]name[/code]. This is used for thumbsticks and thumbpads found on many controllers. </description> </method> - <method name="get_is_active" qualifiers="const"> - <return type="bool" /> + <method name="get_tracker_hand" qualifiers="const"> + <return type="int" enum="XRPositionalTracker.TrackerHand" /> <description> - Returns [code]true[/code] if the bound controller is active. XR systems attempt to track active controllers. + Returns the hand holding this controller, if known. See [enum XRPositionalTracker.TrackerHand]. </description> </method> - <method name="get_joystick_axis" qualifiers="const"> + <method name="get_value" qualifiers="const"> <return type="float" /> - <argument index="0" name="axis" type="int" /> - <description> - Returns the value of the given axis for things like triggers, touchpads, etc. that are embedded into the controller. - </description> - </method> - <method name="get_joystick_id" qualifiers="const"> - <return type="int" /> - <description> - Returns the ID of the joystick object bound to this. Every controller tracked by the [XRServer] that has buttons and axis will also be registered as a joystick within Godot. This means that all the normal joystick tracking and input mapping will work for buttons and axis found on the AR/VR controllers. This ID is purely offered as information so you can link up the controller with its joystick entry. - </description> - </method> - <method name="get_mesh" qualifiers="const"> - <return type="Mesh" /> + <argument index="0" name="name" type="StringName" /> <description> - If provided by the [XRInterface], this returns a mesh associated with the controller. This can be used to visualize the controller. - </description> - </method> - <method name="get_tracker_hand" qualifiers="const"> - <return type="int" enum="XRPositionalTracker.TrackerHand" /> - <description> - Returns the hand holding this controller, if known. See [enum XRPositionalTracker.TrackerHand]. + Returns a numeric value for the input with the given [code]name[/code]. This is used for triggers and grip sensors. </description> </method> <method name="is_button_pressed" qualifiers="const"> <return type="bool" /> - <argument index="0" name="button" type="int" /> + <argument index="0" name="name" type="StringName" /> <description> - Returns [code]true[/code] if the button at index [code]button[/code] is pressed. See [enum JoyButton]. + Returns [code]true[/code] if the button with the given [code]name[/code] is pressed. </description> </method> </methods> <members> - <member name="controller_id" type="int" setter="set_controller_id" getter="get_controller_id" default="1"> - The controller's ID. - A controller ID of 0 is unbound and will always result in an inactive node. Controller ID 1 is reserved for the first controller that identifies itself as the left-hand controller and ID 2 is reserved for the first controller that identifies itself as the right-hand controller. - For any other controller that the [XRServer] detects, we continue with controller ID 3. - When a controller is turned off, its slot is freed. This ensures controllers will keep the same ID even when controllers with lower IDs are turned off. - </member> <member name="rumble" type="float" setter="set_rumble" getter="get_rumble" default="0.0"> The degree to which the controller vibrates. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code]. If changed, updates [member XRPositionalTracker.rumble] accordingly. This is a useful property to animate if you want the controller to vibrate for a limited duration. @@ -71,21 +49,29 @@ </members> <signals> <signal name="button_pressed"> - <argument index="0" name="button" type="int" /> + <argument index="0" name="name" type="String" /> <description> Emitted when a button on this controller is pressed. </description> </signal> <signal name="button_released"> - <argument index="0" name="button" type="int" /> + <argument index="0" name="name" type="String" /> <description> Emitted when a button on this controller is released. </description> </signal> - <signal name="mesh_updated"> - <argument index="0" name="mesh" type="Mesh" /> + <signal name="input_axis_changed"> + <argument index="0" name="name" type="String" /> + <argument index="1" name="value" type="Vector2" /> + <description> + Emitted when a thumbstick or thumbpad on this controller is moved. + </description> + </signal> + <signal name="input_value_changed"> + <argument index="0" name="name" type="String" /> + <argument index="1" name="value" type="float" /> <description> - Emitted when the mesh associated with the controller changes or when one becomes available. Generally speaking this will be a static mesh after becoming available. + Emitted when a trigger or similar input on this controller changes value. </description> </signal> </signals> diff --git a/doc/classes/XRInterface.xml b/doc/classes/XRInterface.xml index ffc2bc138d..7ae70f97a2 100644 --- a/doc/classes/XRInterface.xml +++ b/doc/classes/XRInterface.xml @@ -29,6 +29,12 @@ Returns the name of this interface (OpenXR, OpenVR, OpenHMD, ARKit, etc). </description> </method> + <method name="get_play_area" qualifiers="const"> + <return type="PackedVector3Array" /> + <description> + Returns an array of vectors that denotes the physical play area mapped to the virtual space around the [XROrigin3D] point. The points form a convex polygon that can be used to react to or visualise the play area. This returns an empty array if this feature is not supported or if the information is not yet available. + </description> + </method> <method name="get_render_target_size"> <return type="Vector2" /> <description> @@ -63,6 +69,34 @@ Is [code]true[/code] if this interface has been initialised. </description> </method> + <method name="set_play_area_mode"> + <return type="bool" /> + <argument index="0" name="mode" type="int" enum="XRInterface.PlayAreaMode" /> + <description> + Sets the active play area mode, will return [code]false[/code] if the mode can't be used with this interface. + </description> + </method> + <method name="supports_play_area_mode"> + <return type="bool" /> + <argument index="0" name="mode" type="int" enum="XRInterface.PlayAreaMode" /> + <description> + Call this to find out if a given play area mode is supported by this interface. + </description> + </method> + <method name="trigger_haptic_pulse"> + <return type="void" /> + <argument index="0" name="action_name" type="String" /> + <argument index="1" name="tracker_name" type="StringName" /> + <argument index="2" name="frequency" type="float" /> + <argument index="3" name="amplitude" type="float" /> + <argument index="4" name="duration_sec" type="float" /> + <argument index="5" name="delay_sec" type="float" /> + <description> + Triggers a haptic pulse on a device associated with this interface. + [code]action_name[/code] is the name of the action for this pulse. + [code]tracker_name[/code] is optional and can be used to direct the pulse to a specific device provided that device is bound to this haptic. + </description> + </method> <method name="uninitialize"> <return type="void" /> <description> @@ -77,7 +111,18 @@ <member name="interface_is_primary" type="bool" setter="set_primary" getter="is_primary" default="false"> [code]true[/code] if this is the primary interface. </member> + <member name="xr_play_area_mode" type="int" setter="set_play_area_mode" getter="get_play_area_mode" enum="XRInterface.PlayAreaMode" default="0"> + The play area mode for this interface. + </member> </members> + <signals> + <signal name="play_area_changed"> + <argument index="0" name="mode" type="int" /> + <description> + Emitted when the play area is changed. This can be a result of the player resetting the boundary or entering a new play area, the player changing the play area mode, the world scale changing or the player resetting their headset orientation. + </description> + </signal> + </signals> <constants> <constant name="XR_NONE" value="0" enum="Capabilities"> No XR capabilities. @@ -88,20 +133,17 @@ <constant name="XR_STEREO" value="2" enum="Capabilities"> This interface supports stereoscopic rendering. </constant> - <constant name="XR_AR" value="4" enum="Capabilities"> - This interface supports AR (video background and real world tracking). - </constant> - <constant name="XR_EXTERNAL" value="8" enum="Capabilities"> - This interface outputs to an external device. If the main viewport is used, the on screen output is an unmodified buffer of either the left or right eye (stretched if the viewport size is not changed to the same aspect ratio of [method get_render_target_size]). Using a separate viewport node frees up the main viewport for other purposes. + <constant name="XR_QUAD" value="4" enum="Capabilities"> + This interface supports quad rendering (not yet supported by Godot). </constant> - <constant name="EYE_MONO" value="0" enum="Eyes"> - Mono output, this is mostly used internally when retrieving positioning information for our camera node or when stereo scopic rendering is not supported. + <constant name="XR_VR" value="8" enum="Capabilities"> + this interface supports VR. </constant> - <constant name="EYE_LEFT" value="1" enum="Eyes"> - Left eye output, this is mostly used internally when rendering the image for the left eye and obtaining positioning and projection information. + <constant name="XR_AR" value="16" enum="Capabilities"> + This interface supports AR (video background and real world tracking). </constant> - <constant name="EYE_RIGHT" value="2" enum="Eyes"> - Right eye output, this is mostly used internally when rendering the image for the right eye and obtaining positioning and projection information. + <constant name="XR_EXTERNAL" value="32" enum="Capabilities"> + This interface outputs to an external device. If the main viewport is used, the on screen output is an unmodified buffer of either the left or right eye (stretched if the viewport size is not changed to the same aspect ratio of [method get_render_target_size]). Using a separate viewport node frees up the main viewport for other purposes. </constant> <constant name="XR_NORMAL_TRACKING" value="0" enum="TrackingStatus"> Tracking is behaving as expected. @@ -118,5 +160,20 @@ <constant name="XR_NOT_TRACKING" value="4" enum="TrackingStatus"> Tracking is not functional (camera not plugged in or obscured, lighthouses turned off, etc.). </constant> + <constant name="XR_PLAY_AREA_UNKNOWN" value="0" enum="PlayAreaMode"> + Play area mode not set or not available. + </constant> + <constant name="XR_PLAY_AREA_3DOF" value="1" enum="PlayAreaMode"> + Play area only supports orientation tracking, no positional tracking, area will center around player. + </constant> + <constant name="XR_PLAY_AREA_SITTING" value="2" enum="PlayAreaMode"> + Player is in seated position, limited positional tracking, fixed guardian around player. + </constant> + <constant name="XR_PLAY_AREA_ROOMSCALE" value="3" enum="PlayAreaMode"> + Player is free to move around, full positional tracking. + </constant> + <constant name="XR_PLAY_AREA_STAGE" value="4" enum="PlayAreaMode"> + Same as roomscale but origin point is fixed to the center of the physical space, XRServer.center_on_hmd disabled. + </constant> </constants> </class> diff --git a/doc/classes/XRInterfaceExtension.xml b/doc/classes/XRInterfaceExtension.xml index 84b46e0ddd..3b5d8e2f10 100644 --- a/doc/classes/XRInterfaceExtension.xml +++ b/doc/classes/XRInterfaceExtension.xml @@ -41,6 +41,16 @@ <description> </description> </method> + <method name="_get_play_area" qualifiers="virtual const"> + <return type="PackedVector3Array" /> + <description> + </description> + </method> + <method name="_get_play_area_mode" qualifiers="virtual const"> + <return type="int" /> + <description> + </description> + </method> <method name="_get_projection_for_view" qualifiers="virtual"> <return type="PackedFloat64Array" /> <argument index="0" name="view" type="int" /> @@ -55,6 +65,22 @@ <description> </description> </method> + <method name="_get_suggested_pose_names" qualifiers="virtual const"> + <return type="PackedStringArray" /> + <argument index="0" name="tracker_name" type="StringName" /> + <description> + </description> + </method> + <method name="_get_suggested_tracker_names" qualifiers="virtual const"> + <return type="PackedStringArray" /> + <description> + </description> + </method> + <method name="_get_tracking_status" qualifiers="virtual const"> + <return type="int" /> + <description> + </description> + </method> <method name="_get_tracking_status" qualifiers="virtual const"> <return type="int" /> <description> @@ -99,6 +125,29 @@ <description> </description> </method> + <method name="_set_play_area_mode" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="mode" type="int" /> + <description> + </description> + </method> + <method name="_supports_play_area_mode" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="mode" type="int" enum="XRInterface.PlayAreaMode" /> + <description> + </description> + </method> + <method name="_trigger_haptic_pulse" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="action_name" type="String" /> + <argument index="1" name="tracker_name" type="StringName" /> + <argument index="2" name="frequency" type="float" /> + <argument index="3" name="amplitude" type="float" /> + <argument index="4" name="duration_sec" type="float" /> + <argument index="5" name="delay_sec" type="float" /> + <description> + </description> + </method> <method name="_uninitialize" qualifiers="virtual"> <return type="void" /> <description> diff --git a/doc/classes/XRNode3D.xml b/doc/classes/XRNode3D.xml new file mode 100644 index 0000000000..2e6d11d729 --- /dev/null +++ b/doc/classes/XRNode3D.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="XRNode3D" inherits="Node3D" version="4.0"> + <brief_description> + A spatial node that has its position automatically updated by the [XRServer]. + </brief_description> + <description> + This node can be bound to a specific pose of a [XRPositionalTracker] and will automatically have its [member Node3D.transform] updated by the [XRServer]. Nodes of this type must be added as children of the [XROrigin3D] node. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_has_tracking_data" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] if the [member tracker] has current tracking data for the [member pose] being tracked. + </description> + </method> + <method name="get_is_active" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] if the [member tracker] has been registered and the [member pose] is being tracked. + </description> + </method> + <method name="get_pose"> + <return type="XRPose" /> + <description> + Returns the [XRPose] containing the current state of the pose being tracked. This gives access to additional properties of this pose. + </description> + </method> + <method name="trigger_haptic_pulse"> + <return type="void" /> + <argument index="0" name="action_name" type="String" /> + <argument index="1" name="frequency" type="float" /> + <argument index="2" name="amplitude" type="float" /> + <argument index="3" name="duration_sec" type="float" /> + <argument index="4" name="delay_sec" type="float" /> + <description> + Triggers a haptic pulse on a device associated with this interface. + [code]action_name[/code] is the name of the action for this pulse. + </description> + </method> + </methods> + <members> + <member name="pose" type="StringName" setter="set_pose_name" getter="get_pose_name" default="&"default""> + The name of the pose we're bound to. Which poses a tracker supports is not known during design time. + Godot defines number of standard pose names such as [code]aim[/code] and [code]grip[/code] but other may be configured within a given [XRInterface]. + </member> + <member name="tracker" type="StringName" setter="set_tracker" getter="get_tracker" default="&"""> + The name of the tracker we're bound to. Which trackers are available is not known during design time. + Godot defines a number of standard trackers such as [code]left_hand[/code] and [code]right_hand[/code] but others may be configured within a given [XRInterface]. + </member> + </members> +</class> diff --git a/doc/classes/XRPose.xml b/doc/classes/XRPose.xml new file mode 100644 index 0000000000..0de2bc9e48 --- /dev/null +++ b/doc/classes/XRPose.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="XRPose" inherits="RefCounted" version="4.0"> + <brief_description> + This object contains all data related to a pose on a tracked object. + </brief_description> + <description> + XR runtimes often identify multiple locations on devices such as controllers that are spatially tracked. + Orientation, location, linear velocity and angular velocity are all provided for each pose by the XR runtime. This object contains this state of a pose. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_adjusted_transform" qualifiers="const"> + <return type="Transform3D" /> + <description> + Returns the [member transform] with world scale and our reference frame applied. This is the transform used to position [XRNode3D] objects. + </description> + </method> + </methods> + <members> + <member name="angular_velocity" type="Vector3" setter="set_angular_velocity" getter="get_angular_velocity" default="Vector3(0, 0, 0)"> + The angular velocity for this pose. + </member> + <member name="has_tracking_data" type="bool" setter="set_has_tracking_data" getter="get_has_tracking_data" default="false"> + If [code]true[/code] our tracking data is up to date. If [code]false[/code] we're no longer receiving new tracking data and our state is whatever that last valid state was. + </member> + <member name="linear_velocity" type="Vector3" setter="set_linear_velocity" getter="get_linear_velocity" default="Vector3(0, 0, 0)"> + The linear velocity of this pose. + </member> + <member name="name" type="StringName" setter="set_name" getter="get_name" default="&"""> + The name of this pose. Pose names are often driven by an action map setup by the user. Godot does suggest a number of pose names that it expects [XRInterface]s to implement: + - [code]root[/code] defines a root location, often used for tracked objects that do not have further nodes. + - [code]aim[/code] defines the tip of a controller with the orientation pointing outwards, for instance: add your raycasts to this. + - [code]grip[/code] defines the location where the user grips the controller + - [code]skeleton[/code] defines the root location a hand mesh should be placed when using hand tracking and the animated skeleton supplied by the XR runtime. + </member> + <member name="transform" type="Transform3D" setter="set_transform" getter="get_transform" default="Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)"> + The transform containing the original and transform as reported by the XR runtime. + </member> + </members> +</class> diff --git a/doc/classes/XRPositionalTracker.xml b/doc/classes/XRPositionalTracker.xml index d231bfde74..bd6a518835 100644 --- a/doc/classes/XRPositionalTracker.xml +++ b/doc/classes/XRPositionalTracker.xml @@ -5,86 +5,113 @@ </brief_description> <description> An instance of this object represents a device that is tracked, such as a controller or anchor point. HMDs aren't represented here as they are handled internally. - As controllers are turned on and the AR/VR interface detects them, instances of this object are automatically added to this list of active tracking objects accessible through the [XRServer]. - The [XRController3D] and [XRAnchor3D] both consume objects of this type and should be used in your project. The positional trackers are just under-the-hood objects that make this all work. These are mostly exposed so that GDNative-based interfaces can interact with them. + As controllers are turned on and the [XRInterface] detects them, instances of this object are automatically added to this list of active tracking objects accessible through the [XRServer]. + The [XRController3D] and [XRAnchor3D] both consume objects of this type and should be used in your project. The positional trackers are just under-the-hood objects that make this all work. These are mostly exposed so that GDExtension-based interfaces can interact with them. </description> <tutorials> <link title="VR documentation index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link> </tutorials> <methods> - <method name="get_joy_id" qualifiers="const"> - <return type="int" /> + <method name="get_input" qualifiers="const"> + <return type="Variant" /> + <argument index="0" name="name" type="StringName" /> <description> - If this is a controller that is being tracked, the controller will also be represented by a joystick entry with this ID. + Returns an input for this tracker. It can return a boolean, float or [Vector2] value depending on whether the input is a button, trigger or thumbstick/thumbpad. </description> </method> - <method name="get_mesh" qualifiers="const"> - <return type="Mesh" /> + <method name="get_pose" qualifiers="const"> + <return type="XRPose" /> + <argument index="0" name="name" type="StringName" /> <description> - Returns the mesh related to a controller or anchor point if one is available. + Returns the current [XRPose] state object for the bound [code]pose[/code]. </description> </method> - <method name="get_orientation" qualifiers="const"> - <return type="Basis" /> + <method name="has_pose" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="name" type="StringName" /> <description> - Returns the controller's orientation matrix. + Returns [code]true[/code] if the bound [code]tracker[/code] is available and is currently tracking the bound [code]pose[/code]. </description> </method> - <method name="get_position" qualifiers="const"> - <return type="Vector3" /> + <method name="invalidate_pose"> + <return type="void" /> + <argument index="0" name="name" type="StringName" /> <description> - Returns the world-space controller position. + Marks this pose as invalid, we don't clear the last reported state but it allows users to decide if trackers need to be hidden if we loose tracking or just remain at their last known position. </description> </method> - <method name="get_tracker_hand" qualifiers="const"> - <return type="int" enum="XRPositionalTracker.TrackerHand" /> + <method name="set_input"> + <return type="void" /> + <argument index="0" name="name" type="StringName" /> + <argument index="1" name="value" type="Variant" /> <description> - Returns the hand holding this tracker, if known. See [enum TrackerHand] constants. + Changes the value for the given input. This method is called by a [XRInterface] implementation and should not be used directly. </description> </method> - <method name="get_tracker_id" qualifiers="const"> - <return type="int" /> + <method name="set_pose"> + <return type="void" /> + <argument index="0" name="name" type="StringName" /> + <argument index="1" name="transform" type="Transform3D" /> + <argument index="2" name="linear_velocity" type="Vector3" /> + <argument index="3" name="angular_velocity" type="Vector3" /> <description> - Returns the internal tracker ID. This uniquely identifies the tracker per tracker type and matches the ID you need to specify for nodes such as the [XRController3D] and [XRAnchor3D] nodes. + Sets the transform, linear velocity and angular velocity for the given pose. This method is called by a [XRInterface] implementation and should not be used directly. </description> </method> - <method name="get_tracker_name" qualifiers="const"> - <return type="StringName" /> + </methods> + <members> + <member name="description" type="String" setter="set_tracker_desc" getter="get_tracker_desc" default=""""> + The description of this tracker. + </member> + <member name="hand" type="int" setter="set_tracker_hand" getter="get_tracker_hand" enum="XRPositionalTracker.TrackerHand" default="0"> + Defines which hand this tracker relates to. + </member> + <member name="name" type="StringName" setter="set_tracker_name" getter="get_tracker_name" default="&"Unknown""> + The unique name of this tracker. The trackers that are available differ between various XR runtimes and can often be configured by the user. Godot maintains a number of reserved names that it expects the [XRInterface] to implement if applicable: + - [code]left_hand[/code] identifies the controller held in the players left hand + - [code]right_hand[/code] identifies the controller held in the players right hand + </member> + <member name="rumble" type="float" setter="set_rumble" getter="get_rumble" default="0.0"> + The degree to which the tracker rumbles. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code]. + </member> + <member name="type" type="int" setter="set_tracker_type" getter="get_tracker_type" enum="XRServer.TrackerType" default="128"> + The type of tracker. + </member> + </members> + <signals> + <signal name="button_pressed"> + <argument index="0" name="name" type="String" /> <description> - Returns the controller or anchor point's name, if applicable. + Emitted when a button on this tracker is pressed. Note that many XR runtimes allow other inputs to be mapped to buttons. </description> - </method> - <method name="get_tracker_type" qualifiers="const"> - <return type="int" enum="XRServer.TrackerType" /> + </signal> + <signal name="button_released"> + <argument index="0" name="name" type="String" /> <description> - Returns the tracker's type, which will be one of the values from the [enum XRServer.TrackerType] enum. + Emitted when a button on this tracker is released. </description> - </method> - <method name="get_transform" qualifiers="const"> - <return type="Transform3D" /> - <argument index="0" name="adjust_by_reference_frame" type="bool" /> + </signal> + <signal name="input_axis_changed"> + <argument index="0" name="name" type="String" /> + <argument index="1" name="vector" type="Vector2" /> <description> - Returns the transform combining this device's orientation and position. + Emitted when a thumbstick or thumbpad on this tracker moves. </description> - </method> - <method name="is_tracking_orientation" qualifiers="const"> - <return type="bool" /> + </signal> + <signal name="input_value_changed"> + <argument index="0" name="name" type="String" /> + <argument index="1" name="value" type="float" /> <description> - Returns [code]true[/code] if this device is tracking orientation. + Emitted when a trigger or similar input on this tracker changes value. </description> - </method> - <method name="is_tracking_position" qualifiers="const"> - <return type="bool" /> + </signal> + <signal name="pose_changed"> + <argument index="0" name="pose" type="XRPose" /> <description> - Returns [code]true[/code] if this device is tracking position. + Emitted when the state of a pose tracked by this tracker changes. </description> - </method> - </methods> - <members> - <member name="rumble" type="float" setter="set_rumble" getter="get_rumble" default="0.0"> - The degree to which the tracker rumbles. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code]. - </member> - </members> + </signal> + </signals> <constants> <constant name="TRACKER_HAND_UNKNOWN" value="0" enum="TrackerHand"> The hand this tracker is held in is unknown or not applicable. diff --git a/doc/classes/XRServer.xml b/doc/classes/XRServer.xml index 0929094fd1..87164ebb52 100644 --- a/doc/classes/XRServer.xml +++ b/doc/classes/XRServer.xml @@ -90,20 +90,21 @@ <method name="get_reference_frame" qualifiers="const"> <return type="Transform3D" /> <description> - Returns the reference frame transform. Mostly used internally and exposed for GDNative build interfaces. + Returns the reference frame transform. Mostly used internally and exposed for GDExtension build interfaces. </description> </method> <method name="get_tracker" qualifiers="const"> <return type="XRPositionalTracker" /> - <argument index="0" name="idx" type="int" /> + <argument index="0" name="tracker_name" type="StringName" /> <description> - Returns the positional tracker at the given ID. + Returns the positional tracker with this name. </description> </method> - <method name="get_tracker_count" qualifiers="const"> - <return type="int" /> + <method name="get_trackers"> + <return type="Dictionary" /> + <argument index="0" name="tracker_types" type="int" /> <description> - Returns the number of trackers currently registered. + Returns a dictionary of trackers for this type. </description> </method> <method name="remove_interface"> @@ -145,7 +146,6 @@ <signal name="tracker_added"> <argument index="0" name="tracker_name" type="StringName" /> <argument index="1" name="type" type="int" /> - <argument index="2" name="id" type="int" /> <description> Emitted when a new tracker has been added. If you don't use a fixed number of controllers or if you're using [XRAnchor3D]s for an AR solution, it is important to react to this signal to add the appropriate [XRController3D] or [XRAnchor3D] nodes related to this new tracker. </description> @@ -153,20 +153,29 @@ <signal name="tracker_removed"> <argument index="0" name="tracker_name" type="StringName" /> <argument index="1" name="type" type="int" /> - <argument index="2" name="id" type="int" /> <description> Emitted when a tracker is removed. You should remove any [XRController3D] or [XRAnchor3D] points if applicable. This is not mandatory, the nodes simply become inactive and will be made active again when a new tracker becomes available (i.e. a new controller is switched on that takes the place of the previous one). </description> </signal> + <signal name="tracker_updated"> + <argument index="0" name="tracker_name" type="StringName" /> + <argument index="1" name="type" type="int" /> + <description> + Emitted when an existing tracker has been updated. This can happen if the user switches controllers. + </description> + </signal> </signals> <constants> - <constant name="TRACKER_CONTROLLER" value="1" enum="TrackerType"> + <constant name="TRACKER_HEAD" value="1" enum="TrackerType"> + The tracker tracks the location of the players head. This is usually a location centered between the players eyes. Note that for handheld AR devices this can be the current location of the device. + </constant> + <constant name="TRACKER_CONTROLLER" value="2" enum="TrackerType"> The tracker tracks the location of a controller. </constant> - <constant name="TRACKER_BASESTATION" value="2" enum="TrackerType"> + <constant name="TRACKER_BASESTATION" value="4" enum="TrackerType"> The tracker tracks the location of a base station. </constant> - <constant name="TRACKER_ANCHOR" value="4" enum="TrackerType"> + <constant name="TRACKER_ANCHOR" value="8" enum="TrackerType"> The tracker tracks the location and size of an AR anchor. </constant> <constant name="TRACKER_ANY_KNOWN" value="127" enum="TrackerType"> diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 3032c31629..193825a73f 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -528,7 +528,7 @@ String OS_Unix::get_executable_path() const { #endif } -void UnixTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) { +void UnixTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) { if (!should_log(true)) { return; } diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index bf82019d38..eb36bf4255 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -102,7 +102,7 @@ public: class UnixTerminalLogger : public StdLogger { public: - virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR); + virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type = ERR_ERROR); virtual ~UnixTerminalLogger(); }; diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index 346b93a87c..251e1c2385 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -37,7 +37,7 @@ #include "scene/gui/center_container.h" #include "scene/resources/font.h" -void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, ErrorHandlerType p_type) { +void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type) { EditorLog *self = (EditorLog *)p_self; if (self->current != Thread::get_caller_id()) { return; @@ -50,6 +50,10 @@ void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_f err_str = String(p_file) + ":" + itos(p_line) + " - " + String(p_error); } + if (p_editor_notify) { + err_str += " (User)"; + } + if (p_type == ERR_HANDLER_WARNING) { self->add_message(err_str, MSG_TYPE_WARNING); } else { diff --git a/editor/editor_log.h b/editor/editor_log.h index 6cbf4bedee..43cc5680bd 100644 --- a/editor/editor_log.h +++ b/editor/editor_log.h @@ -136,7 +136,7 @@ private: bool is_loading_state = false; // Used to disable saving requests while loading (some signals from buttons will try trigger a save, which happens during loading). Timer *save_state_timer; - static void _error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, ErrorHandlerType p_type); + static void _error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type); ErrorHandlerList eh; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 2f92f60d5e..ffcb75ba2c 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -95,6 +95,7 @@ #include "editor/editor_settings.h" #include "editor/editor_spin_slider.h" #include "editor/editor_themes.h" +#include "editor/editor_toaster.h" #include "editor/editor_translation_parser.h" #include "editor/export_template_manager.h" #include "editor/filesystem_dock.h" @@ -6748,6 +6749,9 @@ EditorNode::EditorNode() { bottom_panel_hb_editors->set_h_size_flags(Control::SIZE_EXPAND_FILL); bottom_panel_hb->add_child(bottom_panel_hb_editors); + editor_toaster = memnew(EditorToaster); + bottom_panel_hb->add_child(editor_toaster); + VBoxContainer *version_info_vbc = memnew(VBoxContainer); bottom_panel_hb->add_child(version_info_vbc); diff --git a/editor/editor_node.h b/editor/editor_node.h index 73feeecfee..5c89823ad8 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -37,6 +37,7 @@ #include "editor/editor_folding.h" #include "editor/editor_native_shader_source_visualizer.h" #include "editor/editor_run.h" +#include "editor/editor_toaster.h" #include "editor/inspector_dock.h" #include "editor/property_editor.h" #include "editor/scene_tree_dock.h" @@ -438,6 +439,7 @@ private: HBoxContainer *bottom_panel_hb; HBoxContainer *bottom_panel_hb_editors; VBoxContainer *bottom_panel_vb; + EditorToaster *editor_toaster; LinkButton *version_btn; Button *bottom_panel_raise; diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 223cc6650c..1da9213b89 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -442,6 +442,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("interface/editor/hide_console_window", false); _initial_set("interface/editor/mouse_extra_buttons_navigate_history", true); _initial_set("interface/editor/save_each_scene_on_quit", true); // Regression + EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/show_internal_errors_in_toast_notifications", 0, "Auto,Enabled,Disabled") // Inspector EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/inspector/max_array_dictionary_items_per_page", 20, "10,100,1") diff --git a/editor/editor_toaster.cpp b/editor/editor_toaster.cpp new file mode 100644 index 0000000000..0d45a7f1d8 --- /dev/null +++ b/editor/editor_toaster.cpp @@ -0,0 +1,511 @@ +/*************************************************************************/ +/* editor_toaster.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor/editor_node.h" +#include "editor/editor_scale.h" +#include "scene/gui/label.h" +#include "scene/gui/panel_container.h" + +#include "editor_toaster.h" + +EditorToaster *EditorToaster::singleton; + +void EditorToaster::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_INTERNAL_PROCESS: { + double delta = get_process_delta_time(); + + // Check if one element is hovered, if so, don't elapse time. + bool hovered = false; + for (const KeyValue<Control *, Toast> &element : toasts) { + if (Rect2(Vector2(), element.key->get_size()).has_point(element.key->get_local_mouse_position())) { + hovered = true; + break; + } + } + + // Elapses the time and remove toasts if needed. + if (!hovered) { + for (const KeyValue<Control *, Toast> &element : toasts) { + if (!element.value.popped || element.value.duration <= 0) { + continue; + } + toasts[element.key].remaining_time -= delta; + if (toasts[element.key].remaining_time < 0) { + close(element.key); + } + element.key->update(); + } + } else { + // Reset the timers when hovered. + for (const KeyValue<Control *, Toast> &element : toasts) { + if (!element.value.popped || element.value.duration <= 0) { + continue; + } + toasts[element.key].remaining_time = element.value.duration; + element.key->update(); + } + } + + // Change alpha over time. + bool needs_update = false; + for (const KeyValue<Control *, Toast> &element : toasts) { + Color modulate = element.key->get_modulate(); + + // Change alpha over time. + if (element.value.popped && modulate.a < 1.0) { + modulate.a += delta * 3; + element.key->set_modulate(modulate); + } else if (!element.value.popped && modulate.a > 0.0) { + modulate.a -= delta * 2; + element.key->set_modulate(modulate); + } + + // Hide element if it is not visible anymore. + if (modulate.a <= 0) { + element.key->hide(); + needs_update = true; + } + } + + if (needs_update) { + _update_vbox_position(); + _update_disable_notifications_button(); + main_button->update(); + } + } break; + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + if (vbox_container->is_visible()) { + main_button->set_icon(get_theme_icon(SNAME("Notification"), SNAME("EditorIcons"))); + } else { + main_button->set_icon(get_theme_icon(SNAME("NotificationDisabled"), SNAME("EditorIcons"))); + } + disable_notifications_button->set_icon(get_theme_icon(SNAME("NotificationDisabled"), SNAME("EditorIcons"))); + + // Styleboxes background. + info_panel_style_background->set_bg_color(get_theme_color("base_color", "Editor")); + + warning_panel_style_background->set_bg_color(get_theme_color("base_color", "Editor")); + warning_panel_style_background->set_border_color(get_theme_color("warning_color", "Editor")); + + error_panel_style_background->set_bg_color(get_theme_color("base_color", "Editor")); + error_panel_style_background->set_border_color(get_theme_color("error_color", "Editor")); + + // Styleboxes progress. + info_panel_style_progress->set_bg_color(get_theme_color("base_color", "Editor").lightened(0.03)); + + warning_panel_style_progress->set_bg_color(get_theme_color("base_color", "Editor").lightened(0.03)); + warning_panel_style_progress->set_border_color(get_theme_color("warning_color", "Editor")); + + error_panel_style_progress->set_bg_color(get_theme_color("base_color", "Editor").lightened(0.03)); + error_panel_style_progress->set_border_color(get_theme_color("error_color", "Editor")); + + main_button->update(); + disable_notifications_button->update(); + } break; + case NOTIFICATION_TRANSFORM_CHANGED: { + _update_vbox_position(); + _update_disable_notifications_button(); + } break; + default: + break; + } +} + +void EditorToaster::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type) { + if (!EditorToaster::get_singleton()) { + return; + } + +#ifdef DEV_ENABLED + bool in_dev = true; +#else + bool in_dev = false; +#endif + + int show_all_setting = EDITOR_GET("interface/editor/show_internal_errors_in_toast_notifications"); + + if (p_editor_notify || (show_all_setting == 0 && in_dev) || show_all_setting == 1) { + String err_str; + if (p_errorexp && p_errorexp[0]) { + err_str = p_errorexp; + } else { + err_str = String(p_error); + } + String tooltip_str = String(p_file) + ":" + itos(p_line); + + if (!p_editor_notify) { + if (p_type == ERR_HANDLER_WARNING) { + err_str = "INTERNAL WARNING: " + err_str; + } else { + err_str = "INTERNAL ERROR: " + err_str; + } + } + + if (p_type == ERR_HANDLER_WARNING) { + EditorToaster::get_singleton()->popup_str(err_str, SEVERITY_WARNING, tooltip_str); + } else { + EditorToaster::get_singleton()->popup_str(err_str, SEVERITY_ERROR, tooltip_str); + } + } +} + +void EditorToaster::_update_vbox_position() { + // This is kind of a workaround because it's hard to keep the VBox anchroed to the bottom. + vbox_container->set_size(Vector2()); + vbox_container->set_position(get_global_position() - vbox_container->get_size() + Vector2(get_size().x, -5 * EDSCALE)); +} + +void EditorToaster::_update_disable_notifications_button() { + bool any_visible = false; + for (KeyValue<Control *, Toast> element : toasts) { + if (element.key->is_visible()) { + any_visible = true; + break; + } + } + + if (!any_visible || !vbox_container->is_visible()) { + disable_notifications_panel->hide(); + } else { + disable_notifications_panel->show(); + disable_notifications_panel->set_position(get_global_position() + Vector2(5 * EDSCALE, -disable_notifications_panel->get_minimum_size().y) + Vector2(get_size().x, -5 * EDSCALE)); + } +} + +void EditorToaster::_auto_hide_or_free_toasts() { + // Hide or free old temporary items. + int visible_temporary = 0; + int temporary = 0; + LocalVector<Control *> to_delete; + for (int i = vbox_container->get_child_count() - 1; i >= 0; i--) { + Control *control = Object::cast_to<Control>(vbox_container->get_child(i)); + if (toasts[control].duration <= 0) { + continue; // Ignore non-temporary toasts. + } + + temporary++; + if (control->is_visible()) { + visible_temporary++; + } + + // Hide + if (visible_temporary > max_temporary_count) { + close(control); + } + + // Free + if (temporary > max_temporary_count * 2) { + to_delete.push_back(control); + } + } + + // Delete the control right away (removed as child) as it might cause issues otherwise when iterative over the vbox_container children. + for (unsigned int i = 0; i < to_delete.size(); i++) { + vbox_container->remove_child(to_delete[i]); + to_delete[i]->queue_delete(); + toasts.erase(to_delete[i]); + } +} + +void EditorToaster::_draw_button() { + bool has_one = false; + Severity highest_severity = SEVERITY_INFO; + for (const KeyValue<Control *, Toast> &element : toasts) { + if (!element.key->is_visible()) { + continue; + } + has_one = true; + if (element.value.severity > highest_severity) { + highest_severity = element.value.severity; + } + } + + if (!has_one) { + return; + } + + Color color; + real_t button_radius = main_button->get_size().x / 8; + switch (highest_severity) { + case SEVERITY_INFO: + color = get_theme_color("accent_color", "Editor"); + break; + case SEVERITY_WARNING: + color = get_theme_color("warning_color", "Editor"); + break; + case SEVERITY_ERROR: + color = get_theme_color("error_color", "Editor"); + break; + default: + break; + } + main_button->draw_circle(Vector2(button_radius * 2, button_radius * 2), button_radius, color); +} + +void EditorToaster::_draw_progress(Control *panel) { + if (toasts.has(panel) && toasts[panel].remaining_time > 0 && toasts[panel].duration > 0) { + Size2 size = panel->get_size(); + size.x *= MIN(1, Math::range_lerp(toasts[panel].remaining_time, 0, toasts[panel].duration, 0, 2)); + + Ref<StyleBoxFlat> stylebox; + switch (toasts[panel].severity) { + case SEVERITY_INFO: + stylebox = info_panel_style_progress; + break; + case SEVERITY_WARNING: + stylebox = warning_panel_style_progress; + break; + case SEVERITY_ERROR: + stylebox = error_panel_style_progress; + break; + default: + break; + } + panel->draw_style_box(stylebox, Rect2(Vector2(), size)); + } +} + +void EditorToaster::_set_notifications_enabled(bool p_enabled) { + vbox_container->set_visible(p_enabled); + if (p_enabled) { + main_button->set_icon(get_theme_icon(SNAME("Notification"), SNAME("EditorIcons"))); + } else { + main_button->set_icon(get_theme_icon(SNAME("NotificationDisabled"), SNAME("EditorIcons"))); + } + _update_disable_notifications_button(); +} + +void EditorToaster::_repop_old() { + // Repop olds, up to max_temporary_count + bool needs_update = false; + int visible = 0; + for (int i = vbox_container->get_child_count() - 1; i >= 0; i--) { + Control *control = Object::cast_to<Control>(vbox_container->get_child(i)); + if (!control->is_visible()) { + control->show(); + toasts[control].remaining_time = toasts[control].duration; + toasts[control].popped = true; + needs_update = true; + } + visible++; + if (visible >= max_temporary_count) { + break; + } + } + if (needs_update) { + _update_vbox_position(); + _update_disable_notifications_button(); + main_button->update(); + } +} + +Control *EditorToaster::popup(Control *p_control, Severity p_severity, double p_time, String p_tooltip) { + // Create the panel according to the severity. + PanelContainer *panel = memnew(PanelContainer); + panel->set_tooltip(p_tooltip); + switch (p_severity) { + case SEVERITY_INFO: + panel->add_theme_style_override("panel", info_panel_style_background); + break; + case SEVERITY_WARNING: + panel->add_theme_style_override("panel", warning_panel_style_background); + break; + case SEVERITY_ERROR: + panel->add_theme_style_override("panel", error_panel_style_background); + break; + default: + break; + } + panel->set_modulate(Color(1, 1, 1, 0)); + panel->connect("draw", callable_bind(callable_mp(this, &EditorToaster::_draw_progress), panel)); + + // Horizontal container. + HBoxContainer *hbox_container = memnew(HBoxContainer); + hbox_container->set_h_size_flags(SIZE_EXPAND_FILL); + panel->add_child(hbox_container); + + // Content control. + p_control->set_h_size_flags(SIZE_EXPAND_FILL); + hbox_container->add_child(p_control); + + // Close button. + if (p_time > 0.0) { + Button *close_button = memnew(Button); + close_button->set_flat(true); + close_button->set_icon(get_theme_icon("Close", "EditorIcons")); + close_button->connect("pressed", callable_bind(callable_mp(this, &EditorToaster::close), panel)); + hbox_container->add_child(close_button); + } + + toasts[panel].severity = p_severity; + if (p_time > 0.0) { + toasts[panel].duration = p_time; + toasts[panel].remaining_time = p_time; + } else { + toasts[panel].duration = -1.0; + } + toasts[panel].popped = true; + vbox_container->add_child(panel); + _auto_hide_or_free_toasts(); + _update_vbox_position(); + _update_disable_notifications_button(); + main_button->update(); + + return panel; +} + +void EditorToaster::popup_str(String p_message, Severity p_severity, String p_tooltip) { + // Check if we already have a popup with the given message. + Control *control = nullptr; + for (KeyValue<Control *, Toast> element : toasts) { + if (element.value.message == p_message && element.value.severity == p_severity && element.value.tooltip == p_tooltip) { + control = element.key; + break; + } + } + + // Create a new message if needed. + if (control == nullptr) { + Label *label = memnew(Label); + + control = popup(label, p_severity, default_message_duration, p_tooltip); + toasts[control].message = p_message; + toasts[control].tooltip = p_tooltip; + toasts[control].count = 1; + } else { + if (toasts[control].popped) { + toasts[control].count += 1; + } else { + toasts[control].count = 1; + } + toasts[control].remaining_time = toasts[control].duration; + toasts[control].popped = true; + control->show(); + vbox_container->move_child(control, vbox_container->get_child_count()); + _auto_hide_or_free_toasts(); + _update_vbox_position(); + _update_disable_notifications_button(); + main_button->update(); + } + + // Retrieve the label back then update the text. + Label *label = Object::cast_to<Label>(control->get_child(0)->get_child(0)); + ERR_FAIL_COND(!label); + if (toasts[control].count == 1) { + label->set_text(p_message); + } else { + label->set_text(vformat("%s (%d)", p_message, toasts[control].count)); + } +} + +void EditorToaster::close(Control *p_control) { + ERR_FAIL_COND(!toasts.has(p_control)); + toasts[p_control].remaining_time = -1.0; + toasts[p_control].popped = false; +} + +EditorToaster *EditorToaster::get_singleton() { + return singleton; +} + +EditorToaster::EditorToaster() { + set_notify_transform(true); + set_process_internal(true); + + // VBox. + vbox_container = memnew(VBoxContainer); + vbox_container->set_as_top_level(true); + vbox_container->connect("resized", callable_mp(this, &EditorToaster::_update_vbox_position)); + add_child(vbox_container); + + // Theming (background). + info_panel_style_background.instantiate(); + info_panel_style_background->set_corner_radius_all(stylebox_radius * EDSCALE); + + warning_panel_style_background.instantiate(); + warning_panel_style_background->set_border_width(SIDE_LEFT, stylebox_radius * EDSCALE); + warning_panel_style_background->set_corner_radius_all(stylebox_radius * EDSCALE); + + error_panel_style_background.instantiate(); + error_panel_style_background->set_border_width(SIDE_LEFT, stylebox_radius * EDSCALE); + error_panel_style_background->set_corner_radius_all(stylebox_radius * EDSCALE); + + Ref<StyleBoxFlat> boxes[] = { info_panel_style_background, warning_panel_style_background, error_panel_style_background }; + for (int i = 0; i < 3; i++) { + boxes[i]->set_default_margin(SIDE_LEFT, int(stylebox_radius * 2.5)); + boxes[i]->set_default_margin(SIDE_RIGHT, int(stylebox_radius * 2.5)); + boxes[i]->set_default_margin(SIDE_TOP, 3); + boxes[i]->set_default_margin(SIDE_BOTTOM, 3); + } + + // Theming (progress). + info_panel_style_progress.instantiate(); + info_panel_style_progress->set_corner_radius_all(stylebox_radius * EDSCALE); + + warning_panel_style_progress.instantiate(); + warning_panel_style_progress->set_border_width(SIDE_LEFT, stylebox_radius * EDSCALE); + warning_panel_style_progress->set_corner_radius_all(stylebox_radius * EDSCALE); + + error_panel_style_progress.instantiate(); + error_panel_style_progress->set_border_width(SIDE_LEFT, stylebox_radius * EDSCALE); + error_panel_style_progress->set_corner_radius_all(stylebox_radius * EDSCALE); + + // Main button. + main_button = memnew(Button); + main_button->set_flat(true); + main_button->connect("pressed", callable_mp(this, &EditorToaster::_set_notifications_enabled), varray(true)); + main_button->connect("pressed", callable_mp(this, &EditorToaster::_repop_old)); + main_button->connect("draw", callable_mp(this, &EditorToaster::_draw_button)); + add_child(main_button); + + // Disable notification button. + disable_notifications_panel = memnew(PanelContainer); + disable_notifications_panel->set_as_top_level(true); + disable_notifications_panel->add_theme_style_override("panel", info_panel_style_background); + add_child(disable_notifications_panel); + + disable_notifications_button = memnew(Button); + disable_notifications_button->set_flat(true); + disable_notifications_button->connect("pressed", callable_mp(this, &EditorToaster::_set_notifications_enabled), varray(false)); + disable_notifications_panel->add_child(disable_notifications_button); + + // Other + singleton = this; + + eh.errfunc = _error_handler; + add_error_handler(&eh); +}; + +EditorToaster::~EditorToaster() { + singleton = nullptr; + remove_error_handler(&eh); +} diff --git a/editor/editor_toaster.h b/editor/editor_toaster.h new file mode 100644 index 0000000000..aac80d8fb1 --- /dev/null +++ b/editor/editor_toaster.h @@ -0,0 +1,116 @@ +/*************************************************************************/ +/* editor_toaster.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef EDITOR_TOASTER_H +#define EDITOR_TOASTER_H + +#include "scene/gui/box_container.h" +#include "scene/gui/button.h" +#include "scene/gui/popup.h" + +#include "core/string/ustring.h" +#include "core/templates/local_vector.h" + +class EditorToaster : public HBoxContainer { + GDCLASS(EditorToaster, HBoxContainer); + +public: + enum Severity { + SEVERITY_INFO = 0, + SEVERITY_WARNING, + SEVERITY_ERROR, + }; + +private: + ErrorHandlerList eh; + + const int stylebox_radius = 3; + + Ref<StyleBoxFlat> info_panel_style_background; + Ref<StyleBoxFlat> warning_panel_style_background; + Ref<StyleBoxFlat> error_panel_style_background; + + Ref<StyleBoxFlat> info_panel_style_progress; + Ref<StyleBoxFlat> warning_panel_style_progress; + Ref<StyleBoxFlat> error_panel_style_progress; + + Button *main_button; + PanelContainer *disable_notifications_panel; + Button *disable_notifications_button; + + VBoxContainer *vbox_container; + const int max_temporary_count = 5; + struct Toast { + Severity severity = SEVERITY_INFO; + + // Timing. + real_t duration = -1.0; + real_t remaining_time = 0.0; + bool popped = false; + + // Messages + String message; + String tooltip; + int count = 0; + }; + Map<Control *, Toast> toasts; + + const double default_message_duration = 5.0; + + static void _error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type); + void _update_vbox_position(); + void _update_disable_notifications_button(); + void _auto_hide_or_free_toasts(); + + void _draw_button(); + void _draw_progress(Control *panel); + + void _set_notifications_enabled(bool p_enabled); + void _repop_old(); + +protected: + static EditorToaster *singleton; + + void _notification(int p_what); + +public: + static EditorToaster *get_singleton(); + + Control *popup(Control *p_control, Severity p_severity = SEVERITY_INFO, double p_time = 0.0, String p_tooltip = String()); + void popup_str(String p_message, Severity p_severity = SEVERITY_INFO, String p_tooltip = String()); + void close(Control *p_control); + + EditorToaster(); + ~EditorToaster(); +}; + +VARIANT_ENUM_CAST(EditorToaster::Severity); + +#endif // EDITOR_TOASTER_H diff --git a/editor/icons/Notification.svg b/editor/icons/Notification.svg new file mode 100644 index 0000000000..1f1f9c3e15 --- /dev/null +++ b/editor/icons/Notification.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12.089506 1.2353795c-.498141-.2384823-1.095292-.027987-1.333775.4701537-.01372.028981-.02341.059557-.03428.089693-.01467.023016-.02777.046925-.04071.071459-.04899-.00527-.09728-.00862-.146087-.011473-1.4730257-.6255101-3.1777024.0153376-3.8738627 1.4563251l-1.7272425 3.6078572s-.3364181.7034345-.8079671 1.1268133c-.00105.0009371-.00239.00174-.00344.00268-.2721193.1337295-.5707545.185826-.8605632.0470816-.4981411-.2384824-1.0952924-.0279876-1.3337749.4701537-.01605.033526-.029907.066894-.041944.1011828-.018769.030371-.036749.06319-.052515.096122-.2384825.4981412-.027988 1.0952923.4701537 1.3337751l9.0196437 4.318106c.498141.238482 1.095292.02799 1.333775-.470154.01577-.03293.0301-.0675.04191-.1012.0192-.03086.0365-.06257.05255-.0961.238483-.498141.02799-1.095292-.470153-1.333775-.901965-.43181-.03834-2.235739-.03834-2.235739l1.727237-3.6078618c.715447-1.4944233.08396-3.2858776-1.410461-4.0013247.238482-.4981411.02799-1.0952926-.470154-1.333775zm-5.5145786 11.3714015c-.322341.673306-.037829 1.480435.6354753 1.802775.6733031.32234 1.4804334.03783 1.8027749-.635476z" fill="#e6e6e6"/></svg> diff --git a/editor/icons/NotificationDisabled.svg b/editor/icons/NotificationDisabled.svg new file mode 100644 index 0000000000..0e4465bee8 --- /dev/null +++ b/editor/icons/NotificationDisabled.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m11.705078 1.1386719c-.389281-.0180576-.770356.1928007-.949219.5664062-.01372.028981-.024286.0597078-.035156.0898438-.01467.023016-.026122.0477316-.039062.0722656-.04899-.00527-.097678-.0088657-.146485-.0117187-1.4730253-.6255102-3.1788394.0160437-3.8749998 1.4570312l-1.7265624 3.6074219s-.3370448.7035743-.8085938 1.1269531l-.0019531.0019531c-.2721193.1337295-.5715196.1856194-.8613281.046875-.4981413-.2384824-1.0955019-.0274382-1.3339844.4707031-.01605.0335262-.0289787.0672737-.0410156.1015626-.0187691.0303709-.0369684.0627711-.0527344.0957031-.2384825.4981412-.0293917 1.0955019.46875 1.3339841l.3398437.16211 10.8984379-6.9394535c-.263272-.3070418-.592225-.5660832-.980469-.7519531.238482-.4981411.027441-1.0935489-.470703-1.3320313-.124536-.0596206-.255006-.091637-.384766-.0976562zm2.435547 2.8652343a.94188849 1 0 0 0 -.566406.1386719l-12.1171878 7.7148439a.94188849 1 0 0 0 -.3222656 1.373047.94188849 1 0 0 0 1.2910156.341797l12.1171878-7.7148441a.94188849 1 0 0 0 .322265-1.3710938.94188849 1 0 0 0 -.724609-.4824219zm-.509766 3.2753907-7.3867184 4.7050781 5.0781254 2.431641c.498141.238482 1.095501.027442 1.333984-.470704.01577-.03293.031159-.067862.042969-.101562.0192-.03086.036684-.062173.052734-.095703.238483-.498141.02744-1.095501-.470703-1.333985-.901965-.431809-.039063-2.236328-.039062-2.236328zm-7.0566402 5.3281251c-.322341.673306-.0365856 1.480394.6367187 1.802734.6733031.32234 1.4803929.036588 1.8027344-.636718z" fill="#e6e6e6"/></svg> diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp index 2a8a3216ed..efccac7b74 100644 --- a/editor/plugins/tiles/atlas_merging_dialog.cpp +++ b/editor/plugins/tiles/atlas_merging_dialog.cpp @@ -118,6 +118,7 @@ void AtlasMergingDialog::_generate_merged(Vector<Ref<TileSetAtlasSource>> p_atla output_image_texture.instantiate(); output_image_texture->create_from_image(output_image); + merged->set_name(p_atlas_sources[0]->get_name()); merged->set_texture(output_image_texture); merged->set_texture_region_size(new_texture_region_size); } diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index 5ca39b82b2..90860759b5 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -152,14 +152,21 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() { Ref<Texture2D> texture; String item_text; + // Common to all type of sources. + if (!source->get_name().is_empty()) { + item_text = vformat(TTR("%s (id:%d)"), source->get_name(), source_id); + } + // Atlas source. TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); if (atlas_source) { texture = atlas_source->get_texture(); - if (texture.is_valid()) { - item_text = vformat("%s (ID: %d)", texture->get_path().get_file(), source_id); - } else { - item_text = vformat("No Texture Atlas Source (ID: %d)", source_id); + if (item_text.is_empty()) { + if (texture.is_valid()) { + item_text = vformat("%s (ID: %d)", texture->get_path().get_file(), source_id); + } else { + item_text = vformat("No Texture Atlas Source (ID: %d)", source_id); + } } } @@ -167,7 +174,9 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() { TileSetScenesCollectionSource *scene_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source); if (scene_collection_source) { texture = get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")); - item_text = vformat(TTR("Scene Collection Source (ID: %d)"), source_id); + if (item_text.is_empty()) { + item_text = vformat(TTR("Scene Collection Source (ID: %d)"), source_id); + } } // Use default if not valid. diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index c43a854d9a..157d28da4f 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -66,10 +66,15 @@ int TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::get_id() { } bool TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::_set(const StringName &p_name, const Variant &p_value) { + String name = p_name; + if (name == "name") { + // Use the resource_name property to store the source's name. + name = "resource_name"; + } bool valid = false; - tile_set_atlas_source->set(p_name, p_value, &valid); + tile_set_atlas_source->set(name, p_value, &valid); if (valid) { - emit_signal(SNAME("changed"), String(p_name).utf8().get_data()); + emit_signal(SNAME("changed"), String(name).utf8().get_data()); } return valid; } @@ -78,12 +83,18 @@ bool TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::_get(const StringN if (!tile_set_atlas_source) { return false; } + String name = p_name; + if (name == "name") { + // Use the resource_name property to store the source's name. + name = "resource_name"; + } bool valid = false; - r_ret = tile_set_atlas_source->get(p_name, &valid); + r_ret = tile_set_atlas_source->get(name, &valid); return valid; } void TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::_get_property_list(List<PropertyInfo> *p_list) const { + p_list->push_back(PropertyInfo(Variant::STRING, "name", PROPERTY_HINT_NONE, "")); p_list->push_back(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D")); p_list->push_back(PropertyInfo(Variant::VECTOR2I, "margins", PROPERTY_HINT_NONE, "")); p_list->push_back(PropertyInfo(Variant::VECTOR2I, "separation", PROPERTY_HINT_NONE, "")); @@ -106,6 +117,10 @@ void TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::edit(Ref<TileSet> ERR_FAIL_COND(p_source_id < 0); ERR_FAIL_COND(p_tile_set->get_source(p_source_id) != p_tile_set_atlas_source); + if (p_tile_set == tile_set && p_tile_set_atlas_source == tile_set_atlas_source && p_source_id == source_id) { + return; + } + // Disconnect to changes. if (tile_set_atlas_source) { tile_set_atlas_source->disconnect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); @@ -157,7 +172,7 @@ bool TileSetAtlasSourceEditor::AtlasTileProxyObject::_set(const StringName &p_na } else if (p_name == "size_in_atlas") { Vector2i as_vector2i = Vector2i(p_value); bool has_room_for_tile = tile_set_atlas_source->has_room_for_tile(coords, as_vector2i, tile_set_atlas_source->get_tile_animation_columns(coords), tile_set_atlas_source->get_tile_animation_separation(coords), tile_set_atlas_source->get_tile_animation_frames_count(coords), coords); - ERR_FAIL_COND_V(!has_room_for_tile, false); + ERR_FAIL_COND_V_EDMSG(!has_room_for_tile, false, "Invalid size or not enough room in the atlas for the tile."); tile_set_atlas_source->move_tile_in_atlas(coords, TileSetSource::INVALID_ATLAS_COORDS, as_vector2i); emit_signal(SNAME("changed"), "size_in_atlas"); return true; diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp index 48d0d9b333..6d0d184942 100644 --- a/editor/plugins/tiles/tile_set_editor.cpp +++ b/editor/plugins/tiles/tile_set_editor.cpp @@ -145,14 +145,21 @@ void TileSetEditor::_update_sources_list(int force_selected_id) { Ref<Texture2D> texture; String item_text; + // Common to all type of sources. + if (!source->get_name().is_empty()) { + item_text = vformat(TTR("%s (id:%d)"), source->get_name(), source_id); + } + // Atlas source. TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); if (atlas_source) { texture = atlas_source->get_texture(); - if (texture.is_valid()) { - item_text = vformat("%s (id:%d)", texture->get_path().get_file(), source_id); - } else { - item_text = vformat(TTR("No Texture Atlas Source (id:%d)"), source_id); + if (item_text.is_empty()) { + if (texture.is_valid()) { + item_text = vformat("%s (id:%d)", texture->get_path().get_file(), source_id); + } else { + item_text = vformat(TTR("No Texture Atlas Source (id:%d)"), source_id); + } } } @@ -160,7 +167,9 @@ void TileSetEditor::_update_sources_list(int force_selected_id) { TileSetScenesCollectionSource *scene_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source); if (scene_collection_source) { texture = get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")); - item_text = vformat(TTR("Scene Collection Source (id:%d)"), source_id); + if (item_text.is_empty()) { + item_text = vformat(TTR("Scene Collection Source (id:%d)"), source_id); + } } // Use default if not valid. diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp index f74b3bf9c2..dc26d380b8 100644 --- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp @@ -56,10 +56,15 @@ int TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::get } bool TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::_set(const StringName &p_name, const Variant &p_value) { + String name = p_name; + if (name == "name") { + // Use the resource_name property to store the source's name. + name = "resource_name"; + } bool valid = false; - tile_set_scenes_collection_source->set(p_name, p_value, &valid); + tile_set_scenes_collection_source->set(name, p_value, &valid); if (valid) { - emit_signal(SNAME("changed"), String(p_name).utf8().get_data()); + emit_signal(SNAME("changed"), String(name).utf8().get_data()); } return valid; } @@ -68,11 +73,20 @@ bool TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::_g if (!tile_set_scenes_collection_source) { return false; } + String name = p_name; + if (name == "name") { + // Use the resource_name property to store the source's name. + name = "resource_name"; + } bool valid = false; - r_ret = tile_set_scenes_collection_source->get(p_name, &valid); + r_ret = tile_set_scenes_collection_source->get(name, &valid); return valid; } +void TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::_get_property_list(List<PropertyInfo> *p_list) const { + p_list->push_back(PropertyInfo(Variant::STRING, "name", PROPERTY_HINT_NONE, "")); +} + void TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::_bind_methods() { // -- Shape and layout -- ClassDB::bind_method(D_METHOD("set_id", "id"), &TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::set_id); @@ -89,6 +103,10 @@ void TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::ed ERR_FAIL_COND(p_source_id < 0); ERR_FAIL_COND(p_tile_set->get_source(p_source_id) != p_tile_set_scenes_collection_source); + if (tile_set == p_tile_set && tile_set_scenes_collection_source == p_tile_set_scenes_collection_source && source_id == p_source_id) { + return; + } + // Disconnect to changes. if (tile_set_scenes_collection_source) { tile_set_scenes_collection_source->disconnect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); @@ -174,6 +192,10 @@ void TileSetScenesCollectionSourceEditor::SceneTileProxyObject::edit(TileSetScen ERR_FAIL_COND(!p_tile_set_scenes_collection_source); ERR_FAIL_COND(!p_tile_set_scenes_collection_source->has_scene_tile_id(p_scene_id)); + if (tile_set_scenes_collection_source == p_tile_set_scenes_collection_source && scene_id == p_scene_id) { + return; + } + tile_set_scenes_collection_source = p_tile_set_scenes_collection_source; scene_id = p_scene_id; diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h index 195aa79bc4..3be7bee714 100644 --- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h @@ -51,6 +51,7 @@ private: protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; static void _bind_methods(); public: diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp index 9063b5c6f8..a5e1b0eab8 100644 --- a/editor/rename_dialog.cpp +++ b/editor/rename_dialog.cpp @@ -459,7 +459,7 @@ String RenameDialog::_substitute(const String &subject, const Node *node, int co return result; } -void RenameDialog::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, ErrorHandlerType p_type) { +void RenameDialog::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type) { RenameDialog *self = (RenameDialog *)p_self; String source_file(p_file); diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h index 7990862b37..4db3ef6740 100644 --- a/editor/rename_dialog.h +++ b/editor/rename_dialog.h @@ -63,7 +63,7 @@ class RenameDialog : public ConfirmationDialog { String _postprocess(const String &subject); void _update_preview(String new_text = ""); void _update_preview_int(int new_value = 0); - static void _error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, ErrorHandlerType p_type); + static void _error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type); SceneTreeEditor *scene_tree_editor; UndoRedo *undo_redo; diff --git a/main/main.cpp b/main/main.cpp index 3cc7923cc2..a07533180a 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2522,6 +2522,9 @@ bool Main::iteration() { bool exit = false; + // process all our active interfaces + XRServer::get_singleton()->_process(); + for (int iters = 0; iters < advance.physics_steps; ++iters) { if (Input::get_singleton()->is_using_input_buffering() && agile_input_event_flushing) { Input::get_singleton()->flush_buffered_events(); diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index b84ce2d192..e0de1a0505 100644 --- a/modules/gdnative/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative/gdnative.cpp @@ -129,13 +129,13 @@ void GDAPI godot_free(void *p_ptr) { // Helper print functions. void GDAPI godot_print_error(const char *p_description, const char *p_function, const char *p_file, int p_line) { - _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_ERROR); + _err_print_error(p_function, p_file, p_line, p_description, false, ERR_HANDLER_ERROR); } void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line) { - _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_WARNING); + _err_print_error(p_function, p_file, p_line, p_description, false, ERR_HANDLER_WARNING); } void GDAPI godot_print_script_error(const char *p_description, const char *p_function, const char *p_file, int p_line) { - _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_SCRIPT); + _err_print_error(p_function, p_file, p_line, p_description, false, ERR_HANDLER_SCRIPT); } void _gdnative_report_version_mismatch(const godot_object *p_library, const char *p_ext, godot_gdnative_api_version p_want, godot_gdnative_api_version p_have) { diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index e9d3749a8d..42865242d3 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -835,7 +835,7 @@ Error GDScript::reload(bool p_keep_state) { GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), parser.get_errors().front()->get().line, "Parser Error: " + parser.get_errors().front()->get().message); } // TODO: Show all error messages. - _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_errors().front()->get().line, ("Parse Error: " + parser.get_errors().front()->get().message).utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_errors().front()->get().line, ("Parse Error: " + parser.get_errors().front()->get().message).utf8().get_data(), false, ERR_HANDLER_SCRIPT); ERR_FAIL_V(ERR_PARSE_ERROR); } @@ -849,7 +849,7 @@ Error GDScript::reload(bool p_keep_state) { const List<GDScriptParser::ParserError>::Element *e = parser.get_errors().front(); while (e != nullptr) { - _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), e->get().line, ("Parse Error: " + e->get().message).utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), e->get().line, ("Parse Error: " + e->get().message).utf8().get_data(), false, ERR_HANDLER_SCRIPT); e = e->next(); } ERR_FAIL_V(ERR_PARSE_ERROR); @@ -869,7 +869,7 @@ Error GDScript::reload(bool p_keep_state) { if (EngineDebugger::is_active()) { GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), compiler.get_error_line(), "Parser Error: " + compiler.get_error()); } - _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), compiler.get_error_line(), ("Compile Error: " + compiler.get_error()).utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), compiler.get_error_line(), ("Compile Error: " + compiler.get_error()).utf8().get_data(), false, ERR_HANDLER_SCRIPT); ERR_FAIL_V(ERR_COMPILATION_FAILED); } else { return err; @@ -879,7 +879,7 @@ Error GDScript::reload(bool p_keep_state) { for (const GDScriptWarning &warning : parser.get_warnings()) { if (EngineDebugger::is_active()) { Vector<ScriptLanguage::StackInfo> si; - EngineDebugger::get_script_debugger()->send_error("", get_path(), warning.start_line, warning.get_name(), warning.get_message(), ERR_HANDLER_WARNING, si); + EngineDebugger::get_script_debugger()->send_error("", get_path(), warning.start_line, warning.get_name(), warning.get_message(), false, ERR_HANDLER_WARNING, si); } } #endif diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 7018c339d7..40f03979c6 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -3315,7 +3315,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a if (!GDScriptLanguage::get_singleton()->debug_break(err_text, false)) { // debugger break did not happen - _err_print_error(err_func.utf8().get_data(), err_file.utf8().get_data(), err_line, err_text.utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error(err_func.utf8().get_data(), err_file.utf8().get_data(), err_line, err_text.utf8().get_data(), false, ERR_HANDLER_SCRIPT); } #endif diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp index 50c1f68440..d2e71efee7 100644 --- a/modules/gdscript/tests/gdscript_test_runner.cpp +++ b/modules/gdscript/tests/gdscript_test_runner.cpp @@ -334,7 +334,7 @@ void GDScriptTest::print_handler(void *p_this, const String &p_message, bool p_e result->output += p_message + "\n"; } -void GDScriptTest::error_handler(void *p_this, const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_explanation, ErrorHandlerType p_type) { +void GDScriptTest::error_handler(void *p_this, const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_explanation, bool p_editor_notify, ErrorHandlerType p_type) { ErrorHandlerData *data = (ErrorHandlerData *)p_this; GDScriptTest *self = data->self; TestResult *result = data->result; diff --git a/modules/gdscript/tests/gdscript_test_runner.h b/modules/gdscript/tests/gdscript_test_runner.h index 9b2d14a371..98c57dc97c 100644 --- a/modules/gdscript/tests/gdscript_test_runner.h +++ b/modules/gdscript/tests/gdscript_test_runner.h @@ -87,7 +87,7 @@ private: public: static void print_handler(void *p_this, const String &p_message, bool p_error); - static void error_handler(void *p_this, const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_explanation, ErrorHandlerType p_type); + static void error_handler(void *p_this, const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_explanation, bool p_editor_notify, ErrorHandlerType p_type); TestResult run_test(); bool generate_output(); diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 7d4bd998f5..b8da3a713b 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -247,7 +247,7 @@ Error GLTFDocument::_parse_json(const String &p_path, Ref<GLTFState> state) { JSON json; err = json.parse(text); if (err != OK) { - _err_print_error("", p_path.utf8().get_data(), json.get_error_line(), json.get_error_message().utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error("", p_path.utf8().get_data(), json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT); return err; } state->json = json.get_data(); @@ -282,7 +282,7 @@ Error GLTFDocument::_parse_glb(const String &p_path, Ref<GLTFState> state) { JSON json; err = json.parse(text); if (err != OK) { - _err_print_error("", p_path.utf8().get_data(), json.get_error_line(), json.get_error_message().utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error("", p_path.utf8().get_data(), json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT); return err; } diff --git a/modules/mobile_vr/doc_classes/MobileVRInterface.xml b/modules/mobile_vr/doc_classes/MobileVRInterface.xml index 04ba82ef51..18a77c8b8d 100644 --- a/modules/mobile_vr/doc_classes/MobileVRInterface.xml +++ b/modules/mobile_vr/doc_classes/MobileVRInterface.xml @@ -37,5 +37,6 @@ <member name="oversample" type="float" setter="set_oversample" getter="get_oversample" default="1.5"> The oversample setting. Because of the lens distortion we have to render our buffers at a higher resolution then the screen can natively handle. A value between 1.5 and 2.0 often provides good results but at the cost of performance. </member> + <member name="xr_play_area_mode" type="int" setter="set_play_area_mode" getter="get_play_area_mode" override="true" enum="XRInterface.PlayAreaMode" default="1" /> </members> </class> diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index fc1a118e4f..ba7353ace2 100644 --- a/modules/mobile_vr/mobile_vr_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -126,6 +126,8 @@ void MobileVRInterface::set_position_from_sensors() { // 9dof is a misleading marketing term coming from 3 accelerometer axis + 3 gyro axis + 3 magnetometer axis = 9 axis // but in reality this only offers 3 dof (yaw, pitch, roll) orientation + Basis orientation; + uint64_t ticks = OS::get_singleton()->get_ticks_usec(); uint64_t ticks_elapsed = ticks - last_ticks; float delta_time = (double)ticks_elapsed / 1000000.0; @@ -207,8 +209,8 @@ void MobileVRInterface::set_position_from_sensors() { }; }; - // JIC - orientation.orthonormalize(); + // and copy to our head transform + head_transform.basis = orientation.orthonormalized(); last_ticks = ticks; }; @@ -318,7 +320,7 @@ bool MobileVRInterface::initialize() { ERR_FAIL_NULL_V(xr_server, false); if (!initialized) { - // reset our sensor data and orientation + // reset our sensor data mag_count = 0; has_gyro = false; sensor_first = true; @@ -326,9 +328,15 @@ bool MobileVRInterface::initialize() { mag_next_max = Vector3(-10000, -10000, -10000); mag_current_min = Vector3(0, 0, 0); mag_current_max = Vector3(0, 0, 0); + head_transform.basis = Basis(); + head_transform.origin = Vector3(0.0, eye_height, 0.0); - // reset our orientation - orientation = Basis(); + // we must create a tracker for our head + head.instantiate(); + head->set_tracker_type(XRServer::TRACKER_HEAD); + head->set_tracker_name("head"); + head->set_tracker_desc("Players head"); + xr_server->add_tracker(head); // make this our primary interface xr_server->set_primary_interface(this); @@ -343,16 +351,38 @@ bool MobileVRInterface::initialize() { void MobileVRInterface::uninitialize() { if (initialized) { + // do any cleanup here... XRServer *xr_server = XRServer::get_singleton(); - if (xr_server != nullptr && xr_server->get_primary_interface() == this) { - // no longer our primary interface - xr_server->set_primary_interface(nullptr); + if (xr_server != nullptr) { + if (head.is_valid()) { + xr_server->remove_tracker(head); + + head.unref(); + } + + if (xr_server->get_primary_interface() == this) { + // no longer our primary interface + xr_server->set_primary_interface(nullptr); + } } initialized = false; }; }; +bool MobileVRInterface::supports_play_area_mode(XRInterface::PlayAreaMode p_mode) { + // This interface has no positional tracking so fix this to 3DOF + return p_mode == XR_PLAY_AREA_3DOF; +} + +XRInterface::PlayAreaMode MobileVRInterface::get_play_area_mode() const { + return XR_PLAY_AREA_3DOF; +} + +bool MobileVRInterface::set_play_area_mode(XRInterface::PlayAreaMode p_mode) { + return p_mode == XR_PLAY_AREA_3DOF; +} + Size2 MobileVRInterface::get_render_target_size() { _THREAD_SAFE_METHOD_ @@ -377,11 +407,10 @@ Transform3D MobileVRInterface::get_camera_transform() { float world_scale = xr_server->get_world_scale(); // just scale our origin point of our transform - Transform3D hmd_transform; - hmd_transform.basis = orientation; - hmd_transform.origin = Vector3(0.0, eye_height * world_scale, 0.0); + Transform3D _head_transform = head_transform; + _head_transform.origin *= world_scale; - transform_for_eye = (xr_server->get_reference_frame()) * hmd_transform; + transform_for_eye = (xr_server->get_reference_frame()) * _head_transform; } return transform_for_eye; @@ -409,11 +438,10 @@ Transform3D MobileVRInterface::get_transform_for_view(uint32_t p_view, const Tra }; // just scale our origin point of our transform - Transform3D hmd_transform; - hmd_transform.basis = orientation; - hmd_transform.origin = Vector3(0.0, eye_height * world_scale, 0.0); + Transform3D _head_transform = head_transform; + _head_transform.origin *= world_scale; - transform_for_eye = p_cam_transform * (xr_server->get_reference_frame()) * hmd_transform * transform_for_eye; + transform_for_eye = p_cam_transform * (xr_server->get_reference_frame()) * _head_transform * transform_for_eye; } else { // huh? well just return what we got.... transform_for_eye = p_cam_transform; @@ -476,7 +504,16 @@ void MobileVRInterface::process() { _THREAD_SAFE_METHOD_ if (initialized) { + // update our head transform orientation set_position_from_sensors(); + + // update our head transform position (should be constant) + head_transform.origin = Vector3(0.0, eye_height, 0.0); + + if (head.is_valid()) { + // Set our head position, note in real space, reference frame and world scale is applied later + head->set_pose("default", head_transform, Vector3(), Vector3()); + } }; }; diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h index a843e1188b..b5bf966247 100644 --- a/modules/mobile_vr/mobile_vr_interface.h +++ b/modules/mobile_vr/mobile_vr_interface.h @@ -53,7 +53,6 @@ class MobileVRInterface : public XRInterface { private: bool initialized = false; XRInterface::TrackingStatus tracking_state; - Basis orientation; // Just set some defaults for these. At some point we need to look at adding a lookup table for common device + headset combos and/or support reading cardboard QR codes double eye_height = 1.85; @@ -68,6 +67,10 @@ private: double k2 = 0.215; double aspect = 1.0; + // at a minimum we need a tracker for our head + Ref<XRPositionalTracker> head; + Transform3D head_transform; + /* logic for processing our sensor data, this was originally in our positional tracker logic but I think that doesn't make sense in hindsight. It only makes marginally more sense to park it here for now, @@ -140,6 +143,10 @@ public: virtual bool initialize() override; virtual void uninitialize() override; + virtual bool supports_play_area_mode(XRInterface::PlayAreaMode p_mode) override; + virtual XRInterface::PlayAreaMode get_play_area_mode() const override; + virtual bool set_play_area_mode(XRInterface::PlayAreaMode p_mode) override; + virtual Size2 get_render_target_size() override; virtual uint32_t get_view_count() override; virtual Transform3D get_camera_transform() override; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 247eee4280..26a04a358d 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -1660,7 +1660,7 @@ bool CSharpInstance::set(const StringName &p_name, const Variant &p_value) { GDMonoProperty *property = top->get_property(p_name); if (property) { - property->set_value(mono_object, GDMonoMarshal::variant_to_mono_object(p_value, property->get_type())); + property->set_value_from_variant(mono_object, p_value); return true; } diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp index 5391b7775e..5c7cf29e88 100644 --- a/modules/mono/mono_gd/gd_mono_property.cpp +++ b/modules/mono/mono_gd/gd_mono_property.cpp @@ -65,6 +65,8 @@ GDMonoProperty::GDMonoProperty(MonoProperty *p_mono_property, GDMonoClass *p_own type.type_class = GDMono::get_singleton()->get_class(param_type_class); } + param_buffer_size = GDMonoMarshal::variant_get_managed_unboxed_size(type); + attrs_fetched = false; attributes = nullptr; } @@ -147,24 +149,20 @@ bool GDMonoProperty::has_setter() { return mono_property_get_set_method(mono_property) != nullptr; } -void GDMonoProperty::set_value(MonoObject *p_object, MonoObject *p_value, MonoException **r_exc) { - MonoMethod *prop_method = mono_property_get_set_method(mono_property); - void *params[1] = { p_value }; - MonoException *exc = nullptr; - GDMonoUtils::runtime_invoke(prop_method, p_object, params, &exc); - if (exc) { - if (r_exc) { - *r_exc = exc; - } else { - GDMonoUtils::set_pending_exception(exc); - } - } -} +void GDMonoProperty::set_value_from_variant(MonoObject *p_object, const Variant &p_value, MonoException **r_exc) { + uint8_t *buffer = (uint8_t *)alloca(param_buffer_size); + unsigned int offset = 0; -void GDMonoProperty::set_value(MonoObject *p_object, void **p_params, MonoException **r_exc) { - MonoException *exc = nullptr; - GDMonoUtils::property_set_value(mono_property, p_object, p_params, &exc); + void *params[1] = { + GDMonoMarshal::variant_to_managed_unboxed(p_value, type, buffer, offset) + }; + +#ifdef DEBUG_ENABLED + CRASH_COND(offset != param_buffer_size); +#endif + MonoException *exc = nullptr; + GDMonoUtils::property_set_value(mono_property, p_object, params, &exc); if (exc) { if (r_exc) { *r_exc = exc; diff --git a/modules/mono/mono_gd/gd_mono_property.h b/modules/mono/mono_gd/gd_mono_property.h index af7a2c02e5..9bb1caa759 100644 --- a/modules/mono/mono_gd/gd_mono_property.h +++ b/modules/mono/mono_gd/gd_mono_property.h @@ -45,6 +45,8 @@ class GDMonoProperty : public IMonoClassMember { bool attrs_fetched; MonoCustomAttrInfo *attributes; + unsigned int param_buffer_size; + public: virtual GDMonoClass *get_enclosing_class() const final { return owner; } @@ -64,8 +66,7 @@ public: _FORCE_INLINE_ ManagedType get_type() const { return type; } - void set_value(MonoObject *p_object, MonoObject *p_value, MonoException **r_exc = nullptr); - void set_value(MonoObject *p_object, void **p_params, MonoException **r_exc = nullptr); + void set_value_from_variant(MonoObject *p_object, const Variant &p_value, MonoException **r_exc = nullptr); MonoObject *get_value(MonoObject *p_object, MonoException **r_exc = nullptr); bool get_bool_value(MonoObject *p_object); diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 54d310e636..8f4e807295 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -1688,7 +1688,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p // debugger break did not happen if (!VisualScriptLanguage::singleton->debug_break(error_str, false)) { - _err_print_error(err_func.utf8().get_data(), err_file.utf8().get_data(), err_line, error_str.utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error(err_func.utf8().get_data(), err_file.utf8().get_data(), err_line, error_str.utf8().get_data(), false, ERR_HANDLER_SCRIPT); } //} diff --git a/modules/webxr/doc_classes/WebXRInterface.xml b/modules/webxr/doc_classes/WebXRInterface.xml index 16d671c9e9..6e224a8242 100644 --- a/modules/webxr/doc_classes/WebXRInterface.xml +++ b/modules/webxr/doc_classes/WebXRInterface.xml @@ -87,7 +87,7 @@ There are several ways to handle "controller" input: - Using [XRController3D] nodes and their [signal XRController3D.button_pressed] and [signal XRController3D.button_released] signals. This is how controllers are typically handled in AR/VR apps in Godot, however, this will only work with advanced VR controllers like the Oculus Touch or Index controllers, for example. The buttons codes are defined by [url=https://immersive-web.github.io/webxr-gamepads-module/#xr-standard-gamepad-mapping]Section 3.3 of the WebXR Gamepads Module[/url]. - Using [method Node._unhandled_input] and [InputEventJoypadButton] or [InputEventJoypadMotion]. This works the same as normal joypads, except the [member InputEvent.device] starts at 100, so the left controller is 100 and the right controller is 101, and the button codes are also defined by [url=https://immersive-web.github.io/webxr-gamepads-module/#xr-standard-gamepad-mapping]Section 3.3 of the WebXR Gamepads Module[/url]. - - Using the [signal select], [signal squeeze] and related signals. This method will work for both advanced VR controllers, and non-traditional "controllers" like a tap on the screen, a spoken voice command or a button press on the device itself. The [code]controller_id[/code] passed to these signals is the same id as used in [member XRController3D.controller_id]. + - Using the [signal select], [signal squeeze] and related signals. This method will work for both advanced VR controllers, and non-traditional "controllers" like a tap on the screen, a spoken voice command or a button press on the device itself. You can use one or all of these methods to allow your game or app to support a wider or narrower set of devices and input methods, or to allow more advanced interactions with more advanced devices. </description> <tutorials> diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp index 10c17aa672..2676b3cf80 100644 --- a/modules/webxr/webxr_interface_js.cpp +++ b/modules/webxr/webxr_interface_js.cpp @@ -163,9 +163,14 @@ String WebXRInterfaceJS::get_reference_space_type() const { Ref<XRPositionalTracker> WebXRInterfaceJS::get_controller(int p_controller_id) const { XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL_V(xr_server, nullptr); + ERR_FAIL_NULL_V(xr_server, Ref<XRPositionalTracker>()); - return xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); + // TODO support more then two controllers + if (p_controller_id >= 0 && p_controller_id < 2) { + return controllers[p_controller_id]; + }; + + return Ref<XRPositionalTracker>(); } String WebXRInterfaceJS::get_visibility_state() const { @@ -224,6 +229,13 @@ bool WebXRInterfaceJS::initialize() { return false; } + // we must create a tracker for our head + head_tracker.instantiate(); + head_tracker->set_tracker_type(XRServer::TRACKER_HEAD); + head_tracker->set_tracker_name("head"); + head_tracker->set_tracker_desc("Players head"); + xr_server->add_tracker(head_tracker); + // make this our primary interface xr_server->set_primary_interface(this); @@ -254,9 +266,17 @@ bool WebXRInterfaceJS::initialize() { void WebXRInterfaceJS::uninitialize() { if (initialized) { XRServer *xr_server = XRServer::get_singleton(); - if (xr_server != nullptr && xr_server->get_primary_interface() == this) { - // no longer our primary interface - xr_server->set_primary_interface(nullptr); + if (xr_server != nullptr) { + if (head_tracker.is_valid()) { + xr_server->remove_tracker(head_tracker); + + head_tracker.unref(); + } + + if (xr_server->get_primary_interface() == this) { + // no longer our primary interface + xr_server->set_primary_interface(nullptr); + } } godot_webxr_uninitialize(); @@ -373,9 +393,9 @@ Vector<BlitToScreen> WebXRInterfaceJS::commit_views(RID p_render_target, const R } // @todo Refactor this to be based on "views" rather than "eyes". - godot_webxr_commit_for_eye(XRInterface::EYE_LEFT); + godot_webxr_commit_for_eye(1); if (godot_webxr_get_view_count() > 1) { - godot_webxr_commit_for_eye(XRInterface::EYE_RIGHT); + godot_webxr_commit_for_eye(2); } return blit_to_screen; @@ -385,6 +405,11 @@ void WebXRInterfaceJS::process() { if (initialized) { godot_webxr_sample_controller_data(); + if (head_tracker.is_valid()) { + // TODO set default pose to our head location (i.e. get_camera_transform without world scale and reference frame applied) + // head_tracker->set_pose("default", head_transform, Vector3(), Vector3()); + } + int controller_count = godot_webxr_get_controller_count(); if (controller_count == 0) { return; @@ -400,51 +425,70 @@ void WebXRInterfaceJS::_update_tracker(int p_controller_id) { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL(xr_server); - Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id + 1); + // need to support more then two controllers... + if (p_controller_id < 0 || p_controller_id > 1) { + return; + } + + Ref<XRPositionalTracker> tracker = controllers[p_controller_id]; if (godot_webxr_is_controller_connected(p_controller_id)) { if (tracker.is_null()) { tracker.instantiate(); tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER); // Controller id's 0 and 1 are always the left and right hands. if (p_controller_id < 2) { - tracker->set_tracker_name(p_controller_id == 0 ? "Left" : "Right"); + tracker->set_tracker_name(p_controller_id == 0 ? "left_hand" : "right_hand"); + tracker->set_tracker_desc(p_controller_id == 0 ? "Left hand controller" : "Right hand controller"); tracker->set_tracker_hand(p_controller_id == 0 ? XRPositionalTracker::TRACKER_HAND_LEFT : XRPositionalTracker::TRACKER_HAND_RIGHT); + } else { + char name[1024]; + sprintf(name, "tracker_%i", p_controller_id); + tracker->set_tracker_name(name); + tracker->set_tracker_desc(name); } - // Use the ids we're giving to our "virtual" gamepads. - tracker->set_joy_id(p_controller_id + 100); xr_server->add_tracker(tracker); } - Input *input = Input::get_singleton(); - float *tracker_matrix = godot_webxr_get_controller_transform(p_controller_id); if (tracker_matrix) { + // Note, poses should NOT have world scale and our reference frame applied! Transform3D transform = _js_matrix_to_transform(tracker_matrix); - tracker->set_position(transform.origin); - tracker->set_orientation(transform.basis); + tracker->set_pose("default", transform, Vector3(), Vector3()); free(tracker_matrix); } + // TODO implement additional poses such as "aim" and "grip" + int *buttons = godot_webxr_get_controller_buttons(p_controller_id); if (buttons) { + // TODO buttons should be named properly, this is just a temporary fix for (int i = 0; i < buttons[0]; i++) { - input->joy_button(p_controller_id + 100, (JoyButton)i, *((float *)buttons + (i + 1))); + char name[1024]; + sprintf(name, "button_%i", i); + + float value = *((float *)buttons + (i + 1)); + bool state = value > 0.0; + tracker->set_input(name, state); } free(buttons); } int *axes = godot_webxr_get_controller_axes(p_controller_id); if (axes) { + // TODO again just a temporary fix, split these between proper float and vector2 inputs for (int i = 0; i < axes[0]; i++) { - Input::JoyAxisValue joy_axis; - joy_axis.min = -1; - joy_axis.value = *((float *)axes + (i + 1)); - input->joy_axis(p_controller_id + 100, (JoyAxis)i, joy_axis); + char name[1024]; + sprintf(name, "axis_%i", i); + + float value = *((float *)axes + (i + 1)); + ; + tracker->set_input(name, value); } free(axes); } } else if (tracker.is_valid()) { xr_server->remove_tracker(tracker); + controllers[p_controller_id].unref(); } } @@ -454,7 +498,7 @@ void WebXRInterfaceJS::_on_controller_changed() { for (int i = 0; i < 2; i++) { bool controller_connected = godot_webxr_is_controller_connected(i); if (controllers_state[i] != controller_connected) { - Input::get_singleton()->joy_connection_changed(i + 100, controller_connected, i == 0 ? "Left" : "Right", ""); + // Input::get_singleton()->joy_connection_changed(i + 100, controller_connected, i == 0 ? "Left" : "Right", ""); controllers_state[i] = controller_connected; } } diff --git a/modules/webxr/webxr_interface_js.h b/modules/webxr/webxr_interface_js.h index eb77f35f39..6e6548c946 100644 --- a/modules/webxr/webxr_interface_js.h +++ b/modules/webxr/webxr_interface_js.h @@ -46,6 +46,7 @@ class WebXRInterfaceJS : public WebXRInterface { private: bool initialized; + Ref<XRPositionalTracker> head_tracker; String session_mode; String required_features; @@ -53,7 +54,9 @@ private: String requested_reference_space_types; String reference_space_type; + // TODO maybe turn into a vector to support more then 2 controllers... bool controllers_state[2]; + Ref<XRPositionalTracker> controllers[2]; Size2 render_targetsize; Transform3D _js_matrix_to_transform(float *p_js_matrix); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index e9cb46ed21..489cbe074b 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -178,7 +178,7 @@ class OSXTerminalLogger : public StdLogger { public: - virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR) { + virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type = ERR_ERROR) { if (!should_log(true)) { return; } diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index 56edf100f6..9dbee58f0e 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -47,13 +47,45 @@ void XRCamera3D::_notification(int p_what) { case NOTIFICATION_EXIT_TREE: { // need to find our XROrigin3D parent and let it know we're no longer its camera! XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); - if (origin != nullptr) { - origin->clear_tracked_camera_if(this); + if (origin != nullptr && origin->get_tracked_camera() == this) { + origin->set_tracked_camera(nullptr); } }; break; }; }; +void XRCamera3D::_changed_tracker(const StringName p_tracker_name, int p_tracker_type) { + if (p_tracker_name == tracker_name) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); + + tracker = xr_server->get_tracker(p_tracker_name); + if (tracker.is_valid()) { + tracker->connect("pose_changed", callable_mp(this, &XRCamera3D::_pose_changed)); + + Ref<XRPose> pose = tracker->get_pose(pose_name); + if (pose.is_valid()) { + set_transform(pose->get_adjusted_transform()); + } + } + } +} + +void XRCamera3D::_removed_tracker(const StringName p_tracker_name, int p_tracker_type) { + if (p_tracker_name == tracker_name) { + if (tracker.is_valid()) { + tracker->disconnect("pose_changed", callable_mp(this, &XRCamera3D::_pose_changed)); + } + tracker.unref(); + } +} + +void XRCamera3D::_pose_changed(const Ref<XRPose> &p_pose) { + if (p_pose->get_name() == pose_name) { + set_transform(p_pose->get_adjusted_transform()); + } +} + TypedArray<String> XRCamera3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); @@ -172,195 +204,215 @@ Vector<Plane> XRCamera3D::get_frustum() const { return cm.get_projection_planes(get_camera_transform()); }; -//////////////////////////////////////////////////////////////////////////////////////////////////// +XRCamera3D::XRCamera3D() { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); -void XRController3D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - set_process_internal(true); - }; break; - case NOTIFICATION_EXIT_TREE: { - set_process_internal(false); - }; break; - case NOTIFICATION_INTERNAL_PROCESS: { - // get our XRServer - XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL(xr_server); - - // find the tracker for our controller - Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); - if (!tracker.is_valid()) { - // this controller is currently turned off - is_active = false; - button_states = 0; - } else { - is_active = true; - set_transform(tracker->get_transform(true)); - - int joy_id = tracker->get_joy_id(); - if (joy_id >= 0) { - int mask = 1; - // check button states - for (int i = 0; i < 16; i++) { - bool was_pressed = (button_states & mask) == mask; - bool is_pressed = Input::get_singleton()->is_joy_button_pressed(joy_id, (JoyButton)i); - - if (!was_pressed && is_pressed) { - emit_signal(SNAME("button_pressed"), i); - button_states += mask; - } else if (was_pressed && !is_pressed) { - emit_signal(SNAME("button_released"), i); - button_states -= mask; - }; - - mask = mask << 1; - }; - - } else { - button_states = 0; - }; - - // check for an updated mesh - Ref<Mesh> trackerMesh = tracker->get_mesh(); - if (mesh != trackerMesh) { - mesh = trackerMesh; - emit_signal(SNAME("mesh_updated"), mesh); - } - }; - }; break; - default: - break; - }; -}; + xr_server->connect("tracker_added", callable_mp(this, &XRCamera3D::_changed_tracker)); + xr_server->connect("tracker_updated", callable_mp(this, &XRCamera3D::_changed_tracker)); + xr_server->connect("tracker_removed", callable_mp(this, &XRCamera3D::_removed_tracker)); +} -void XRController3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_controller_id", "controller_id"), &XRController3D::set_controller_id); - ClassDB::bind_method(D_METHOD("get_controller_id"), &XRController3D::get_controller_id); - ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_id", PROPERTY_HINT_RANGE, "0,32,1"), "set_controller_id", "get_controller_id"); - ClassDB::bind_method(D_METHOD("get_controller_name"), &XRController3D::get_controller_name); +XRCamera3D::~XRCamera3D() { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); - // passthroughs to information about our related joystick - ClassDB::bind_method(D_METHOD("get_joystick_id"), &XRController3D::get_joystick_id); - ClassDB::bind_method(D_METHOD("is_button_pressed", "button"), &XRController3D::is_button_pressed); - ClassDB::bind_method(D_METHOD("get_joystick_axis", "axis"), &XRController3D::get_joystick_axis); + xr_server->disconnect("tracker_added", callable_mp(this, &XRCamera3D::_changed_tracker)); + xr_server->disconnect("tracker_updated", callable_mp(this, &XRCamera3D::_changed_tracker)); + xr_server->disconnect("tracker_removed", callable_mp(this, &XRCamera3D::_removed_tracker)); +} - ClassDB::bind_method(D_METHOD("get_is_active"), &XRController3D::get_is_active); - ClassDB::bind_method(D_METHOD("get_tracker_hand"), &XRController3D::get_tracker_hand); +//////////////////////////////////////////////////////////////////////////////////////////////////// +// XRNode3D is a node that has it's transform updated by an XRPositionalTracker. +// Note that trackers are only available in runtime and only after an XRInterface registers one. +// So we bind by name and as long as a tracker isn't available, our node remains inactive. - ClassDB::bind_method(D_METHOD("get_rumble"), &XRController3D::get_rumble); - ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRController3D::set_rumble); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_rumble", "get_rumble"); - ADD_PROPERTY_DEFAULT("rumble", 0.0); +void XRNode3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_tracker", "tracker_name"), &XRNode3D::set_tracker); + ClassDB::bind_method(D_METHOD("get_tracker"), &XRNode3D::get_tracker); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "tracker", PROPERTY_HINT_ENUM_SUGGESTION), "set_tracker", "get_tracker"); - ClassDB::bind_method(D_METHOD("get_mesh"), &XRController3D::get_mesh); + ClassDB::bind_method(D_METHOD("set_pose_name", "pose"), &XRNode3D::set_pose_name); + ClassDB::bind_method(D_METHOD("get_pose_name"), &XRNode3D::get_pose_name); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "pose", PROPERTY_HINT_ENUM_SUGGESTION), "set_pose_name", "get_pose_name"); - ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::INT, "button"))); - ADD_SIGNAL(MethodInfo("button_released", PropertyInfo(Variant::INT, "button"))); - ADD_SIGNAL(MethodInfo("mesh_updated", PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"))); + ClassDB::bind_method(D_METHOD("get_is_active"), &XRNode3D::get_is_active); + ClassDB::bind_method(D_METHOD("get_has_tracking_data"), &XRNode3D::get_has_tracking_data); + ClassDB::bind_method(D_METHOD("get_pose"), &XRNode3D::get_pose); + ClassDB::bind_method(D_METHOD("trigger_haptic_pulse", "action_name", "frequency", "amplitude", "duration_sec", "delay_sec"), &XRNode3D::trigger_haptic_pulse); }; -void XRController3D::set_controller_id(int p_controller_id) { - // We don't check any bounds here, this controller may not yet be active and just be a place holder until it is. - // Note that setting this to 0 means this node is not bound to a controller yet. - controller_id = p_controller_id; - update_configuration_warnings(); -}; +void XRNode3D::_validate_property(PropertyInfo &property) const { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); -int XRController3D::get_controller_id() const { - return controller_id; -}; + if (property.name == "tracker") { + PackedStringArray names = xr_server->get_suggested_tracker_names(); + String hint_string; + for (const String &name : names) { + hint_string += name + ","; + } + property.hint_string = hint_string; + } else if (property.name == "pose") { + PackedStringArray names = xr_server->get_suggested_pose_names(tracker_name); + String hint_string; + for (const String &name : names) { + hint_string += name + ","; + } + property.hint_string = hint_string; + } +} -String XRController3D::get_controller_name() const { - // get our XRServer - XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL_V(xr_server, String()); +void XRNode3D::set_tracker(const StringName p_tracker_name) { + if (tracker.is_valid() && tracker->get_tracker_name() == p_tracker_name) { + // didn't change + return; + } - Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); - if (!tracker.is_valid()) { - return String("Not connected"); - }; + // just in case + _unbind_tracker(); - return tracker->get_tracker_name(); -}; + // copy the name + tracker_name = p_tracker_name; + pose_name = "default"; -int XRController3D::get_joystick_id() const { - // get our XRServer - XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL_V(xr_server, 0); + // see if it's already available + _bind_tracker(); - Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); - if (!tracker.is_valid()) { - // No tracker? no joystick id... (0 is our first joystick) - return -1; - }; + update_configuration_warnings(); + notify_property_list_changed(); +} - return tracker->get_joy_id(); -}; +StringName XRNode3D::get_tracker() const { + return tracker_name; +} -bool XRController3D::is_button_pressed(int p_button) const { - int joy_id = get_joystick_id(); - if (joy_id == -1) { - return false; - }; +void XRNode3D::set_pose_name(const StringName p_pose_name) { + pose_name = p_pose_name; - return Input::get_singleton()->is_joy_button_pressed(joy_id, (JoyButton)p_button); -}; + // Update pose if we are bound to a tracker with a valid pose + Ref<XRPose> pose = get_pose(); + if (pose.is_valid()) { + set_transform(pose->get_adjusted_transform()); + } +} -float XRController3D::get_joystick_axis(int p_axis) const { - int joy_id = get_joystick_id(); - if (joy_id == -1) { - return 0.0; - }; +StringName XRNode3D::get_pose_name() const { + return pose_name; +} - return Input::get_singleton()->get_joy_axis(joy_id, (JoyAxis)p_axis); -}; +bool XRNode3D::get_is_active() const { + if (tracker.is_null()) { + return false; + } else if (!tracker->has_pose(pose_name)) { + return false; + } else { + return true; + } +} -real_t XRController3D::get_rumble() const { - // get our XRServer +bool XRNode3D::get_has_tracking_data() const { + if (tracker.is_null()) { + return false; + } else if (!tracker->has_pose(pose_name)) { + return false; + } else { + return tracker->get_pose(pose_name)->get_has_tracking_data(); + } +} + +void XRNode3D::trigger_haptic_pulse(const String &p_action_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec) { + // TODO need to link trackers to the interface that registered them so we can call this on the correct interface. + // For now this works fine as in 99% of the cases we only have our primary interface active XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL_V(xr_server, 0.0); + if (xr_server != nullptr) { + Ref<XRInterface> xr_interface = xr_server->get_primary_interface(); + if (xr_interface.is_valid()) { + xr_interface->trigger_haptic_pulse(p_action_name, tracker_name, p_frequency, p_amplitude, p_duration_sec, p_delay_sec); + } + } +} - Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); - if (!tracker.is_valid()) { - return 0.0; - }; +Ref<XRPose> XRNode3D::get_pose() { + if (tracker.is_valid()) { + return tracker->get_pose(pose_name); + } else { + return Ref<XRPose>(); + } +} - return tracker->get_rumble(); -}; +void XRNode3D::_bind_tracker() { + ERR_FAIL_COND_MSG(tracker.is_valid(), "Unbind the current tracker first"); -void XRController3D::set_rumble(real_t p_rumble) { - // get our XRServer XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL(xr_server); + if (xr_server != nullptr) { + tracker = xr_server->get_tracker(tracker_name); + if (tracker.is_null()) { + // It is possible and valid if the tracker isn't available (yet), in this case we just exit + return; + } + + tracker->connect("pose_changed", callable_mp(this, &XRNode3D::_pose_changed)); + + Ref<XRPose> pose = get_pose(); + if (pose.is_valid()) { + set_transform(pose->get_adjusted_transform()); + } + } +} - Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); +void XRNode3D::_unbind_tracker() { if (tracker.is_valid()) { - tracker->set_rumble(p_rumble); - }; -}; + tracker->disconnect("pose_changed", callable_mp(this, &XRNode3D::_pose_changed)); -Ref<Mesh> XRController3D::get_mesh() const { - return mesh; + tracker.unref(); + } } -bool XRController3D::get_is_active() const { - return is_active; -}; +void XRNode3D::_changed_tracker(const StringName p_tracker_name, int p_tracker_type) { + if (p_tracker_name == p_tracker_name) { + // just in case unref our current tracker + _unbind_tracker(); -XRPositionalTracker::TrackerHand XRController3D::get_tracker_hand() const { - // get our XRServer + // get our new tracker + _bind_tracker(); + } +} + +void XRNode3D::_removed_tracker(const StringName p_tracker_name, int p_tracker_type) { + if (p_tracker_name == p_tracker_name) { + // unref our tracker, it's no longer available + _unbind_tracker(); + } +} + +void XRNode3D::_pose_changed(const Ref<XRPose> &p_pose) { + if (p_pose.is_valid() && p_pose->get_name() == pose_name) { + set_transform(p_pose->get_adjusted_transform()); + } +} + +XRNode3D::XRNode3D() { XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL_V(xr_server, XRPositionalTracker::TRACKER_HAND_UNKNOWN); + ERR_FAIL_NULL(xr_server); - Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); - if (!tracker.is_valid()) { - return XRPositionalTracker::TRACKER_HAND_UNKNOWN; - }; + xr_server->connect("tracker_added", callable_mp(this, &XRNode3D::_changed_tracker)); + xr_server->connect("tracker_updated", callable_mp(this, &XRNode3D::_changed_tracker)); + xr_server->connect("tracker_removed", callable_mp(this, &XRNode3D::_removed_tracker)); +} - return tracker->get_tracker_hand(); -}; +XRNode3D::~XRNode3D() { + _unbind_tracker(); + + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); + + xr_server->disconnect("tracker_added", callable_mp(this, &XRNode3D::_changed_tracker)); + xr_server->disconnect("tracker_updated", callable_mp(this, &XRNode3D::_changed_tracker)); + xr_server->disconnect("tracker_removed", callable_mp(this, &XRNode3D::_removed_tracker)); +} -TypedArray<String> XRController3D::get_configuration_warnings() const { +TypedArray<String> XRNode3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (is_visible() && is_inside_tree()) { @@ -370,130 +422,171 @@ TypedArray<String> XRController3D::get_configuration_warnings() const { warnings.push_back(TTR("XRController3D must have an XROrigin3D node as its parent.")); } - if (controller_id == 0) { - warnings.push_back(TTR("The controller ID must not be 0 or this controller won't be bound to an actual controller.")); + if (tracker_name == "") { + warnings.push_back(TTR("No tracker name is set.")); + } + + if (pose_name == "") { + warnings.push_back(TTR("No pose is set.")); } } return warnings; -}; +} //////////////////////////////////////////////////////////////////////////////////////////////////// -void XRAnchor3D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - set_process_internal(true); - }; break; - case NOTIFICATION_EXIT_TREE: { - set_process_internal(false); - }; break; - case NOTIFICATION_INTERNAL_PROCESS: { - // get our XRServer - XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL(xr_server); - - // find the tracker for our anchor - Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id); - if (!tracker.is_valid()) { - // this anchor is currently not available - is_active = false; - } else { - is_active = true; - Transform3D transform; - - // we'll need our world_scale - real_t world_scale = xr_server->get_world_scale(); - - // get our info from our tracker - transform.basis = tracker->get_orientation(); - transform.origin = tracker->get_position(); // <-- already adjusted to world scale - - // our basis is scaled to the size of the plane the anchor is tracking - // extract the size from our basis and reset the scale - size = transform.basis.get_scale() * world_scale; - transform.basis.orthonormalize(); - - // apply our reference frame and set our transform - set_transform(xr_server->get_reference_frame() * transform); - - // check for an updated mesh - Ref<Mesh> trackerMesh = tracker->get_mesh(); - if (mesh != trackerMesh) { - mesh = trackerMesh; - emit_signal(SNAME("mesh_updated"), mesh); - } - }; - }; break; - default: - break; - }; -}; - -void XRAnchor3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_anchor_id", "anchor_id"), &XRAnchor3D::set_anchor_id); - ClassDB::bind_method(D_METHOD("get_anchor_id"), &XRAnchor3D::get_anchor_id); - ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_id", PROPERTY_HINT_RANGE, "0,32,1"), "set_anchor_id", "get_anchor_id"); - ClassDB::bind_method(D_METHOD("get_anchor_name"), &XRAnchor3D::get_anchor_name); +void XRController3D::_bind_methods() { + // passthroughs to information about our related joystick + ClassDB::bind_method(D_METHOD("is_button_pressed", "name"), &XRController3D::is_button_pressed); + ClassDB::bind_method(D_METHOD("get_value", "name"), &XRController3D::get_value); + ClassDB::bind_method(D_METHOD("get_axis", "name"), &XRController3D::get_axis); - ClassDB::bind_method(D_METHOD("get_is_active"), &XRAnchor3D::get_is_active); - ClassDB::bind_method(D_METHOD("get_size"), &XRAnchor3D::get_size); + ClassDB::bind_method(D_METHOD("get_tracker_hand"), &XRController3D::get_tracker_hand); - ClassDB::bind_method(D_METHOD("get_plane"), &XRAnchor3D::get_plane); + ClassDB::bind_method(D_METHOD("get_rumble"), &XRController3D::get_rumble); + ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRController3D::set_rumble); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_rumble", "get_rumble"); + ADD_PROPERTY_DEFAULT("rumble", 0.0); - ClassDB::bind_method(D_METHOD("get_mesh"), &XRAnchor3D::get_mesh); - ADD_SIGNAL(MethodInfo("mesh_updated", PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"))); + ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::STRING, "name"))); + ADD_SIGNAL(MethodInfo("button_released", PropertyInfo(Variant::STRING, "name"))); + ADD_SIGNAL(MethodInfo("input_value_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::FLOAT, "value"))); + ADD_SIGNAL(MethodInfo("input_axis_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::VECTOR2, "value"))); }; -void XRAnchor3D::set_anchor_id(int p_anchor_id) { - // We don't check any bounds here, this anchor may not yet be active and just be a place holder until it is. - // Note that setting this to 0 means this node is not bound to an anchor yet. - anchor_id = p_anchor_id; - update_configuration_warnings(); -}; +void XRController3D::_bind_tracker() { + XRNode3D::_bind_tracker(); + if (tracker.is_valid()) { + // bind to input signals + tracker->connect("button_pressed", callable_mp(this, &XRController3D::_button_pressed)); + tracker->connect("button_released", callable_mp(this, &XRController3D::_button_released)); + tracker->connect("input_value_changed", callable_mp(this, &XRController3D::_input_value_changed)); + tracker->connect("input_axis_changed", callable_mp(this, &XRController3D::_input_axis_changed)); + } +} -int XRAnchor3D::get_anchor_id() const { - return anchor_id; -}; +void XRController3D::_unbind_tracker() { + if (tracker.is_valid()) { + // unbind input signals + tracker->disconnect("button_pressed", callable_mp(this, &XRController3D::_button_pressed)); + tracker->disconnect("button_released", callable_mp(this, &XRController3D::_button_released)); + tracker->disconnect("input_value_changed", callable_mp(this, &XRController3D::_input_value_changed)); + tracker->disconnect("input_axis_changed", callable_mp(this, &XRController3D::_input_axis_changed)); + } -Vector3 XRAnchor3D::get_size() const { - return size; -}; + XRNode3D::_unbind_tracker(); +} -String XRAnchor3D::get_anchor_name() const { - // get our XRServer - XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL_V(xr_server, String()); +void XRController3D::_button_pressed(const String &p_name) { + // just pass it on... + emit_signal("button_pressed", p_name); +} - Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id); - if (!tracker.is_valid()) { - return String("Not connected"); - }; +void XRController3D::_button_released(const String &p_name) { + // just pass it on... + emit_signal("button_released", p_name); +} - return tracker->get_tracker_name(); -}; +void XRController3D::_input_value_changed(const String &p_name, float p_value) { + // just pass it on... + emit_signal("input_value_changed", p_name, p_value); +} -bool XRAnchor3D::get_is_active() const { - return is_active; -}; +void XRController3D::_input_axis_changed(const String &p_name, Vector2 p_value) { + // just pass it on... + emit_signal("input_axis_changed", p_name, p_value); +} -TypedArray<String> XRAnchor3D::get_configuration_warnings() const { - TypedArray<String> warnings = Node::get_configuration_warnings(); +bool XRController3D::is_button_pressed(const StringName &p_name) const { + if (tracker.is_valid()) { + // Inputs should already be of the correct type, our XR runtime handles conversions between raw input and the desired type + bool pressed = tracker->get_input(p_name); + return pressed; + } else { + return false; + } +} - if (is_visible() && is_inside_tree()) { - // must be child node of XROrigin3D! - XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); - if (origin == nullptr) { - warnings.push_back(TTR("XRAnchor3D must have an XROrigin3D node as its parent.")); - } +float XRController3D::get_value(const StringName &p_name) const { + if (tracker.is_valid()) { + // Inputs should already be of the correct type, our XR runtime handles conversions between raw input and the desired type, but just in case we convert + Variant input = tracker->get_input(p_name); + switch (input.get_type()) { + case Variant::BOOL: { + bool value = input; + return value ? 1.0 : 0.0; + } break; + case Variant::FLOAT: { + float value = input; + return value; + } break; + default: + return 0.0; + }; + } else { + return 0.0; + } +} - if (anchor_id == 0) { - warnings.push_back(TTR("The anchor ID must not be 0 or this anchor won't be bound to an actual anchor.")); +Vector2 XRController3D::get_axis(const StringName &p_name) const { + if (tracker.is_valid()) { + // Inputs should already be of the correct type, our XR runtime handles conversions between raw input and the desired type, but just in case we convert + Variant input = tracker->get_input(p_name); + switch (input.get_type()) { + case Variant::BOOL: { + bool value = input; + return Vector2(value ? 1.0 : 0.0, 0.0); + } break; + case Variant::FLOAT: { + float value = input; + return Vector2(value, 0.0); + } break; + case Variant::VECTOR2: { + Vector2 axis = input; + return axis; + } + default: + return Vector2(); } + } else { + return Vector2(); } +} - return warnings; -}; +real_t XRController3D::get_rumble() const { + if (!tracker.is_valid()) { + return 0.0; + } + + return tracker->get_rumble(); +} + +void XRController3D::set_rumble(real_t p_rumble) { + if (tracker.is_valid()) { + tracker->set_rumble(p_rumble); + } +} + +XRPositionalTracker::TrackerHand XRController3D::get_tracker_hand() const { + // get our XRServer + if (!tracker.is_valid()) { + return XRPositionalTracker::TRACKER_HAND_UNKNOWN; + } + + return tracker->get_tracker_hand(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void XRAnchor3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_size"), &XRAnchor3D::get_size); + ClassDB::bind_method(D_METHOD("get_plane"), &XRAnchor3D::get_plane); +} + +Vector3 XRAnchor3D::get_size() const { + return size; +} Plane XRAnchor3D::get_plane() const { Vector3 location = get_position(); @@ -502,10 +595,6 @@ Plane XRAnchor3D::get_plane() const { Plane plane(orientation.get_axis(1).normalized(), location); return plane; -}; - -Ref<Mesh> XRAnchor3D::get_mesh() const { - return mesh; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -525,23 +614,21 @@ TypedArray<String> XROrigin3D::get_configuration_warnings() const { } return warnings; -}; +} void XROrigin3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_world_scale", "world_scale"), &XROrigin3D::set_world_scale); ClassDB::bind_method(D_METHOD("get_world_scale"), &XROrigin3D::get_world_scale); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "world_scale"), "set_world_scale", "get_world_scale"); -}; +} void XROrigin3D::set_tracked_camera(XRCamera3D *p_tracked_camera) { tracked_camera = p_tracked_camera; -}; +} -void XROrigin3D::clear_tracked_camera_if(XRCamera3D *p_tracked_camera) { - if (tracked_camera == p_tracked_camera) { - tracked_camera = nullptr; - }; -}; +XRCamera3D *XROrigin3D::get_tracked_camera() const { + return tracked_camera; +} real_t XROrigin3D::get_world_scale() const { // get our XRServer @@ -549,7 +636,7 @@ real_t XROrigin3D::get_world_scale() const { ERR_FAIL_NULL_V(xr_server, 1.0); return xr_server->get_world_scale(); -}; +} void XROrigin3D::set_world_scale(real_t p_world_scale) { // get our XRServer @@ -557,7 +644,7 @@ void XROrigin3D::set_world_scale(real_t p_world_scale) { ERR_FAIL_NULL(xr_server); xr_server->set_world_scale(p_world_scale); -}; +} void XROrigin3D::_notification(int p_what) { // get our XRServer @@ -596,4 +683,4 @@ void XROrigin3D::_notification(int p_what) { interface->notification(p_what); } } -}; +} diff --git a/scene/3d/xr_nodes.h b/scene/3d/xr_nodes.h index 6e54ff83d7..5e7d06093d 100644 --- a/scene/3d/xr_nodes.h +++ b/scene/3d/xr_nodes.h @@ -45,8 +45,18 @@ class XRCamera3D : public Camera3D { GDCLASS(XRCamera3D, Camera3D); protected: + // The name and pose for our HMD tracker is currently the only hardcoded bit. + // If we ever are able to support multiple HMDs we may need to make this settable. + StringName tracker_name = "head"; + StringName pose_name = "default"; + Ref<XRPositionalTracker> tracker; + void _notification(int p_what); + void _changed_tracker(const StringName p_tracker_name, int p_tracker_type); + void _removed_tracker(const StringName p_tracker_name, int p_tracker_type); + void _pose_changed(const Ref<XRPose> &p_pose); + public: TypedArray<String> get_configuration_warnings() const override; @@ -55,48 +65,88 @@ public: virtual Vector3 project_position(const Point2 &p_point, real_t p_z_depth) const override; virtual Vector<Plane> get_frustum() const override; - XRCamera3D() {} - ~XRCamera3D() {} + XRCamera3D(); + ~XRCamera3D(); }; /* - XRController3D is a helper node that automatically updates its position based on tracker data. + XRNode3D is a helper node that implements binding to a tracker. It must be a child node of our XROrigin node */ -class XRController3D : public Node3D { - GDCLASS(XRController3D, Node3D); +class XRNode3D : public Node3D { + GDCLASS(XRNode3D, Node3D); private: - int controller_id = 1; + StringName tracker_name; + StringName pose_name = "default"; bool is_active = true; - int button_states = 0; - Ref<Mesh> mesh; protected: - void _notification(int p_what); + Ref<XRPositionalTracker> tracker; + static void _bind_methods(); -public: - void set_controller_id(int p_controller_id); - int get_controller_id() const; - String get_controller_name() const; + virtual void _bind_tracker(); + virtual void _unbind_tracker(); + void _changed_tracker(const StringName p_tracker_name, int p_tracker_type); + void _removed_tracker(const StringName p_tracker_name, int p_tracker_type); - int get_joystick_id() const; - bool is_button_pressed(int p_button) const; - float get_joystick_axis(int p_axis) const; + void _pose_changed(const Ref<XRPose> &p_pose); - real_t get_rumble() const; - void set_rumble(real_t p_rumble); +public: + virtual void _validate_property(PropertyInfo &property) const override; + void set_tracker(const StringName p_tracker_name); + StringName get_tracker() const; + + void set_pose_name(const StringName p_pose); + StringName get_pose_name() const; bool get_is_active() const; - XRPositionalTracker::TrackerHand get_tracker_hand() const; + bool get_has_tracking_data() const; - Ref<Mesh> get_mesh() const; + void trigger_haptic_pulse(const String &p_action_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec = 0); + + Ref<XRPose> get_pose(); TypedArray<String> get_configuration_warnings() const override; + XRNode3D(); + ~XRNode3D(); +}; + +/* + XRController3D is a helper node that automatically updates its position based on tracker data. + + It must be a child node of our XROrigin node +*/ + +class XRController3D : public XRNode3D { + GDCLASS(XRController3D, XRNode3D); + +private: +protected: + static void _bind_methods(); + + virtual void _bind_tracker() override; + virtual void _unbind_tracker() override; + + void _button_pressed(const String &p_name); + void _button_released(const String &p_name); + void _input_value_changed(const String &p_name, float p_value); + void _input_axis_changed(const String &p_name, Vector2 p_value); + +public: + bool is_button_pressed(const StringName &p_name) const; + float get_value(const StringName &p_name) const; + Vector2 get_axis(const StringName &p_name) const; + + real_t get_rumble() const; + void set_rumble(real_t p_rumble); + + XRPositionalTracker::TrackerHand get_tracker_hand() const; + XRController3D() {} ~XRController3D() {} }; @@ -106,33 +156,19 @@ public: It must be a child node of our XROrigin3D node */ -class XRAnchor3D : public Node3D { - GDCLASS(XRAnchor3D, Node3D); +class XRAnchor3D : public XRNode3D { + GDCLASS(XRAnchor3D, XRNode3D); private: - int anchor_id = 1; - bool is_active = true; Vector3 size; - Ref<Mesh> mesh; protected: - void _notification(int p_what); static void _bind_methods(); public: - void set_anchor_id(int p_anchor_id); - int get_anchor_id() const; - String get_anchor_name() const; - - bool get_is_active() const; Vector3 get_size() const; - Plane get_plane() const; - Ref<Mesh> get_mesh() const; - - TypedArray<String> get_configuration_warnings() const override; - XRAnchor3D() {} ~XRAnchor3D() {} }; @@ -159,7 +195,7 @@ public: TypedArray<String> get_configuration_warnings() const override; void set_tracked_camera(XRCamera3D *p_tracked_camera); - void clear_tracked_camera_if(XRCamera3D *p_tracked_camera); + XRCamera3D *get_tracked_camera() const; real_t get_world_scale() const; void set_world_scale(real_t p_world_scale); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index bf8f7291be..f293c8a8e6 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -450,6 +450,7 @@ void register_scene_types() { GDREGISTER_CLASS(Camera3D); GDREGISTER_CLASS(AudioListener3D); GDREGISTER_CLASS(XRCamera3D); + GDREGISTER_VIRTUAL_CLASS(XRNode3D); GDREGISTER_CLASS(XRController3D); GDREGISTER_CLASS(XRAnchor3D); GDREGISTER_CLASS(XROrigin3D); @@ -940,10 +941,8 @@ void register_scene_types() { ClassDB::add_compatibility_class("Path", "Path3D"); ClassDB::add_compatibility_class("PathFollow", "PathFollow3D"); ClassDB::add_compatibility_class("PhysicalBone", "PhysicalBone3D"); - ClassDB::add_compatibility_class("Physics2DDirectBodyStateSW", "PhysicsDirectBodyState2DSW"); ClassDB::add_compatibility_class("Physics2DDirectBodyState", "PhysicsDirectBodyState2D"); ClassDB::add_compatibility_class("Physics2DDirectSpaceState", "PhysicsDirectSpaceState2D"); - ClassDB::add_compatibility_class("Physics2DServerSW", "PhysicsServer2DSW"); ClassDB::add_compatibility_class("Physics2DServer", "PhysicsServer2D"); ClassDB::add_compatibility_class("Physics2DShapeQueryParameters", "PhysicsShapeQueryParameters2D"); ClassDB::add_compatibility_class("Physics2DTestMotionResult", "PhysicsTestMotionResult2D"); diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index a420134626..ab704c6f78 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -1131,8 +1131,10 @@ void AudioServer::start_playback_stream(Ref<AudioStreamPlayback> p_playback, Map AudioStreamPlaybackBusDetails *new_bus_details = new AudioStreamPlaybackBusDetails(); int idx = 0; for (KeyValue<StringName, Vector<AudioFrame>> pair : p_bus_volumes) { - ERR_FAIL_COND(pair.value.size() < channel_count); - ERR_FAIL_COND(pair.value.size() != MAX_CHANNELS_PER_BUS); + if (pair.value.size() < channel_count || pair.value.size() != MAX_CHANNELS_PER_BUS) { + delete new_bus_details; + ERR_FAIL(); + } new_bus_details->bus_active[idx] = true; new_bus_details->bus[idx] = pair.key; diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/godot_area_2d.cpp index c85b1575e3..7cb202dd1f 100644 --- a/servers/physics_2d/area_2d_sw.cpp +++ b/servers/physics_2d/godot_area_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* area_2d_sw.cpp */ +/* godot_area_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,31 +28,31 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "area_2d_sw.h" -#include "body_2d_sw.h" -#include "space_2d_sw.h" +#include "godot_area_2d.h" +#include "godot_body_2d.h" +#include "godot_space_2d.h" -Area2DSW::BodyKey::BodyKey(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { +GodotArea2D::BodyKey::BodyKey(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { rid = p_body->get_self(); instance_id = p_body->get_instance_id(); body_shape = p_body_shape; area_shape = p_area_shape; } -Area2DSW::BodyKey::BodyKey(Area2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { +GodotArea2D::BodyKey::BodyKey(GodotArea2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { rid = p_body->get_self(); instance_id = p_body->get_instance_id(); body_shape = p_body_shape; area_shape = p_area_shape; } -void Area2DSW::_shapes_changed() { +void GodotArea2D::_shapes_changed() { if (!moved_list.in_list() && get_space()) { get_space()->area_add_to_moved_list(&moved_list); } } -void Area2DSW::set_transform(const Transform2D &p_transform) { +void GodotArea2D::set_transform(const Transform2D &p_transform) { if (!moved_list.in_list() && get_space()) { get_space()->area_add_to_moved_list(&moved_list); } @@ -61,7 +61,7 @@ void Area2DSW::set_transform(const Transform2D &p_transform) { _set_inv_transform(p_transform.affine_inverse()); } -void Area2DSW::set_space(Space2DSW *p_space) { +void GodotArea2D::set_space(GodotSpace2D *p_space) { if (get_space()) { if (monitor_query_list.in_list()) { get_space()->area_remove_from_monitor_query_list(&monitor_query_list); @@ -77,7 +77,7 @@ void Area2DSW::set_space(Space2DSW *p_space) { _set_space(p_space); } -void Area2DSW::set_monitor_callback(ObjectID p_id, const StringName &p_method) { +void GodotArea2D::set_monitor_callback(ObjectID p_id, const StringName &p_method) { if (p_id == monitor_callback_id) { monitor_callback_method = p_method; return; @@ -98,7 +98,7 @@ void Area2DSW::set_monitor_callback(ObjectID p_id, const StringName &p_method) { } } -void Area2DSW::set_area_monitor_callback(ObjectID p_id, const StringName &p_method) { +void GodotArea2D::set_area_monitor_callback(ObjectID p_id, const StringName &p_method) { if (p_id == area_monitor_callback_id) { area_monitor_callback_method = p_method; return; @@ -119,7 +119,7 @@ void Area2DSW::set_area_monitor_callback(ObjectID p_id, const StringName &p_meth } } -void Area2DSW::set_space_override_mode(PhysicsServer2D::AreaSpaceOverrideMode p_mode) { +void GodotArea2D::set_space_override_mode(PhysicsServer2D::AreaSpaceOverrideMode p_mode) { bool do_override = p_mode != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED; if (do_override == (space_override_mode != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED)) { return; @@ -129,7 +129,7 @@ void Area2DSW::set_space_override_mode(PhysicsServer2D::AreaSpaceOverrideMode p_ _shape_changed(); } -void Area2DSW::set_param(PhysicsServer2D::AreaParameter p_param, const Variant &p_value) { +void GodotArea2D::set_param(PhysicsServer2D::AreaParameter p_param, const Variant &p_value) { switch (p_param) { case PhysicsServer2D::AREA_PARAM_GRAVITY: gravity = p_value; @@ -158,7 +158,7 @@ void Area2DSW::set_param(PhysicsServer2D::AreaParameter p_param, const Variant & } } -Variant Area2DSW::get_param(PhysicsServer2D::AreaParameter p_param) const { +Variant GodotArea2D::get_param(PhysicsServer2D::AreaParameter p_param) const { switch (p_param) { case PhysicsServer2D::AREA_PARAM_GRAVITY: return gravity; @@ -181,7 +181,7 @@ Variant Area2DSW::get_param(PhysicsServer2D::AreaParameter p_param) const { return Variant(); } -void Area2DSW::_queue_monitor_update() { +void GodotArea2D::_queue_monitor_update() { ERR_FAIL_COND(!get_space()); if (!monitor_query_list.in_list()) { @@ -189,7 +189,7 @@ void Area2DSW::_queue_monitor_update() { } } -void Area2DSW::set_monitorable(bool p_monitorable) { +void GodotArea2D::set_monitorable(bool p_monitorable) { if (monitorable == p_monitorable) { return; } @@ -198,7 +198,7 @@ void Area2DSW::set_monitorable(bool p_monitorable) { _set_static(!monitorable); } -void Area2DSW::call_queries() { +void GodotArea2D::call_queries() { if (monitor_callback_id.is_valid() && !monitored_bodies.is_empty()) { Variant res[5]; Variant *resptr[5]; @@ -274,7 +274,7 @@ void Area2DSW::call_queries() { } } -void Area2DSW::compute_gravity(const Vector2 &p_position, Vector2 &r_gravity) const { +void GodotArea2D::compute_gravity(const Vector2 &p_position, Vector2 &r_gravity) const { if (is_gravity_point()) { const real_t gravity_distance_scale = get_gravity_distance_scale(); Vector2 v = get_transform().xform(get_gravity_vector()) - p_position; @@ -294,12 +294,12 @@ void Area2DSW::compute_gravity(const Vector2 &p_position, Vector2 &r_gravity) co } } -Area2DSW::Area2DSW() : - CollisionObject2DSW(TYPE_AREA), +GodotArea2D::GodotArea2D() : + GodotCollisionObject2D(TYPE_AREA), monitor_query_list(this), moved_list(this) { _set_static(true); //areas are not active by default } -Area2DSW::~Area2DSW() { +GodotArea2D::~GodotArea2D() { } diff --git a/servers/physics_2d/area_2d_sw.h b/servers/physics_2d/godot_area_2d.h index 0b7c791ed5..daa03d39e3 100644 --- a/servers/physics_2d/area_2d_sw.h +++ b/servers/physics_2d/godot_area_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* area_2d_sw.h */ +/* godot_area_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,18 +28,19 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AREA_2D_SW_H -#define AREA_2D_SW_H +#ifndef GODOT_AREA_2D_H +#define GODOT_AREA_2D_H + +#include "godot_collision_object_2d.h" -#include "collision_object_2d_sw.h" #include "core/templates/self_list.h" #include "servers/physics_server_2d.h" -class Space2DSW; -class Body2DSW; -class Constraint2DSW; +class GodotSpace2D; +class GodotBody2D; +class GodotConstraint2D; -class Area2DSW : public CollisionObject2DSW { +class GodotArea2D : public GodotCollisionObject2D { PhysicsServer2D::AreaSpaceOverrideMode space_override_mode = PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED; real_t gravity = 9.80665; Vector2 gravity_vector = Vector2(0, -1); @@ -57,8 +58,8 @@ class Area2DSW : public CollisionObject2DSW { ObjectID area_monitor_callback_id; StringName area_monitor_callback_method; - SelfList<Area2DSW> monitor_query_list; - SelfList<Area2DSW> moved_list; + SelfList<GodotArea2D> monitor_query_list; + SelfList<GodotArea2D> moved_list; struct BodyKey { RID rid; @@ -79,8 +80,8 @@ class Area2DSW : public CollisionObject2DSW { } _FORCE_INLINE_ BodyKey() {} - BodyKey(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape); - BodyKey(Area2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape); + BodyKey(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape); + BodyKey(GodotArea2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape); }; struct BodyState { @@ -92,7 +93,7 @@ class Area2DSW : public CollisionObject2DSW { Map<BodyKey, BodyState> monitored_bodies; Map<BodyKey, BodyState> monitored_areas; - Set<Constraint2DSW *> constraints; + Set<GodotConstraint2D *> constraints; virtual void _shapes_changed(); void _queue_monitor_update(); @@ -104,11 +105,11 @@ public: void set_area_monitor_callback(ObjectID p_id, const StringName &p_method); _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id.is_valid(); } - _FORCE_INLINE_ void add_body_to_query(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape); - _FORCE_INLINE_ void remove_body_from_query(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape); + _FORCE_INLINE_ void add_body_to_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape); + _FORCE_INLINE_ void remove_body_from_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape); - _FORCE_INLINE_ void add_area_to_query(Area2DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape); - _FORCE_INLINE_ void remove_area_from_query(Area2DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape); + _FORCE_INLINE_ void add_area_to_query(GodotArea2D *p_area, uint32_t p_area_shape, uint32_t p_self_shape); + _FORCE_INLINE_ void remove_area_from_query(GodotArea2D *p_area, uint32_t p_area_shape, uint32_t p_self_shape); void set_param(PhysicsServer2D::AreaParameter p_param, const Variant &p_value); Variant get_param(PhysicsServer2D::AreaParameter p_param) const; @@ -140,9 +141,9 @@ public: _FORCE_INLINE_ void set_priority(int p_priority) { priority = p_priority; } _FORCE_INLINE_ int get_priority() const { return priority; } - _FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint) { constraints.insert(p_constraint); } - _FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint) { constraints.erase(p_constraint); } - _FORCE_INLINE_ const Set<Constraint2DSW *> &get_constraints() const { return constraints; } + _FORCE_INLINE_ void add_constraint(GodotConstraint2D *p_constraint) { constraints.insert(p_constraint); } + _FORCE_INLINE_ void remove_constraint(GodotConstraint2D *p_constraint) { constraints.erase(p_constraint); } + _FORCE_INLINE_ const Set<GodotConstraint2D *> &get_constraints() const { return constraints; } _FORCE_INLINE_ void clear_constraints() { constraints.clear(); } void set_monitorable(bool p_monitorable); @@ -150,17 +151,17 @@ public: void set_transform(const Transform2D &p_transform); - void set_space(Space2DSW *p_space); + void set_space(GodotSpace2D *p_space); void call_queries(); void compute_gravity(const Vector2 &p_position, Vector2 &r_gravity) const; - Area2DSW(); - ~Area2DSW(); + GodotArea2D(); + ~GodotArea2D(); }; -void Area2DSW::add_body_to_query(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { +void GodotArea2D::add_body_to_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { BodyKey bk(p_body, p_body_shape, p_area_shape); monitored_bodies[bk].inc(); if (!monitor_query_list.in_list()) { @@ -168,7 +169,7 @@ void Area2DSW::add_body_to_query(Body2DSW *p_body, uint32_t p_body_shape, uint32 } } -void Area2DSW::remove_body_from_query(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { +void GodotArea2D::remove_body_from_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { BodyKey bk(p_body, p_body_shape, p_area_shape); monitored_bodies[bk].dec(); if (!monitor_query_list.in_list()) { @@ -176,7 +177,7 @@ void Area2DSW::remove_body_from_query(Body2DSW *p_body, uint32_t p_body_shape, u } } -void Area2DSW::add_area_to_query(Area2DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { +void GodotArea2D::add_area_to_query(GodotArea2D *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { BodyKey bk(p_area, p_area_shape, p_self_shape); monitored_areas[bk].inc(); if (!monitor_query_list.in_list()) { @@ -184,7 +185,7 @@ void Area2DSW::add_area_to_query(Area2DSW *p_area, uint32_t p_area_shape, uint32 } } -void Area2DSW::remove_area_from_query(Area2DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { +void GodotArea2D::remove_area_from_query(GodotArea2D *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { BodyKey bk(p_area, p_area_shape, p_self_shape); monitored_areas[bk].dec(); if (!monitor_query_list.in_list()) { @@ -192,4 +193,4 @@ void Area2DSW::remove_area_from_query(Area2DSW *p_area, uint32_t p_area_shape, u } } -#endif // AREA_2D_SW_H +#endif // GODOT_AREA_2D_H diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/godot_area_pair_2d.cpp index 4f1148c26f..fdb95aa262 100644 --- a/servers/physics_2d/area_pair_2d_sw.cpp +++ b/servers/physics_2d/godot_area_pair_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* area_pair_2d_sw.cpp */ +/* godot_area_pair_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,12 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "area_pair_2d_sw.h" -#include "collision_solver_2d_sw.h" +#include "godot_area_pair_2d.h" +#include "godot_collision_solver_2d.h" -bool AreaPair2DSW::setup(real_t p_step) { +bool GodotAreaPair2D::setup(real_t p_step) { bool result = false; - if (area->collides_with(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), Vector2(), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), Vector2(), nullptr, this)) { + if (area->collides_with(body) && GodotCollisionSolver2D::solve(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), Vector2(), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), Vector2(), nullptr, this)) { result = true; } @@ -51,7 +51,7 @@ bool AreaPair2DSW::setup(real_t p_step) { return process_collision; } -bool AreaPair2DSW::pre_solve(real_t p_step) { +bool GodotAreaPair2D::pre_solve(real_t p_step) { if (!process_collision) { return false; } @@ -77,11 +77,11 @@ bool AreaPair2DSW::pre_solve(real_t p_step) { return false; // Never do any post solving. } -void AreaPair2DSW::solve(real_t p_step) { +void GodotAreaPair2D::solve(real_t p_step) { // Nothing to do. } -AreaPair2DSW::AreaPair2DSW(Body2DSW *p_body, int p_body_shape, Area2DSW *p_area, int p_area_shape) { +GodotAreaPair2D::GodotAreaPair2D(GodotBody2D *p_body, int p_body_shape, GodotArea2D *p_area, int p_area_shape) { body = p_body; area = p_area; body_shape = p_body_shape; @@ -93,7 +93,7 @@ AreaPair2DSW::AreaPair2DSW(Body2DSW *p_body, int p_body_shape, Area2DSW *p_area, } } -AreaPair2DSW::~AreaPair2DSW() { +GodotAreaPair2D::~GodotAreaPair2D() { if (colliding) { if (area->get_space_override_mode() != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED) { body->remove_area(area); @@ -108,10 +108,10 @@ AreaPair2DSW::~AreaPair2DSW() { ////////////////////////////////// -bool Area2Pair2DSW::setup(real_t p_step) { +bool GodotArea2Pair2D::setup(real_t p_step) { bool result_a = area_a->collides_with(area_b); bool result_b = area_b->collides_with(area_a); - if ((result_a || result_b) && !CollisionSolver2DSW::solve(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), Vector2(), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), Vector2(), nullptr, this)) { + if ((result_a || result_b) && !GodotCollisionSolver2D::solve(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), Vector2(), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), Vector2(), nullptr, this)) { result_a = false; result_b = false; } @@ -139,7 +139,7 @@ bool Area2Pair2DSW::setup(real_t p_step) { return process_collision; } -bool Area2Pair2DSW::pre_solve(real_t p_step) { +bool GodotArea2Pair2D::pre_solve(real_t p_step) { if (process_collision_a) { if (colliding_a) { area_a->add_area_to_query(area_b, shape_b, shape_a); @@ -159,11 +159,11 @@ bool Area2Pair2DSW::pre_solve(real_t p_step) { return false; // Never do any post solving. } -void Area2Pair2DSW::solve(real_t p_step) { +void GodotArea2Pair2D::solve(real_t p_step) { // Nothing to do. } -Area2Pair2DSW::Area2Pair2DSW(Area2DSW *p_area_a, int p_shape_a, Area2DSW *p_area_b, int p_shape_b) { +GodotArea2Pair2D::GodotArea2Pair2D(GodotArea2D *p_area_a, int p_shape_a, GodotArea2D *p_area_b, int p_shape_b) { area_a = p_area_a; area_b = p_area_b; shape_a = p_shape_a; @@ -172,7 +172,7 @@ Area2Pair2DSW::Area2Pair2DSW(Area2DSW *p_area_a, int p_shape_a, Area2DSW *p_area area_b->add_constraint(this); } -Area2Pair2DSW::~Area2Pair2DSW() { +GodotArea2Pair2D::~GodotArea2Pair2D() { if (colliding_a) { if (area_a->has_area_monitor_callback()) { area_a->remove_area_from_query(area_b, shape_b, shape_a); diff --git a/servers/physics_2d/area_pair_2d_sw.h b/servers/physics_2d/godot_area_pair_2d.h index 66e9f1afee..7a9677f714 100644 --- a/servers/physics_2d/area_pair_2d_sw.h +++ b/servers/physics_2d/godot_area_pair_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* area_pair_2d_sw.h */ +/* godot_area_pair_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,16 +28,16 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AREA_PAIR_2D_SW_H -#define AREA_PAIR_2D_SW_H +#ifndef GODOT_AREA_PAIR_2D_H +#define GODOT_AREA_PAIR_2D_H -#include "area_2d_sw.h" -#include "body_2d_sw.h" -#include "constraint_2d_sw.h" +#include "godot_area_2d.h" +#include "godot_body_2d.h" +#include "godot_constraint_2d.h" -class AreaPair2DSW : public Constraint2DSW { - Body2DSW *body = nullptr; - Area2DSW *area = nullptr; +class GodotAreaPair2D : public GodotConstraint2D { + GodotBody2D *body = nullptr; + GodotArea2D *area = nullptr; int body_shape = 0; int area_shape = 0; bool colliding = false; @@ -48,13 +48,13 @@ public: virtual bool pre_solve(real_t p_step) override; virtual void solve(real_t p_step) override; - AreaPair2DSW(Body2DSW *p_body, int p_body_shape, Area2DSW *p_area, int p_area_shape); - ~AreaPair2DSW(); + GodotAreaPair2D(GodotBody2D *p_body, int p_body_shape, GodotArea2D *p_area, int p_area_shape); + ~GodotAreaPair2D(); }; -class Area2Pair2DSW : public Constraint2DSW { - Area2DSW *area_a = nullptr; - Area2DSW *area_b = nullptr; +class GodotArea2Pair2D : public GodotConstraint2D { + GodotArea2D *area_a = nullptr; + GodotArea2D *area_b = nullptr; int shape_a = 0; int shape_b = 0; bool colliding_a = false; @@ -67,8 +67,8 @@ public: virtual bool pre_solve(real_t p_step) override; virtual void solve(real_t p_step) override; - Area2Pair2DSW(Area2DSW *p_area_a, int p_shape_a, Area2DSW *p_area_b, int p_shape_b); - ~Area2Pair2DSW(); + GodotArea2Pair2D(GodotArea2D *p_area_a, int p_shape_a, GodotArea2D *p_area_b, int p_shape_b); + ~GodotArea2Pair2D(); }; -#endif // AREA_PAIR_2D_SW_H +#endif // GODOT_AREA_PAIR_2D_H diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/godot_body_2d.cpp index 38b98b7bca..b0885a1f7b 100644 --- a/servers/physics_2d/body_2d_sw.cpp +++ b/servers/physics_2d/godot_body_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_2d_sw.cpp */ +/* godot_body_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,19 +28,19 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "body_2d_sw.h" +#include "godot_body_2d.h" -#include "area_2d_sw.h" -#include "body_direct_state_2d_sw.h" -#include "space_2d_sw.h" +#include "godot_area_2d.h" +#include "godot_body_direct_state_2d.h" +#include "godot_space_2d.h" -void Body2DSW::_mass_properties_changed() { +void GodotBody2D::_mass_properties_changed() { if (get_space() && !mass_properties_update_list.in_list() && (calculate_inertia || calculate_center_of_mass)) { get_space()->body_add_to_mass_properties_update_list(&mass_properties_update_list); } } -void Body2DSW::update_mass_properties() { +void GodotBody2D::update_mass_properties() { //update shapes and motions switch (mode) { @@ -83,7 +83,7 @@ void Body2DSW::update_mass_properties() { continue; } - const Shape2DSW *shape = get_shape(i); + const GodotShape2D *shape = get_shape(i); real_t area = get_shape_aabb(i).get_area(); if (area == 0.0) { @@ -121,13 +121,13 @@ void Body2DSW::update_mass_properties() { } } -void Body2DSW::reset_mass_properties() { +void GodotBody2D::reset_mass_properties() { calculate_inertia = true; calculate_center_of_mass = true; _mass_properties_changed(); } -void Body2DSW::set_active(bool p_active) { +void GodotBody2D::set_active(bool p_active) { if (active == p_active) { return; } @@ -146,7 +146,7 @@ void Body2DSW::set_active(bool p_active) { } } -void Body2DSW::set_param(PhysicsServer2D::BodyParameter p_param, const Variant &p_value) { +void GodotBody2D::set_param(PhysicsServer2D::BodyParameter p_param, const Variant &p_value) { switch (p_param) { case PhysicsServer2D::BODY_PARAM_BOUNCE: { bounce = p_value; @@ -195,7 +195,7 @@ void Body2DSW::set_param(PhysicsServer2D::BodyParameter p_param, const Variant & } } -Variant Body2DSW::get_param(PhysicsServer2D::BodyParameter p_param) const { +Variant GodotBody2D::get_param(PhysicsServer2D::BodyParameter p_param) const { switch (p_param) { case PhysicsServer2D::BODY_PARAM_BOUNCE: { return bounce; @@ -228,7 +228,7 @@ Variant Body2DSW::get_param(PhysicsServer2D::BodyParameter p_param) const { return 0; } -void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) { +void GodotBody2D::set_mode(PhysicsServer2D::BodyMode p_mode) { PhysicsServer2D::BodyMode prev = mode; mode = p_mode; @@ -267,16 +267,16 @@ void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) { } } -PhysicsServer2D::BodyMode Body2DSW::get_mode() const { +PhysicsServer2D::BodyMode GodotBody2D::get_mode() const { return mode; } -void Body2DSW::_shapes_changed() { +void GodotBody2D::_shapes_changed() { _mass_properties_changed(); wakeup_neighbours(); } -void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_variant) { +void GodotBody2D::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_variant) { switch (p_state) { case PhysicsServer2D::BODY_STATE_TRANSFORM: { if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC) { @@ -344,7 +344,7 @@ void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_va } } -Variant Body2DSW::get_state(PhysicsServer2D::BodyState p_state) const { +Variant GodotBody2D::get_state(PhysicsServer2D::BodyState p_state) const { switch (p_state) { case PhysicsServer2D::BODY_STATE_TRANSFORM: { return get_transform(); @@ -366,7 +366,7 @@ Variant Body2DSW::get_state(PhysicsServer2D::BodyState p_state) const { return Variant(); } -void Body2DSW::set_space(Space2DSW *p_space) { +void GodotBody2D::set_space(GodotSpace2D *p_space) { if (get_space()) { wakeup_neighbours(); @@ -391,7 +391,7 @@ void Body2DSW::set_space(Space2DSW *p_space) { } } -void Body2DSW::_compute_area_gravity_and_damping(const Area2DSW *p_area) { +void GodotBody2D::_compute_area_gravity_and_damping(const GodotArea2D *p_area) { Vector2 area_gravity; p_area->compute_gravity(get_transform().get_origin(), area_gravity); gravity += area_gravity; @@ -400,13 +400,13 @@ void Body2DSW::_compute_area_gravity_and_damping(const Area2DSW *p_area) { area_angular_damp += p_area->get_angular_damp(); } -void Body2DSW::integrate_forces(real_t p_step) { +void GodotBody2D::integrate_forces(real_t p_step) { if (mode == PhysicsServer2D::BODY_MODE_STATIC) { return; } - Area2DSW *def_area = get_space()->get_default_area(); - // Area2DSW *damp_area = def_area; + GodotArea2D *def_area = get_space()->get_default_area(); + // GodotArea2D *damp_area = def_area; ERR_FAIL_COND(!def_area); int ac = areas.size(); @@ -528,7 +528,7 @@ void Body2DSW::integrate_forces(real_t p_step) { contact_count = 0; } -void Body2DSW::integrate_velocities(real_t p_step) { +void GodotBody2D::integrate_velocities(real_t p_step) { if (mode == PhysicsServer2D::BODY_MODE_STATIC) { return; } @@ -570,17 +570,17 @@ void Body2DSW::integrate_velocities(real_t p_step) { } } -void Body2DSW::wakeup_neighbours() { - for (const Pair<Constraint2DSW *, int> &E : constraint_list) { - const Constraint2DSW *c = E.first; - Body2DSW **n = c->get_body_ptr(); +void GodotBody2D::wakeup_neighbours() { + for (const Pair<GodotConstraint2D *, int> &E : constraint_list) { + const GodotConstraint2D *c = E.first; + GodotBody2D **n = c->get_body_ptr(); int bc = c->get_body_count(); for (int i = 0; i < bc; i++) { if (i == E.second) { continue; } - Body2DSW *b = n[i]; + GodotBody2D *b = n[i]; if (b->mode < PhysicsServer2D::BODY_MODE_DYNAMIC) { continue; } @@ -592,7 +592,7 @@ void Body2DSW::wakeup_neighbours() { } } -void Body2DSW::call_queries() { +void GodotBody2D::call_queries() { if (fi_callback_data) { if (!fi_callback_data->callable.get_object()) { set_force_integration_callback(Callable()); @@ -616,7 +616,7 @@ void Body2DSW::call_queries() { } } -bool Body2DSW::sleep_test(real_t p_step) { +bool GodotBody2D::sleep_test(real_t p_step) { if (mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC) { return true; } else if (!can_sleep) { @@ -633,12 +633,12 @@ bool Body2DSW::sleep_test(real_t p_step) { } } -void Body2DSW::set_state_sync_callback(void *p_instance, PhysicsServer2D::BodyStateCallback p_callback) { +void GodotBody2D::set_state_sync_callback(void *p_instance, PhysicsServer2D::BodyStateCallback p_callback) { body_state_callback_instance = p_instance; body_state_callback = p_callback; } -void Body2DSW::set_force_integration_callback(const Callable &p_callable, const Variant &p_udata) { +void GodotBody2D::set_force_integration_callback(const Callable &p_callable, const Variant &p_udata) { if (p_callable.get_object()) { if (!fi_callback_data) { fi_callback_data = memnew(ForceIntegrationCallbackData); @@ -651,23 +651,23 @@ void Body2DSW::set_force_integration_callback(const Callable &p_callable, const } } -PhysicsDirectBodyState2DSW *Body2DSW::get_direct_state() { +GodotPhysicsDirectBodyState2D *GodotBody2D::get_direct_state() { if (!direct_state) { - direct_state = memnew(PhysicsDirectBodyState2DSW); + direct_state = memnew(GodotPhysicsDirectBodyState2D); direct_state->body = this; } return direct_state; } -Body2DSW::Body2DSW() : - CollisionObject2DSW(TYPE_BODY), +GodotBody2D::GodotBody2D() : + GodotCollisionObject2D(TYPE_BODY), active_list(this), mass_properties_update_list(this), direct_state_query_list(this) { _set_static(false); } -Body2DSW::~Body2DSW() { +GodotBody2D::~GodotBody2D() { if (fi_callback_data) { memdelete(fi_callback_data); } diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/godot_body_2d.h index 822ff76fae..c4f3578f1b 100644 --- a/servers/physics_2d/body_2d_sw.h +++ b/servers/physics_2d/godot_body_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_2d_sw.h */ +/* godot_body_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,19 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BODY_2D_SW_H -#define BODY_2D_SW_H +#ifndef GODOT_BODY_2D_H +#define GODOT_BODY_2D_H + +#include "godot_area_2d.h" +#include "godot_collision_object_2d.h" -#include "area_2d_sw.h" -#include "collision_object_2d_sw.h" #include "core/templates/list.h" #include "core/templates/pair.h" #include "core/templates/vset.h" -class Constraint2DSW; -class PhysicsDirectBodyState2DSW; +class GodotConstraint2D; +class GodotPhysicsDirectBodyState2D; -class Body2DSW : public CollisionObject2DSW { +class GodotBody2D : public GodotCollisionObject2D { PhysicsServer2D::BodyMode mode = PhysicsServer2D::BODY_MODE_DYNAMIC; Vector2 biased_linear_velocity; @@ -79,9 +80,9 @@ class Body2DSW : public CollisionObject2DSW { Vector2 applied_force; real_t applied_torque = 0.0; - SelfList<Body2DSW> active_list; - SelfList<Body2DSW> mass_properties_update_list; - SelfList<Body2DSW> direct_state_query_list; + SelfList<GodotBody2D> active_list; + SelfList<GodotBody2D> mass_properties_update_list; + SelfList<GodotBody2D> direct_state_query_list; VSet<RID> exceptions; PhysicsServer2D::CCDMode continuous_cd_mode = PhysicsServer2D::CCD_MODE_DISABLED; @@ -93,15 +94,15 @@ class Body2DSW : public CollisionObject2DSW { virtual void _shapes_changed(); Transform2D new_transform; - List<Pair<Constraint2DSW *, int>> constraint_list; + List<Pair<GodotConstraint2D *, int>> constraint_list; struct AreaCMP { - Area2DSW *area = nullptr; + GodotArea2D *area = nullptr; int refCount = 0; _FORCE_INLINE_ bool operator==(const AreaCMP &p_cmp) const { return area->get_self() == p_cmp.area->get_self(); } _FORCE_INLINE_ bool operator<(const AreaCMP &p_cmp) const { return area->get_priority() < p_cmp.area->get_priority(); } _FORCE_INLINE_ AreaCMP() {} - _FORCE_INLINE_ AreaCMP(Area2DSW *p_area) { + _FORCE_INLINE_ AreaCMP(GodotArea2D *p_area) { area = p_area; refCount = 1; } @@ -134,21 +135,21 @@ class Body2DSW : public CollisionObject2DSW { ForceIntegrationCallbackData *fi_callback_data = nullptr; - PhysicsDirectBodyState2DSW *direct_state = nullptr; + GodotPhysicsDirectBodyState2D *direct_state = nullptr; uint64_t island_step = 0; - _FORCE_INLINE_ void _compute_area_gravity_and_damping(const Area2DSW *p_area); + _FORCE_INLINE_ void _compute_area_gravity_and_damping(const GodotArea2D *p_area); - friend class PhysicsDirectBodyState2DSW; // i give up, too many functions to expose + friend class GodotPhysicsDirectBodyState2D; // i give up, too many functions to expose public: void set_state_sync_callback(void *p_instance, PhysicsServer2D::BodyStateCallback p_callback); void set_force_integration_callback(const Callable &p_callable, const Variant &p_udata = Variant()); - PhysicsDirectBodyState2DSW *get_direct_state(); + GodotPhysicsDirectBodyState2D *get_direct_state(); - _FORCE_INLINE_ void add_area(Area2DSW *p_area) { + _FORCE_INLINE_ void add_area(GodotArea2D *p_area) { int index = areas.find(AreaCMP(p_area)); if (index > -1) { areas.write[index].refCount += 1; @@ -157,7 +158,7 @@ public: } } - _FORCE_INLINE_ void remove_area(Area2DSW *p_area) { + _FORCE_INLINE_ void remove_area(GodotArea2D *p_area) { int index = areas.find(AreaCMP(p_area)); if (index > -1) { areas.write[index].refCount -= 1; @@ -188,9 +189,9 @@ public: _FORCE_INLINE_ uint64_t get_island_step() const { return island_step; } _FORCE_INLINE_ void set_island_step(uint64_t p_step) { island_step = p_step; } - _FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint, int p_pos) { constraint_list.push_back({ p_constraint, p_pos }); } - _FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint, int p_pos) { constraint_list.erase({ p_constraint, p_pos }); } - const List<Pair<Constraint2DSW *, int>> &get_constraint_list() const { return constraint_list; } + _FORCE_INLINE_ void add_constraint(GodotConstraint2D *p_constraint, int p_pos) { constraint_list.push_back({ p_constraint, p_pos }); } + _FORCE_INLINE_ void remove_constraint(GodotConstraint2D *p_constraint, int p_pos) { constraint_list.erase({ p_constraint, p_pos }); } + const List<Pair<GodotConstraint2D *, int>> &get_constraint_list() const { return constraint_list; } _FORCE_INLINE_ void clear_constraint_list() { constraint_list.clear(); } _FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; } @@ -267,7 +268,7 @@ public: _FORCE_INLINE_ void set_continuous_collision_detection_mode(PhysicsServer2D::CCDMode p_mode) { continuous_cd_mode = p_mode; } _FORCE_INLINE_ PhysicsServer2D::CCDMode get_continuous_collision_detection_mode() const { return continuous_cd_mode; } - void set_space(Space2DSW *p_space); + void set_space(GodotSpace2D *p_space); void update_mass_properties(); void reset_mass_properties(); @@ -302,13 +303,13 @@ public: bool sleep_test(real_t p_step); - Body2DSW(); - ~Body2DSW(); + GodotBody2D(); + ~GodotBody2D(); }; //add contact inline -void Body2DSW::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) { +void GodotBody2D::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) { int c_max = contacts.size(); if (c_max == 0) { @@ -350,4 +351,4 @@ void Body2DSW::add_contact(const Vector2 &p_local_pos, const Vector2 &p_local_no c[idx].collider_velocity_at_pos = p_collider_velocity_at_pos; } -#endif // BODY_2D_SW_H +#endif // GODOT_BODY_2D_H diff --git a/servers/physics_2d/body_direct_state_2d_sw.cpp b/servers/physics_2d/godot_body_direct_state_2d.cpp index b0673b9006..300c302c79 100644 --- a/servers/physics_2d/body_direct_state_2d_sw.cpp +++ b/servers/physics_2d/godot_body_direct_state_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_direct_state_2d_sw.cpp */ +/* godot_body_direct_state_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,151 +28,151 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "body_direct_state_2d_sw.h" +#include "godot_body_direct_state_2d.h" -#include "body_2d_sw.h" -#include "physics_server_2d_sw.h" -#include "space_2d_sw.h" +#include "godot_body_2d.h" +#include "godot_physics_server_2d.h" +#include "godot_space_2d.h" -Vector2 PhysicsDirectBodyState2DSW::get_total_gravity() const { +Vector2 GodotPhysicsDirectBodyState2D::get_total_gravity() const { return body->gravity; } -real_t PhysicsDirectBodyState2DSW::get_total_angular_damp() const { +real_t GodotPhysicsDirectBodyState2D::get_total_angular_damp() const { return body->area_angular_damp; } -real_t PhysicsDirectBodyState2DSW::get_total_linear_damp() const { +real_t GodotPhysicsDirectBodyState2D::get_total_linear_damp() const { return body->area_linear_damp; } -Vector2 PhysicsDirectBodyState2DSW::get_center_of_mass() const { +Vector2 GodotPhysicsDirectBodyState2D::get_center_of_mass() const { return body->get_center_of_mass(); } -real_t PhysicsDirectBodyState2DSW::get_inverse_mass() const { +real_t GodotPhysicsDirectBodyState2D::get_inverse_mass() const { return body->get_inv_mass(); } -real_t PhysicsDirectBodyState2DSW::get_inverse_inertia() const { +real_t GodotPhysicsDirectBodyState2D::get_inverse_inertia() const { return body->get_inv_inertia(); } -void PhysicsDirectBodyState2DSW::set_linear_velocity(const Vector2 &p_velocity) { +void GodotPhysicsDirectBodyState2D::set_linear_velocity(const Vector2 &p_velocity) { body->wakeup(); body->set_linear_velocity(p_velocity); } -Vector2 PhysicsDirectBodyState2DSW::get_linear_velocity() const { +Vector2 GodotPhysicsDirectBodyState2D::get_linear_velocity() const { return body->get_linear_velocity(); } -void PhysicsDirectBodyState2DSW::set_angular_velocity(real_t p_velocity) { +void GodotPhysicsDirectBodyState2D::set_angular_velocity(real_t p_velocity) { body->wakeup(); body->set_angular_velocity(p_velocity); } -real_t PhysicsDirectBodyState2DSW::get_angular_velocity() const { +real_t GodotPhysicsDirectBodyState2D::get_angular_velocity() const { return body->get_angular_velocity(); } -void PhysicsDirectBodyState2DSW::set_transform(const Transform2D &p_transform) { +void GodotPhysicsDirectBodyState2D::set_transform(const Transform2D &p_transform) { body->set_state(PhysicsServer2D::BODY_STATE_TRANSFORM, p_transform); } -Transform2D PhysicsDirectBodyState2DSW::get_transform() const { +Transform2D GodotPhysicsDirectBodyState2D::get_transform() const { return body->get_transform(); } -Vector2 PhysicsDirectBodyState2DSW::get_velocity_at_local_position(const Vector2 &p_position) const { +Vector2 GodotPhysicsDirectBodyState2D::get_velocity_at_local_position(const Vector2 &p_position) const { return body->get_velocity_in_local_point(p_position); } -void PhysicsDirectBodyState2DSW::add_central_force(const Vector2 &p_force) { +void GodotPhysicsDirectBodyState2D::add_central_force(const Vector2 &p_force) { body->wakeup(); body->add_central_force(p_force); } -void PhysicsDirectBodyState2DSW::add_force(const Vector2 &p_force, const Vector2 &p_position) { +void GodotPhysicsDirectBodyState2D::add_force(const Vector2 &p_force, const Vector2 &p_position) { body->wakeup(); body->add_force(p_force, p_position); } -void PhysicsDirectBodyState2DSW::add_torque(real_t p_torque) { +void GodotPhysicsDirectBodyState2D::add_torque(real_t p_torque) { body->wakeup(); body->add_torque(p_torque); } -void PhysicsDirectBodyState2DSW::apply_central_impulse(const Vector2 &p_impulse) { +void GodotPhysicsDirectBodyState2D::apply_central_impulse(const Vector2 &p_impulse) { body->wakeup(); body->apply_central_impulse(p_impulse); } -void PhysicsDirectBodyState2DSW::apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position) { +void GodotPhysicsDirectBodyState2D::apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position) { body->wakeup(); body->apply_impulse(p_impulse, p_position); } -void PhysicsDirectBodyState2DSW::apply_torque_impulse(real_t p_torque) { +void GodotPhysicsDirectBodyState2D::apply_torque_impulse(real_t p_torque) { body->wakeup(); body->apply_torque_impulse(p_torque); } -void PhysicsDirectBodyState2DSW::set_sleep_state(bool p_enable) { +void GodotPhysicsDirectBodyState2D::set_sleep_state(bool p_enable) { body->set_active(!p_enable); } -bool PhysicsDirectBodyState2DSW::is_sleeping() const { +bool GodotPhysicsDirectBodyState2D::is_sleeping() const { return !body->is_active(); } -int PhysicsDirectBodyState2DSW::get_contact_count() const { +int GodotPhysicsDirectBodyState2D::get_contact_count() const { return body->contact_count; } -Vector2 PhysicsDirectBodyState2DSW::get_contact_local_position(int p_contact_idx) const { +Vector2 GodotPhysicsDirectBodyState2D::get_contact_local_position(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Vector2()); return body->contacts[p_contact_idx].local_pos; } -Vector2 PhysicsDirectBodyState2DSW::get_contact_local_normal(int p_contact_idx) const { +Vector2 GodotPhysicsDirectBodyState2D::get_contact_local_normal(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Vector2()); return body->contacts[p_contact_idx].local_normal; } -int PhysicsDirectBodyState2DSW::get_contact_local_shape(int p_contact_idx) const { +int GodotPhysicsDirectBodyState2D::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; } -RID PhysicsDirectBodyState2DSW::get_contact_collider(int p_contact_idx) const { +RID GodotPhysicsDirectBodyState2D::get_contact_collider(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, RID()); return body->contacts[p_contact_idx].collider; } -Vector2 PhysicsDirectBodyState2DSW::get_contact_collider_position(int p_contact_idx) const { +Vector2 GodotPhysicsDirectBodyState2D::get_contact_collider_position(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Vector2()); return body->contacts[p_contact_idx].collider_pos; } -ObjectID PhysicsDirectBodyState2DSW::get_contact_collider_id(int p_contact_idx) const { +ObjectID GodotPhysicsDirectBodyState2D::get_contact_collider_id(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, ObjectID()); return body->contacts[p_contact_idx].collider_instance_id; } -int PhysicsDirectBodyState2DSW::get_contact_collider_shape(int p_contact_idx) const { +int GodotPhysicsDirectBodyState2D::get_contact_collider_shape(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, 0); return body->contacts[p_contact_idx].collider_shape; } -Vector2 PhysicsDirectBodyState2DSW::get_contact_collider_velocity_at_position(int p_contact_idx) const { +Vector2 GodotPhysicsDirectBodyState2D::get_contact_collider_velocity_at_position(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Vector2()); return body->contacts[p_contact_idx].collider_velocity_at_pos; } -PhysicsDirectSpaceState2D *PhysicsDirectBodyState2DSW::get_space_state() { +PhysicsDirectSpaceState2D *GodotPhysicsDirectBodyState2D::get_space_state() { return body->get_space()->get_direct_state(); } -real_t PhysicsDirectBodyState2DSW::get_step() const { +real_t GodotPhysicsDirectBodyState2D::get_step() const { return body->get_space()->get_last_step(); } diff --git a/servers/physics_2d/body_direct_state_2d_sw.h b/servers/physics_2d/godot_body_direct_state_2d.h index 4266b24842..2f3e8e5095 100644 --- a/servers/physics_2d/body_direct_state_2d_sw.h +++ b/servers/physics_2d/godot_body_direct_state_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_direct_state_2d_sw.h */ +/* godot_body_direct_state_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,18 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BODY_DIRECT_STATE_2D_SW_H -#define BODY_DIRECT_STATE_2D_SW_H +#ifndef GODOT_BODY_DIRECT_STATE_2D_H +#define GODOT_BODY_DIRECT_STATE_2D_H #include "servers/physics_server_2d.h" -class Body2DSW; +class GodotBody2D; -class PhysicsDirectBodyState2DSW : public PhysicsDirectBodyState2D { - GDCLASS(PhysicsDirectBodyState2DSW, PhysicsDirectBodyState2D); +class GodotPhysicsDirectBodyState2D : public PhysicsDirectBodyState2D { + GDCLASS(GodotPhysicsDirectBodyState2D, PhysicsDirectBodyState2D); public: - Body2DSW *body = nullptr; + GodotBody2D *body = nullptr; virtual Vector2 get_total_gravity() const override; virtual real_t get_total_angular_damp() const override; @@ -88,4 +88,4 @@ public: virtual real_t get_step() const override; }; -#endif // BODY_2D_SW_H +#endif // GODOT_BODY_DIRECT_STATE_2D_H diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/godot_body_pair_2d.cpp index 8bcc4609f4..97eeefbfe6 100644 --- a/servers/physics_2d/body_pair_2d_sw.cpp +++ b/servers/physics_2d/godot_body_pair_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_pair_2d_sw.cpp */ +/* godot_body_pair_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,20 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "body_pair_2d_sw.h" -#include "collision_solver_2d_sw.h" -#include "space_2d_sw.h" +#include "godot_body_pair_2d.h" +#include "godot_collision_solver_2d.h" +#include "godot_space_2d.h" #define POSITION_CORRECTION #define ACCUMULATE_IMPULSES -void BodyPair2DSW::_add_contact(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_self) { - BodyPair2DSW *self = (BodyPair2DSW *)p_self; +void GodotBodyPair2D::_add_contact(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_self) { + GodotBodyPair2D *self = (GodotBodyPair2D *)p_self; self->_contact_added_callback(p_point_A, p_point_B); } -void BodyPair2DSW::_contact_added_callback(const Vector2 &p_point_A, const Vector2 &p_point_B) { +void GodotBodyPair2D::_contact_added_callback(const Vector2 &p_point_A, const Vector2 &p_point_B) { // check if we already have the contact Vector2 local_A = A->get_inv_transform().basis_xform(p_point_A); @@ -121,7 +121,7 @@ void BodyPair2DSW::_contact_added_callback(const Vector2 &p_point_A, const Vecto } } -void BodyPair2DSW::_validate_contacts() { +void GodotBodyPair2D::_validate_contacts() { //make sure to erase contacts that are no longer valid real_t max_separation = space->get_contact_max_separation(); @@ -164,7 +164,7 @@ void BodyPair2DSW::_validate_contacts() { } } -bool BodyPair2DSW::_test_ccd(real_t p_step, Body2DSW *p_A, int p_shape_A, const Transform2D &p_xform_A, Body2DSW *p_B, int p_shape_B, const Transform2D &p_xform_B, bool p_swap_result) { +bool GodotBodyPair2D::_test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A, const Transform2D &p_xform_A, GodotBody2D *p_B, int p_shape_B, const Transform2D &p_xform_B, bool p_swap_result) { Vector2 motion = p_A->get_linear_velocity() * p_step; real_t mlen = motion.length(); if (mlen < CMP_EPSILON) { @@ -217,15 +217,15 @@ bool BodyPair2DSW::_test_ccd(real_t p_step, Body2DSW *p_A, int p_shape_A, const return true; } -real_t combine_bounce(Body2DSW *A, Body2DSW *B) { +real_t combine_bounce(GodotBody2D *A, GodotBody2D *B) { return CLAMP(A->get_bounce() + B->get_bounce(), 0, 1); } -real_t combine_friction(Body2DSW *A, Body2DSW *B) { +real_t combine_friction(GodotBody2D *A, GodotBody2D *B) { return ABS(MIN(A->get_friction(), B->get_friction())); } -bool BodyPair2DSW::setup(real_t p_step) { +bool GodotBodyPair2D::setup(real_t p_step) { if (!A->interacts_with(B) || A->has_exception(B->get_self()) || B->has_exception(A->get_self())) { collided = false; return false; @@ -257,8 +257,8 @@ bool BodyPair2DSW::setup(real_t p_step) { xform_Bu.elements[2] -= offset_A; Transform2D xform_B = xform_Bu * B->get_shape_transform(shape_B); - Shape2DSW *shape_A_ptr = A->get_shape(shape_A); - Shape2DSW *shape_B_ptr = B->get_shape(shape_B); + GodotShape2D *shape_A_ptr = A->get_shape(shape_A); + GodotShape2D *shape_B_ptr = B->get_shape(shape_B); Vector2 motion_A, motion_B; @@ -271,7 +271,7 @@ bool BodyPair2DSW::setup(real_t p_step) { bool prev_collided = collided; - collided = CollisionSolver2DSW::solve(shape_A_ptr, xform_A, motion_A, shape_B_ptr, xform_B, motion_B, _add_contact, this, &sep_axis); + collided = GodotCollisionSolver2D::solve(shape_A_ptr, xform_A, motion_A, shape_B_ptr, xform_B, motion_B, _add_contact, this, &sep_axis); if (!collided) { //test ccd (currently just a raycast) @@ -344,7 +344,7 @@ bool BodyPair2DSW::setup(real_t p_step) { return true; } -bool BodyPair2DSW::pre_solve(real_t p_step) { +bool GodotBodyPair2D::pre_solve(real_t p_step) { if (!collided || oneway_disabled) { return false; } @@ -353,8 +353,8 @@ bool BodyPair2DSW::pre_solve(real_t p_step) { real_t bias = 0.3; - Shape2DSW *shape_A_ptr = A->get_shape(shape_A); - Shape2DSW *shape_B_ptr = B->get_shape(shape_B); + GodotShape2D *shape_A_ptr = A->get_shape(shape_A); + GodotShape2D *shape_B_ptr = B->get_shape(shape_B); if (shape_A_ptr->get_custom_bias() || shape_B_ptr->get_custom_bias()) { if (shape_A_ptr->get_custom_bias() == 0) { @@ -466,7 +466,7 @@ bool BodyPair2DSW::pre_solve(real_t p_step) { return do_process; } -void BodyPair2DSW::solve(real_t p_step) { +void GodotBodyPair2D::solve(real_t p_step) { if (!collided || oneway_disabled) { return; } @@ -528,8 +528,8 @@ void BodyPair2DSW::solve(real_t p_step) { } } -BodyPair2DSW::BodyPair2DSW(Body2DSW *p_A, int p_shape_A, Body2DSW *p_B, int p_shape_B) : - Constraint2DSW(_arr, 2) { +GodotBodyPair2D::GodotBodyPair2D(GodotBody2D *p_A, int p_shape_A, GodotBody2D *p_B, int p_shape_B) : + GodotConstraint2D(_arr, 2) { A = p_A; B = p_B; shape_A = p_shape_A; @@ -539,7 +539,7 @@ BodyPair2DSW::BodyPair2DSW(Body2DSW *p_A, int p_shape_A, Body2DSW *p_B, int p_sh B->add_constraint(this, 1); } -BodyPair2DSW::~BodyPair2DSW() { +GodotBodyPair2D::~GodotBodyPair2D() { A->remove_constraint(this, 0); B->remove_constraint(this, 1); } diff --git a/servers/physics_2d/body_pair_2d_sw.h b/servers/physics_2d/godot_body_pair_2d.h index db4f3eba69..0938ab542b 100644 --- a/servers/physics_2d/body_pair_2d_sw.h +++ b/servers/physics_2d/godot_body_pair_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_pair_2d_sw.h */ +/* godot_body_pair_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,23 +28,23 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BODY_PAIR_2D_SW_H -#define BODY_PAIR_2D_SW_H +#ifndef GODOT_BODY_PAIR_2D_H +#define GODOT_BODY_PAIR_2D_H -#include "body_2d_sw.h" -#include "constraint_2d_sw.h" +#include "godot_body_2d.h" +#include "godot_constraint_2d.h" -class BodyPair2DSW : public Constraint2DSW { +class GodotBodyPair2D : public GodotConstraint2D { enum { MAX_CONTACTS = 2 }; union { struct { - Body2DSW *A; - Body2DSW *B; + GodotBody2D *A; + GodotBody2D *B; }; - Body2DSW *_arr[2] = { nullptr, nullptr }; + GodotBody2D *_arr[2] = { nullptr, nullptr }; }; int shape_A = 0; @@ -53,7 +53,7 @@ class BodyPair2DSW : public Constraint2DSW { bool collide_A = false; bool collide_B = false; - Space2DSW *space = nullptr; + GodotSpace2D *space = nullptr; struct Contact { Vector2 position; @@ -81,7 +81,7 @@ class BodyPair2DSW : public Constraint2DSW { bool oneway_disabled = false; bool report_contacts_only = false; - bool _test_ccd(real_t p_step, Body2DSW *p_A, int p_shape_A, const Transform2D &p_xform_A, Body2DSW *p_B, int p_shape_B, const Transform2D &p_xform_B, bool p_swap_result = false); + bool _test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A, const Transform2D &p_xform_A, GodotBody2D *p_B, int p_shape_B, const Transform2D &p_xform_B, bool p_swap_result = false); void _validate_contacts(); static void _add_contact(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_self); _FORCE_INLINE_ void _contact_added_callback(const Vector2 &p_point_A, const Vector2 &p_point_B); @@ -91,8 +91,8 @@ public: virtual bool pre_solve(real_t p_step) override; virtual void solve(real_t p_step) override; - BodyPair2DSW(Body2DSW *p_A, int p_shape_A, Body2DSW *p_B, int p_shape_B); - ~BodyPair2DSW(); + GodotBodyPair2D(GodotBody2D *p_A, int p_shape_A, GodotBody2D *p_B, int p_shape_B); + ~GodotBodyPair2D(); }; -#endif // BODY_PAIR_2D_SW_H +#endif // GODOT_BODY_PAIR_2D_H diff --git a/servers/physics_2d/broad_phase_2d_sw.cpp b/servers/physics_2d/godot_broad_phase_2d.cpp index 7f0af48b1f..4b35f8d996 100644 --- a/servers/physics_2d/broad_phase_2d_sw.cpp +++ b/servers/physics_2d/godot_broad_phase_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* broad_phase_2d_sw.cpp */ +/* godot_broad_phase_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,9 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "broad_phase_2d_sw.h" +#include "godot_broad_phase_2d.h" -BroadPhase2DSW::CreateFunction BroadPhase2DSW::create_func = nullptr; +GodotBroadPhase2D::CreateFunction GodotBroadPhase2D::create_func = nullptr; -BroadPhase2DSW::~BroadPhase2DSW() { +GodotBroadPhase2D::~GodotBroadPhase2D() { } diff --git a/servers/physics_2d/broad_phase_2d_sw.h b/servers/physics_2d/godot_broad_phase_2d.h index 0f82f06b9c..7017a6e41f 100644 --- a/servers/physics_2d/broad_phase_2d_sw.h +++ b/servers/physics_2d/godot_broad_phase_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* broad_phase_2d_sw.h */ +/* godot_broad_phase_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,44 +28,44 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BROAD_PHASE_2D_SW_H -#define BROAD_PHASE_2D_SW_H +#ifndef GODOT_BROAD_PHASE_2D_H +#define GODOT_BROAD_PHASE_2D_H #include "core/math/math_funcs.h" #include "core/math/rect2.h" -class CollisionObject2DSW; +class GodotCollisionObject2D; -class BroadPhase2DSW { +class GodotBroadPhase2D { public: - typedef BroadPhase2DSW *(*CreateFunction)(); + typedef GodotBroadPhase2D *(*CreateFunction)(); static CreateFunction create_func; typedef uint32_t ID; - typedef void *(*PairCallback)(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_userdata); - typedef void (*UnpairCallback)(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_data, void *p_userdata); + typedef void *(*PairCallback)(GodotCollisionObject2D *A, int p_subindex_A, GodotCollisionObject2D *B, int p_subindex_B, void *p_userdata); + typedef void (*UnpairCallback)(GodotCollisionObject2D *A, int p_subindex_A, GodotCollisionObject2D *B, int p_subindex_B, void *p_data, void *p_userdata); // 0 is an invalid ID - virtual ID create(CollisionObject2DSW *p_object_, int p_subindex = 0, const Rect2 &p_aabb = Rect2(), bool p_static = false) = 0; + virtual ID create(GodotCollisionObject2D *p_object_, int p_subindex = 0, const Rect2 &p_aabb = Rect2(), bool p_static = false) = 0; virtual void move(ID p_id, const Rect2 &p_aabb) = 0; virtual void set_static(ID p_id, bool p_static) = 0; virtual void remove(ID p_id) = 0; - virtual CollisionObject2DSW *get_object(ID p_id) const = 0; + virtual GodotCollisionObject2D *get_object(ID p_id) const = 0; virtual bool is_static(ID p_id) const = 0; virtual int get_subindex(ID p_id) const = 0; - virtual int cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; - virtual int cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; + virtual int cull_segment(const Vector2 &p_from, const Vector2 &p_to, GodotCollisionObject2D **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; + virtual int cull_aabb(const Rect2 &p_aabb, GodotCollisionObject2D **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata) = 0; virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) = 0; virtual void update() = 0; - virtual ~BroadPhase2DSW(); + virtual ~GodotBroadPhase2D(); }; -#endif // BROAD_PHASE_2D_SW_H +#endif // GODOT_BROAD_PHASE_2D_H diff --git a/servers/physics_2d/broad_phase_2d_bvh.cpp b/servers/physics_2d/godot_broad_phase_2d_bvh.cpp index 0df7086c5a..9ec6b0a6b7 100644 --- a/servers/physics_2d/broad_phase_2d_bvh.cpp +++ b/servers/physics_2d/godot_broad_phase_2d_bvh.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* broad_phase_2d_bvh.cpp */ +/* godot_broad_phase_2d_bvh.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,51 +28,51 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "broad_phase_2d_bvh.h" -#include "collision_object_2d_sw.h" +#include "godot_broad_phase_2d_bvh.h" +#include "godot_collision_object_2d.h" -BroadPhase2DSW::ID BroadPhase2DBVH::create(CollisionObject2DSW *p_object, int p_subindex, const Rect2 &p_aabb, bool p_static) { +GodotBroadPhase2D::ID GodotBroadPhase2DBVH::create(GodotCollisionObject2D *p_object, int p_subindex, const Rect2 &p_aabb, bool p_static) { ID oid = bvh.create(p_object, true, p_aabb, p_subindex, !p_static, 1 << p_object->get_type(), p_static ? 0 : 0xFFFFF); // Pair everything, don't care? return oid + 1; } -void BroadPhase2DBVH::move(ID p_id, const Rect2 &p_aabb) { +void GodotBroadPhase2DBVH::move(ID p_id, const Rect2 &p_aabb) { bvh.move(p_id - 1, p_aabb); } -void BroadPhase2DBVH::set_static(ID p_id, bool p_static) { - CollisionObject2DSW *it = bvh.get(p_id - 1); +void GodotBroadPhase2DBVH::set_static(ID p_id, bool p_static) { + GodotCollisionObject2D *it = bvh.get(p_id - 1); bvh.set_pairable(p_id - 1, !p_static, 1 << it->get_type(), p_static ? 0 : 0xFFFFF, false); // Pair everything, don't care? } -void BroadPhase2DBVH::remove(ID p_id) { +void GodotBroadPhase2DBVH::remove(ID p_id) { bvh.erase(p_id - 1); } -CollisionObject2DSW *BroadPhase2DBVH::get_object(ID p_id) const { - CollisionObject2DSW *it = bvh.get(p_id - 1); +GodotCollisionObject2D *GodotBroadPhase2DBVH::get_object(ID p_id) const { + GodotCollisionObject2D *it = bvh.get(p_id - 1); ERR_FAIL_COND_V(!it, nullptr); return it; } -bool BroadPhase2DBVH::is_static(ID p_id) const { +bool GodotBroadPhase2DBVH::is_static(ID p_id) const { return !bvh.is_pairable(p_id - 1); } -int BroadPhase2DBVH::get_subindex(ID p_id) const { +int GodotBroadPhase2DBVH::get_subindex(ID p_id) const { return bvh.get_subindex(p_id - 1); } -int BroadPhase2DBVH::cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { +int GodotBroadPhase2DBVH::cull_segment(const Vector2 &p_from, const Vector2 &p_to, GodotCollisionObject2D **p_results, int p_max_results, int *p_result_indices) { return bvh.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices); } -int BroadPhase2DBVH::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { +int GodotBroadPhase2DBVH::cull_aabb(const Rect2 &p_aabb, GodotCollisionObject2D **p_results, int p_max_results, int *p_result_indices) { return bvh.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices); } -void *BroadPhase2DBVH::_pair_callback(void *self, uint32_t p_A, CollisionObject2DSW *p_object_A, int subindex_A, uint32_t p_B, CollisionObject2DSW *p_object_B, int subindex_B) { - BroadPhase2DBVH *bpo = (BroadPhase2DBVH *)(self); +void *GodotBroadPhase2DBVH::_pair_callback(void *self, uint32_t p_A, GodotCollisionObject2D *p_object_A, int subindex_A, uint32_t p_B, GodotCollisionObject2D *p_object_B, int subindex_B) { + GodotBroadPhase2DBVH *bpo = (GodotBroadPhase2DBVH *)(self); if (!bpo->pair_callback) { return nullptr; } @@ -80,8 +80,8 @@ void *BroadPhase2DBVH::_pair_callback(void *self, uint32_t p_A, CollisionObject2 return bpo->pair_callback(p_object_A, subindex_A, p_object_B, subindex_B, bpo->pair_userdata); } -void BroadPhase2DBVH::_unpair_callback(void *self, uint32_t p_A, CollisionObject2DSW *p_object_A, int subindex_A, uint32_t p_B, CollisionObject2DSW *p_object_B, int subindex_B, void *pairdata) { - BroadPhase2DBVH *bpo = (BroadPhase2DBVH *)(self); +void GodotBroadPhase2DBVH::_unpair_callback(void *self, uint32_t p_A, GodotCollisionObject2D *p_object_A, int subindex_A, uint32_t p_B, GodotCollisionObject2D *p_object_B, int subindex_B, void *pairdata) { + GodotBroadPhase2DBVH *bpo = (GodotBroadPhase2DBVH *)(self); if (!bpo->unpair_callback) { return; } @@ -89,25 +89,25 @@ void BroadPhase2DBVH::_unpair_callback(void *self, uint32_t p_A, CollisionObject bpo->unpair_callback(p_object_A, subindex_A, p_object_B, subindex_B, pairdata, bpo->unpair_userdata); } -void BroadPhase2DBVH::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { +void GodotBroadPhase2DBVH::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { pair_callback = p_pair_callback; pair_userdata = p_userdata; } -void BroadPhase2DBVH::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { +void GodotBroadPhase2DBVH::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { unpair_callback = p_unpair_callback; unpair_userdata = p_userdata; } -void BroadPhase2DBVH::update() { +void GodotBroadPhase2DBVH::update() { bvh.update(); } -BroadPhase2DSW *BroadPhase2DBVH::_create() { - return memnew(BroadPhase2DBVH); +GodotBroadPhase2D *GodotBroadPhase2DBVH::_create() { + return memnew(GodotBroadPhase2DBVH); } -BroadPhase2DBVH::BroadPhase2DBVH() { +GodotBroadPhase2DBVH::GodotBroadPhase2DBVH() { bvh.set_pair_callback(_pair_callback, this); bvh.set_unpair_callback(_unpair_callback, this); } diff --git a/servers/physics_2d/broad_phase_2d_bvh.h b/servers/physics_2d/godot_broad_phase_2d_bvh.h index ea02a98417..19b49f3499 100644 --- a/servers/physics_2d/broad_phase_2d_bvh.h +++ b/servers/physics_2d/godot_broad_phase_2d_bvh.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* broad_phase_2d_bvh.h */ +/* godot_broad_phase_2d_bvh.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,19 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BROAD_PHASE_2D_BVH_H -#define BROAD_PHASE_2D_BVH_H +#ifndef GODOT_BROAD_PHASE_2D_BVH_H +#define GODOT_BROAD_PHASE_2D_BVH_H + +#include "godot_broad_phase_2d.h" -#include "broad_phase_2d_sw.h" #include "core/math/bvh.h" #include "core/math/rect2.h" #include "core/math/vector2.h" -class BroadPhase2DBVH : public BroadPhase2DSW { - BVH_Manager<CollisionObject2DSW, true, 128, Rect2, Vector2> bvh; +class GodotBroadPhase2DBVH : public GodotBroadPhase2D { + BVH_Manager<GodotCollisionObject2D, true, 128, Rect2, Vector2> bvh; - static void *_pair_callback(void *, uint32_t, CollisionObject2DSW *, int, uint32_t, CollisionObject2DSW *, int); - static void _unpair_callback(void *, uint32_t, CollisionObject2DSW *, int, uint32_t, CollisionObject2DSW *, int, void *); + static void *_pair_callback(void *, uint32_t, GodotCollisionObject2D *, int, uint32_t, GodotCollisionObject2D *, int); + static void _unpair_callback(void *, uint32_t, GodotCollisionObject2D *, int, uint32_t, GodotCollisionObject2D *, int, void *); PairCallback pair_callback = nullptr; void *pair_userdata = nullptr; @@ -49,25 +50,25 @@ class BroadPhase2DBVH : public BroadPhase2DSW { public: // 0 is an invalid ID - virtual ID create(CollisionObject2DSW *p_object, int p_subindex = 0, const Rect2 &p_aabb = Rect2(), bool p_static = false); + virtual ID create(GodotCollisionObject2D *p_object, int p_subindex = 0, const Rect2 &p_aabb = Rect2(), bool p_static = false); virtual void move(ID p_id, const Rect2 &p_aabb); virtual void set_static(ID p_id, bool p_static); virtual void remove(ID p_id); - virtual CollisionObject2DSW *get_object(ID p_id) const; + virtual GodotCollisionObject2D *get_object(ID p_id) const; virtual bool is_static(ID p_id) const; virtual int get_subindex(ID p_id) const; - virtual int cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = nullptr); - virtual int cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = nullptr); + virtual int cull_segment(const Vector2 &p_from, const Vector2 &p_to, GodotCollisionObject2D **p_results, int p_max_results, int *p_result_indices = nullptr); + virtual int cull_aabb(const Rect2 &p_aabb, GodotCollisionObject2D **p_results, int p_max_results, int *p_result_indices = nullptr); virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata); virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata); virtual void update(); - static BroadPhase2DSW *_create(); - BroadPhase2DBVH(); + static GodotBroadPhase2D *_create(); + GodotBroadPhase2DBVH(); }; -#endif // BROAD_PHASE_2D_BVH_H +#endif // GODOT_BROAD_PHASE_2D_BVH_H diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/godot_collision_object_2d.cpp index bc7d277152..3d4ebbedcd 100644 --- a/servers/physics_2d/collision_object_2d_sw.cpp +++ b/servers/physics_2d/godot_collision_object_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_object_2d_sw.cpp */ +/* godot_collision_object_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "collision_object_2d_sw.h" -#include "servers/physics_2d/physics_server_2d_sw.h" -#include "space_2d_sw.h" +#include "godot_collision_object_2d.h" +#include "godot_physics_server_2d.h" +#include "godot_space_2d.h" -void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_transform, bool p_disabled) { +void GodotCollisionObject2D::add_shape(GodotShape2D *p_shape, const Transform2D &p_transform, bool p_disabled) { Shape s; s.shape = p_shape; s.xform = p_transform; @@ -45,11 +45,11 @@ void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_tra p_shape->add_owner(this); if (!pending_shape_update_list.in_list()) { - PhysicsServer2DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); + GodotPhysicsServer2D::godot_singleton->pending_shape_update_list.add(&pending_shape_update_list); } } -void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) { +void GodotCollisionObject2D::set_shape(int p_index, GodotShape2D *p_shape) { ERR_FAIL_INDEX(p_index, shapes.size()); shapes[p_index].shape->remove_owner(this); shapes.write[p_index].shape = p_shape; @@ -57,25 +57,25 @@ void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) { p_shape->add_owner(this); if (!pending_shape_update_list.in_list()) { - PhysicsServer2DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); + GodotPhysicsServer2D::godot_singleton->pending_shape_update_list.add(&pending_shape_update_list); } } -void CollisionObject2DSW::set_shape_transform(int p_index, const Transform2D &p_transform) { +void GodotCollisionObject2D::set_shape_transform(int p_index, const Transform2D &p_transform) { ERR_FAIL_INDEX(p_index, shapes.size()); shapes.write[p_index].xform = p_transform; shapes.write[p_index].xform_inv = p_transform.affine_inverse(); if (!pending_shape_update_list.in_list()) { - PhysicsServer2DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); + GodotPhysicsServer2D::godot_singleton->pending_shape_update_list.add(&pending_shape_update_list); } } -void CollisionObject2DSW::set_shape_disabled(int p_idx, bool p_disabled) { +void GodotCollisionObject2D::set_shape_disabled(int p_idx, bool p_disabled) { ERR_FAIL_INDEX(p_idx, shapes.size()); - CollisionObject2DSW::Shape &shape = shapes.write[p_idx]; + GodotCollisionObject2D::Shape &shape = shapes.write[p_idx]; if (shape.disabled == p_disabled) { return; } @@ -90,16 +90,16 @@ void CollisionObject2DSW::set_shape_disabled(int p_idx, bool p_disabled) { space->get_broadphase()->remove(shape.bpid); shape.bpid = 0; if (!pending_shape_update_list.in_list()) { - PhysicsServer2DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); + GodotPhysicsServer2D::godot_singleton->pending_shape_update_list.add(&pending_shape_update_list); } } else if (!p_disabled && shape.bpid == 0) { if (!pending_shape_update_list.in_list()) { - PhysicsServer2DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); + GodotPhysicsServer2D::godot_singleton->pending_shape_update_list.add(&pending_shape_update_list); } } } -void CollisionObject2DSW::remove_shape(Shape2DSW *p_shape) { +void GodotCollisionObject2D::remove_shape(GodotShape2D *p_shape) { //remove a shape, all the times it appears for (int i = 0; i < shapes.size(); i++) { if (shapes[i].shape == p_shape) { @@ -109,7 +109,7 @@ void CollisionObject2DSW::remove_shape(Shape2DSW *p_shape) { } } -void CollisionObject2DSW::remove_shape(int p_index) { +void GodotCollisionObject2D::remove_shape(int p_index) { //remove anything from shape to be erased to end, so subindices don't change ERR_FAIL_INDEX(p_index, shapes.size()); for (int i = p_index; i < shapes.size(); i++) { @@ -124,13 +124,13 @@ void CollisionObject2DSW::remove_shape(int p_index) { shapes.remove(p_index); if (!pending_shape_update_list.in_list()) { - PhysicsServer2DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); + GodotPhysicsServer2D::godot_singleton->pending_shape_update_list.add(&pending_shape_update_list); } // _update_shapes(); // _shapes_changed(); } -void CollisionObject2DSW::_set_static(bool p_static) { +void GodotCollisionObject2D::_set_static(bool p_static) { if (_static == p_static) { return; } @@ -147,7 +147,7 @@ void CollisionObject2DSW::_set_static(bool p_static) { } } -void CollisionObject2DSW::_unregister_shapes() { +void GodotCollisionObject2D::_unregister_shapes() { for (int i = 0; i < shapes.size(); i++) { Shape &s = shapes.write[i]; if (s.bpid > 0) { @@ -157,7 +157,7 @@ void CollisionObject2DSW::_unregister_shapes() { } } -void CollisionObject2DSW::_update_shapes() { +void GodotCollisionObject2D::_update_shapes() { if (!space) { return; } @@ -184,7 +184,7 @@ void CollisionObject2DSW::_update_shapes() { } } -void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) { +void GodotCollisionObject2D::_update_shapes_with_motion(const Vector2 &p_motion) { if (!space) { return; } @@ -211,7 +211,7 @@ void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) { } } -void CollisionObject2DSW::_set_space(Space2DSW *p_space) { +void GodotCollisionObject2D::_set_space(GodotSpace2D *p_space) { if (space) { space->remove_object(this); @@ -232,12 +232,12 @@ void CollisionObject2DSW::_set_space(Space2DSW *p_space) { } } -void CollisionObject2DSW::_shape_changed() { +void GodotCollisionObject2D::_shape_changed() { _update_shapes(); _shapes_changed(); } -CollisionObject2DSW::CollisionObject2DSW(Type p_type) : +GodotCollisionObject2D::GodotCollisionObject2D(Type p_type) : pending_shape_update_list(this) { type = p_type; } diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/godot_collision_object_2d.h index ca258a906a..7233857808 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/godot_collision_object_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_object_2d_sw.h */ +/* godot_collision_object_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,17 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef COLLISION_OBJECT_2D_SW_H -#define COLLISION_OBJECT_2D_SW_H +#ifndef GODOT_COLLISION_OBJECT_2D_H +#define GODOT_COLLISION_OBJECT_2D_H + +#include "godot_broad_phase_2d.h" +#include "godot_shape_2d.h" -#include "broad_phase_2d_sw.h" #include "core/templates/self_list.h" #include "servers/physics_server_2d.h" -#include "shape_2d_sw.h" -class Space2DSW; +class GodotSpace2D; -class CollisionObject2DSW : public ShapeOwner2DSW { +class GodotCollisionObject2D : public GodotShapeOwner2D { public: enum Type { TYPE_AREA, @@ -55,23 +56,23 @@ private: struct Shape { Transform2D xform; Transform2D xform_inv; - BroadPhase2DSW::ID bpid = 0; + GodotBroadPhase2D::ID bpid = 0; Rect2 aabb_cache; //for rayqueries - Shape2DSW *shape = nullptr; + GodotShape2D *shape = nullptr; bool disabled = false; bool one_way_collision = false; real_t one_way_collision_margin = 0.0; }; Vector<Shape> shapes; - Space2DSW *space = nullptr; + GodotSpace2D *space = nullptr; Transform2D transform; Transform2D inv_transform; uint32_t collision_mask = 1; uint32_t collision_layer = 1; bool _static = true; - SelfList<CollisionObject2DSW> pending_shape_update_list; + SelfList<GodotCollisionObject2D> pending_shape_update_list; void _update_shapes(); @@ -89,9 +90,9 @@ protected: void _set_static(bool p_static); virtual void _shapes_changed() = 0; - void _set_space(Space2DSW *p_space); + void _set_space(GodotSpace2D *p_space); - CollisionObject2DSW(Type p_type); + GodotCollisionObject2D(Type p_type); public: _FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; } @@ -106,12 +107,12 @@ public: void _shape_changed(); _FORCE_INLINE_ Type get_type() const { return type; } - void add_shape(Shape2DSW *p_shape, const Transform2D &p_transform = Transform2D(), bool p_disabled = false); - void set_shape(int p_index, Shape2DSW *p_shape); + void add_shape(GodotShape2D *p_shape, const Transform2D &p_transform = Transform2D(), bool p_disabled = false); + void set_shape(int p_index, GodotShape2D *p_shape); void set_shape_transform(int p_index, const Transform2D &p_transform); _FORCE_INLINE_ int get_shape_count() const { return shapes.size(); } - _FORCE_INLINE_ Shape2DSW *get_shape(int p_index) const { + _FORCE_INLINE_ GodotShape2D *get_shape(int p_index) const { CRASH_BAD_INDEX(p_index, shapes.size()); return shapes[p_index].shape; } @@ -130,7 +131,7 @@ public: _FORCE_INLINE_ const Transform2D &get_transform() const { return transform; } _FORCE_INLINE_ const Transform2D &get_inv_transform() const { return inv_transform; } - _FORCE_INLINE_ Space2DSW *get_space() const { return space; } + _FORCE_INLINE_ GodotSpace2D *get_space() const { return space; } void set_shape_disabled(int p_idx, bool p_disabled); _FORCE_INLINE_ bool is_shape_disabled(int p_idx) const { @@ -165,25 +166,25 @@ public: } _FORCE_INLINE_ uint32_t get_collision_layer() const { return collision_layer; } - void remove_shape(Shape2DSW *p_shape); + void remove_shape(GodotShape2D *p_shape); void remove_shape(int p_index); - virtual void set_space(Space2DSW *p_space) = 0; + virtual void set_space(GodotSpace2D *p_space) = 0; _FORCE_INLINE_ bool is_static() const { return _static; } void set_pickable(bool p_pickable) { pickable = p_pickable; } _FORCE_INLINE_ bool is_pickable() const { return pickable; } - _FORCE_INLINE_ bool collides_with(CollisionObject2DSW *p_other) const { + _FORCE_INLINE_ bool collides_with(GodotCollisionObject2D *p_other) const { return p_other->collision_layer & collision_mask; } - _FORCE_INLINE_ bool interacts_with(CollisionObject2DSW *p_other) const { + _FORCE_INLINE_ bool interacts_with(GodotCollisionObject2D *p_other) const { return collision_layer & p_other->collision_mask || p_other->collision_layer & collision_mask; } - virtual ~CollisionObject2DSW() {} + virtual ~GodotCollisionObject2D() {} }; -#endif // COLLISION_OBJECT_2D_SW_H +#endif // GODOT_COLLISION_OBJECT_2D_H diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/godot_collision_solver_2d.cpp index 527bb1b0b2..25371b9885 100644 --- a/servers/physics_2d/collision_solver_2d_sw.cpp +++ b/servers/physics_2d/godot_collision_solver_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_solver_2d_sw.cpp */ +/* godot_collision_solver_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "collision_solver_2d_sw.h" -#include "collision_solver_2d_sat.h" +#include "godot_collision_solver_2d.h" +#include "godot_collision_solver_2d_sat.h" #define collision_solver sat_2d_calculate_penetration //#define collision_solver gjk_epa_calculate_penetration -bool CollisionSolver2DSW::solve_static_world_boundary(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { - const WorldBoundaryShape2DSW *world_boundary = static_cast<const WorldBoundaryShape2DSW *>(p_shape_A); +bool GodotCollisionSolver2D::solve_static_world_boundary(const GodotShape2D *p_shape_A, const Transform2D &p_transform_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { + const GodotWorldBoundaryShape2D *world_boundary = static_cast<const GodotWorldBoundaryShape2D *>(p_shape_A); if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_WORLD_BOUNDARY) { return false; } @@ -73,8 +73,8 @@ bool CollisionSolver2DSW::solve_static_world_boundary(const Shape2DSW *p_shape_A return found; } -bool CollisionSolver2DSW::solve_separation_ray(const Shape2DSW *p_shape_A, const Vector2 &p_motion_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *r_sep_axis, real_t p_margin) { - const SeparationRayShape2DSW *ray = static_cast<const SeparationRayShape2DSW *>(p_shape_A); +bool GodotCollisionSolver2D::solve_separation_ray(const GodotShape2D *p_shape_A, const Vector2 &p_motion_A, const Transform2D &p_transform_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *r_sep_axis, real_t p_margin) { + const GodotSeparationRayShape2D *ray = static_cast<const GodotSeparationRayShape2D *>(p_shape_A); if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_SEPARATION_RAY) { return false; } @@ -134,13 +134,13 @@ bool CollisionSolver2DSW::solve_separation_ray(const Shape2DSW *p_shape_A, const struct _ConcaveCollisionInfo2D { const Transform2D *transform_A = nullptr; - const Shape2DSW *shape_A = nullptr; + const GodotShape2D *shape_A = nullptr; const Transform2D *transform_B = nullptr; Vector2 motion_A; Vector2 motion_B; real_t margin_A = 0.0; real_t margin_B = 0.0; - CollisionSolver2DSW::CallbackResult result_callback; + GodotCollisionSolver2D::CallbackResult result_callback; void *userdata = nullptr; bool swap_result = false; bool collided = false; @@ -149,7 +149,7 @@ struct _ConcaveCollisionInfo2D { Vector2 *sep_axis = nullptr; }; -bool CollisionSolver2DSW::concave_callback(void *p_userdata, Shape2DSW *p_convex) { +bool GodotCollisionSolver2D::concave_callback(void *p_userdata, GodotShape2D *p_convex) { _ConcaveCollisionInfo2D &cinfo = *(_ConcaveCollisionInfo2D *)(p_userdata); cinfo.aabb_tests++; @@ -165,8 +165,8 @@ bool CollisionSolver2DSW::concave_callback(void *p_userdata, Shape2DSW *p_convex return !cinfo.result_callback; } -bool CollisionSolver2DSW::solve_concave(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *r_sep_axis, real_t p_margin_A, real_t p_margin_B) { - const ConcaveShape2DSW *concave_B = static_cast<const ConcaveShape2DSW *>(p_shape_B); +bool GodotCollisionSolver2D::solve_concave(const GodotShape2D *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *r_sep_axis, real_t p_margin_A, real_t p_margin_B) { + const GodotConcaveShape2D *concave_B = static_cast<const GodotConcaveShape2D *>(p_shape_B); _ConcaveCollisionInfo2D cinfo; cinfo.transform_A = &p_transform_A; @@ -209,7 +209,7 @@ bool CollisionSolver2DSW::solve_concave(const Shape2DSW *p_shape_A, const Transf return cinfo.collided; } -bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, Vector2 *r_sep_axis, real_t p_margin_A, real_t p_margin_B) { +bool GodotCollisionSolver2D::solve(const GodotShape2D *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, Vector2 *r_sep_axis, real_t p_margin_A, real_t p_margin_B) { PhysicsServer2D::ShapeType type_A = p_shape_A->get_type(); PhysicsServer2D::ShapeType type_B = p_shape_B->get_type(); bool concave_A = p_shape_A->is_concave(); diff --git a/servers/physics_2d/collision_solver_2d_sw.h b/servers/physics_2d/godot_collision_solver_2d.h index b87247b89a..f10815a444 100644 --- a/servers/physics_2d/collision_solver_2d_sw.h +++ b/servers/physics_2d/godot_collision_solver_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_solver_2d_sw.h */ +/* godot_collision_solver_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,23 +28,23 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef COLLISION_SOLVER_2D_SW_H -#define COLLISION_SOLVER_2D_SW_H +#ifndef GODOT_COLLISION_SOLVER_2D_H +#define GODOT_COLLISION_SOLVER_2D_H -#include "shape_2d_sw.h" +#include "godot_shape_2d.h" -class CollisionSolver2DSW { +class GodotCollisionSolver2D { public: typedef void (*CallbackResult)(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_userdata); private: - static bool solve_static_world_boundary(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); - static bool concave_callback(void *p_userdata, Shape2DSW *p_convex); - static bool solve_concave(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *r_sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); - static bool solve_separation_ray(const Shape2DSW *p_shape_A, const Vector2 &p_motion_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *r_sep_axis = nullptr, real_t p_margin = 0); + static bool solve_static_world_boundary(const GodotShape2D *p_shape_A, const Transform2D &p_transform_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); + static bool concave_callback(void *p_userdata, GodotShape2D *p_convex); + static bool solve_concave(const GodotShape2D *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *r_sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); + static bool solve_separation_ray(const GodotShape2D *p_shape_A, const Vector2 &p_motion_A, const Transform2D &p_transform_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *r_sep_axis = nullptr, real_t p_margin = 0); public: - static bool solve(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, Vector2 *r_sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); + static bool solve(const GodotShape2D *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, Vector2 *r_sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); }; -#endif // COLLISION_SOLVER_2D_SW_H +#endif // GODOT_COLLISION_SOLVER_2D_H diff --git a/servers/physics_2d/collision_solver_2d_sat.cpp b/servers/physics_2d/godot_collision_solver_2d_sat.cpp index 2e67cc6520..63053e8259 100644 --- a/servers/physics_2d/collision_solver_2d_sat.cpp +++ b/servers/physics_2d/godot_collision_solver_2d_sat.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_solver_2d_sat.cpp */ +/* godot_collision_solver_2d_sat.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,12 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "collision_solver_2d_sat.h" +#include "godot_collision_solver_2d_sat.h" #include "core/math/geometry_2d.h" struct _CollectorCallback2D { - CollisionSolver2DSW::CallbackResult callback; + GodotCollisionSolver2D::CallbackResult callback; void *userdata = nullptr; bool swap = false; bool collided = false; @@ -384,14 +384,14 @@ public: (castB && !separator.test_axis(((m_a) - ((m_b) + p_motion_b)).normalized())) || \ (castA && castB && !separator.test_axis(((m_a) + p_motion_a - ((m_b) + p_motion_b)).normalized()))) -typedef void (*CollisionFunc)(const Shape2DSW *, const Transform2D &, const Shape2DSW *, const Transform2D &, _CollectorCallback2D *p_collector, const Vector2 &, const Vector2 &, real_t, real_t); +typedef void (*CollisionFunc)(const GodotShape2D *, const Transform2D &, const GodotShape2D *, const Transform2D &, _CollectorCallback2D *p_collector, const Vector2 &, const Vector2 &, real_t, real_t); template <bool castA, bool castB, bool withMargin> -static void _collision_segment_segment(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a); - const SegmentShape2DSW *segment_B = static_cast<const SegmentShape2DSW *>(p_b); +static void _collision_segment_segment(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotSegmentShape2D *segment_A = static_cast<const GodotSegmentShape2D *>(p_a); + const GodotSegmentShape2D *segment_B = static_cast<const GodotSegmentShape2D *>(p_b); - SeparatorAxisTest2D<SegmentShape2DSW, SegmentShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, segment_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotSegmentShape2D, GodotSegmentShape2D, castA, castB, withMargin> separator(segment_A, p_transform_a, segment_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -430,11 +430,11 @@ static void _collision_segment_segment(const Shape2DSW *p_a, const Transform2D & } template <bool castA, bool castB, bool withMargin> -static void _collision_segment_circle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a); - const CircleShape2DSW *circle_B = static_cast<const CircleShape2DSW *>(p_b); +static void _collision_segment_circle(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotSegmentShape2D *segment_A = static_cast<const GodotSegmentShape2D *>(p_a); + const GodotCircleShape2D *circle_B = static_cast<const GodotCircleShape2D *>(p_b); - SeparatorAxisTest2D<SegmentShape2DSW, CircleShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, circle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotSegmentShape2D, GodotCircleShape2D, castA, castB, withMargin> separator(segment_A, p_transform_a, circle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -463,11 +463,11 @@ static void _collision_segment_circle(const Shape2DSW *p_a, const Transform2D &p } template <bool castA, bool castB, bool withMargin> -static void _collision_segment_rectangle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a); - const RectangleShape2DSW *rectangle_B = static_cast<const RectangleShape2DSW *>(p_b); +static void _collision_segment_rectangle(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotSegmentShape2D *segment_A = static_cast<const GodotSegmentShape2D *>(p_a); + const GodotRectangleShape2D *rectangle_B = static_cast<const GodotRectangleShape2D *>(p_b); - SeparatorAxisTest2D<SegmentShape2DSW, RectangleShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, rectangle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotSegmentShape2D, GodotRectangleShape2D, castA, castB, withMargin> separator(segment_A, p_transform_a, rectangle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -534,11 +534,11 @@ static void _collision_segment_rectangle(const Shape2DSW *p_a, const Transform2D } template <bool castA, bool castB, bool withMargin> -static void _collision_segment_capsule(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a); - const CapsuleShape2DSW *capsule_B = static_cast<const CapsuleShape2DSW *>(p_b); +static void _collision_segment_capsule(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotSegmentShape2D *segment_A = static_cast<const GodotSegmentShape2D *>(p_a); + const GodotCapsuleShape2D *capsule_B = static_cast<const GodotCapsuleShape2D *>(p_b); - SeparatorAxisTest2D<SegmentShape2DSW, CapsuleShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotSegmentShape2D, GodotCapsuleShape2D, castA, castB, withMargin> separator(segment_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -575,11 +575,11 @@ static void _collision_segment_capsule(const Shape2DSW *p_a, const Transform2D & } template <bool castA, bool castB, bool withMargin> -static void _collision_segment_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a); - const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b); +static void _collision_segment_convex_polygon(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotSegmentShape2D *segment_A = static_cast<const GodotSegmentShape2D *>(p_a); + const GodotConvexPolygonShape2D *convex_B = static_cast<const GodotConvexPolygonShape2D *>(p_b); - SeparatorAxisTest2D<SegmentShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotSegmentShape2D, GodotConvexPolygonShape2D, castA, castB, withMargin> separator(segment_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -614,11 +614,11 @@ static void _collision_segment_convex_polygon(const Shape2DSW *p_a, const Transf ///////// template <bool castA, bool castB, bool withMargin> -static void _collision_circle_circle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const CircleShape2DSW *circle_A = static_cast<const CircleShape2DSW *>(p_a); - const CircleShape2DSW *circle_B = static_cast<const CircleShape2DSW *>(p_b); +static void _collision_circle_circle(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotCircleShape2D *circle_A = static_cast<const GodotCircleShape2D *>(p_a); + const GodotCircleShape2D *circle_B = static_cast<const GodotCircleShape2D *>(p_b); - SeparatorAxisTest2D<CircleShape2DSW, CircleShape2DSW, castA, castB, withMargin> separator(circle_A, p_transform_a, circle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotCircleShape2D, GodotCircleShape2D, castA, castB, withMargin> separator(circle_A, p_transform_a, circle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -636,11 +636,11 @@ static void _collision_circle_circle(const Shape2DSW *p_a, const Transform2D &p_ } template <bool castA, bool castB, bool withMargin> -static void _collision_circle_rectangle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const CircleShape2DSW *circle_A = static_cast<const CircleShape2DSW *>(p_a); - const RectangleShape2DSW *rectangle_B = static_cast<const RectangleShape2DSW *>(p_b); +static void _collision_circle_rectangle(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotCircleShape2D *circle_A = static_cast<const GodotCircleShape2D *>(p_a); + const GodotRectangleShape2D *rectangle_B = static_cast<const GodotRectangleShape2D *>(p_b); - SeparatorAxisTest2D<CircleShape2DSW, RectangleShape2DSW, castA, castB, withMargin> separator(circle_A, p_transform_a, rectangle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotCircleShape2D, GodotRectangleShape2D, castA, castB, withMargin> separator(circle_A, p_transform_a, rectangle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -694,11 +694,11 @@ static void _collision_circle_rectangle(const Shape2DSW *p_a, const Transform2D } template <bool castA, bool castB, bool withMargin> -static void _collision_circle_capsule(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const CircleShape2DSW *circle_A = static_cast<const CircleShape2DSW *>(p_a); - const CapsuleShape2DSW *capsule_B = static_cast<const CapsuleShape2DSW *>(p_b); +static void _collision_circle_capsule(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotCircleShape2D *circle_A = static_cast<const GodotCircleShape2D *>(p_a); + const GodotCapsuleShape2D *capsule_B = static_cast<const GodotCapsuleShape2D *>(p_b); - SeparatorAxisTest2D<CircleShape2DSW, CapsuleShape2DSW, castA, castB, withMargin> separator(circle_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotCircleShape2D, GodotCapsuleShape2D, castA, castB, withMargin> separator(circle_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -727,11 +727,11 @@ static void _collision_circle_capsule(const Shape2DSW *p_a, const Transform2D &p } template <bool castA, bool castB, bool withMargin> -static void _collision_circle_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const CircleShape2DSW *circle_A = static_cast<const CircleShape2DSW *>(p_a); - const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b); +static void _collision_circle_convex_polygon(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotCircleShape2D *circle_A = static_cast<const GodotCircleShape2D *>(p_a); + const GodotConvexPolygonShape2D *convex_B = static_cast<const GodotConvexPolygonShape2D *>(p_b); - SeparatorAxisTest2D<CircleShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(circle_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotCircleShape2D, GodotConvexPolygonShape2D, castA, castB, withMargin> separator(circle_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -758,11 +758,11 @@ static void _collision_circle_convex_polygon(const Shape2DSW *p_a, const Transfo ///////// template <bool castA, bool castB, bool withMargin> -static void _collision_rectangle_rectangle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const RectangleShape2DSW *rectangle_A = static_cast<const RectangleShape2DSW *>(p_a); - const RectangleShape2DSW *rectangle_B = static_cast<const RectangleShape2DSW *>(p_b); +static void _collision_rectangle_rectangle(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotRectangleShape2D *rectangle_A = static_cast<const GodotRectangleShape2D *>(p_a); + const GodotRectangleShape2D *rectangle_B = static_cast<const GodotRectangleShape2D *>(p_b); - SeparatorAxisTest2D<RectangleShape2DSW, RectangleShape2DSW, castA, castB, withMargin> separator(rectangle_A, p_transform_a, rectangle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotRectangleShape2D, GodotRectangleShape2D, castA, castB, withMargin> separator(rectangle_A, p_transform_a, rectangle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -832,11 +832,11 @@ static void _collision_rectangle_rectangle(const Shape2DSW *p_a, const Transform } template <bool castA, bool castB, bool withMargin> -static void _collision_rectangle_capsule(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const RectangleShape2DSW *rectangle_A = static_cast<const RectangleShape2DSW *>(p_a); - const CapsuleShape2DSW *capsule_B = static_cast<const CapsuleShape2DSW *>(p_b); +static void _collision_rectangle_capsule(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotRectangleShape2D *rectangle_A = static_cast<const GodotRectangleShape2D *>(p_a); + const GodotCapsuleShape2D *capsule_B = static_cast<const GodotCapsuleShape2D *>(p_b); - SeparatorAxisTest2D<RectangleShape2DSW, CapsuleShape2DSW, castA, castB, withMargin> separator(rectangle_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotRectangleShape2D, GodotCapsuleShape2D, castA, castB, withMargin> separator(rectangle_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -910,11 +910,11 @@ static void _collision_rectangle_capsule(const Shape2DSW *p_a, const Transform2D } template <bool castA, bool castB, bool withMargin> -static void _collision_rectangle_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const RectangleShape2DSW *rectangle_A = static_cast<const RectangleShape2DSW *>(p_a); - const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b); +static void _collision_rectangle_convex_polygon(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotRectangleShape2D *rectangle_A = static_cast<const GodotRectangleShape2D *>(p_a); + const GodotConvexPolygonShape2D *convex_B = static_cast<const GodotConvexPolygonShape2D *>(p_b); - SeparatorAxisTest2D<RectangleShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(rectangle_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotRectangleShape2D, GodotConvexPolygonShape2D, castA, castB, withMargin> separator(rectangle_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -972,11 +972,11 @@ static void _collision_rectangle_convex_polygon(const Shape2DSW *p_a, const Tran ///////// template <bool castA, bool castB, bool withMargin> -static void _collision_capsule_capsule(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const CapsuleShape2DSW *capsule_A = static_cast<const CapsuleShape2DSW *>(p_a); - const CapsuleShape2DSW *capsule_B = static_cast<const CapsuleShape2DSW *>(p_b); +static void _collision_capsule_capsule(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotCapsuleShape2D *capsule_A = static_cast<const GodotCapsuleShape2D *>(p_a); + const GodotCapsuleShape2D *capsule_B = static_cast<const GodotCapsuleShape2D *>(p_b); - SeparatorAxisTest2D<CapsuleShape2DSW, CapsuleShape2DSW, castA, castB, withMargin> separator(capsule_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotCapsuleShape2D, GodotCapsuleShape2D, castA, castB, withMargin> separator(capsule_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -1020,11 +1020,11 @@ static void _collision_capsule_capsule(const Shape2DSW *p_a, const Transform2D & } template <bool castA, bool castB, bool withMargin> -static void _collision_capsule_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const CapsuleShape2DSW *capsule_A = static_cast<const CapsuleShape2DSW *>(p_a); - const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b); +static void _collision_capsule_convex_polygon(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotCapsuleShape2D *capsule_A = static_cast<const GodotCapsuleShape2D *>(p_a); + const GodotConvexPolygonShape2D *convex_B = static_cast<const GodotConvexPolygonShape2D *>(p_b); - SeparatorAxisTest2D<CapsuleShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(capsule_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotCapsuleShape2D, GodotConvexPolygonShape2D, castA, castB, withMargin> separator(capsule_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -1066,11 +1066,11 @@ static void _collision_capsule_convex_polygon(const Shape2DSW *p_a, const Transf ///////// template <bool castA, bool castB, bool withMargin> -static void _collision_convex_polygon_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const ConvexPolygonShape2DSW *convex_A = static_cast<const ConvexPolygonShape2DSW *>(p_a); - const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b); +static void _collision_convex_polygon_convex_polygon(const GodotShape2D *p_a, const Transform2D &p_transform_a, const GodotShape2D *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { + const GodotConvexPolygonShape2D *convex_A = static_cast<const GodotConvexPolygonShape2D *>(p_a); + const GodotConvexPolygonShape2D *convex_B = static_cast<const GodotConvexPolygonShape2D *>(p_b); - SeparatorAxisTest2D<ConvexPolygonShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(convex_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); + SeparatorAxisTest2D<GodotConvexPolygonShape2D, GodotConvexPolygonShape2D, castA, castB, withMargin> separator(convex_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); if (!separator.test_previous_axis()) { return; @@ -1107,7 +1107,7 @@ static void _collision_convex_polygon_convex_polygon(const Shape2DSW *p_a, const //////// -bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CollisionSolver2DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap, Vector2 *sep_axis, real_t p_margin_A, real_t p_margin_B) { +bool sat_2d_calculate_penetration(const GodotShape2D *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, GodotCollisionSolver2D::CallbackResult p_result_callback, void *p_userdata, bool p_swap, Vector2 *sep_axis, real_t p_margin_A, real_t p_margin_B) { PhysicsServer2D::ShapeType type_A = p_shape_A->get_type(); ERR_FAIL_COND_V(type_A == PhysicsServer2D::SHAPE_WORLD_BOUNDARY, false); @@ -1359,8 +1359,8 @@ bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D callback.collided = false; callback.sep_axis = sep_axis; - const Shape2DSW *A = p_shape_A; - const Shape2DSW *B = p_shape_B; + const GodotShape2D *A = p_shape_A; + const GodotShape2D *B = p_shape_B; const Transform2D *transform_A = &p_transform_A; const Transform2D *transform_B = &p_transform_B; const Vector2 *motion_A = &p_motion_A; diff --git a/servers/physics_2d/collision_solver_2d_sat.h b/servers/physics_2d/godot_collision_solver_2d_sat.h index 49cc5176f9..1517b90a19 100644 --- a/servers/physics_2d/collision_solver_2d_sat.h +++ b/servers/physics_2d/godot_collision_solver_2d_sat.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_solver_2d_sat.h */ +/* godot_collision_solver_2d_sat.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef COLLISION_SOLVER_2D_SAT_H -#define COLLISION_SOLVER_2D_SAT_H +#ifndef GODOT_COLLISION_SOLVER_2D_SAT_H +#define GODOT_COLLISION_SOLVER_2D_SAT_H -#include "collision_solver_2d_sw.h" +#include "godot_collision_solver_2d.h" -bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CollisionSolver2DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, Vector2 *sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); +bool sat_2d_calculate_penetration(const GodotShape2D *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, GodotCollisionSolver2D::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, Vector2 *sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); -#endif // COLLISION_SOLVER_2D_SAT_H +#endif // GODOT_COLLISION_SOLVER_2D_SAT_H diff --git a/servers/physics_2d/constraint_2d_sw.h b/servers/physics_2d/godot_constraint_2d.h index df300d666d..84f975e583 100644 --- a/servers/physics_2d/constraint_2d_sw.h +++ b/servers/physics_2d/godot_constraint_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* constraint_2d_sw.h */ +/* godot_constraint_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CONSTRAINT_2D_SW_H -#define CONSTRAINT_2D_SW_H +#ifndef GODOT_CONSTRAINT_2D_H +#define GODOT_CONSTRAINT_2D_H -#include "body_2d_sw.h" +#include "godot_body_2d.h" -class Constraint2DSW { - Body2DSW **_body_ptr; +class GodotConstraint2D { + GodotBody2D **_body_ptr; int _body_count; uint64_t island_step = 0; bool disabled_collisions_between_bodies = true; @@ -42,7 +42,7 @@ class Constraint2DSW { RID self; protected: - Constraint2DSW(Body2DSW **p_body_ptr = nullptr, int p_body_count = 0) { + GodotConstraint2D(GodotBody2D **p_body_ptr = nullptr, int p_body_count = 0) { _body_ptr = p_body_ptr; _body_count = p_body_count; } @@ -54,7 +54,7 @@ public: _FORCE_INLINE_ uint64_t get_island_step() const { return island_step; } _FORCE_INLINE_ void set_island_step(uint64_t p_step) { island_step = p_step; } - _FORCE_INLINE_ Body2DSW **get_body_ptr() const { return _body_ptr; } + _FORCE_INLINE_ GodotBody2D **get_body_ptr() const { return _body_ptr; } _FORCE_INLINE_ int get_body_count() const { return _body_count; } _FORCE_INLINE_ void disable_collisions_between_bodies(const bool p_disabled) { disabled_collisions_between_bodies = p_disabled; } @@ -64,7 +64,7 @@ public: virtual bool pre_solve(real_t p_step) = 0; virtual void solve(real_t p_step) = 0; - virtual ~Constraint2DSW() {} + virtual ~GodotConstraint2D() {} }; -#endif // CONSTRAINT_2D_SW_H +#endif // GODOT_CONSTRAINT_2D_H diff --git a/servers/physics_2d/joints_2d_sw.cpp b/servers/physics_2d/godot_joints_2d.cpp index b46397b8e6..7c08c2f4b4 100644 --- a/servers/physics_2d/joints_2d_sw.cpp +++ b/servers/physics_2d/godot_joints_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* joints_2d_sw.cpp */ +/* godot_joints_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,9 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "joints_2d_sw.h" +#include "godot_joints_2d.h" -#include "space_2d_sw.h" +#include "godot_space_2d.h" //based on chipmunk joint constraints @@ -55,7 +55,7 @@ * SOFTWARE. */ -void Joint2DSW::copy_settings_from(Joint2DSW *p_joint) { +void GodotJoint2D::copy_settings_from(GodotJoint2D *p_joint) { set_self(p_joint->get_self()); set_max_force(p_joint->get_max_force()); set_bias(p_joint->get_bias()); @@ -63,7 +63,7 @@ void Joint2DSW::copy_settings_from(Joint2DSW *p_joint) { disable_collisions_between_bodies(p_joint->is_disabled_collisions_between_bodies()); } -static inline real_t k_scalar(Body2DSW *a, Body2DSW *b, const Vector2 &rA, const Vector2 &rB, const Vector2 &n) { +static inline real_t k_scalar(GodotBody2D *a, GodotBody2D *b, const Vector2 &rA, const Vector2 &rB, const Vector2 &n) { real_t value = 0.0; { @@ -82,7 +82,7 @@ static inline real_t k_scalar(Body2DSW *a, Body2DSW *b, const Vector2 &rA, const } static inline Vector2 -relative_velocity(Body2DSW *a, Body2DSW *b, Vector2 rA, Vector2 rB) { +relative_velocity(GodotBody2D *a, GodotBody2D *b, Vector2 rA, Vector2 rB) { Vector2 sum = a->get_linear_velocity() - (rA - a->get_center_of_mass()).orthogonal() * a->get_angular_velocity(); if (b) { return (b->get_linear_velocity() - (rB - b->get_center_of_mass()).orthogonal() * b->get_angular_velocity()) - sum; @@ -92,11 +92,11 @@ relative_velocity(Body2DSW *a, Body2DSW *b, Vector2 rA, Vector2 rB) { } static inline real_t -normal_relative_velocity(Body2DSW *a, Body2DSW *b, Vector2 rA, Vector2 rB, Vector2 n) { +normal_relative_velocity(GodotBody2D *a, GodotBody2D *b, Vector2 rA, Vector2 rB, Vector2 n) { return relative_velocity(a, b, rA, rB).dot(n); } -bool PinJoint2DSW::setup(real_t p_step) { +bool GodotPinJoint2D::setup(real_t p_step) { dynamic_A = (A->get_mode() > PhysicsServer2D::BODY_MODE_KINEMATIC); dynamic_B = (B->get_mode() > PhysicsServer2D::BODY_MODE_KINEMATIC); @@ -104,7 +104,7 @@ bool PinJoint2DSW::setup(real_t p_step) { return false; } - Space2DSW *space = A->get_space(); + GodotSpace2D *space = A->get_space(); ERR_FAIL_COND_V(!space, false); rA = A->get_transform().basis_xform(anchor_A); @@ -158,7 +158,7 @@ inline Vector2 custom_cross(const Vector2 &p_vec, real_t p_other) { return Vector2(p_other * p_vec.y, -p_other * p_vec.x); } -bool PinJoint2DSW::pre_solve(real_t p_step) { +bool GodotPinJoint2D::pre_solve(real_t p_step) { // Apply accumulated impulse. if (dynamic_A) { A->apply_impulse(-P, rA); @@ -170,7 +170,7 @@ bool PinJoint2DSW::pre_solve(real_t p_step) { return true; } -void PinJoint2DSW::solve(real_t p_step) { +void GodotPinJoint2D::solve(real_t p_step) { // compute relative velocity Vector2 vA = A->get_linear_velocity() - custom_cross(rA - A->get_center_of_mass(), A->get_angular_velocity()); @@ -193,21 +193,21 @@ void PinJoint2DSW::solve(real_t p_step) { P += impulse; } -void PinJoint2DSW::set_param(PhysicsServer2D::PinJointParam p_param, real_t p_value) { +void GodotPinJoint2D::set_param(PhysicsServer2D::PinJointParam p_param, real_t p_value) { if (p_param == PhysicsServer2D::PIN_JOINT_SOFTNESS) { softness = p_value; } } -real_t PinJoint2DSW::get_param(PhysicsServer2D::PinJointParam p_param) const { +real_t GodotPinJoint2D::get_param(PhysicsServer2D::PinJointParam p_param) const { if (p_param == PhysicsServer2D::PIN_JOINT_SOFTNESS) { return softness; } ERR_FAIL_V(0); } -PinJoint2DSW::PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p_body_b) : - Joint2DSW(_arr, p_body_b ? 2 : 1) { +GodotPinJoint2D::GodotPinJoint2D(const Vector2 &p_pos, GodotBody2D *p_body_a, GodotBody2D *p_body_b) : + GodotJoint2D(_arr, p_body_b ? 2 : 1) { A = p_body_a; B = p_body_b; anchor_A = p_body_a->get_inv_transform().xform(p_pos); @@ -224,7 +224,7 @@ PinJoint2DSW::PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p ////////////////////////////////////////////// static inline void -k_tensor(Body2DSW *a, Body2DSW *b, Vector2 r1, Vector2 r2, Vector2 *k1, Vector2 *k2) { +k_tensor(GodotBody2D *a, GodotBody2D *b, Vector2 r1, Vector2 r2, Vector2 *k1, Vector2 *k2) { // calculate mass matrix // If I wasn't lazy and wrote a proper matrix class, this wouldn't be so gross... real_t k11, k12, k21, k22; @@ -273,7 +273,7 @@ mult_k(const Vector2 &vr, const Vector2 &k1, const Vector2 &k2) { return Vector2(vr.dot(k1), vr.dot(k2)); } -bool GrooveJoint2DSW::setup(real_t p_step) { +bool GodotGrooveJoint2D::setup(real_t p_step) { dynamic_A = (A->get_mode() > PhysicsServer2D::BODY_MODE_KINEMATIC); dynamic_B = (B->get_mode() > PhysicsServer2D::BODY_MODE_KINEMATIC); @@ -281,7 +281,7 @@ bool GrooveJoint2DSW::setup(real_t p_step) { return false; } - Space2DSW *space = A->get_space(); + GodotSpace2D *space = A->get_space(); ERR_FAIL_COND_V(!space, false); // calculate endpoints in worldspace @@ -329,7 +329,7 @@ bool GrooveJoint2DSW::setup(real_t p_step) { return true; } -bool GrooveJoint2DSW::pre_solve(real_t p_step) { +bool GodotGrooveJoint2D::pre_solve(real_t p_step) { // Apply accumulated impulse. if (dynamic_A) { A->apply_impulse(-jn_acc, rA); @@ -341,7 +341,7 @@ bool GrooveJoint2DSW::pre_solve(real_t p_step) { return true; } -void GrooveJoint2DSW::solve(real_t p_step) { +void GodotGrooveJoint2D::solve(real_t p_step) { // compute impulse Vector2 vr = relative_velocity(A, B, rA, rB); @@ -361,8 +361,8 @@ void GrooveJoint2DSW::solve(real_t p_step) { } } -GrooveJoint2DSW::GrooveJoint2DSW(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, Body2DSW *p_body_a, Body2DSW *p_body_b) : - Joint2DSW(_arr, 2) { +GodotGrooveJoint2D::GodotGrooveJoint2D(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, GodotBody2D *p_body_a, GodotBody2D *p_body_b) : + GodotJoint2D(_arr, 2) { A = p_body_a; B = p_body_b; @@ -379,7 +379,7 @@ GrooveJoint2DSW::GrooveJoint2DSW(const Vector2 &p_a_groove1, const Vector2 &p_a_ ////////////////////////////////////////////// ////////////////////////////////////////////// -bool DampedSpringJoint2DSW::setup(real_t p_step) { +bool GodotDampedSpringJoint2D::setup(real_t p_step) { dynamic_A = (A->get_mode() > PhysicsServer2D::BODY_MODE_KINEMATIC); dynamic_B = (B->get_mode() > PhysicsServer2D::BODY_MODE_KINEMATIC); @@ -412,7 +412,7 @@ bool DampedSpringJoint2DSW::setup(real_t p_step) { return true; } -bool DampedSpringJoint2DSW::pre_solve(real_t p_step) { +bool GodotDampedSpringJoint2D::pre_solve(real_t p_step) { // Apply spring force. if (dynamic_A) { A->apply_impulse(-j, rA); @@ -424,7 +424,7 @@ bool DampedSpringJoint2DSW::pre_solve(real_t p_step) { return true; } -void DampedSpringJoint2DSW::solve(real_t p_step) { +void GodotDampedSpringJoint2D::solve(real_t p_step) { // compute relative velocity real_t vrn = normal_relative_velocity(A, B, rA, rB, n) - target_vrn; @@ -442,7 +442,7 @@ void DampedSpringJoint2DSW::solve(real_t p_step) { } } -void DampedSpringJoint2DSW::set_param(PhysicsServer2D::DampedSpringParam p_param, real_t p_value) { +void GodotDampedSpringJoint2D::set_param(PhysicsServer2D::DampedSpringParam p_param, real_t p_value) { switch (p_param) { case PhysicsServer2D::DAMPED_SPRING_REST_LENGTH: { rest_length = p_value; @@ -456,7 +456,7 @@ void DampedSpringJoint2DSW::set_param(PhysicsServer2D::DampedSpringParam p_param } } -real_t DampedSpringJoint2DSW::get_param(PhysicsServer2D::DampedSpringParam p_param) const { +real_t GodotDampedSpringJoint2D::get_param(PhysicsServer2D::DampedSpringParam p_param) const { switch (p_param) { case PhysicsServer2D::DAMPED_SPRING_REST_LENGTH: { return rest_length; @@ -472,8 +472,8 @@ real_t DampedSpringJoint2DSW::get_param(PhysicsServer2D::DampedSpringParam p_par ERR_FAIL_V(0); } -DampedSpringJoint2DSW::DampedSpringJoint2DSW(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, Body2DSW *p_body_a, Body2DSW *p_body_b) : - Joint2DSW(_arr, 2) { +GodotDampedSpringJoint2D::GodotDampedSpringJoint2D(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, GodotBody2D *p_body_a, GodotBody2D *p_body_b) : + GodotJoint2D(_arr, 2) { A = p_body_a; B = p_body_b; anchor_A = A->get_inv_transform().xform(p_anchor_a); diff --git a/servers/physics_2d/joints_2d_sw.h b/servers/physics_2d/godot_joints_2d.h index e2a7c0c91e..4c97190d01 100644 --- a/servers/physics_2d/joints_2d_sw.h +++ b/servers/physics_2d/godot_joints_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* joints_2d_sw.h */ +/* godot_joints_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef JOINTS_2D_SW_H -#define JOINTS_2D_SW_H +#ifndef GODOT_JOINTS_2D_H +#define GODOT_JOINTS_2D_H -#include "body_2d_sw.h" -#include "constraint_2d_sw.h" +#include "godot_body_2d.h" +#include "godot_constraint_2d.h" -class Joint2DSW : public Constraint2DSW { +class GodotJoint2D : public GodotConstraint2D { real_t bias = 0; real_t max_bias = 3.40282e+38; real_t max_force = 3.40282e+38; @@ -57,15 +57,15 @@ public: virtual bool pre_solve(real_t p_step) override { return false; } virtual void solve(real_t p_step) override {} - void copy_settings_from(Joint2DSW *p_joint); + void copy_settings_from(GodotJoint2D *p_joint); virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_MAX; } - Joint2DSW(Body2DSW **p_body_ptr = nullptr, int p_body_count = 0) : - Constraint2DSW(p_body_ptr, p_body_count) {} + GodotJoint2D(GodotBody2D **p_body_ptr = nullptr, int p_body_count = 0) : + GodotConstraint2D(p_body_ptr, p_body_count) {} - virtual ~Joint2DSW() { + virtual ~GodotJoint2D() { for (int i = 0; i < get_body_count(); i++) { - Body2DSW *body = get_body_ptr()[i]; + GodotBody2D *body = get_body_ptr()[i]; if (body) { body->remove_constraint(this, i); } @@ -73,14 +73,14 @@ public: }; }; -class PinJoint2DSW : public Joint2DSW { +class GodotPinJoint2D : public GodotJoint2D { union { struct { - Body2DSW *A; - Body2DSW *B; + GodotBody2D *A; + GodotBody2D *B; }; - Body2DSW *_arr[2] = { nullptr, nullptr }; + GodotBody2D *_arr[2] = { nullptr, nullptr }; }; Transform2D M; @@ -101,17 +101,17 @@ public: void set_param(PhysicsServer2D::PinJointParam p_param, real_t p_value); real_t get_param(PhysicsServer2D::PinJointParam p_param) const; - PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p_body_b = nullptr); + GodotPinJoint2D(const Vector2 &p_pos, GodotBody2D *p_body_a, GodotBody2D *p_body_b = nullptr); }; -class GrooveJoint2DSW : public Joint2DSW { +class GodotGrooveJoint2D : public GodotJoint2D { union { struct { - Body2DSW *A; - Body2DSW *B; + GodotBody2D *A; + GodotBody2D *B; }; - Body2DSW *_arr[2] = { nullptr, nullptr }; + GodotBody2D *_arr[2] = { nullptr, nullptr }; }; Vector2 A_groove_1; @@ -135,17 +135,17 @@ public: virtual bool pre_solve(real_t p_step) override; virtual void solve(real_t p_step) override; - GrooveJoint2DSW(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, Body2DSW *p_body_a, Body2DSW *p_body_b); + GodotGrooveJoint2D(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, GodotBody2D *p_body_a, GodotBody2D *p_body_b); }; -class DampedSpringJoint2DSW : public Joint2DSW { +class GodotDampedSpringJoint2D : public GodotJoint2D { union { struct { - Body2DSW *A; - Body2DSW *B; + GodotBody2D *A; + GodotBody2D *B; }; - Body2DSW *_arr[2] = { nullptr, nullptr }; + GodotBody2D *_arr[2] = { nullptr, nullptr }; }; Vector2 anchor_A; @@ -172,7 +172,7 @@ public: void set_param(PhysicsServer2D::DampedSpringParam p_param, real_t p_value); real_t get_param(PhysicsServer2D::DampedSpringParam p_param) const; - DampedSpringJoint2DSW(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, Body2DSW *p_body_a, Body2DSW *p_body_b); + GodotDampedSpringJoint2D(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, GodotBody2D *p_body_a, GodotBody2D *p_body_b); }; -#endif // JOINTS_2D_SW_H +#endif // GODOT_JOINTS_2D_H diff --git a/servers/physics_2d/godot_physics_server_2d.cpp b/servers/physics_2d/godot_physics_server_2d.cpp new file mode 100644 index 0000000000..c86f87fc03 --- /dev/null +++ b/servers/physics_2d/godot_physics_server_2d.cpp @@ -0,0 +1,1350 @@ +/*************************************************************************/ +/* godot_physics_server_2d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "godot_physics_server_2d.h" + +#include "godot_body_direct_state_2d.h" +#include "godot_broad_phase_2d_bvh.h" +#include "godot_collision_solver_2d.h" + +#include "core/config/project_settings.h" +#include "core/debugger/engine_debugger.h" +#include "core/os/os.h" + +#define FLUSH_QUERY_CHECK(m_object) \ + ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead."); + +RID GodotPhysicsServer2D::_shape_create(ShapeType p_shape) { + GodotShape2D *shape = nullptr; + switch (p_shape) { + case SHAPE_WORLD_BOUNDARY: { + shape = memnew(GodotWorldBoundaryShape2D); + } break; + case SHAPE_SEPARATION_RAY: { + shape = memnew(GodotSeparationRayShape2D); + } break; + case SHAPE_SEGMENT: { + shape = memnew(GodotSegmentShape2D); + } break; + case SHAPE_CIRCLE: { + shape = memnew(GodotCircleShape2D); + } break; + case SHAPE_RECTANGLE: { + shape = memnew(GodotRectangleShape2D); + } break; + case SHAPE_CAPSULE: { + shape = memnew(GodotCapsuleShape2D); + } break; + case SHAPE_CONVEX_POLYGON: { + shape = memnew(GodotConvexPolygonShape2D); + } break; + case SHAPE_CONCAVE_POLYGON: { + shape = memnew(GodotConcavePolygonShape2D); + } break; + case SHAPE_CUSTOM: { + ERR_FAIL_V(RID()); + + } break; + } + + RID id = shape_owner.make_rid(shape); + shape->set_self(id); + + return id; +} + +RID GodotPhysicsServer2D::world_boundary_shape_create() { + return _shape_create(SHAPE_WORLD_BOUNDARY); +} + +RID GodotPhysicsServer2D::separation_ray_shape_create() { + return _shape_create(SHAPE_SEPARATION_RAY); +} + +RID GodotPhysicsServer2D::segment_shape_create() { + return _shape_create(SHAPE_SEGMENT); +} + +RID GodotPhysicsServer2D::circle_shape_create() { + return _shape_create(SHAPE_CIRCLE); +} + +RID GodotPhysicsServer2D::rectangle_shape_create() { + return _shape_create(SHAPE_RECTANGLE); +} + +RID GodotPhysicsServer2D::capsule_shape_create() { + return _shape_create(SHAPE_CAPSULE); +} + +RID GodotPhysicsServer2D::convex_polygon_shape_create() { + return _shape_create(SHAPE_CONVEX_POLYGON); +} + +RID GodotPhysicsServer2D::concave_polygon_shape_create() { + return _shape_create(SHAPE_CONCAVE_POLYGON); +} + +void GodotPhysicsServer2D::shape_set_data(RID p_shape, const Variant &p_data) { + GodotShape2D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND(!shape); + shape->set_data(p_data); +}; + +void GodotPhysicsServer2D::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) { + GodotShape2D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND(!shape); + shape->set_custom_bias(p_bias); +} + +PhysicsServer2D::ShapeType GodotPhysicsServer2D::shape_get_type(RID p_shape) const { + const GodotShape2D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND_V(!shape, SHAPE_CUSTOM); + return shape->get_type(); +}; + +Variant GodotPhysicsServer2D::shape_get_data(RID p_shape) const { + const GodotShape2D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND_V(!shape, Variant()); + ERR_FAIL_COND_V(!shape->is_configured(), Variant()); + return shape->get_data(); +}; + +real_t GodotPhysicsServer2D::shape_get_custom_solver_bias(RID p_shape) const { + const GodotShape2D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND_V(!shape, 0); + return shape->get_custom_bias(); +} + +void GodotPhysicsServer2D::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_userdata) { + CollCbkData *cbk = (CollCbkData *)p_userdata; + + if (cbk->max == 0) { + return; + } + + Vector2 rel_dir = (p_point_A - p_point_B); + real_t rel_length2 = rel_dir.length_squared(); + if (cbk->valid_dir != Vector2()) { + if (cbk->valid_depth < 10e20) { + if (rel_length2 > cbk->valid_depth * cbk->valid_depth || + (rel_length2 > CMP_EPSILON && cbk->valid_dir.dot(rel_dir.normalized()) < CMP_EPSILON)) { + cbk->invalid_by_dir++; + return; + } + } else { + if (rel_length2 > 0 && cbk->valid_dir.dot(rel_dir.normalized()) < CMP_EPSILON) { + return; + } + } + } + + if (cbk->amount == cbk->max) { + //find least deep + real_t min_depth = 1e20; + int min_depth_idx = 0; + for (int i = 0; i < cbk->amount; i++) { + real_t d = cbk->ptr[i * 2 + 0].distance_squared_to(cbk->ptr[i * 2 + 1]); + if (d < min_depth) { + min_depth = d; + min_depth_idx = i; + } + } + + if (rel_length2 < min_depth) { + return; + } + cbk->ptr[min_depth_idx * 2 + 0] = p_point_A; + cbk->ptr[min_depth_idx * 2 + 1] = p_point_B; + cbk->passed++; + + } else { + cbk->ptr[cbk->amount * 2 + 0] = p_point_A; + cbk->ptr[cbk->amount * 2 + 1] = p_point_B; + cbk->amount++; + cbk->passed++; + } +} + +bool GodotPhysicsServer2D::shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) { + GodotShape2D *shape_A = shape_owner.get_or_null(p_shape_A); + ERR_FAIL_COND_V(!shape_A, false); + GodotShape2D *shape_B = shape_owner.get_or_null(p_shape_B); + ERR_FAIL_COND_V(!shape_B, false); + + if (p_result_max == 0) { + return GodotCollisionSolver2D::solve(shape_A, p_xform_A, p_motion_A, shape_B, p_xform_B, p_motion_B, nullptr, nullptr); + } + + CollCbkData cbk; + cbk.max = p_result_max; + cbk.amount = 0; + cbk.passed = 0; + cbk.ptr = r_results; + + bool res = GodotCollisionSolver2D::solve(shape_A, p_xform_A, p_motion_A, shape_B, p_xform_B, p_motion_B, _shape_col_cbk, &cbk); + r_result_count = cbk.amount; + return res; +} + +RID GodotPhysicsServer2D::space_create() { + GodotSpace2D *space = memnew(GodotSpace2D); + RID id = space_owner.make_rid(space); + space->set_self(id); + RID area_id = area_create(); + GodotArea2D *area = area_owner.get_or_null(area_id); + ERR_FAIL_COND_V(!area, RID()); + space->set_default_area(area); + area->set_space(space); + area->set_priority(-1); + + return id; +}; + +void GodotPhysicsServer2D::space_set_active(RID p_space, bool p_active) { + GodotSpace2D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND(!space); + if (p_active) { + active_spaces.insert(space); + } else { + active_spaces.erase(space); + } +} + +bool GodotPhysicsServer2D::space_is_active(RID p_space) const { + const GodotSpace2D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND_V(!space, false); + + return active_spaces.has(space); +} + +void GodotPhysicsServer2D::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) { + GodotSpace2D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND(!space); + + space->set_param(p_param, p_value); +} + +real_t GodotPhysicsServer2D::space_get_param(RID p_space, SpaceParameter p_param) const { + const GodotSpace2D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND_V(!space, 0); + return space->get_param(p_param); +} + +void GodotPhysicsServer2D::space_set_debug_contacts(RID p_space, int p_max_contacts) { + GodotSpace2D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND(!space); + space->set_debug_contacts(p_max_contacts); +} + +Vector<Vector2> GodotPhysicsServer2D::space_get_contacts(RID p_space) const { + GodotSpace2D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND_V(!space, Vector<Vector2>()); + return space->get_debug_contacts(); +} + +int GodotPhysicsServer2D::space_get_contact_count(RID p_space) const { + GodotSpace2D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND_V(!space, 0); + return space->get_debug_contact_count(); +} + +PhysicsDirectSpaceState2D *GodotPhysicsServer2D::space_get_direct_state(RID p_space) { + GodotSpace2D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND_V(!space, nullptr); + ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); + + return space->get_direct_state(); +} + +RID GodotPhysicsServer2D::area_create() { + GodotArea2D *area = memnew(GodotArea2D); + RID rid = area_owner.make_rid(area); + area->set_self(rid); + return rid; +}; + +void GodotPhysicsServer2D::area_set_space(RID p_area, RID p_space) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + GodotSpace2D *space = nullptr; + if (p_space.is_valid()) { + space = space_owner.get_or_null(p_space); + ERR_FAIL_COND(!space); + } + + if (area->get_space() == space) { + return; //pointless + } + + area->clear_constraints(); + area->set_space(space); +}; + +RID GodotPhysicsServer2D::area_get_space(RID p_area) const { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, RID()); + + GodotSpace2D *space = area->get_space(); + if (!space) { + return RID(); + } + return space->get_self(); +}; + +void GodotPhysicsServer2D::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_space_override_mode(p_mode); +} + +PhysicsServer2D::AreaSpaceOverrideMode GodotPhysicsServer2D::area_get_space_override_mode(RID p_area) const { + const GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, AREA_SPACE_OVERRIDE_DISABLED); + + return area->get_space_override_mode(); +} + +void GodotPhysicsServer2D::area_add_shape(RID p_area, RID p_shape, const Transform2D &p_transform, bool p_disabled) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + GodotShape2D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND(!shape); + + area->add_shape(shape, p_transform, p_disabled); +} + +void GodotPhysicsServer2D::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + GodotShape2D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND(!shape); + ERR_FAIL_COND(!shape->is_configured()); + + area->set_shape(p_shape_idx, shape); +} + +void GodotPhysicsServer2D::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform2D &p_transform) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_shape_transform(p_shape_idx, p_transform); +} + +void GodotPhysicsServer2D::area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + ERR_FAIL_INDEX(p_shape, area->get_shape_count()); + FLUSH_QUERY_CHECK(area); + + area->set_shape_disabled(p_shape, p_disabled); +} + +int GodotPhysicsServer2D::area_get_shape_count(RID p_area) const { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, -1); + + return area->get_shape_count(); +} + +RID GodotPhysicsServer2D::area_get_shape(RID p_area, int p_shape_idx) const { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, RID()); + + GodotShape2D *shape = area->get_shape(p_shape_idx); + ERR_FAIL_COND_V(!shape, RID()); + + return shape->get_self(); +} + +Transform2D GodotPhysicsServer2D::area_get_shape_transform(RID p_area, int p_shape_idx) const { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, Transform2D()); + + return area->get_shape_transform(p_shape_idx); +} + +void GodotPhysicsServer2D::area_remove_shape(RID p_area, int p_shape_idx) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->remove_shape(p_shape_idx); +} + +void GodotPhysicsServer2D::area_clear_shapes(RID p_area) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + while (area->get_shape_count()) { + area->remove_shape(0); + } +} + +void GodotPhysicsServer2D::area_attach_object_instance_id(RID p_area, ObjectID p_id) { + if (space_owner.owns(p_area)) { + GodotSpace2D *space = space_owner.get_or_null(p_area); + p_area = space->get_default_area()->get_self(); + } + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + area->set_instance_id(p_id); +} + +ObjectID GodotPhysicsServer2D::area_get_object_instance_id(RID p_area) const { + if (space_owner.owns(p_area)) { + GodotSpace2D *space = space_owner.get_or_null(p_area); + p_area = space->get_default_area()->get_self(); + } + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, ObjectID()); + return area->get_instance_id(); +} + +void GodotPhysicsServer2D::area_attach_canvas_instance_id(RID p_area, ObjectID p_id) { + if (space_owner.owns(p_area)) { + GodotSpace2D *space = space_owner.get_or_null(p_area); + p_area = space->get_default_area()->get_self(); + } + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + area->set_canvas_instance_id(p_id); +} + +ObjectID GodotPhysicsServer2D::area_get_canvas_instance_id(RID p_area) const { + if (space_owner.owns(p_area)) { + GodotSpace2D *space = space_owner.get_or_null(p_area); + p_area = space->get_default_area()->get_self(); + } + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, ObjectID()); + return area->get_canvas_instance_id(); +} + +void GodotPhysicsServer2D::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) { + if (space_owner.owns(p_area)) { + GodotSpace2D *space = space_owner.get_or_null(p_area); + p_area = space->get_default_area()->get_self(); + } + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + area->set_param(p_param, p_value); +}; + +void GodotPhysicsServer2D::area_set_transform(RID p_area, const Transform2D &p_transform) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + area->set_transform(p_transform); +}; + +Variant GodotPhysicsServer2D::area_get_param(RID p_area, AreaParameter p_param) const { + if (space_owner.owns(p_area)) { + GodotSpace2D *space = space_owner.get_or_null(p_area); + p_area = space->get_default_area()->get_self(); + } + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, Variant()); + + return area->get_param(p_param); +}; + +Transform2D GodotPhysicsServer2D::area_get_transform(RID p_area) const { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, Transform2D()); + + return area->get_transform(); +}; + +void GodotPhysicsServer2D::area_set_pickable(RID p_area, bool p_pickable) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + area->set_pickable(p_pickable); +} + +void GodotPhysicsServer2D::area_set_monitorable(RID p_area, bool p_monitorable) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + FLUSH_QUERY_CHECK(area); + + area->set_monitorable(p_monitorable); +} + +void GodotPhysicsServer2D::area_set_collision_mask(RID p_area, uint32_t p_mask) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_collision_mask(p_mask); +} + +void GodotPhysicsServer2D::area_set_collision_layer(RID p_area, uint32_t p_layer) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_collision_layer(p_layer); +} + +void GodotPhysicsServer2D::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); +} + +void GodotPhysicsServer2D::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); +} + +/* BODY API */ + +RID GodotPhysicsServer2D::body_create() { + GodotBody2D *body = memnew(GodotBody2D); + RID rid = body_owner.make_rid(body); + body->set_self(rid); + return rid; +} + +void GodotPhysicsServer2D::body_set_space(RID p_body, RID p_space) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + GodotSpace2D *space = nullptr; + if (p_space.is_valid()) { + space = space_owner.get_or_null(p_space); + ERR_FAIL_COND(!space); + } + + if (body->get_space() == space) { + return; //pointless + } + + body->clear_constraint_list(); + body->set_space(space); +}; + +RID GodotPhysicsServer2D::body_get_space(RID p_body) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, RID()); + + GodotSpace2D *space = body->get_space(); + if (!space) { + return RID(); + } + return space->get_self(); +}; + +void GodotPhysicsServer2D::body_set_mode(RID p_body, BodyMode p_mode) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + FLUSH_QUERY_CHECK(body); + + body->set_mode(p_mode); +}; + +PhysicsServer2D::BodyMode GodotPhysicsServer2D::body_get_mode(RID p_body) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, BODY_MODE_STATIC); + + return body->get_mode(); +}; + +void GodotPhysicsServer2D::body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform, bool p_disabled) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + GodotShape2D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND(!shape); + + body->add_shape(shape, p_transform, p_disabled); +} + +void GodotPhysicsServer2D::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + GodotShape2D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND(!shape); + ERR_FAIL_COND(!shape->is_configured()); + + body->set_shape(p_shape_idx, shape); +} + +void GodotPhysicsServer2D::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform2D &p_transform) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_shape_transform(p_shape_idx, p_transform); +} + +int GodotPhysicsServer2D::body_get_shape_count(RID p_body) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, -1); + + return body->get_shape_count(); +} + +RID GodotPhysicsServer2D::body_get_shape(RID p_body, int p_shape_idx) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, RID()); + + GodotShape2D *shape = body->get_shape(p_shape_idx); + ERR_FAIL_COND_V(!shape, RID()); + + return shape->get_self(); +} + +Transform2D GodotPhysicsServer2D::body_get_shape_transform(RID p_body, int p_shape_idx) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, Transform2D()); + + return body->get_shape_transform(p_shape_idx); +} + +void GodotPhysicsServer2D::body_remove_shape(RID p_body, int p_shape_idx) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->remove_shape(p_shape_idx); +} + +void GodotPhysicsServer2D::body_clear_shapes(RID p_body) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + while (body->get_shape_count()) { + body->remove_shape(0); + } +} + +void GodotPhysicsServer2D::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); + FLUSH_QUERY_CHECK(body); + + body->set_shape_disabled(p_shape_idx, p_disabled); +} + +void GodotPhysicsServer2D::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); + FLUSH_QUERY_CHECK(body); + + body->set_shape_as_one_way_collision(p_shape_idx, p_enable, p_margin); +} + +void GodotPhysicsServer2D::body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + body->set_continuous_collision_detection_mode(p_mode); +} + +GodotPhysicsServer2D::CCDMode GodotPhysicsServer2D::body_get_continuous_collision_detection_mode(RID p_body) const { + const GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, CCD_MODE_DISABLED); + + return body->get_continuous_collision_detection_mode(); +} + +void GodotPhysicsServer2D::body_attach_object_instance_id(RID p_body, ObjectID p_id) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_instance_id(p_id); +}; + +ObjectID GodotPhysicsServer2D::body_get_object_instance_id(RID p_body) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, ObjectID()); + + return body->get_instance_id(); +}; + +void GodotPhysicsServer2D::body_attach_canvas_instance_id(RID p_body, ObjectID p_id) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_canvas_instance_id(p_id); +}; + +ObjectID GodotPhysicsServer2D::body_get_canvas_instance_id(RID p_body) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, ObjectID()); + + return body->get_canvas_instance_id(); +}; + +void GodotPhysicsServer2D::body_set_collision_layer(RID p_body, uint32_t p_layer) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + body->set_collision_layer(p_layer); +}; + +uint32_t GodotPhysicsServer2D::body_get_collision_layer(RID p_body) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, 0); + + return body->get_collision_layer(); +}; + +void GodotPhysicsServer2D::body_set_collision_mask(RID p_body, uint32_t p_mask) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + body->set_collision_mask(p_mask); +}; + +uint32_t GodotPhysicsServer2D::body_get_collision_mask(RID p_body) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, 0); + + return body->get_collision_mask(); +}; + +void GodotPhysicsServer2D::body_set_param(RID p_body, BodyParameter p_param, const Variant &p_value) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_param(p_param, p_value); +}; + +Variant GodotPhysicsServer2D::body_get_param(RID p_body, BodyParameter p_param) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, 0); + + return body->get_param(p_param); +}; + +void GodotPhysicsServer2D::body_reset_mass_properties(RID p_body) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + return body->reset_mass_properties(); +} + +void GodotPhysicsServer2D::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_state(p_state, p_variant); +}; + +Variant GodotPhysicsServer2D::body_get_state(RID p_body, BodyState p_state) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, Variant()); + + return body->get_state(p_state); +}; + +void GodotPhysicsServer2D::body_set_applied_force(RID p_body, const Vector2 &p_force) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_applied_force(p_force); + body->wakeup(); +}; + +Vector2 GodotPhysicsServer2D::body_get_applied_force(RID p_body) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, Vector2()); + return body->get_applied_force(); +}; + +void GodotPhysicsServer2D::body_set_applied_torque(RID p_body, real_t p_torque) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_applied_torque(p_torque); + body->wakeup(); +}; + +real_t GodotPhysicsServer2D::body_get_applied_torque(RID p_body) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, 0); + + return body->get_applied_torque(); +}; + +void GodotPhysicsServer2D::body_apply_central_impulse(RID p_body, const Vector2 &p_impulse) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->apply_central_impulse(p_impulse); + body->wakeup(); +} + +void GodotPhysicsServer2D::body_apply_torque_impulse(RID p_body, real_t p_torque) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + _update_shapes(); + + body->apply_torque_impulse(p_torque); + body->wakeup(); +} + +void GodotPhysicsServer2D::body_apply_impulse(RID p_body, const Vector2 &p_impulse, const Vector2 &p_position) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + _update_shapes(); + + body->apply_impulse(p_impulse, p_position); + body->wakeup(); +}; + +void GodotPhysicsServer2D::body_add_central_force(RID p_body, const Vector2 &p_force) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->add_central_force(p_force); + body->wakeup(); +}; + +void GodotPhysicsServer2D::body_add_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->add_force(p_force, p_position); + body->wakeup(); +}; + +void GodotPhysicsServer2D::body_add_torque(RID p_body, real_t p_torque) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->add_torque(p_torque); + body->wakeup(); +}; + +void GodotPhysicsServer2D::body_set_axis_velocity(RID p_body, const Vector2 &p_axis_velocity) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + _update_shapes(); + + Vector2 v = body->get_linear_velocity(); + Vector2 axis = p_axis_velocity.normalized(); + v -= axis * axis.dot(v); + v += p_axis_velocity; + body->set_linear_velocity(v); + body->wakeup(); +}; + +void GodotPhysicsServer2D::body_add_collision_exception(RID p_body, RID p_body_b) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->add_exception(p_body_b); + body->wakeup(); +}; + +void GodotPhysicsServer2D::body_remove_collision_exception(RID p_body, RID p_body_b) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->remove_exception(p_body_b); + body->wakeup(); +}; + +void GodotPhysicsServer2D::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + for (int i = 0; i < body->get_exceptions().size(); i++) { + p_exceptions->push_back(body->get_exceptions()[i]); + } +}; + +void GodotPhysicsServer2D::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); +}; + +real_t GodotPhysicsServer2D::body_get_contacts_reported_depth_threshold(RID p_body) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, 0); + return 0; +}; + +void GodotPhysicsServer2D::body_set_omit_force_integration(RID p_body, bool p_omit) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_omit_force_integration(p_omit); +}; + +bool GodotPhysicsServer2D::body_is_omitting_force_integration(RID p_body) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, false); + return body->get_omit_force_integration(); +}; + +void GodotPhysicsServer2D::body_set_max_contacts_reported(RID p_body, int p_contacts) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + body->set_max_contacts_reported(p_contacts); +} + +int GodotPhysicsServer2D::body_get_max_contacts_reported(RID p_body) const { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, -1); + return body->get_max_contacts_reported(); +} + +void GodotPhysicsServer2D::body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + body->set_state_sync_callback(p_instance, p_callback); +} + +void GodotPhysicsServer2D::body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + body->set_force_integration_callback(p_callable, p_udata); +} + +bool GodotPhysicsServer2D::body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, false); + ERR_FAIL_INDEX_V(p_body_shape, body->get_shape_count(), false); + + return shape_collide(body->get_shape(p_body_shape)->get_self(), body->get_transform() * body->get_shape_transform(p_body_shape), Vector2(), p_shape, p_shape_xform, p_motion, r_results, p_result_max, r_result_count); +} + +void GodotPhysicsServer2D::body_set_pickable(RID p_body, bool p_pickable) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + body->set_pickable(p_pickable); +} + +bool GodotPhysicsServer2D::body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result) { + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, false); + ERR_FAIL_COND_V(!body->get_space(), false); + ERR_FAIL_COND_V(body->get_space()->is_locked(), false); + + _update_shapes(); + + return body->get_space()->test_body_motion(body, p_parameters, r_result); +} + +PhysicsDirectBodyState2D *GodotPhysicsServer2D::body_get_direct_state(RID p_body) { + ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); + + GodotBody2D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, nullptr); + + ERR_FAIL_COND_V(!body->get_space(), nullptr); + ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); + + return body->get_direct_state(); +} + +/* JOINT API */ + +RID GodotPhysicsServer2D::joint_create() { + GodotJoint2D *joint = memnew(GodotJoint2D); + RID joint_rid = joint_owner.make_rid(joint); + joint->set_self(joint_rid); + return joint_rid; +} + +void GodotPhysicsServer2D::joint_clear(RID p_joint) { + GodotJoint2D *joint = joint_owner.get_or_null(p_joint); + if (joint->get_type() != JOINT_TYPE_MAX) { + GodotJoint2D *empty_joint = memnew(GodotJoint2D); + empty_joint->copy_settings_from(joint); + + joint_owner.replace(p_joint, empty_joint); + memdelete(joint); + } +} + +void GodotPhysicsServer2D::joint_set_param(RID p_joint, JointParam p_param, real_t p_value) { + GodotJoint2D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!joint); + + switch (p_param) { + case JOINT_PARAM_BIAS: + joint->set_bias(p_value); + break; + case JOINT_PARAM_MAX_BIAS: + joint->set_max_bias(p_value); + break; + case JOINT_PARAM_MAX_FORCE: + joint->set_max_force(p_value); + break; + } +} + +real_t GodotPhysicsServer2D::joint_get_param(RID p_joint, JointParam p_param) const { + const GodotJoint2D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, -1); + + switch (p_param) { + case JOINT_PARAM_BIAS: + return joint->get_bias(); + break; + case JOINT_PARAM_MAX_BIAS: + return joint->get_max_bias(); + break; + case JOINT_PARAM_MAX_FORCE: + return joint->get_max_force(); + break; + } + + return 0; +} + +void GodotPhysicsServer2D::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) { + GodotJoint2D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!joint); + + joint->disable_collisions_between_bodies(p_disable); + + if (2 == joint->get_body_count()) { + GodotBody2D *body_a = *joint->get_body_ptr(); + GodotBody2D *body_b = *(joint->get_body_ptr() + 1); + + if (p_disable) { + body_add_collision_exception(body_a->get_self(), body_b->get_self()); + body_add_collision_exception(body_b->get_self(), body_a->get_self()); + } else { + body_remove_collision_exception(body_a->get_self(), body_b->get_self()); + body_remove_collision_exception(body_b->get_self(), body_a->get_self()); + } + } +} + +bool GodotPhysicsServer2D::joint_is_disabled_collisions_between_bodies(RID p_joint) const { + const GodotJoint2D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, true); + + return joint->is_disabled_collisions_between_bodies(); +} + +void GodotPhysicsServer2D::joint_make_pin(RID p_joint, const Vector2 &p_pos, RID p_body_a, RID p_body_b) { + GodotBody2D *A = body_owner.get_or_null(p_body_a); + ERR_FAIL_COND(!A); + GodotBody2D *B = nullptr; + if (body_owner.owns(p_body_b)) { + B = body_owner.get_or_null(p_body_b); + ERR_FAIL_COND(!B); + } + + GodotJoint2D *prev_joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); + + GodotJoint2D *joint = memnew(GodotPinJoint2D(p_pos, A, B)); + + joint_owner.replace(p_joint, joint); + joint->copy_settings_from(prev_joint); + memdelete(prev_joint); +} + +void GodotPhysicsServer2D::joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) { + GodotBody2D *A = body_owner.get_or_null(p_body_a); + ERR_FAIL_COND(!A); + + GodotBody2D *B = body_owner.get_or_null(p_body_b); + ERR_FAIL_COND(!B); + + GodotJoint2D *prev_joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); + + GodotJoint2D *joint = memnew(GodotGrooveJoint2D(p_a_groove1, p_a_groove2, p_b_anchor, A, B)); + + joint_owner.replace(p_joint, joint); + joint->copy_settings_from(prev_joint); + memdelete(prev_joint); +} + +void GodotPhysicsServer2D::joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b) { + GodotBody2D *A = body_owner.get_or_null(p_body_a); + ERR_FAIL_COND(!A); + + GodotBody2D *B = body_owner.get_or_null(p_body_b); + ERR_FAIL_COND(!B); + + GodotJoint2D *prev_joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); + + GodotJoint2D *joint = memnew(GodotDampedSpringJoint2D(p_anchor_a, p_anchor_b, A, B)); + + joint_owner.replace(p_joint, joint); + joint->copy_settings_from(prev_joint); + memdelete(prev_joint); +} + +void GodotPhysicsServer2D::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { + GodotJoint2D *j = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!j); + ERR_FAIL_COND(j->get_type() != JOINT_TYPE_PIN); + + GodotPinJoint2D *pin_joint = static_cast<GodotPinJoint2D *>(j); + pin_joint->set_param(p_param, p_value); +} + +real_t GodotPhysicsServer2D::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { + GodotJoint2D *j = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!j, 0); + ERR_FAIL_COND_V(j->get_type() != JOINT_TYPE_PIN, 0); + + GodotPinJoint2D *pin_joint = static_cast<GodotPinJoint2D *>(j); + return pin_joint->get_param(p_param); +} + +void GodotPhysicsServer2D::damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value) { + GodotJoint2D *j = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!j); + ERR_FAIL_COND(j->get_type() != JOINT_TYPE_DAMPED_SPRING); + + GodotDampedSpringJoint2D *dsj = static_cast<GodotDampedSpringJoint2D *>(j); + dsj->set_param(p_param, p_value); +} + +real_t GodotPhysicsServer2D::damped_spring_joint_get_param(RID p_joint, DampedSpringParam p_param) const { + GodotJoint2D *j = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!j, 0); + ERR_FAIL_COND_V(j->get_type() != JOINT_TYPE_DAMPED_SPRING, 0); + + GodotDampedSpringJoint2D *dsj = static_cast<GodotDampedSpringJoint2D *>(j); + return dsj->get_param(p_param); +} + +PhysicsServer2D::JointType GodotPhysicsServer2D::joint_get_type(RID p_joint) const { + GodotJoint2D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, JOINT_TYPE_PIN); + + return joint->get_type(); +} + +void GodotPhysicsServer2D::free(RID p_rid) { + _update_shapes(); // just in case + + if (shape_owner.owns(p_rid)) { + GodotShape2D *shape = shape_owner.get_or_null(p_rid); + + while (shape->get_owners().size()) { + GodotShapeOwner2D *so = shape->get_owners().front()->key(); + so->remove_shape(shape); + } + + shape_owner.free(p_rid); + memdelete(shape); + } else if (body_owner.owns(p_rid)) { + GodotBody2D *body = body_owner.get_or_null(p_rid); + + /* + if (body->get_state_query()) + _clear_query(body->get_state_query()); + + if (body->get_direct_state_query()) + _clear_query(body->get_direct_state_query()); + */ + + body_set_space(p_rid, RID()); + + while (body->get_shape_count()) { + body->remove_shape(0); + } + + body_owner.free(p_rid); + memdelete(body); + + } else if (area_owner.owns(p_rid)) { + GodotArea2D *area = area_owner.get_or_null(p_rid); + + /* + if (area->get_monitor_query()) + _clear_query(area->get_monitor_query()); + */ + + area->set_space(nullptr); + + while (area->get_shape_count()) { + area->remove_shape(0); + } + + area_owner.free(p_rid); + memdelete(area); + } else if (space_owner.owns(p_rid)) { + GodotSpace2D *space = space_owner.get_or_null(p_rid); + + while (space->get_objects().size()) { + GodotCollisionObject2D *co = (GodotCollisionObject2D *)space->get_objects().front()->get(); + co->set_space(nullptr); + } + + active_spaces.erase(space); + free(space->get_default_area()->get_self()); + space_owner.free(p_rid); + memdelete(space); + } else if (joint_owner.owns(p_rid)) { + GodotJoint2D *joint = joint_owner.get_or_null(p_rid); + + joint_owner.free(p_rid); + memdelete(joint); + + } else { + ERR_FAIL_MSG("Invalid ID."); + } +}; + +void GodotPhysicsServer2D::set_active(bool p_active) { + active = p_active; +}; + +void GodotPhysicsServer2D::set_collision_iterations(int p_iterations) { + iterations = p_iterations; +}; + +void GodotPhysicsServer2D::init() { + doing_sync = false; + iterations = 8; // 8? + stepper = memnew(GodotStep2D); +}; + +void GodotPhysicsServer2D::step(real_t p_step) { + if (!active) { + return; + } + + _update_shapes(); + + island_count = 0; + active_objects = 0; + collision_pairs = 0; + for (Set<const GodotSpace2D *>::Element *E = active_spaces.front(); E; E = E->next()) { + stepper->step((GodotSpace2D *)E->get(), p_step, iterations); + island_count += E->get()->get_island_count(); + active_objects += E->get()->get_active_objects(); + collision_pairs += E->get()->get_collision_pairs(); + } +}; + +void GodotPhysicsServer2D::sync() { + doing_sync = true; +}; + +void GodotPhysicsServer2D::flush_queries() { + if (!active) { + return; + } + + flushing_queries = true; + + uint64_t time_beg = OS::get_singleton()->get_ticks_usec(); + + for (Set<const GodotSpace2D *>::Element *E = active_spaces.front(); E; E = E->next()) { + GodotSpace2D *space = (GodotSpace2D *)E->get(); + space->call_queries(); + } + + flushing_queries = false; + + if (EngineDebugger::is_profiling("servers")) { + uint64_t total_time[GodotSpace2D::ELAPSED_TIME_MAX]; + static const char *time_name[GodotSpace2D::ELAPSED_TIME_MAX] = { + "integrate_forces", + "generate_islands", + "setup_constraints", + "solve_constraints", + "integrate_velocities" + }; + + for (int i = 0; i < GodotSpace2D::ELAPSED_TIME_MAX; i++) { + total_time[i] = 0; + } + + for (Set<const GodotSpace2D *>::Element *E = active_spaces.front(); E; E = E->next()) { + for (int i = 0; i < GodotSpace2D::ELAPSED_TIME_MAX; i++) { + total_time[i] += E->get()->get_elapsed_time(GodotSpace2D::ElapsedTime(i)); + } + } + + Array values; + values.resize(GodotSpace2D::ELAPSED_TIME_MAX * 2); + for (int i = 0; i < GodotSpace2D::ELAPSED_TIME_MAX; i++) { + values[i * 2 + 0] = time_name[i]; + values[i * 2 + 1] = USEC_TO_SEC(total_time[i]); + } + values.push_back("flush_queries"); + values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg)); + + values.push_front("physics_2d"); + EngineDebugger::profiler_add_frame_data("servers", values); + } +} + +void GodotPhysicsServer2D::end_sync() { + doing_sync = false; +} + +void GodotPhysicsServer2D::finish() { + memdelete(stepper); +}; + +void GodotPhysicsServer2D::_update_shapes() { + while (pending_shape_update_list.first()) { + pending_shape_update_list.first()->self()->_shape_changed(); + pending_shape_update_list.remove(pending_shape_update_list.first()); + } +} + +int GodotPhysicsServer2D::get_process_info(ProcessInfo p_info) { + switch (p_info) { + case INFO_ACTIVE_OBJECTS: { + return active_objects; + } break; + case INFO_COLLISION_PAIRS: { + return collision_pairs; + } break; + case INFO_ISLAND_COUNT: { + return island_count; + } break; + } + + return 0; +} + +GodotPhysicsServer2D *GodotPhysicsServer2D::godot_singleton = nullptr; + +GodotPhysicsServer2D::GodotPhysicsServer2D(bool p_using_threads) { + godot_singleton = this; + GodotBroadPhase2D::create_func = GodotBroadPhase2DBVH::_create; + + using_threads = p_using_threads; +}; diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/godot_physics_server_2d.h index b8e375a087..a8a1e71d13 100644 --- a/servers/physics_2d/physics_server_2d_sw.h +++ b/servers/physics_2d/godot_physics_server_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* physics_server_2d_sw.h */ +/* godot_physics_server_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,21 +28,22 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PHYSICS_2D_SERVER_SW -#define PHYSICS_2D_SERVER_SW +#ifndef GODOT_PHYSICS_SERVER_2D_H +#define GODOT_PHYSICS_SERVER_2D_H + +#include "godot_joints_2d.h" +#include "godot_shape_2d.h" +#include "godot_space_2d.h" +#include "godot_step_2d.h" #include "core/templates/rid_owner.h" -#include "joints_2d_sw.h" #include "servers/physics_server_2d.h" -#include "shape_2d_sw.h" -#include "space_2d_sw.h" -#include "step_2d_sw.h" -class PhysicsServer2DSW : public PhysicsServer2D { - GDCLASS(PhysicsServer2DSW, PhysicsServer2D); +class GodotPhysicsServer2D : public PhysicsServer2D { + GDCLASS(GodotPhysicsServer2D, PhysicsServer2D); - friend class PhysicsDirectSpaceState2DSW; - friend class PhysicsDirectBodyState2DSW; + friend class GodotPhysicsDirectSpaceState2D; + friend class GodotPhysicsDirectBodyState2D; bool active = true; int iterations = 0; bool doing_sync = false; @@ -55,20 +56,19 @@ class PhysicsServer2DSW : public PhysicsServer2D { bool flushing_queries = false; - Step2DSW *stepper = nullptr; - Set<const Space2DSW *> active_spaces; + GodotStep2D *stepper = nullptr; + Set<const GodotSpace2D *> active_spaces; - mutable RID_PtrOwner<Shape2DSW, true> shape_owner; - mutable RID_PtrOwner<Space2DSW, true> space_owner; - mutable RID_PtrOwner<Area2DSW, true> area_owner; - mutable RID_PtrOwner<Body2DSW, true> body_owner; - mutable RID_PtrOwner<Joint2DSW, true> joint_owner; + mutable RID_PtrOwner<GodotShape2D, true> shape_owner; + mutable RID_PtrOwner<GodotSpace2D, true> space_owner; + mutable RID_PtrOwner<GodotArea2D, true> area_owner; + mutable RID_PtrOwner<GodotBody2D, true> body_owner; + mutable RID_PtrOwner<GodotJoint2D, true> joint_owner; - static PhysicsServer2DSW *singletonsw; + static GodotPhysicsServer2D *godot_singleton; - //void _clear_query(Query2DSW *p_query); - friend class CollisionObject2DSW; - SelfList<CollisionObject2DSW>::List pending_shape_update_list; + friend class GodotCollisionObject2D; + SelfList<GodotCollisionObject2D>::List pending_shape_update_list; void _update_shapes(); RID _shape_create(ShapeType p_shape); @@ -292,8 +292,8 @@ public: int get_process_info(ProcessInfo p_info) override; - PhysicsServer2DSW(bool p_using_threads = false); - ~PhysicsServer2DSW() {} + GodotPhysicsServer2D(bool p_using_threads = false); + ~GodotPhysicsServer2D() {} }; -#endif +#endif // GODOT_PHYSICS_SERVER_2D_H diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/godot_shape_2d.cpp index bde882ac24..3604004324 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/godot_shape_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* shape_2d_sw.cpp */ +/* godot_shape_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,29 +28,29 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "shape_2d_sw.h" +#include "godot_shape_2d.h" #include "core/math/geometry_2d.h" #include "core/templates/sort_array.h" -void Shape2DSW::configure(const Rect2 &p_aabb) { +void GodotShape2D::configure(const Rect2 &p_aabb) { aabb = p_aabb; configured = true; - for (const KeyValue<ShapeOwner2DSW *, int> &E : owners) { - ShapeOwner2DSW *co = (ShapeOwner2DSW *)E.key; + for (const KeyValue<GodotShapeOwner2D *, int> &E : owners) { + GodotShapeOwner2D *co = (GodotShapeOwner2D *)E.key; co->_shape_changed(); } } -Vector2 Shape2DSW::get_support(const Vector2 &p_normal) const { +Vector2 GodotShape2D::get_support(const Vector2 &p_normal) const { Vector2 res[2]; int amnt; get_supports(p_normal, res, amnt); return res[0]; } -void Shape2DSW::add_owner(ShapeOwner2DSW *p_owner) { - Map<ShapeOwner2DSW *, int>::Element *E = owners.find(p_owner); +void GodotShape2D::add_owner(GodotShapeOwner2D *p_owner) { + Map<GodotShapeOwner2D *, int>::Element *E = owners.find(p_owner); if (E) { E->get()++; } else { @@ -58,8 +58,8 @@ void Shape2DSW::add_owner(ShapeOwner2DSW *p_owner) { } } -void Shape2DSW::remove_owner(ShapeOwner2DSW *p_owner) { - Map<ShapeOwner2DSW *, int>::Element *E = owners.find(p_owner); +void GodotShape2D::remove_owner(GodotShapeOwner2D *p_owner) { + Map<GodotShapeOwner2D *, int>::Element *E = owners.find(p_owner); ERR_FAIL_COND(!E); E->get()--; if (E->get() == 0) { @@ -67,15 +67,15 @@ void Shape2DSW::remove_owner(ShapeOwner2DSW *p_owner) { } } -bool Shape2DSW::is_owner(ShapeOwner2DSW *p_owner) const { +bool GodotShape2D::is_owner(GodotShapeOwner2D *p_owner) const { return owners.has(p_owner); } -const Map<ShapeOwner2DSW *, int> &Shape2DSW::get_owners() const { +const Map<GodotShapeOwner2D *, int> &GodotShape2D::get_owners() const { return owners; } -Shape2DSW::~Shape2DSW() { +GodotShape2D::~GodotShape2D() { ERR_FAIL_COND(owners.size()); } @@ -83,15 +83,15 @@ Shape2DSW::~Shape2DSW() { /*********************************************************/ /*********************************************************/ -void WorldBoundaryShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { +void GodotWorldBoundaryShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { r_amount = 0; } -bool WorldBoundaryShape2DSW::contains_point(const Vector2 &p_point) const { +bool GodotWorldBoundaryShape2D::contains_point(const Vector2 &p_point) const { return normal.dot(p_point) < d; } -bool WorldBoundaryShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { +bool GodotWorldBoundaryShape2D::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { Vector2 segment = p_begin - p_end; real_t den = normal.dot(segment); @@ -113,11 +113,11 @@ bool WorldBoundaryShape2DSW::intersect_segment(const Vector2 &p_begin, const Vec return true; } -real_t WorldBoundaryShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { +real_t GodotWorldBoundaryShape2D::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { return 0; } -void WorldBoundaryShape2DSW::set_data(const Variant &p_data) { +void GodotWorldBoundaryShape2D::set_data(const Variant &p_data) { ERR_FAIL_COND(p_data.get_type() != Variant::ARRAY); Array arr = p_data; ERR_FAIL_COND(arr.size() != 2); @@ -126,7 +126,7 @@ void WorldBoundaryShape2DSW::set_data(const Variant &p_data) { configure(Rect2(Vector2(-1e4, -1e4), Vector2(1e4 * 2, 1e4 * 2))); } -Variant WorldBoundaryShape2DSW::get_data() const { +Variant GodotWorldBoundaryShape2D::get_data() const { Array arr; arr.resize(2); arr[0] = normal; @@ -138,7 +138,7 @@ Variant WorldBoundaryShape2DSW::get_data() const { /*********************************************************/ /*********************************************************/ -void SeparationRayShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { +void GodotSeparationRayShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { r_amount = 1; if (p_normal.y > 0) { @@ -148,26 +148,26 @@ void SeparationRayShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_su } } -bool SeparationRayShape2DSW::contains_point(const Vector2 &p_point) const { +bool GodotSeparationRayShape2D::contains_point(const Vector2 &p_point) const { return false; } -bool SeparationRayShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { +bool GodotSeparationRayShape2D::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { return false; //rays can't be intersected } -real_t SeparationRayShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { +real_t GodotSeparationRayShape2D::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { return 0; //rays are mass-less } -void SeparationRayShape2DSW::set_data(const Variant &p_data) { +void GodotSeparationRayShape2D::set_data(const Variant &p_data) { Dictionary d = p_data; length = d["length"]; slide_on_slope = d["slide_on_slope"]; configure(Rect2(0, 0, 0.001, length)); } -Variant SeparationRayShape2DSW::get_data() const { +Variant GodotSeparationRayShape2D::get_data() const { Dictionary d; d["length"] = length; d["slide_on_slope"] = slide_on_slope; @@ -178,7 +178,7 @@ Variant SeparationRayShape2DSW::get_data() const { /*********************************************************/ /*********************************************************/ -void SegmentShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { +void GodotSegmentShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { if (Math::abs(p_normal.dot(n)) > _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) { r_supports[0] = a; r_supports[1] = b; @@ -195,11 +195,11 @@ void SegmentShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports r_amount = 1; } -bool SegmentShape2DSW::contains_point(const Vector2 &p_point) const { +bool GodotSegmentShape2D::contains_point(const Vector2 &p_point) const { return false; } -bool SegmentShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { +bool GodotSegmentShape2D::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { if (!Geometry2D::segment_intersects_segment(p_begin, p_end, a, b, &r_point)) { return false; } @@ -213,11 +213,11 @@ bool SegmentShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 & return true; } -real_t SegmentShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { +real_t GodotSegmentShape2D::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { return p_mass * ((a * p_scale).distance_squared_to(b * p_scale)) / 12; } -void SegmentShape2DSW::set_data(const Variant &p_data) { +void GodotSegmentShape2D::set_data(const Variant &p_data) { ERR_FAIL_COND(p_data.get_type() != Variant::RECT2); Rect2 r = p_data; @@ -237,7 +237,7 @@ void SegmentShape2DSW::set_data(const Variant &p_data) { configure(aabb); } -Variant SegmentShape2DSW::get_data() const { +Variant GodotSegmentShape2D::get_data() const { Rect2 r; r.position = a; r.size = b; @@ -248,16 +248,16 @@ Variant SegmentShape2DSW::get_data() const { /*********************************************************/ /*********************************************************/ -void CircleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { +void GodotCircleShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { r_amount = 1; *r_supports = p_normal * radius; } -bool CircleShape2DSW::contains_point(const Vector2 &p_point) const { +bool GodotCircleShape2D::contains_point(const Vector2 &p_point) const { return p_point.length_squared() < radius * radius; } -bool CircleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { +bool GodotCircleShape2D::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { Vector2 line_vec = p_end - p_begin; real_t a, b, c; @@ -283,19 +283,19 @@ bool CircleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p return true; } -real_t CircleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { +real_t GodotCircleShape2D::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { real_t a = radius * p_scale.x; real_t b = radius * p_scale.y; return p_mass * (a * a + b * b) / 4; } -void CircleShape2DSW::set_data(const Variant &p_data) { +void GodotCircleShape2D::set_data(const Variant &p_data) { ERR_FAIL_COND(!p_data.is_num()); radius = p_data; configure(Rect2(-radius, -radius, radius * 2, radius * 2)); } -Variant CircleShape2DSW::get_data() const { +Variant GodotCircleShape2D::get_data() const { return radius; } @@ -303,7 +303,7 @@ Variant CircleShape2DSW::get_data() const { /*********************************************************/ /*********************************************************/ -void RectangleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { +void GodotRectangleShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { for (int i = 0; i < 2; i++) { Vector2 ag; ag[i] = 1.0; @@ -333,7 +333,7 @@ void RectangleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_suppor (p_normal.y < 0) ? -half_extents.y : half_extents.y); } -bool RectangleShape2DSW::contains_point(const Vector2 &p_point) const { +bool GodotRectangleShape2D::contains_point(const Vector2 &p_point) const { real_t x = p_point.x; real_t y = p_point.y; real_t edge_x = half_extents.x; @@ -341,23 +341,23 @@ bool RectangleShape2DSW::contains_point(const Vector2 &p_point) const { return (x >= -edge_x) && (x < edge_x) && (y >= -edge_y) && (y < edge_y); } -bool RectangleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { +bool GodotRectangleShape2D::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { return get_aabb().intersects_segment(p_begin, p_end, &r_point, &r_normal); } -real_t RectangleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { +real_t GodotRectangleShape2D::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { Vector2 he2 = half_extents * 2 * p_scale; return p_mass * he2.dot(he2) / 12.0; } -void RectangleShape2DSW::set_data(const Variant &p_data) { +void GodotRectangleShape2D::set_data(const Variant &p_data) { ERR_FAIL_COND(p_data.get_type() != Variant::VECTOR2); half_extents = p_data; configure(Rect2(-half_extents, half_extents * 2.0)); } -Variant RectangleShape2DSW::get_data() const { +Variant GodotRectangleShape2D::get_data() const { return half_extents; } @@ -365,7 +365,7 @@ Variant RectangleShape2DSW::get_data() const { /*********************************************************/ /*********************************************************/ -void CapsuleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { +void GodotCapsuleShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { Vector2 n = p_normal; real_t d = n.y; @@ -392,7 +392,7 @@ void CapsuleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports } } -bool CapsuleShape2DSW::contains_point(const Vector2 &p_point) const { +bool GodotCapsuleShape2D::contains_point(const Vector2 &p_point) const { Vector2 p = p_point; p.y = Math::abs(p.y); p.y -= height * 0.5 - radius; @@ -403,7 +403,7 @@ bool CapsuleShape2DSW::contains_point(const Vector2 &p_point) const { return p.length_squared() < radius * radius; } -bool CapsuleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { +bool GodotCapsuleShape2D::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { real_t d = 1e10; Vector2 n = (p_end - p_begin).normalized(); bool collided = false; @@ -463,12 +463,12 @@ bool CapsuleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 & return collided; //todo } -real_t CapsuleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { +real_t GodotCapsuleShape2D::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { Vector2 he2 = Vector2(radius * 2, height) * p_scale; return p_mass * he2.dot(he2) / 12.0; } -void CapsuleShape2DSW::set_data(const Variant &p_data) { +void GodotCapsuleShape2D::set_data(const Variant &p_data) { ERR_FAIL_COND(p_data.get_type() != Variant::ARRAY && p_data.get_type() != Variant::VECTOR2); if (p_data.get_type() == Variant::ARRAY) { @@ -486,7 +486,7 @@ void CapsuleShape2DSW::set_data(const Variant &p_data) { configure(Rect2(-he, he * 2)); } -Variant CapsuleShape2DSW::get_data() const { +Variant GodotCapsuleShape2D::get_data() const { return Point2(height, radius); } @@ -494,7 +494,7 @@ Variant CapsuleShape2DSW::get_data() const { /*********************************************************/ /*********************************************************/ -void ConvexPolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { +void GodotConvexPolygonShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { int support_idx = -1; real_t d = -1e10; r_amount = 0; @@ -522,7 +522,7 @@ void ConvexPolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_su r_supports[0] = points[support_idx].pos; } -bool ConvexPolygonShape2DSW::contains_point(const Vector2 &p_point) const { +bool GodotConvexPolygonShape2D::contains_point(const Vector2 &p_point) const { bool out = false; bool in = false; @@ -538,7 +538,7 @@ bool ConvexPolygonShape2DSW::contains_point(const Vector2 &p_point) const { return in != out; } -bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { +bool GodotConvexPolygonShape2D::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { Vector2 n = (p_end - p_begin).normalized(); real_t d = 1e10; bool inters = false; @@ -568,7 +568,7 @@ bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vec return inters; } -real_t ConvexPolygonShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { +real_t GodotConvexPolygonShape2D::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { ERR_FAIL_COND_V_MSG(point_count == 0, 0, "Convex polygon shape has no points."); Rect2 aabb; aabb.position = points[0].pos * p_scale; @@ -579,7 +579,7 @@ real_t ConvexPolygonShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 return p_mass * aabb.size.dot(aabb.size) / 12.0; } -void ConvexPolygonShape2DSW::set_data(const Variant &p_data) { +void GodotConvexPolygonShape2D::set_data(const Variant &p_data) { #ifdef REAL_T_IS_DOUBLE ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT64_ARRAY); #else @@ -635,7 +635,7 @@ void ConvexPolygonShape2DSW::set_data(const Variant &p_data) { configure(aabb); } -Variant ConvexPolygonShape2DSW::get_data() const { +Variant GodotConvexPolygonShape2D::get_data() const { Vector<Vector2> dvr; dvr.resize(point_count); @@ -647,7 +647,7 @@ Variant ConvexPolygonShape2DSW::get_data() const { return dvr; } -ConvexPolygonShape2DSW::~ConvexPolygonShape2DSW() { +GodotConvexPolygonShape2D::~GodotConvexPolygonShape2D() { if (points) { memdelete_arr(points); } @@ -655,7 +655,7 @@ ConvexPolygonShape2DSW::~ConvexPolygonShape2DSW() { ////////////////////////////////////////////////// -void ConcavePolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { +void GodotConcavePolygonShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { real_t d = -1e10; int idx = -1; for (int i = 0; i < points.size(); i++) { @@ -671,11 +671,11 @@ void ConcavePolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_s *r_supports = points[idx]; } -bool ConcavePolygonShape2DSW::contains_point(const Vector2 &p_point) const { +bool GodotConcavePolygonShape2D::contains_point(const Vector2 &p_point) const { return false; //sorry } -bool ConcavePolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { +bool GodotConcavePolygonShape2D::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { if (segments.size() == 0 || points.size() == 0) { return false; } @@ -783,7 +783,7 @@ bool ConcavePolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Ve return inters; } -int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) { +int GodotConcavePolygonShape2D::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) { if (p_len == 1) { bvh_depth = MAX(p_depth, bvh_depth); bvh.push_back(*p_bvh); @@ -821,7 +821,7 @@ int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) { return node_idx; } -void ConcavePolygonShape2DSW::set_data(const Variant &p_data) { +void GodotConcavePolygonShape2D::set_data(const Variant &p_data) { #ifdef REAL_T_IS_DOUBLE ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT64_ARRAY); #else @@ -898,7 +898,7 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) { configure(aabb); } -Variant ConcavePolygonShape2DSW::get_data() const { +Variant GodotConcavePolygonShape2D::get_data() const { Vector<Vector2> rsegments; int len = segments.size(); rsegments.resize(len * 2); @@ -911,7 +911,7 @@ Variant ConcavePolygonShape2DSW::get_data() const { return rsegments; } -void ConcavePolygonShape2DSW::cull(const Rect2 &p_local_aabb, QueryCallback p_callback, void *p_userdata) const { +void GodotConcavePolygonShape2D::cull(const Rect2 &p_local_aabb, QueryCallback p_callback, void *p_userdata) const { uint32_t *stack = (uint32_t *)alloca(sizeof(int) * bvh_depth); enum { @@ -957,7 +957,7 @@ void ConcavePolygonShape2DSW::cull(const Rect2 &p_local_aabb, QueryCallback p_ca Vector2 a = pointptr[s.points[0]]; Vector2 b = pointptr[s.points[1]]; - SegmentShape2DSW ss(a, b, (b - a).orthogonal().normalized()); + GodotSegmentShape2D ss(a, b, (b - a).orthogonal().normalized()); if (p_callback(p_userdata, &ss)) { return; diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/godot_shape_2d.h index c118826284..25d113aafb 100644 --- a/servers/physics_2d/shape_2d_sw.h +++ b/servers/physics_2d/godot_shape_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* shape_2d_sw.h */ +/* godot_shape_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,29 +28,29 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SHAPE_2D_2DSW_H -#define SHAPE_2D_2DSW_H +#ifndef GODOT_SHAPE_2D_H +#define GODOT_SHAPE_2D_H #include "servers/physics_server_2d.h" #define _SEGMENT_IS_VALID_SUPPORT_THRESHOLD 0.99998 -class Shape2DSW; +class GodotShape2D; -class ShapeOwner2DSW { +class GodotShapeOwner2D { public: virtual void _shape_changed() = 0; - virtual void remove_shape(Shape2DSW *p_shape) = 0; + virtual void remove_shape(GodotShape2D *p_shape) = 0; - virtual ~ShapeOwner2DSW() {} + virtual ~GodotShapeOwner2D() {} }; -class Shape2DSW { +class GodotShape2D { RID self; Rect2 aabb; bool configured = false; real_t custom_bias = 0.0; - Map<ShapeOwner2DSW *, int> owners; + Map<GodotShapeOwner2D *, int> owners; protected: void configure(const Rect2 &p_aabb); @@ -83,10 +83,10 @@ public: _FORCE_INLINE_ void set_custom_bias(real_t p_bias) { custom_bias = p_bias; } _FORCE_INLINE_ real_t get_custom_bias() const { return custom_bias; } - void add_owner(ShapeOwner2DSW *p_owner); - void remove_owner(ShapeOwner2DSW *p_owner); - bool is_owner(ShapeOwner2DSW *p_owner) const; - const Map<ShapeOwner2DSW *, int> &get_owners() const; + void add_owner(GodotShapeOwner2D *p_owner); + void remove_owner(GodotShapeOwner2D *p_owner); + bool is_owner(GodotShapeOwner2D *p_owner) const; + const Map<GodotShapeOwner2D *, int> &get_owners() const; _FORCE_INLINE_ void get_supports_transformed_cast(const Vector2 &p_cast, const Vector2 &p_normal, const Transform2D &p_xform, Vector2 *r_supports, int &r_amount) const { get_supports(p_xform.basis_xform_inv(p_normal).normalized(), r_supports, r_amount); @@ -121,8 +121,8 @@ public: } } } - Shape2DSW() {} - virtual ~Shape2DSW(); + GodotShape2D() {} + virtual ~GodotShape2D(); }; //let the optimizer do the magic @@ -141,7 +141,7 @@ public: r_max = MAX(maxa, maxb); \ } -class WorldBoundaryShape2DSW : public Shape2DSW { +class GodotWorldBoundaryShape2D : public GodotShape2D { Vector2 normal; real_t d = 0.0; @@ -178,7 +178,7 @@ public: } }; -class SeparationRayShape2DSW : public Shape2DSW { +class GodotSeparationRayShape2D : public GodotShape2D { real_t length = 0.0; bool slide_on_slope = false; @@ -211,11 +211,11 @@ public: DEFAULT_PROJECT_RANGE_CAST - _FORCE_INLINE_ SeparationRayShape2DSW() {} - _FORCE_INLINE_ SeparationRayShape2DSW(real_t p_length) { length = p_length; } + _FORCE_INLINE_ GodotSeparationRayShape2D() {} + _FORCE_INLINE_ GodotSeparationRayShape2D(real_t p_length) { length = p_length; } }; -class SegmentShape2DSW : public Shape2DSW { +class GodotSegmentShape2D : public GodotShape2D { Vector2 a; Vector2 b; Vector2 n; @@ -251,15 +251,15 @@ public: DEFAULT_PROJECT_RANGE_CAST - _FORCE_INLINE_ SegmentShape2DSW() {} - _FORCE_INLINE_ SegmentShape2DSW(const Vector2 &p_a, const Vector2 &p_b, const Vector2 &p_n) { + _FORCE_INLINE_ GodotSegmentShape2D() {} + _FORCE_INLINE_ GodotSegmentShape2D(const Vector2 &p_a, const Vector2 &p_b, const Vector2 &p_n) { a = p_a; b = p_b; n = p_n; } }; -class CircleShape2DSW : public Shape2DSW { +class GodotCircleShape2D : public GodotShape2D { real_t radius; public: @@ -292,7 +292,7 @@ public: DEFAULT_PROJECT_RANGE_CAST }; -class RectangleShape2DSW : public Shape2DSW { +class GodotRectangleShape2D : public GodotShape2D { Vector2 half_extents; public: @@ -336,7 +336,7 @@ public: return (p_xform.xform(he) - p_circle).normalized(); } - _FORCE_INLINE_ Vector2 get_box_axis(const Transform2D &p_xform, const Transform2D &p_xform_inv, const RectangleShape2DSW *p_B, const Transform2D &p_B_xform, const Transform2D &p_B_xform_inv) const { + _FORCE_INLINE_ Vector2 get_box_axis(const Transform2D &p_xform, const Transform2D &p_xform_inv, const GodotRectangleShape2D *p_B, const Transform2D &p_B_xform, const Transform2D &p_B_xform_inv) const { Vector2 a, b; { @@ -364,7 +364,7 @@ public: DEFAULT_PROJECT_RANGE_CAST }; -class CapsuleShape2DSW : public Shape2DSW { +class GodotCapsuleShape2D : public GodotShape2D { real_t radius = 0.0; real_t height = 0.0; @@ -405,7 +405,7 @@ public: DEFAULT_PROJECT_RANGE_CAST }; -class ConvexPolygonShape2DSW : public Shape2DSW { +class GodotConvexPolygonShape2D : public GodotShape2D { struct Point { Vector2 pos; Vector2 normal; //normal to next segment @@ -457,21 +457,21 @@ public: DEFAULT_PROJECT_RANGE_CAST - ConvexPolygonShape2DSW() {} - ~ConvexPolygonShape2DSW(); + GodotConvexPolygonShape2D() {} + ~GodotConvexPolygonShape2D(); }; -class ConcaveShape2DSW : public Shape2DSW { +class GodotConcaveShape2D : public GodotShape2D { public: virtual bool is_concave() const override { return true; } // Returns true to stop the query. - typedef bool (*QueryCallback)(void *p_userdata, Shape2DSW *p_convex); + typedef bool (*QueryCallback)(void *p_userdata, GodotShape2D *p_convex); virtual void cull(const Rect2 &p_local_aabb, QueryCallback p_callback, void *p_userdata) const = 0; }; -class ConcavePolygonShape2DSW : public ConcaveShape2DSW { +class GodotConcavePolygonShape2D : public GodotConcaveShape2D { struct Segment { int points[2] = {}; }; @@ -507,13 +507,13 @@ public: virtual void project_rangev(const Vector2 &p_normal, const Transform2D &p_transform, real_t &r_min, real_t &r_max) const override { r_min = 0; r_max = 0; - ERR_FAIL_MSG("Unsupported call to project_rangev in ConcavePolygonShape2DSW"); + ERR_FAIL_MSG("Unsupported call to project_rangev in GodotConcavePolygonShape2D"); } void project_range(const Vector2 &p_normal, const Transform2D &p_transform, real_t &r_min, real_t &r_max) const { r_min = 0; r_max = 0; - ERR_FAIL_MSG("Unsupported call to project_range in ConcavePolygonShape2DSW"); + ERR_FAIL_MSG("Unsupported call to project_range in GodotConcavePolygonShape2D"); } virtual void get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const override; @@ -533,4 +533,4 @@ public: #undef DEFAULT_PROJECT_RANGE_CAST -#endif // SHAPE_2D_2DSW_H +#endif // GODOT_SHAPE_2D_H diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/godot_space_2d.cpp index dd0780b5ff..d72014a8ed 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/godot_space_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* space_2d_sw.cpp */ +/* godot_space_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,32 +28,33 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "space_2d_sw.h" +#include "godot_space_2d.h" + +#include "godot_collision_solver_2d.h" +#include "godot_physics_server_2d.h" -#include "collision_solver_2d_sw.h" #include "core/os/os.h" #include "core/templates/pair.h" -#include "physics_server_2d_sw.h" #define TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR 0.05 -_FORCE_INLINE_ static bool _can_collide_with(CollisionObject2DSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +_FORCE_INLINE_ static bool _can_collide_with(GodotCollisionObject2D *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (!(p_object->get_collision_layer() & p_collision_mask)) { return false; } - if (p_object->get_type() == CollisionObject2DSW::TYPE_AREA && !p_collide_with_areas) { + if (p_object->get_type() == GodotCollisionObject2D::TYPE_AREA && !p_collide_with_areas) { return false; } - if (p_object->get_type() == CollisionObject2DSW::TYPE_BODY && !p_collide_with_bodies) { + if (p_object->get_type() == GodotCollisionObject2D::TYPE_BODY && !p_collide_with_bodies) { return false; } return true; } -int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point, bool p_filter_by_canvas, ObjectID p_canvas_instance_id) { +int GodotPhysicsDirectSpaceState2D::_intersect_point_impl(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point, bool p_filter_by_canvas, ObjectID p_canvas_instance_id) { if (p_result_max <= 0) { return 0; } @@ -62,7 +63,7 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S aabb.position = p_point - Vector2(0.00001, 0.00001); aabb.size = Vector2(0.00002, 0.00002); - int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); + int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int cc = 0; @@ -75,7 +76,7 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S continue; } - const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; + const GodotCollisionObject2D *col_obj = space->intersection_query_results[i]; if (p_pick_point && !col_obj->is_pickable()) { continue; @@ -87,7 +88,7 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S int shape_idx = space->intersection_query_subindex_results[i]; - Shape2DSW *shape = col_obj->get_shape(shape_idx); + GodotShape2D *shape = col_obj->get_shape(shape_idx); Vector2 local_point = (col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).affine_inverse().xform(p_point); @@ -112,15 +113,15 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S return cc; } -int PhysicsDirectSpaceState2DSW::intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point) { +int GodotPhysicsDirectSpaceState2D::intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point) { return _intersect_point_impl(p_point, r_results, p_result_max, p_exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas, p_pick_point); } -int PhysicsDirectSpaceState2DSW::intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point) { +int GodotPhysicsDirectSpaceState2D::intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point) { return _intersect_point_impl(p_point, r_results, p_result_max, p_exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas, p_pick_point, true, p_canvas_instance_id); } -bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +bool GodotPhysicsDirectSpaceState2D::intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { ERR_FAIL_COND_V(space->locked, false); Vector2 begin, end; @@ -129,14 +130,14 @@ bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vec end = p_to; normal = (end - begin).normalized(); - int amount = space->broadphase->cull_segment(begin, end, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); + int amount = space->broadphase->cull_segment(begin, end, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); //todo, create another array that references results, compute AABBs and check closest point to ray origin, sort, and stop evaluating results when beyond first collision bool collided = false; Vector2 res_point, res_normal; int res_shape; - const CollisionObject2DSW *res_obj; + const GodotCollisionObject2D *res_obj; real_t min_d = 1e10; for (int i = 0; i < amount; i++) { @@ -148,7 +149,7 @@ bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vec continue; } - const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; + const GodotCollisionObject2D *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; Transform2D inv_xform = col_obj->get_shape_inv_transform(shape_idx) * col_obj->get_inv_transform(); @@ -162,7 +163,7 @@ bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vec local_to = col_obj->get_inv_transform().xform(end); local_to = col_obj->get_shape_inv_transform(shape_idx).xform(local_to);*/ - const Shape2DSW *shape = col_obj->get_shape(shape_idx); + const GodotShape2D *shape = col_obj->get_shape(shape_idx); Vector2 shape_point, shape_normal; @@ -199,18 +200,18 @@ bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vec return true; } -int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +int GodotPhysicsDirectSpaceState2D::intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) { return 0; } - Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.get_or_null(p_shape); + GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); Rect2 aabb = p_xform.xform(shape->get_aabb()); aabb = aabb.grow(p_margin); - int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); + int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int cc = 0; @@ -227,10 +228,10 @@ int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Trans continue; } - const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; + const GodotCollisionObject2D *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; - if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), nullptr, nullptr, nullptr, p_margin)) { + if (!GodotCollisionSolver2D::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), nullptr, nullptr, nullptr, p_margin)) { continue; } @@ -247,15 +248,15 @@ int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Trans return cc; } -bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.get_or_null(p_shape); +bool GodotPhysicsDirectSpaceState2D::cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { + GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, false); Rect2 aabb = p_xform.xform(shape->get_aabb()); aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion aabb = aabb.grow(p_margin); - int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); + int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); real_t best_safe = 1; real_t best_unsafe = 1; @@ -269,17 +270,17 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor continue; //ignore excluded } - const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; + const GodotCollisionObject2D *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? - if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) { + if (!GodotCollisionSolver2D::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) { continue; } //test initial overlap, ignore objects it's inside of. - if (CollisionSolver2DSW::solve(shape, p_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) { + if (GodotCollisionSolver2D::solve(shape, p_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) { continue; } @@ -293,7 +294,7 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor real_t fraction = low + (hi - low) * fraction_coeff; Vector2 sep = mnormal; //important optimization for this to work fast enough - bool collided = CollisionSolver2DSW::solve(shape, p_xform, p_motion * fraction, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, &sep, p_margin); + bool collided = GodotCollisionSolver2D::solve(shape, p_xform, p_motion * fraction, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, &sep, p_margin); if (collided) { hi = fraction; @@ -330,38 +331,38 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor return true; } -bool PhysicsDirectSpaceState2DSW::collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +bool GodotPhysicsDirectSpaceState2D::collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) { return false; } - Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.get_or_null(p_shape); + GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); Rect2 aabb = p_shape_xform.xform(shape->get_aabb()); aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion aabb = aabb.grow(p_margin); - int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); + int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); bool collided = false; r_result_count = 0; - PhysicsServer2DSW::CollCbkData cbk; + GodotPhysicsServer2D::CollCbkData cbk; cbk.max = p_result_max; cbk.amount = 0; cbk.passed = 0; cbk.ptr = r_results; - CollisionSolver2DSW::CallbackResult cbkres = PhysicsServer2DSW::_shape_col_cbk; + GodotCollisionSolver2D::CallbackResult cbkres = GodotPhysicsServer2D::_shape_col_cbk; - PhysicsServer2DSW::CollCbkData *cbkptr = &cbk; + GodotPhysicsServer2D::CollCbkData *cbkptr = &cbk; for (int i = 0; i < amount; i++) { if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { continue; } - const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; + const GodotCollisionObject2D *col_obj = space->intersection_query_results[i]; if (p_exclude.has(col_obj->get_self())) { continue; @@ -372,7 +373,7 @@ bool PhysicsDirectSpaceState2DSW::collide_shape(RID p_shape, const Transform2D & cbk.valid_dir = Vector2(); cbk.valid_depth = 0; - if (CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, nullptr, p_margin)) { + if (GodotCollisionSolver2D::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, nullptr, p_margin)) { collided = cbk.amount > 0; } } @@ -383,8 +384,8 @@ bool PhysicsDirectSpaceState2DSW::collide_shape(RID p_shape, const Transform2D & } struct _RestCallbackData2D { - const CollisionObject2DSW *object = nullptr; - const CollisionObject2DSW *best_object = nullptr; + const GodotCollisionObject2D *object = nullptr; + const GodotCollisionObject2D *best_object = nullptr; int local_shape = 0; int best_local_shape = 0; int shape = 0; @@ -431,8 +432,8 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B, rd->best_local_shape = rd->local_shape; } -bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.get_or_null(p_shape); +bool GodotPhysicsDirectSpaceState2D::rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { + GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR; @@ -441,7 +442,7 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion aabb = aabb.grow(p_margin); - int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); + int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); _RestCallbackData2D rcd; rcd.best_len = 0; @@ -454,7 +455,7 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh continue; } - const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; + const GodotCollisionObject2D *col_obj = space->intersection_query_results[i]; if (p_exclude.has(col_obj->get_self())) { continue; @@ -466,7 +467,7 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh rcd.object = col_obj; rcd.shape = shape_idx; rcd.local_shape = 0; - bool sc = CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, nullptr, p_margin); + bool sc = GodotCollisionSolver2D::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, nullptr, p_margin); if (!sc) { continue; } @@ -481,8 +482,8 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh r_info->normal = rcd.best_normal; r_info->point = rcd.best_contact; r_info->rid = rcd.best_object->get_self(); - if (rcd.best_object->get_type() == CollisionObject2DSW::TYPE_BODY) { - const Body2DSW *body = static_cast<const Body2DSW *>(rcd.best_object); + if (rcd.best_object->get_type() == GodotCollisionObject2D::TYPE_BODY) { + const GodotBody2D *body = static_cast<const GodotBody2D *>(rcd.best_object); Vector2 rel_vec = r_info->point - (body->get_transform().get_origin() + body->get_center_of_mass()); r_info->linear_velocity = Vector2(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity(); @@ -495,7 +496,7 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh //////////////////////////////////////////////////////////////////////////////////////////////////////////// -int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) { +int GodotSpace2D::_cull_aabb_for_body(GodotBody2D *p_body, const Rect2 &p_aabb) { int amount = broadphase->cull_aabb(p_aabb, intersection_query_results, INTERSECTION_QUERY_MAX, intersection_query_subindex_results); for (int i = 0; i < amount; i++) { @@ -503,11 +504,11 @@ int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) { if (intersection_query_results[i] == p_body) { keep = false; - } else if (intersection_query_results[i]->get_type() == CollisionObject2DSW::TYPE_AREA) { + } else if (intersection_query_results[i]->get_type() == GodotCollisionObject2D::TYPE_AREA) { keep = false; - } else if (!p_body->collides_with(static_cast<Body2DSW *>(intersection_query_results[i]))) { + } else if (!p_body->collides_with(static_cast<GodotBody2D *>(intersection_query_results[i]))) { keep = false; - } else if (static_cast<Body2DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) { + } else if (static_cast<GodotBody2D *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) { keep = false; } @@ -525,7 +526,7 @@ int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) { return amount; } -bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::MotionParameters &p_parameters, PhysicsServer2D::MotionResult *r_result) { +bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::MotionParameters &p_parameters, PhysicsServer2D::MotionResult *r_result) { //give me back regular physics engine logic //this is madness //and most people using this function will think @@ -587,7 +588,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion Vector2 sr[max_results * 2]; do { - PhysicsServer2DSW::CollCbkData cbk; + GodotPhysicsServer2D::CollCbkData cbk; cbk.max = max_results; cbk.amount = 0; cbk.passed = 0; @@ -595,8 +596,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion cbk.invalid_by_dir = 0; excluded_shape_pair_count = 0; //last step is the one valid - PhysicsServer2DSW::CollCbkData *cbkptr = &cbk; - CollisionSolver2DSW::CallbackResult cbkres = PhysicsServer2DSW::_shape_col_cbk; + GodotPhysicsServer2D::CollCbkData *cbkptr = &cbk; + GodotCollisionSolver2D::CallbackResult cbkres = GodotPhysicsServer2D::_shape_col_cbk; bool collided = false; @@ -607,11 +608,11 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion continue; } - Shape2DSW *body_shape = p_body->get_shape(j); + GodotShape2D *body_shape = p_body->get_shape(j); Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j); for (int i = 0; i < amount; i++) { - const CollisionObject2DSW *col_obj = intersection_query_results[i]; + const GodotCollisionObject2D *col_obj = intersection_query_results[i]; if (p_parameters.exclude_bodies.has(col_obj->get_self())) { continue; } @@ -630,8 +631,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion cbk.valid_depth = MAX(owc_margin, p_parameters.margin); //user specified, but never less than actual margin or it won't work cbk.invalid_by_dir = 0; - if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) { - const Body2DSW *b = static_cast<const Body2DSW *>(col_obj); + if (col_obj->get_type() == GodotCollisionObject2D::TYPE_BODY) { + const GodotBody2D *b = static_cast<const GodotBody2D *>(col_obj); if (b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_DYNAMIC) { //fix for moving platforms (kinematic and dynamic), margin is increased by how much it moved in the given direction Vector2 lv = b->get_linear_velocity(); @@ -651,8 +652,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion int current_passed = cbk.passed; //save how many points passed collision bool did_collide = false; - Shape2DSW *against_shape = col_obj->get_shape(shape_idx); - if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, p_parameters.margin)) { + GodotShape2D *against_shape = col_obj->get_shape(shape_idx); + if (GodotCollisionSolver2D::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, p_parameters.margin)) { did_collide = cbk.passed > current_passed; //more passed, so collision actually existed } @@ -727,13 +728,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion continue; } - Shape2DSW *body_shape = p_body->get_shape(body_shape_idx); + GodotShape2D *body_shape = p_body->get_shape(body_shape_idx); // Colliding separation rays allows to properly snap to the ground, // otherwise it's not needed in regular motion. if (!p_parameters.collide_separation_ray && (body_shape->get_type() == PhysicsServer2D::SHAPE_SEPARATION_RAY)) { // When slide on slope is on, separation ray shape acts like a regular shape. - if (!static_cast<SeparationRayShape2DSW *>(body_shape)->get_slide_on_slope()) { + if (!static_cast<GodotSeparationRayShape2D *>(body_shape)->get_slide_on_slope()) { continue; } } @@ -746,7 +747,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion real_t best_unsafe = 1; for (int i = 0; i < amount; i++) { - const CollisionObject2DSW *col_obj = intersection_query_results[i]; + const GodotCollisionObject2D *col_obj = intersection_query_results[i]; if (p_parameters.exclude_bodies.has(col_obj->get_self())) { continue; } @@ -755,7 +756,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion } int col_shape_idx = intersection_query_subindex_results[i]; - Shape2DSW *against_shape = col_obj->get_shape(col_shape_idx); + GodotShape2D *against_shape = col_obj->get_shape(col_shape_idx); bool excluded = false; @@ -772,12 +773,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion Transform2D col_obj_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(col_shape_idx); //test initial overlap, does it collide if going all the way? - if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_parameters.motion, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, nullptr, 0)) { + if (!GodotCollisionSolver2D::solve(body_shape, body_shape_xform, p_parameters.motion, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, nullptr, 0)) { continue; } //test initial overlap - if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, nullptr, 0)) { + if (GodotCollisionSolver2D::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, nullptr, 0)) { if (body_shape->allows_one_way_collision() && col_obj->is_shape_set_as_one_way_collision(col_shape_idx)) { Vector2 direction = col_obj_shape_xform.get_axis(1).normalized(); if (motion_normal.dot(direction) < 0) { @@ -797,7 +798,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion real_t fraction = low + (hi - low) * fraction_coeff; Vector2 sep = motion_normal; //important optimization for this to work fast enough - bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_parameters.motion * fraction, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, &sep, 0); + bool collided = GodotCollisionSolver2D::solve(body_shape, body_shape_xform, p_parameters.motion * fraction, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, &sep, 0); if (collided) { hi = fraction; @@ -824,7 +825,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion if (body_shape->allows_one_way_collision() && col_obj->is_shape_set_as_one_way_collision(col_shape_idx)) { Vector2 cd[2]; - PhysicsServer2DSW::CollCbkData cbk; + GodotPhysicsServer2D::CollCbkData cbk; cbk.max = 1; cbk.amount = 0; cbk.passed = 0; @@ -834,7 +835,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion cbk.valid_depth = 10e20; Vector2 sep = motion_normal; //important optimization for this to work fast enough - bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_parameters.motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(col_shape_idx), col_obj_shape_xform, Vector2(), PhysicsServer2DSW::_shape_col_cbk, &cbk, &sep, 0); + bool collided = GodotCollisionSolver2D::solve(body_shape, body_shape_xform, p_parameters.motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(col_shape_idx), col_obj_shape_xform, Vector2(), GodotPhysicsServer2D::_shape_col_cbk, &cbk, &sep, 0); if (!collided || cbk.amount == 0) { continue; } @@ -891,14 +892,14 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion } Transform2D body_shape_xform = ugt * p_body->get_shape_transform(j); - Shape2DSW *body_shape = p_body->get_shape(j); + GodotShape2D *body_shape = p_body->get_shape(j); body_aabb.position += p_parameters.motion * unsafe; int amount = _cull_aabb_for_body(p_body, body_aabb); for (int i = 0; i < amount; i++) { - const CollisionObject2DSW *col_obj = intersection_query_results[i]; + const GodotCollisionObject2D *col_obj = intersection_query_results[i]; if (p_parameters.exclude_bodies.has(col_obj->get_self())) { continue; } @@ -908,7 +909,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion int shape_idx = intersection_query_subindex_results[i]; - Shape2DSW *against_shape = col_obj->get_shape(shape_idx); + GodotShape2D *against_shape = col_obj->get_shape(shape_idx); bool excluded = false; for (int k = 0; k < excluded_shape_pair_count; k++) { @@ -929,8 +930,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion real_t owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx); rcd.valid_depth = MAX(owc_margin, p_parameters.margin); //user specified, but never less than actual margin or it won't work - if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) { - const Body2DSW *b = static_cast<const Body2DSW *>(col_obj); + if (col_obj->get_type() == GodotCollisionObject2D::TYPE_BODY) { + const GodotBody2D *b = static_cast<const GodotBody2D *>(col_obj); if (b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_DYNAMIC) { //fix for moving platforms (kinematic and dynamic), margin is increased by how much it moved in the given direction Vector2 lv = b->get_linear_velocity(); @@ -949,7 +950,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion rcd.object = col_obj; rcd.shape = shape_idx; rcd.local_shape = j; - bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), _rest_cbk_result, &rcd, nullptr, p_parameters.margin); + bool sc = GodotCollisionSolver2D::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), _rest_cbk_result, &rcd, nullptr, p_parameters.margin); if (!sc) { continue; } @@ -968,7 +969,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion r_result->collision_safe_fraction = safe; r_result->collision_unsafe_fraction = unsafe; - const Body2DSW *body = static_cast<const Body2DSW *>(rcd.best_object); + const GodotBody2D *body = static_cast<const GodotBody2D *>(rcd.best_object); Vector2 rel_vec = r_result->collision_point - (body->get_transform().get_origin() + body->get_center_of_mass()); r_result->collider_velocity = Vector2(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity(); @@ -990,134 +991,134 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion return collided; } -void *Space2DSW::_broadphase_pair(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_self) { +void *GodotSpace2D::_broadphase_pair(GodotCollisionObject2D *A, int p_subindex_A, GodotCollisionObject2D *B, int p_subindex_B, void *p_self) { if (!A->interacts_with(B)) { return nullptr; } - CollisionObject2DSW::Type type_A = A->get_type(); - CollisionObject2DSW::Type type_B = B->get_type(); + GodotCollisionObject2D::Type type_A = A->get_type(); + GodotCollisionObject2D::Type type_B = B->get_type(); if (type_A > type_B) { SWAP(A, B); SWAP(p_subindex_A, p_subindex_B); SWAP(type_A, type_B); } - Space2DSW *self = (Space2DSW *)p_self; + GodotSpace2D *self = (GodotSpace2D *)p_self; self->collision_pairs++; - if (type_A == CollisionObject2DSW::TYPE_AREA) { - Area2DSW *area = static_cast<Area2DSW *>(A); - if (type_B == CollisionObject2DSW::TYPE_AREA) { - Area2DSW *area_b = static_cast<Area2DSW *>(B); - Area2Pair2DSW *area2_pair = memnew(Area2Pair2DSW(area_b, p_subindex_B, area, p_subindex_A)); + if (type_A == GodotCollisionObject2D::TYPE_AREA) { + GodotArea2D *area = static_cast<GodotArea2D *>(A); + if (type_B == GodotCollisionObject2D::TYPE_AREA) { + GodotArea2D *area_b = static_cast<GodotArea2D *>(B); + GodotArea2Pair2D *area2_pair = memnew(GodotArea2Pair2D(area_b, p_subindex_B, area, p_subindex_A)); return area2_pair; } else { - Body2DSW *body = static_cast<Body2DSW *>(B); - AreaPair2DSW *area_pair = memnew(AreaPair2DSW(body, p_subindex_B, area, p_subindex_A)); + GodotBody2D *body = static_cast<GodotBody2D *>(B); + GodotAreaPair2D *area_pair = memnew(GodotAreaPair2D(body, p_subindex_B, area, p_subindex_A)); return area_pair; } } else { - BodyPair2DSW *b = memnew(BodyPair2DSW((Body2DSW *)A, p_subindex_A, (Body2DSW *)B, p_subindex_B)); + GodotBodyPair2D *b = memnew(GodotBodyPair2D((GodotBody2D *)A, p_subindex_A, (GodotBody2D *)B, p_subindex_B)); return b; } return nullptr; } -void Space2DSW::_broadphase_unpair(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_data, void *p_self) { +void GodotSpace2D::_broadphase_unpair(GodotCollisionObject2D *A, int p_subindex_A, GodotCollisionObject2D *B, int p_subindex_B, void *p_data, void *p_self) { if (!p_data) { return; } - Space2DSW *self = (Space2DSW *)p_self; + GodotSpace2D *self = (GodotSpace2D *)p_self; self->collision_pairs--; - Constraint2DSW *c = (Constraint2DSW *)p_data; + GodotConstraint2D *c = (GodotConstraint2D *)p_data; memdelete(c); } -const SelfList<Body2DSW>::List &Space2DSW::get_active_body_list() const { +const SelfList<GodotBody2D>::List &GodotSpace2D::get_active_body_list() const { return active_list; } -void Space2DSW::body_add_to_active_list(SelfList<Body2DSW> *p_body) { +void GodotSpace2D::body_add_to_active_list(SelfList<GodotBody2D> *p_body) { active_list.add(p_body); } -void Space2DSW::body_remove_from_active_list(SelfList<Body2DSW> *p_body) { +void GodotSpace2D::body_remove_from_active_list(SelfList<GodotBody2D> *p_body) { active_list.remove(p_body); } -void Space2DSW::body_add_to_mass_properties_update_list(SelfList<Body2DSW> *p_body) { +void GodotSpace2D::body_add_to_mass_properties_update_list(SelfList<GodotBody2D> *p_body) { mass_properties_update_list.add(p_body); } -void Space2DSW::body_remove_from_mass_properties_update_list(SelfList<Body2DSW> *p_body) { +void GodotSpace2D::body_remove_from_mass_properties_update_list(SelfList<GodotBody2D> *p_body) { mass_properties_update_list.remove(p_body); } -BroadPhase2DSW *Space2DSW::get_broadphase() { +GodotBroadPhase2D *GodotSpace2D::get_broadphase() { return broadphase; } -void Space2DSW::add_object(CollisionObject2DSW *p_object) { +void GodotSpace2D::add_object(GodotCollisionObject2D *p_object) { ERR_FAIL_COND(objects.has(p_object)); objects.insert(p_object); } -void Space2DSW::remove_object(CollisionObject2DSW *p_object) { +void GodotSpace2D::remove_object(GodotCollisionObject2D *p_object) { ERR_FAIL_COND(!objects.has(p_object)); objects.erase(p_object); } -const Set<CollisionObject2DSW *> &Space2DSW::get_objects() const { +const Set<GodotCollisionObject2D *> &GodotSpace2D::get_objects() const { return objects; } -void Space2DSW::body_add_to_state_query_list(SelfList<Body2DSW> *p_body) { +void GodotSpace2D::body_add_to_state_query_list(SelfList<GodotBody2D> *p_body) { state_query_list.add(p_body); } -void Space2DSW::body_remove_from_state_query_list(SelfList<Body2DSW> *p_body) { +void GodotSpace2D::body_remove_from_state_query_list(SelfList<GodotBody2D> *p_body) { state_query_list.remove(p_body); } -void Space2DSW::area_add_to_monitor_query_list(SelfList<Area2DSW> *p_area) { +void GodotSpace2D::area_add_to_monitor_query_list(SelfList<GodotArea2D> *p_area) { monitor_query_list.add(p_area); } -void Space2DSW::area_remove_from_monitor_query_list(SelfList<Area2DSW> *p_area) { +void GodotSpace2D::area_remove_from_monitor_query_list(SelfList<GodotArea2D> *p_area) { monitor_query_list.remove(p_area); } -void Space2DSW::area_add_to_moved_list(SelfList<Area2DSW> *p_area) { +void GodotSpace2D::area_add_to_moved_list(SelfList<GodotArea2D> *p_area) { area_moved_list.add(p_area); } -void Space2DSW::area_remove_from_moved_list(SelfList<Area2DSW> *p_area) { +void GodotSpace2D::area_remove_from_moved_list(SelfList<GodotArea2D> *p_area) { area_moved_list.remove(p_area); } -const SelfList<Area2DSW>::List &Space2DSW::get_moved_area_list() const { +const SelfList<GodotArea2D>::List &GodotSpace2D::get_moved_area_list() const { return area_moved_list; } -void Space2DSW::call_queries() { +void GodotSpace2D::call_queries() { while (state_query_list.first()) { - Body2DSW *b = state_query_list.first()->self(); + GodotBody2D *b = state_query_list.first()->self(); state_query_list.remove(state_query_list.first()); b->call_queries(); } while (monitor_query_list.first()) { - Area2DSW *a = monitor_query_list.first()->self(); + GodotArea2D *a = monitor_query_list.first()->self(); monitor_query_list.remove(monitor_query_list.first()); a->call_queries(); } } -void Space2DSW::setup() { +void GodotSpace2D::setup() { contact_debug_count = 0; while (mass_properties_update_list.first()) { @@ -1126,11 +1127,11 @@ void Space2DSW::setup() { } } -void Space2DSW::update() { +void GodotSpace2D::update() { broadphase->update(); } -void Space2DSW::set_param(PhysicsServer2D::SpaceParameter p_param, real_t p_value) { +void GodotSpace2D::set_param(PhysicsServer2D::SpaceParameter p_param, real_t p_value) { switch (p_param) { case PhysicsServer2D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: contact_recycle_radius = p_value; @@ -1156,7 +1157,7 @@ void Space2DSW::set_param(PhysicsServer2D::SpaceParameter p_param, real_t p_valu } } -real_t Space2DSW::get_param(PhysicsServer2D::SpaceParameter p_param) const { +real_t GodotSpace2D::get_param(PhysicsServer2D::SpaceParameter p_param) const { switch (p_param) { case PhysicsServer2D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: return contact_recycle_radius; @@ -1176,37 +1177,37 @@ real_t Space2DSW::get_param(PhysicsServer2D::SpaceParameter p_param) const { return 0; } -void Space2DSW::lock() { +void GodotSpace2D::lock() { locked = true; } -void Space2DSW::unlock() { +void GodotSpace2D::unlock() { locked = false; } -bool Space2DSW::is_locked() const { +bool GodotSpace2D::is_locked() const { return locked; } -PhysicsDirectSpaceState2DSW *Space2DSW::get_direct_state() { +GodotPhysicsDirectSpaceState2D *GodotSpace2D::get_direct_state() { return direct_access; } -Space2DSW::Space2DSW() { +GodotSpace2D::GodotSpace2D() { body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_linear", 2.0); body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_angular", Math::deg2rad(8.0)); body_time_to_sleep = GLOBAL_DEF("physics/2d/time_before_sleep", 0.5); ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/time_before_sleep", PropertyInfo(Variant::FLOAT, "physics/2d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); - broadphase = BroadPhase2DSW::create_func(); + broadphase = GodotBroadPhase2D::create_func(); broadphase->set_pair_callback(_broadphase_pair, this); broadphase->set_unpair_callback(_broadphase_unpair, this); - direct_access = memnew(PhysicsDirectSpaceState2DSW); + direct_access = memnew(GodotPhysicsDirectSpaceState2D); direct_access->space = this; } -Space2DSW::~Space2DSW() { +GodotSpace2D::~GodotSpace2D() { memdelete(broadphase); memdelete(direct_access); } diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/godot_space_2d.h index 746b5c6c9a..97e2928a9d 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/godot_space_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* space_2d_sw.h */ +/* godot_space_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,26 +28,27 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SPACE_2D_SW_H -#define SPACE_2D_SW_H +#ifndef GODOT_SPACE_2D_H +#define GODOT_SPACE_2D_H + +#include "godot_area_2d.h" +#include "godot_area_pair_2d.h" +#include "godot_body_2d.h" +#include "godot_body_pair_2d.h" +#include "godot_broad_phase_2d.h" +#include "godot_collision_object_2d.h" -#include "area_2d_sw.h" -#include "area_pair_2d_sw.h" -#include "body_2d_sw.h" -#include "body_pair_2d_sw.h" -#include "broad_phase_2d_sw.h" -#include "collision_object_2d_sw.h" #include "core/config/project_settings.h" #include "core/templates/hash_map.h" #include "core/typedefs.h" -class PhysicsDirectSpaceState2DSW : public PhysicsDirectSpaceState2D { - GDCLASS(PhysicsDirectSpaceState2DSW, PhysicsDirectSpaceState2D); +class GodotPhysicsDirectSpaceState2D : public PhysicsDirectSpaceState2D { + GDCLASS(GodotPhysicsDirectSpaceState2D, PhysicsDirectSpaceState2D); int _intersect_point_impl(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point, bool p_filter_by_canvas = false, ObjectID p_canvas_instance_id = ObjectID()); public: - Space2DSW *space = nullptr; + GodotSpace2D *space = nullptr; virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) override; virtual int intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) override; @@ -57,10 +58,10 @@ public: virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; - PhysicsDirectSpaceState2DSW() {} + GodotPhysicsDirectSpaceState2D() {} }; -class Space2DSW { +class GodotSpace2D { public: enum ElapsedTime { ELAPSED_TIME_INTEGRATE_FORCES, @@ -74,29 +75,29 @@ public: private: struct ExcludedShapeSW { - Shape2DSW *local_shape = nullptr; - const CollisionObject2DSW *against_object = nullptr; + GodotShape2D *local_shape = nullptr; + const GodotCollisionObject2D *against_object = nullptr; int against_shape_index = 0; }; uint64_t elapsed_time[ELAPSED_TIME_MAX] = {}; - PhysicsDirectSpaceState2DSW *direct_access = nullptr; + GodotPhysicsDirectSpaceState2D *direct_access = nullptr; RID self; - BroadPhase2DSW *broadphase; - SelfList<Body2DSW>::List active_list; - SelfList<Body2DSW>::List mass_properties_update_list; - SelfList<Body2DSW>::List state_query_list; - SelfList<Area2DSW>::List monitor_query_list; - SelfList<Area2DSW>::List area_moved_list; + GodotBroadPhase2D *broadphase; + SelfList<GodotBody2D>::List active_list; + SelfList<GodotBody2D>::List mass_properties_update_list; + SelfList<GodotBody2D>::List state_query_list; + SelfList<GodotArea2D>::List monitor_query_list; + SelfList<GodotArea2D>::List area_moved_list; - static void *_broadphase_pair(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_self); - static void _broadphase_unpair(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_data, void *p_self); + static void *_broadphase_pair(GodotCollisionObject2D *A, int p_subindex_A, GodotCollisionObject2D *B, int p_subindex_B, void *p_self); + static void _broadphase_unpair(GodotCollisionObject2D *A, int p_subindex_A, GodotCollisionObject2D *B, int p_subindex_B, void *p_data, void *p_self); - Set<CollisionObject2DSW *> objects; + Set<GodotCollisionObject2D *> objects; - Area2DSW *area = nullptr; + GodotArea2D *area = nullptr; real_t contact_recycle_radius = 1.0; real_t contact_max_separation = 1.5; @@ -107,7 +108,7 @@ private: INTERSECTION_QUERY_MAX = 2048 }; - CollisionObject2DSW *intersection_query_results[INTERSECTION_QUERY_MAX]; + GodotCollisionObject2D *intersection_query_results[INTERSECTION_QUERY_MAX]; int intersection_query_subindex_results[INTERSECTION_QUERY_MAX]; real_t body_linear_velocity_sleep_threshold = 0.0; @@ -122,40 +123,40 @@ private: int active_objects = 0; int collision_pairs = 0; - int _cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb); + int _cull_aabb_for_body(GodotBody2D *p_body, const Rect2 &p_aabb); Vector<Vector2> contact_debug; int contact_debug_count = 0; - friend class PhysicsDirectSpaceState2DSW; + friend class GodotPhysicsDirectSpaceState2D; public: _FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; } _FORCE_INLINE_ RID get_self() const { return self; } - void set_default_area(Area2DSW *p_area) { area = p_area; } - Area2DSW *get_default_area() const { return area; } + void set_default_area(GodotArea2D *p_area) { area = p_area; } + GodotArea2D *get_default_area() const { return area; } - const SelfList<Body2DSW>::List &get_active_body_list() const; - void body_add_to_active_list(SelfList<Body2DSW> *p_body); - void body_remove_from_active_list(SelfList<Body2DSW> *p_body); - void body_add_to_mass_properties_update_list(SelfList<Body2DSW> *p_body); - void body_remove_from_mass_properties_update_list(SelfList<Body2DSW> *p_body); - void area_add_to_moved_list(SelfList<Area2DSW> *p_area); - void area_remove_from_moved_list(SelfList<Area2DSW> *p_area); - const SelfList<Area2DSW>::List &get_moved_area_list() const; + const SelfList<GodotBody2D>::List &get_active_body_list() const; + void body_add_to_active_list(SelfList<GodotBody2D> *p_body); + void body_remove_from_active_list(SelfList<GodotBody2D> *p_body); + void body_add_to_mass_properties_update_list(SelfList<GodotBody2D> *p_body); + void body_remove_from_mass_properties_update_list(SelfList<GodotBody2D> *p_body); + void area_add_to_moved_list(SelfList<GodotArea2D> *p_area); + void area_remove_from_moved_list(SelfList<GodotArea2D> *p_area); + const SelfList<GodotArea2D>::List &get_moved_area_list() const; - void body_add_to_state_query_list(SelfList<Body2DSW> *p_body); - void body_remove_from_state_query_list(SelfList<Body2DSW> *p_body); + void body_add_to_state_query_list(SelfList<GodotBody2D> *p_body); + void body_remove_from_state_query_list(SelfList<GodotBody2D> *p_body); - void area_add_to_monitor_query_list(SelfList<Area2DSW> *p_area); - void area_remove_from_monitor_query_list(SelfList<Area2DSW> *p_area); + void area_add_to_monitor_query_list(SelfList<GodotArea2D> *p_area); + void area_remove_from_monitor_query_list(SelfList<GodotArea2D> *p_area); - BroadPhase2DSW *get_broadphase(); + GodotBroadPhase2D *get_broadphase(); - void add_object(CollisionObject2DSW *p_object); - void remove_object(CollisionObject2DSW *p_object); - const Set<CollisionObject2DSW *> &get_objects() const; + void add_object(GodotCollisionObject2D *p_object); + void remove_object(GodotCollisionObject2D *p_object); + const Set<GodotCollisionObject2D *> &get_objects() const; _FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; } _FORCE_INLINE_ real_t get_contact_max_separation() const { return contact_max_separation; } @@ -187,7 +188,7 @@ public: int get_collision_pairs() const { return collision_pairs; } - bool test_body_motion(Body2DSW *p_body, const PhysicsServer2D::MotionParameters &p_parameters, PhysicsServer2D::MotionResult *r_result); + bool test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::MotionParameters &p_parameters, PhysicsServer2D::MotionResult *r_result); void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); } _FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.is_empty(); } @@ -199,13 +200,13 @@ public: _FORCE_INLINE_ Vector<Vector2> get_debug_contacts() { return contact_debug; } _FORCE_INLINE_ int get_debug_contact_count() { return contact_debug_count; } - PhysicsDirectSpaceState2DSW *get_direct_state(); + GodotPhysicsDirectSpaceState2D *get_direct_state(); void set_elapsed_time(ElapsedTime p_time, uint64_t p_msec) { elapsed_time[p_time] = p_msec; } uint64_t get_elapsed_time(ElapsedTime p_time) const { return elapsed_time[p_time]; } - Space2DSW(); - ~Space2DSW(); + GodotSpace2D(); + ~GodotSpace2D(); }; -#endif // SPACE_2D_SW_H +#endif // GODOT_SPACE_2D_H diff --git a/servers/physics_2d/step_2d_sw.cpp b/servers/physics_2d/godot_step_2d.cpp index a03e30f850..3010315571 100644 --- a/servers/physics_2d/step_2d_sw.cpp +++ b/servers/physics_2d/godot_step_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* step_2d_sw.cpp */ +/* godot_step_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "step_2d_sw.h" +#include "godot_step_2d.h" #include "core/os/os.h" @@ -38,7 +38,7 @@ #define ISLAND_SIZE_RESERVE 512 #define CONSTRAINT_COUNT_RESERVE 1024 -void Step2DSW::_populate_island(Body2DSW *p_body, LocalVector<Body2DSW *> &p_body_island, LocalVector<Constraint2DSW *> &p_constraint_island) { +void GodotStep2D::_populate_island(GodotBody2D *p_body, LocalVector<GodotBody2D *> &p_body_island, LocalVector<GodotConstraint2D *> &p_constraint_island) { p_body->set_island_step(_step); if (p_body->get_mode() > PhysicsServer2D::BODY_MODE_KINEMATIC) { @@ -46,8 +46,8 @@ void Step2DSW::_populate_island(Body2DSW *p_body, LocalVector<Body2DSW *> &p_bod p_body_island.push_back(p_body); } - for (const Pair<Constraint2DSW *, int> &E : p_body->get_constraint_list()) { - Constraint2DSW *constraint = (Constraint2DSW *)E.first; + for (const Pair<GodotConstraint2D *, int> &E : p_body->get_constraint_list()) { + GodotConstraint2D *constraint = (GodotConstraint2D *)E.first; if (constraint->get_island_step() == _step) { continue; // Already processed. } @@ -59,7 +59,7 @@ void Step2DSW::_populate_island(Body2DSW *p_body, LocalVector<Body2DSW *> &p_bod if (i == E.second) { continue; } - Body2DSW *other_body = constraint->get_body_ptr()[i]; + GodotBody2D *other_body = constraint->get_body_ptr()[i]; if (other_body->get_island_step() == _step) { continue; // Already processed. } @@ -71,16 +71,16 @@ void Step2DSW::_populate_island(Body2DSW *p_body, LocalVector<Body2DSW *> &p_bod } } -void Step2DSW::_setup_contraint(uint32_t p_constraint_index, void *p_userdata) { - Constraint2DSW *constraint = all_constraints[p_constraint_index]; +void GodotStep2D::_setup_contraint(uint32_t p_constraint_index, void *p_userdata) { + GodotConstraint2D *constraint = all_constraints[p_constraint_index]; constraint->setup(delta); } -void Step2DSW::_pre_solve_island(LocalVector<Constraint2DSW *> &p_constraint_island) const { +void GodotStep2D::_pre_solve_island(LocalVector<GodotConstraint2D *> &p_constraint_island) const { uint32_t constraint_count = p_constraint_island.size(); uint32_t valid_constraint_count = 0; for (uint32_t constraint_index = 0; constraint_index < constraint_count; ++constraint_index) { - Constraint2DSW *constraint = p_constraint_island[constraint_index]; + GodotConstraint2D *constraint = p_constraint_island[constraint_index]; if (p_constraint_island[constraint_index]->pre_solve(delta)) { // Keep this constraint for solving. p_constraint_island[valid_constraint_count++] = constraint; @@ -89,8 +89,8 @@ void Step2DSW::_pre_solve_island(LocalVector<Constraint2DSW *> &p_constraint_isl p_constraint_island.resize(valid_constraint_count); } -void Step2DSW::_solve_island(uint32_t p_island_index, void *p_userdata) const { - const LocalVector<Constraint2DSW *> &constraint_island = constraint_islands[p_island_index]; +void GodotStep2D::_solve_island(uint32_t p_island_index, void *p_userdata) const { + const LocalVector<GodotConstraint2D *> &constraint_island = constraint_islands[p_island_index]; for (int i = 0; i < iterations; i++) { uint32_t constraint_count = constraint_island.size(); @@ -100,12 +100,12 @@ void Step2DSW::_solve_island(uint32_t p_island_index, void *p_userdata) const { } } -void Step2DSW::_check_suspend(LocalVector<Body2DSW *> &p_body_island) const { +void GodotStep2D::_check_suspend(LocalVector<GodotBody2D *> &p_body_island) const { bool can_sleep = true; uint32_t body_count = p_body_island.size(); for (uint32_t body_index = 0; body_index < body_count; ++body_index) { - Body2DSW *body = p_body_island[body_index]; + GodotBody2D *body = p_body_island[body_index]; if (!body->sleep_test(delta)) { can_sleep = false; @@ -114,7 +114,7 @@ void Step2DSW::_check_suspend(LocalVector<Body2DSW *> &p_body_island) const { // Put all to sleep or wake up everyone. for (uint32_t body_index = 0; body_index < body_count; ++body_index) { - Body2DSW *body = p_body_island[body_index]; + GodotBody2D *body = p_body_island[body_index]; bool active = body->is_active(); @@ -124,7 +124,7 @@ void Step2DSW::_check_suspend(LocalVector<Body2DSW *> &p_body_island) const { } } -void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { +void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta, int p_iterations) { p_space->lock(); // can't access space during this p_space->setup(); //update inertias, etc @@ -134,7 +134,7 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { iterations = p_iterations; delta = p_delta; - const SelfList<Body2DSW>::List *body_list = &p_space->get_active_body_list(); + const SelfList<GodotBody2D>::List *body_list = &p_space->get_active_body_list(); /* INTEGRATE FORCES */ @@ -143,7 +143,7 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { int active_count = 0; - const SelfList<Body2DSW> *b = body_list->first(); + const SelfList<GodotBody2D> *b = body_list->first(); while (b) { b->self()->integrate_forces(p_delta); b = b->next(); @@ -154,7 +154,7 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); - p_space->set_elapsed_time(Space2DSW::ELAPSED_TIME_INTEGRATE_FORCES, profile_endtime - profile_begtime); + p_space->set_elapsed_time(GodotSpace2D::ELAPSED_TIME_INTEGRATE_FORCES, profile_endtime - profile_begtime); profile_begtime = profile_endtime; } @@ -162,11 +162,11 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { uint32_t island_count = 0; - const SelfList<Area2DSW>::List &aml = p_space->get_moved_area_list(); + const SelfList<GodotArea2D>::List &aml = p_space->get_moved_area_list(); while (aml.first()) { - for (const Set<Constraint2DSW *>::Element *E = aml.first()->self()->get_constraints().front(); E; E = E->next()) { - Constraint2DSW *constraint = E->get(); + for (const Set<GodotConstraint2D *>::Element *E = aml.first()->self()->get_constraints().front(); E; E = E->next()) { + GodotConstraint2D *constraint = E->get(); if (constraint->get_island_step() == _step) { continue; } @@ -177,13 +177,13 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { if (constraint_islands.size() < island_count) { constraint_islands.resize(island_count); } - LocalVector<Constraint2DSW *> &constraint_island = constraint_islands[island_count - 1]; + LocalVector<GodotConstraint2D *> &constraint_island = constraint_islands[island_count - 1]; constraint_island.clear(); all_constraints.push_back(constraint); constraint_island.push_back(constraint); } - p_space->area_remove_from_moved_list((SelfList<Area2DSW> *)aml.first()); //faster to remove here + p_space->area_remove_from_moved_list((SelfList<GodotArea2D> *)aml.first()); //faster to remove here } /* GENERATE CONSTRAINT ISLANDS FOR ACTIVE RIGID BODIES */ @@ -193,14 +193,14 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { uint32_t body_island_count = 0; while (b) { - Body2DSW *body = b->self(); + GodotBody2D *body = b->self(); if (body->get_island_step() != _step) { ++body_island_count; if (body_islands.size() < body_island_count) { body_islands.resize(body_island_count); } - LocalVector<Body2DSW *> &body_island = body_islands[body_island_count - 1]; + LocalVector<GodotBody2D *> &body_island = body_islands[body_island_count - 1]; body_island.clear(); body_island.reserve(BODY_ISLAND_SIZE_RESERVE); @@ -208,7 +208,7 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { if (constraint_islands.size() < island_count) { constraint_islands.resize(island_count); } - LocalVector<Constraint2DSW *> &constraint_island = constraint_islands[island_count - 1]; + LocalVector<GodotConstraint2D *> &constraint_island = constraint_islands[island_count - 1]; constraint_island.clear(); constraint_island.reserve(ISLAND_SIZE_RESERVE); @@ -229,18 +229,18 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); - p_space->set_elapsed_time(Space2DSW::ELAPSED_TIME_GENERATE_ISLANDS, profile_endtime - profile_begtime); + p_space->set_elapsed_time(GodotSpace2D::ELAPSED_TIME_GENERATE_ISLANDS, profile_endtime - profile_begtime); profile_begtime = profile_endtime; } /* SETUP CONSTRAINTS / PROCESS COLLISIONS */ uint32_t total_contraint_count = all_constraints.size(); - work_pool.do_work(total_contraint_count, this, &Step2DSW::_setup_contraint, nullptr); + work_pool.do_work(total_contraint_count, this, &GodotStep2D::_setup_contraint, nullptr); { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); - p_space->set_elapsed_time(Space2DSW::ELAPSED_TIME_SETUP_CONSTRAINTS, profile_endtime - profile_begtime); + p_space->set_elapsed_time(GodotSpace2D::ELAPSED_TIME_SETUP_CONSTRAINTS, profile_endtime - profile_begtime); profile_begtime = profile_endtime; } @@ -256,14 +256,14 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { // Warning: _solve_island modifies the constraint islands for optimization purpose, // their content is not reliable after these calls and shouldn't be used anymore. if (island_count > 1) { - work_pool.do_work(island_count, this, &Step2DSW::_solve_island, nullptr); + work_pool.do_work(island_count, this, &GodotStep2D::_solve_island, nullptr); } else if (island_count > 0) { _solve_island(0); } { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); - p_space->set_elapsed_time(Space2DSW::ELAPSED_TIME_SOLVE_CONSTRAINTS, profile_endtime - profile_begtime); + p_space->set_elapsed_time(GodotSpace2D::ELAPSED_TIME_SOLVE_CONSTRAINTS, profile_endtime - profile_begtime); profile_begtime = profile_endtime; } @@ -271,7 +271,7 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { b = body_list->first(); while (b) { - const SelfList<Body2DSW> *n = b->next(); + const SelfList<GodotBody2D> *n = b->next(); b->self()->integrate_velocities(p_delta); b = n; // in case it shuts itself down } @@ -284,7 +284,7 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); - p_space->set_elapsed_time(Space2DSW::ELAPSED_TIME_INTEGRATE_VELOCITIES, profile_endtime - profile_begtime); + p_space->set_elapsed_time(GodotSpace2D::ELAPSED_TIME_INTEGRATE_VELOCITIES, profile_endtime - profile_begtime); //profile_begtime=profile_endtime; } @@ -295,7 +295,7 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { _step++; } -Step2DSW::Step2DSW() { +GodotStep2D::GodotStep2D() { body_islands.reserve(BODY_ISLAND_COUNT_RESERVE); constraint_islands.reserve(ISLAND_COUNT_RESERVE); all_constraints.reserve(CONSTRAINT_COUNT_RESERVE); @@ -303,6 +303,6 @@ Step2DSW::Step2DSW() { work_pool.init(); } -Step2DSW::~Step2DSW() { +GodotStep2D::~GodotStep2D() { work_pool.finish(); } diff --git a/servers/physics_2d/step_2d_sw.h b/servers/physics_2d/godot_step_2d.h index de8e76cc99..efec243632 100644 --- a/servers/physics_2d/step_2d_sw.h +++ b/servers/physics_2d/godot_step_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* step_2d_sw.h */ +/* godot_step_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,15 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef STEP_2D_SW_H -#define STEP_2D_SW_H +#ifndef GODOT_STEP_2D_H +#define GODOT_STEP_2D_H -#include "space_2d_sw.h" +#include "godot_space_2d.h" #include "core/templates/local_vector.h" #include "core/templates/thread_work_pool.h" -class Step2DSW { +class GodotStep2D { uint64_t _step = 1; int iterations = 0; @@ -44,20 +44,20 @@ class Step2DSW { ThreadWorkPool work_pool; - LocalVector<LocalVector<Body2DSW *>> body_islands; - LocalVector<LocalVector<Constraint2DSW *>> constraint_islands; - LocalVector<Constraint2DSW *> all_constraints; + LocalVector<LocalVector<GodotBody2D *>> body_islands; + LocalVector<LocalVector<GodotConstraint2D *>> constraint_islands; + LocalVector<GodotConstraint2D *> all_constraints; - void _populate_island(Body2DSW *p_body, LocalVector<Body2DSW *> &p_body_island, LocalVector<Constraint2DSW *> &p_constraint_island); + void _populate_island(GodotBody2D *p_body, LocalVector<GodotBody2D *> &p_body_island, LocalVector<GodotConstraint2D *> &p_constraint_island); void _setup_contraint(uint32_t p_constraint_index, void *p_userdata = nullptr); - void _pre_solve_island(LocalVector<Constraint2DSW *> &p_constraint_island) const; + void _pre_solve_island(LocalVector<GodotConstraint2D *> &p_constraint_island) const; void _solve_island(uint32_t p_island_index, void *p_userdata = nullptr) const; - void _check_suspend(LocalVector<Body2DSW *> &p_body_island) const; + void _check_suspend(LocalVector<GodotBody2D *> &p_body_island) const; public: - void step(Space2DSW *p_space, real_t p_delta, int p_iterations); - Step2DSW(); - ~Step2DSW(); + void step(GodotSpace2D *p_space, real_t p_delta, int p_iterations); + GodotStep2D(); + ~GodotStep2D(); }; -#endif // STEP_2D_SW_H +#endif // GODOT_STEP_2D_H diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp deleted file mode 100644 index c2205e33b0..0000000000 --- a/servers/physics_2d/physics_server_2d_sw.cpp +++ /dev/null @@ -1,1349 +0,0 @@ -/*************************************************************************/ -/* physics_server_2d_sw.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "physics_server_2d_sw.h" - -#include "body_direct_state_2d_sw.h" -#include "broad_phase_2d_bvh.h" -#include "collision_solver_2d_sw.h" -#include "core/config/project_settings.h" -#include "core/debugger/engine_debugger.h" -#include "core/os/os.h" - -#define FLUSH_QUERY_CHECK(m_object) \ - ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead."); - -RID PhysicsServer2DSW::_shape_create(ShapeType p_shape) { - Shape2DSW *shape = nullptr; - switch (p_shape) { - case SHAPE_WORLD_BOUNDARY: { - shape = memnew(WorldBoundaryShape2DSW); - } break; - case SHAPE_SEPARATION_RAY: { - shape = memnew(SeparationRayShape2DSW); - } break; - case SHAPE_SEGMENT: { - shape = memnew(SegmentShape2DSW); - } break; - case SHAPE_CIRCLE: { - shape = memnew(CircleShape2DSW); - } break; - case SHAPE_RECTANGLE: { - shape = memnew(RectangleShape2DSW); - } break; - case SHAPE_CAPSULE: { - shape = memnew(CapsuleShape2DSW); - } break; - case SHAPE_CONVEX_POLYGON: { - shape = memnew(ConvexPolygonShape2DSW); - } break; - case SHAPE_CONCAVE_POLYGON: { - shape = memnew(ConcavePolygonShape2DSW); - } break; - case SHAPE_CUSTOM: { - ERR_FAIL_V(RID()); - - } break; - } - - RID id = shape_owner.make_rid(shape); - shape->set_self(id); - - return id; -} - -RID PhysicsServer2DSW::world_boundary_shape_create() { - return _shape_create(SHAPE_WORLD_BOUNDARY); -} - -RID PhysicsServer2DSW::separation_ray_shape_create() { - return _shape_create(SHAPE_SEPARATION_RAY); -} - -RID PhysicsServer2DSW::segment_shape_create() { - return _shape_create(SHAPE_SEGMENT); -} - -RID PhysicsServer2DSW::circle_shape_create() { - return _shape_create(SHAPE_CIRCLE); -} - -RID PhysicsServer2DSW::rectangle_shape_create() { - return _shape_create(SHAPE_RECTANGLE); -} - -RID PhysicsServer2DSW::capsule_shape_create() { - return _shape_create(SHAPE_CAPSULE); -} - -RID PhysicsServer2DSW::convex_polygon_shape_create() { - return _shape_create(SHAPE_CONVEX_POLYGON); -} - -RID PhysicsServer2DSW::concave_polygon_shape_create() { - return _shape_create(SHAPE_CONCAVE_POLYGON); -} - -void PhysicsServer2DSW::shape_set_data(RID p_shape, const Variant &p_data) { - Shape2DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - shape->set_data(p_data); -}; - -void PhysicsServer2DSW::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) { - Shape2DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - shape->set_custom_bias(p_bias); -} - -PhysicsServer2D::ShapeType PhysicsServer2DSW::shape_get_type(RID p_shape) const { - const Shape2DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND_V(!shape, SHAPE_CUSTOM); - return shape->get_type(); -}; - -Variant PhysicsServer2DSW::shape_get_data(RID p_shape) const { - const Shape2DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND_V(!shape, Variant()); - ERR_FAIL_COND_V(!shape->is_configured(), Variant()); - return shape->get_data(); -}; - -real_t PhysicsServer2DSW::shape_get_custom_solver_bias(RID p_shape) const { - const Shape2DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND_V(!shape, 0); - return shape->get_custom_bias(); -} - -void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_userdata) { - CollCbkData *cbk = (CollCbkData *)p_userdata; - - if (cbk->max == 0) { - return; - } - - Vector2 rel_dir = (p_point_A - p_point_B); - real_t rel_length2 = rel_dir.length_squared(); - if (cbk->valid_dir != Vector2()) { - if (cbk->valid_depth < 10e20) { - if (rel_length2 > cbk->valid_depth * cbk->valid_depth || - (rel_length2 > CMP_EPSILON && cbk->valid_dir.dot(rel_dir.normalized()) < CMP_EPSILON)) { - cbk->invalid_by_dir++; - return; - } - } else { - if (rel_length2 > 0 && cbk->valid_dir.dot(rel_dir.normalized()) < CMP_EPSILON) { - return; - } - } - } - - if (cbk->amount == cbk->max) { - //find least deep - real_t min_depth = 1e20; - int min_depth_idx = 0; - for (int i = 0; i < cbk->amount; i++) { - real_t d = cbk->ptr[i * 2 + 0].distance_squared_to(cbk->ptr[i * 2 + 1]); - if (d < min_depth) { - min_depth = d; - min_depth_idx = i; - } - } - - if (rel_length2 < min_depth) { - return; - } - cbk->ptr[min_depth_idx * 2 + 0] = p_point_A; - cbk->ptr[min_depth_idx * 2 + 1] = p_point_B; - cbk->passed++; - - } else { - cbk->ptr[cbk->amount * 2 + 0] = p_point_A; - cbk->ptr[cbk->amount * 2 + 1] = p_point_B; - cbk->amount++; - cbk->passed++; - } -} - -bool PhysicsServer2DSW::shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) { - Shape2DSW *shape_A = shape_owner.get_or_null(p_shape_A); - ERR_FAIL_COND_V(!shape_A, false); - Shape2DSW *shape_B = shape_owner.get_or_null(p_shape_B); - ERR_FAIL_COND_V(!shape_B, false); - - if (p_result_max == 0) { - return CollisionSolver2DSW::solve(shape_A, p_xform_A, p_motion_A, shape_B, p_xform_B, p_motion_B, nullptr, nullptr); - } - - CollCbkData cbk; - cbk.max = p_result_max; - cbk.amount = 0; - cbk.passed = 0; - cbk.ptr = r_results; - - bool res = CollisionSolver2DSW::solve(shape_A, p_xform_A, p_motion_A, shape_B, p_xform_B, p_motion_B, _shape_col_cbk, &cbk); - r_result_count = cbk.amount; - return res; -} - -RID PhysicsServer2DSW::space_create() { - Space2DSW *space = memnew(Space2DSW); - RID id = space_owner.make_rid(space); - space->set_self(id); - RID area_id = area_create(); - Area2DSW *area = area_owner.get_or_null(area_id); - ERR_FAIL_COND_V(!area, RID()); - space->set_default_area(area); - area->set_space(space); - area->set_priority(-1); - - return id; -}; - -void PhysicsServer2DSW::space_set_active(RID p_space, bool p_active) { - Space2DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - if (p_active) { - active_spaces.insert(space); - } else { - active_spaces.erase(space); - } -} - -bool PhysicsServer2DSW::space_is_active(RID p_space) const { - const Space2DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, false); - - return active_spaces.has(space); -} - -void PhysicsServer2DSW::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) { - Space2DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - - space->set_param(p_param, p_value); -} - -real_t PhysicsServer2DSW::space_get_param(RID p_space, SpaceParameter p_param) const { - const Space2DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, 0); - return space->get_param(p_param); -} - -void PhysicsServer2DSW::space_set_debug_contacts(RID p_space, int p_max_contacts) { - Space2DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - space->set_debug_contacts(p_max_contacts); -} - -Vector<Vector2> PhysicsServer2DSW::space_get_contacts(RID p_space) const { - Space2DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, Vector<Vector2>()); - return space->get_debug_contacts(); -} - -int PhysicsServer2DSW::space_get_contact_count(RID p_space) const { - Space2DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, 0); - return space->get_debug_contact_count(); -} - -PhysicsDirectSpaceState2D *PhysicsServer2DSW::space_get_direct_state(RID p_space) { - Space2DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, nullptr); - ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); - - return space->get_direct_state(); -} - -RID PhysicsServer2DSW::area_create() { - Area2DSW *area = memnew(Area2DSW); - RID rid = area_owner.make_rid(area); - area->set_self(rid); - return rid; -}; - -void PhysicsServer2DSW::area_set_space(RID p_area, RID p_space) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - Space2DSW *space = nullptr; - if (p_space.is_valid()) { - space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - } - - if (area->get_space() == space) { - return; //pointless - } - - area->clear_constraints(); - area->set_space(space); -}; - -RID PhysicsServer2DSW::area_get_space(RID p_area) const { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, RID()); - - Space2DSW *space = area->get_space(); - if (!space) { - return RID(); - } - return space->get_self(); -}; - -void PhysicsServer2DSW::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_space_override_mode(p_mode); -} - -PhysicsServer2D::AreaSpaceOverrideMode PhysicsServer2DSW::area_get_space_override_mode(RID p_area) const { - const Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, AREA_SPACE_OVERRIDE_DISABLED); - - return area->get_space_override_mode(); -} - -void PhysicsServer2DSW::area_add_shape(RID p_area, RID p_shape, const Transform2D &p_transform, bool p_disabled) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - Shape2DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - - area->add_shape(shape, p_transform, p_disabled); -} - -void PhysicsServer2DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - Shape2DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - ERR_FAIL_COND(!shape->is_configured()); - - area->set_shape(p_shape_idx, shape); -} - -void PhysicsServer2DSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform2D &p_transform) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_shape_transform(p_shape_idx, p_transform); -} - -void PhysicsServer2DSW::area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - ERR_FAIL_INDEX(p_shape, area->get_shape_count()); - FLUSH_QUERY_CHECK(area); - - area->set_shape_disabled(p_shape, p_disabled); -} - -int PhysicsServer2DSW::area_get_shape_count(RID p_area) const { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, -1); - - return area->get_shape_count(); -} - -RID PhysicsServer2DSW::area_get_shape(RID p_area, int p_shape_idx) const { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, RID()); - - Shape2DSW *shape = area->get_shape(p_shape_idx); - ERR_FAIL_COND_V(!shape, RID()); - - return shape->get_self(); -} - -Transform2D PhysicsServer2DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, Transform2D()); - - return area->get_shape_transform(p_shape_idx); -} - -void PhysicsServer2DSW::area_remove_shape(RID p_area, int p_shape_idx) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->remove_shape(p_shape_idx); -} - -void PhysicsServer2DSW::area_clear_shapes(RID p_area) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - while (area->get_shape_count()) { - area->remove_shape(0); - } -} - -void PhysicsServer2DSW::area_attach_object_instance_id(RID p_area, ObjectID p_id) { - if (space_owner.owns(p_area)) { - Space2DSW *space = space_owner.get_or_null(p_area); - p_area = space->get_default_area()->get_self(); - } - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - area->set_instance_id(p_id); -} - -ObjectID PhysicsServer2DSW::area_get_object_instance_id(RID p_area) const { - if (space_owner.owns(p_area)) { - Space2DSW *space = space_owner.get_or_null(p_area); - p_area = space->get_default_area()->get_self(); - } - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, ObjectID()); - return area->get_instance_id(); -} - -void PhysicsServer2DSW::area_attach_canvas_instance_id(RID p_area, ObjectID p_id) { - if (space_owner.owns(p_area)) { - Space2DSW *space = space_owner.get_or_null(p_area); - p_area = space->get_default_area()->get_self(); - } - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - area->set_canvas_instance_id(p_id); -} - -ObjectID PhysicsServer2DSW::area_get_canvas_instance_id(RID p_area) const { - if (space_owner.owns(p_area)) { - Space2DSW *space = space_owner.get_or_null(p_area); - p_area = space->get_default_area()->get_self(); - } - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, ObjectID()); - return area->get_canvas_instance_id(); -} - -void PhysicsServer2DSW::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) { - if (space_owner.owns(p_area)) { - Space2DSW *space = space_owner.get_or_null(p_area); - p_area = space->get_default_area()->get_self(); - } - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - area->set_param(p_param, p_value); -}; - -void PhysicsServer2DSW::area_set_transform(RID p_area, const Transform2D &p_transform) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - area->set_transform(p_transform); -}; - -Variant PhysicsServer2DSW::area_get_param(RID p_area, AreaParameter p_param) const { - if (space_owner.owns(p_area)) { - Space2DSW *space = space_owner.get_or_null(p_area); - p_area = space->get_default_area()->get_self(); - } - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, Variant()); - - return area->get_param(p_param); -}; - -Transform2D PhysicsServer2DSW::area_get_transform(RID p_area) const { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, Transform2D()); - - return area->get_transform(); -}; - -void PhysicsServer2DSW::area_set_pickable(RID p_area, bool p_pickable) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - area->set_pickable(p_pickable); -} - -void PhysicsServer2DSW::area_set_monitorable(RID p_area, bool p_monitorable) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - FLUSH_QUERY_CHECK(area); - - area->set_monitorable(p_monitorable); -} - -void PhysicsServer2DSW::area_set_collision_mask(RID p_area, uint32_t p_mask) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_collision_mask(p_mask); -} - -void PhysicsServer2DSW::area_set_collision_layer(RID p_area, uint32_t p_layer) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_collision_layer(p_layer); -} - -void PhysicsServer2DSW::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); -} - -void PhysicsServer2DSW::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - Area2DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); -} - -/* BODY API */ - -RID PhysicsServer2DSW::body_create() { - Body2DSW *body = memnew(Body2DSW); - RID rid = body_owner.make_rid(body); - body->set_self(rid); - return rid; -} - -void PhysicsServer2DSW::body_set_space(RID p_body, RID p_space) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - Space2DSW *space = nullptr; - if (p_space.is_valid()) { - space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - } - - if (body->get_space() == space) { - return; //pointless - } - - body->clear_constraint_list(); - body->set_space(space); -}; - -RID PhysicsServer2DSW::body_get_space(RID p_body) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, RID()); - - Space2DSW *space = body->get_space(); - if (!space) { - return RID(); - } - return space->get_self(); -}; - -void PhysicsServer2DSW::body_set_mode(RID p_body, BodyMode p_mode) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - FLUSH_QUERY_CHECK(body); - - body->set_mode(p_mode); -}; - -PhysicsServer2D::BodyMode PhysicsServer2DSW::body_get_mode(RID p_body) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, BODY_MODE_STATIC); - - return body->get_mode(); -}; - -void PhysicsServer2DSW::body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform, bool p_disabled) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - Shape2DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - - body->add_shape(shape, p_transform, p_disabled); -} - -void PhysicsServer2DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - Shape2DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - ERR_FAIL_COND(!shape->is_configured()); - - body->set_shape(p_shape_idx, shape); -} - -void PhysicsServer2DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform2D &p_transform) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_shape_transform(p_shape_idx, p_transform); -} - -int PhysicsServer2DSW::body_get_shape_count(RID p_body) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, -1); - - return body->get_shape_count(); -} - -RID PhysicsServer2DSW::body_get_shape(RID p_body, int p_shape_idx) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, RID()); - - Shape2DSW *shape = body->get_shape(p_shape_idx); - ERR_FAIL_COND_V(!shape, RID()); - - return shape->get_self(); -} - -Transform2D PhysicsServer2DSW::body_get_shape_transform(RID p_body, int p_shape_idx) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, Transform2D()); - - return body->get_shape_transform(p_shape_idx); -} - -void PhysicsServer2DSW::body_remove_shape(RID p_body, int p_shape_idx) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->remove_shape(p_shape_idx); -} - -void PhysicsServer2DSW::body_clear_shapes(RID p_body) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - while (body->get_shape_count()) { - body->remove_shape(0); - } -} - -void PhysicsServer2DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); - FLUSH_QUERY_CHECK(body); - - body->set_shape_disabled(p_shape_idx, p_disabled); -} - -void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); - FLUSH_QUERY_CHECK(body); - - body->set_shape_as_one_way_collision(p_shape_idx, p_enable, p_margin); -} - -void PhysicsServer2DSW::body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_continuous_collision_detection_mode(p_mode); -} - -PhysicsServer2DSW::CCDMode PhysicsServer2DSW::body_get_continuous_collision_detection_mode(RID p_body) const { - const Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, CCD_MODE_DISABLED); - - return body->get_continuous_collision_detection_mode(); -} - -void PhysicsServer2DSW::body_attach_object_instance_id(RID p_body, ObjectID p_id) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_instance_id(p_id); -}; - -ObjectID PhysicsServer2DSW::body_get_object_instance_id(RID p_body) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, ObjectID()); - - return body->get_instance_id(); -}; - -void PhysicsServer2DSW::body_attach_canvas_instance_id(RID p_body, ObjectID p_id) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_canvas_instance_id(p_id); -}; - -ObjectID PhysicsServer2DSW::body_get_canvas_instance_id(RID p_body) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, ObjectID()); - - return body->get_canvas_instance_id(); -}; - -void PhysicsServer2DSW::body_set_collision_layer(RID p_body, uint32_t p_layer) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_collision_layer(p_layer); -}; - -uint32_t PhysicsServer2DSW::body_get_collision_layer(RID p_body) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_collision_layer(); -}; - -void PhysicsServer2DSW::body_set_collision_mask(RID p_body, uint32_t p_mask) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_collision_mask(p_mask); -}; - -uint32_t PhysicsServer2DSW::body_get_collision_mask(RID p_body) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_collision_mask(); -}; - -void PhysicsServer2DSW::body_set_param(RID p_body, BodyParameter p_param, const Variant &p_value) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_param(p_param, p_value); -}; - -Variant PhysicsServer2DSW::body_get_param(RID p_body, BodyParameter p_param) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_param(p_param); -}; - -void PhysicsServer2DSW::body_reset_mass_properties(RID p_body) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - return body->reset_mass_properties(); -} - -void PhysicsServer2DSW::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_state(p_state, p_variant); -}; - -Variant PhysicsServer2DSW::body_get_state(RID p_body, BodyState p_state) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, Variant()); - - return body->get_state(p_state); -}; - -void PhysicsServer2DSW::body_set_applied_force(RID p_body, const Vector2 &p_force) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_applied_force(p_force); - body->wakeup(); -}; - -Vector2 PhysicsServer2DSW::body_get_applied_force(RID p_body) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, Vector2()); - return body->get_applied_force(); -}; - -void PhysicsServer2DSW::body_set_applied_torque(RID p_body, real_t p_torque) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_applied_torque(p_torque); - body->wakeup(); -}; - -real_t PhysicsServer2DSW::body_get_applied_torque(RID p_body) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_applied_torque(); -}; - -void PhysicsServer2DSW::body_apply_central_impulse(RID p_body, const Vector2 &p_impulse) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->apply_central_impulse(p_impulse); - body->wakeup(); -} - -void PhysicsServer2DSW::body_apply_torque_impulse(RID p_body, real_t p_torque) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - _update_shapes(); - - body->apply_torque_impulse(p_torque); - body->wakeup(); -} - -void PhysicsServer2DSW::body_apply_impulse(RID p_body, const Vector2 &p_impulse, const Vector2 &p_position) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - _update_shapes(); - - body->apply_impulse(p_impulse, p_position); - body->wakeup(); -}; - -void PhysicsServer2DSW::body_add_central_force(RID p_body, const Vector2 &p_force) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->add_central_force(p_force); - body->wakeup(); -}; - -void PhysicsServer2DSW::body_add_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->add_force(p_force, p_position); - body->wakeup(); -}; - -void PhysicsServer2DSW::body_add_torque(RID p_body, real_t p_torque) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->add_torque(p_torque); - body->wakeup(); -}; - -void PhysicsServer2DSW::body_set_axis_velocity(RID p_body, const Vector2 &p_axis_velocity) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - _update_shapes(); - - Vector2 v = body->get_linear_velocity(); - Vector2 axis = p_axis_velocity.normalized(); - v -= axis * axis.dot(v); - v += p_axis_velocity; - body->set_linear_velocity(v); - body->wakeup(); -}; - -void PhysicsServer2DSW::body_add_collision_exception(RID p_body, RID p_body_b) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->add_exception(p_body_b); - body->wakeup(); -}; - -void PhysicsServer2DSW::body_remove_collision_exception(RID p_body, RID p_body_b) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->remove_exception(p_body_b); - body->wakeup(); -}; - -void PhysicsServer2DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - for (int i = 0; i < body->get_exceptions().size(); i++) { - p_exceptions->push_back(body->get_exceptions()[i]); - } -}; - -void PhysicsServer2DSW::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); -}; - -real_t PhysicsServer2DSW::body_get_contacts_reported_depth_threshold(RID p_body) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - return 0; -}; - -void PhysicsServer2DSW::body_set_omit_force_integration(RID p_body, bool p_omit) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_omit_force_integration(p_omit); -}; - -bool PhysicsServer2DSW::body_is_omitting_force_integration(RID p_body) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, false); - return body->get_omit_force_integration(); -}; - -void PhysicsServer2DSW::body_set_max_contacts_reported(RID p_body, int p_contacts) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_max_contacts_reported(p_contacts); -} - -int PhysicsServer2DSW::body_get_max_contacts_reported(RID p_body) const { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, -1); - return body->get_max_contacts_reported(); -} - -void PhysicsServer2DSW::body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_state_sync_callback(p_instance, p_callback); -} - -void PhysicsServer2DSW::body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_force_integration_callback(p_callable, p_udata); -} - -bool PhysicsServer2DSW::body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, false); - ERR_FAIL_INDEX_V(p_body_shape, body->get_shape_count(), false); - - return shape_collide(body->get_shape(p_body_shape)->get_self(), body->get_transform() * body->get_shape_transform(p_body_shape), Vector2(), p_shape, p_shape_xform, p_motion, r_results, p_result_max, r_result_count); -} - -void PhysicsServer2DSW::body_set_pickable(RID p_body, bool p_pickable) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_pickable(p_pickable); -} - -bool PhysicsServer2DSW::body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result) { - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, false); - ERR_FAIL_COND_V(!body->get_space(), false); - ERR_FAIL_COND_V(body->get_space()->is_locked(), false); - - _update_shapes(); - - return body->get_space()->test_body_motion(body, p_parameters, r_result); -} - -PhysicsDirectBodyState2D *PhysicsServer2DSW::body_get_direct_state(RID p_body) { - ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); - - Body2DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, nullptr); - - ERR_FAIL_COND_V(!body->get_space(), nullptr); - ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); - - return body->get_direct_state(); -} - -/* JOINT API */ - -RID PhysicsServer2DSW::joint_create() { - Joint2DSW *joint = memnew(Joint2DSW); - RID joint_rid = joint_owner.make_rid(joint); - joint->set_self(joint_rid); - return joint_rid; -} - -void PhysicsServer2DSW::joint_clear(RID p_joint) { - Joint2DSW *joint = joint_owner.get_or_null(p_joint); - if (joint->get_type() != JOINT_TYPE_MAX) { - Joint2DSW *empty_joint = memnew(Joint2DSW); - empty_joint->copy_settings_from(joint); - - joint_owner.replace(p_joint, empty_joint); - memdelete(joint); - } -} - -void PhysicsServer2DSW::joint_set_param(RID p_joint, JointParam p_param, real_t p_value) { - Joint2DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - - switch (p_param) { - case JOINT_PARAM_BIAS: - joint->set_bias(p_value); - break; - case JOINT_PARAM_MAX_BIAS: - joint->set_max_bias(p_value); - break; - case JOINT_PARAM_MAX_FORCE: - joint->set_max_force(p_value); - break; - } -} - -real_t PhysicsServer2DSW::joint_get_param(RID p_joint, JointParam p_param) const { - const Joint2DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, -1); - - switch (p_param) { - case JOINT_PARAM_BIAS: - return joint->get_bias(); - break; - case JOINT_PARAM_MAX_BIAS: - return joint->get_max_bias(); - break; - case JOINT_PARAM_MAX_FORCE: - return joint->get_max_force(); - break; - } - - return 0; -} - -void PhysicsServer2DSW::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) { - Joint2DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - - joint->disable_collisions_between_bodies(p_disable); - - if (2 == joint->get_body_count()) { - Body2DSW *body_a = *joint->get_body_ptr(); - Body2DSW *body_b = *(joint->get_body_ptr() + 1); - - if (p_disable) { - body_add_collision_exception(body_a->get_self(), body_b->get_self()); - body_add_collision_exception(body_b->get_self(), body_a->get_self()); - } else { - body_remove_collision_exception(body_a->get_self(), body_b->get_self()); - body_remove_collision_exception(body_b->get_self(), body_a->get_self()); - } - } -} - -bool PhysicsServer2DSW::joint_is_disabled_collisions_between_bodies(RID p_joint) const { - const Joint2DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, true); - - return joint->is_disabled_collisions_between_bodies(); -} - -void PhysicsServer2DSW::joint_make_pin(RID p_joint, const Vector2 &p_pos, RID p_body_a, RID p_body_b) { - Body2DSW *A = body_owner.get_or_null(p_body_a); - ERR_FAIL_COND(!A); - Body2DSW *B = nullptr; - if (body_owner.owns(p_body_b)) { - B = body_owner.get_or_null(p_body_b); - ERR_FAIL_COND(!B); - } - - Joint2DSW *prev_joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(prev_joint == nullptr); - - Joint2DSW *joint = memnew(PinJoint2DSW(p_pos, A, B)); - - joint_owner.replace(p_joint, joint); - joint->copy_settings_from(prev_joint); - memdelete(prev_joint); -} - -void PhysicsServer2DSW::joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) { - Body2DSW *A = body_owner.get_or_null(p_body_a); - ERR_FAIL_COND(!A); - - Body2DSW *B = body_owner.get_or_null(p_body_b); - ERR_FAIL_COND(!B); - - Joint2DSW *prev_joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(prev_joint == nullptr); - - Joint2DSW *joint = memnew(GrooveJoint2DSW(p_a_groove1, p_a_groove2, p_b_anchor, A, B)); - - joint_owner.replace(p_joint, joint); - joint->copy_settings_from(prev_joint); - memdelete(prev_joint); -} - -void PhysicsServer2DSW::joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b) { - Body2DSW *A = body_owner.get_or_null(p_body_a); - ERR_FAIL_COND(!A); - - Body2DSW *B = body_owner.get_or_null(p_body_b); - ERR_FAIL_COND(!B); - - Joint2DSW *prev_joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(prev_joint == nullptr); - - Joint2DSW *joint = memnew(DampedSpringJoint2DSW(p_anchor_a, p_anchor_b, A, B)); - - joint_owner.replace(p_joint, joint); - joint->copy_settings_from(prev_joint); - memdelete(prev_joint); -} - -void PhysicsServer2DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { - Joint2DSW *j = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!j); - ERR_FAIL_COND(j->get_type() != JOINT_TYPE_PIN); - - PinJoint2DSW *pin_joint = static_cast<PinJoint2DSW *>(j); - pin_joint->set_param(p_param, p_value); -} - -real_t PhysicsServer2DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { - Joint2DSW *j = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!j, 0); - ERR_FAIL_COND_V(j->get_type() != JOINT_TYPE_PIN, 0); - - PinJoint2DSW *pin_joint = static_cast<PinJoint2DSW *>(j); - return pin_joint->get_param(p_param); -} - -void PhysicsServer2DSW::damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value) { - Joint2DSW *j = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!j); - ERR_FAIL_COND(j->get_type() != JOINT_TYPE_DAMPED_SPRING); - - DampedSpringJoint2DSW *dsj = static_cast<DampedSpringJoint2DSW *>(j); - dsj->set_param(p_param, p_value); -} - -real_t PhysicsServer2DSW::damped_spring_joint_get_param(RID p_joint, DampedSpringParam p_param) const { - Joint2DSW *j = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!j, 0); - ERR_FAIL_COND_V(j->get_type() != JOINT_TYPE_DAMPED_SPRING, 0); - - DampedSpringJoint2DSW *dsj = static_cast<DampedSpringJoint2DSW *>(j); - return dsj->get_param(p_param); -} - -PhysicsServer2D::JointType PhysicsServer2DSW::joint_get_type(RID p_joint) const { - Joint2DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, JOINT_TYPE_PIN); - - return joint->get_type(); -} - -void PhysicsServer2DSW::free(RID p_rid) { - _update_shapes(); // just in case - - if (shape_owner.owns(p_rid)) { - Shape2DSW *shape = shape_owner.get_or_null(p_rid); - - while (shape->get_owners().size()) { - ShapeOwner2DSW *so = shape->get_owners().front()->key(); - so->remove_shape(shape); - } - - shape_owner.free(p_rid); - memdelete(shape); - } else if (body_owner.owns(p_rid)) { - Body2DSW *body = body_owner.get_or_null(p_rid); - - /* - if (body->get_state_query()) - _clear_query(body->get_state_query()); - - if (body->get_direct_state_query()) - _clear_query(body->get_direct_state_query()); - */ - - body_set_space(p_rid, RID()); - - while (body->get_shape_count()) { - body->remove_shape(0); - } - - body_owner.free(p_rid); - memdelete(body); - - } else if (area_owner.owns(p_rid)) { - Area2DSW *area = area_owner.get_or_null(p_rid); - - /* - if (area->get_monitor_query()) - _clear_query(area->get_monitor_query()); - */ - - area->set_space(nullptr); - - while (area->get_shape_count()) { - area->remove_shape(0); - } - - area_owner.free(p_rid); - memdelete(area); - } else if (space_owner.owns(p_rid)) { - Space2DSW *space = space_owner.get_or_null(p_rid); - - while (space->get_objects().size()) { - CollisionObject2DSW *co = (CollisionObject2DSW *)space->get_objects().front()->get(); - co->set_space(nullptr); - } - - active_spaces.erase(space); - free(space->get_default_area()->get_self()); - space_owner.free(p_rid); - memdelete(space); - } else if (joint_owner.owns(p_rid)) { - Joint2DSW *joint = joint_owner.get_or_null(p_rid); - - joint_owner.free(p_rid); - memdelete(joint); - - } else { - ERR_FAIL_MSG("Invalid ID."); - } -}; - -void PhysicsServer2DSW::set_active(bool p_active) { - active = p_active; -}; - -void PhysicsServer2DSW::set_collision_iterations(int p_iterations) { - iterations = p_iterations; -}; - -void PhysicsServer2DSW::init() { - doing_sync = false; - iterations = 8; // 8? - stepper = memnew(Step2DSW); -}; - -void PhysicsServer2DSW::step(real_t p_step) { - if (!active) { - return; - } - - _update_shapes(); - - island_count = 0; - active_objects = 0; - collision_pairs = 0; - for (Set<const Space2DSW *>::Element *E = active_spaces.front(); E; E = E->next()) { - stepper->step((Space2DSW *)E->get(), p_step, iterations); - island_count += E->get()->get_island_count(); - active_objects += E->get()->get_active_objects(); - collision_pairs += E->get()->get_collision_pairs(); - } -}; - -void PhysicsServer2DSW::sync() { - doing_sync = true; -}; - -void PhysicsServer2DSW::flush_queries() { - if (!active) { - return; - } - - flushing_queries = true; - - uint64_t time_beg = OS::get_singleton()->get_ticks_usec(); - - for (Set<const Space2DSW *>::Element *E = active_spaces.front(); E; E = E->next()) { - Space2DSW *space = (Space2DSW *)E->get(); - space->call_queries(); - } - - flushing_queries = false; - - if (EngineDebugger::is_profiling("servers")) { - uint64_t total_time[Space2DSW::ELAPSED_TIME_MAX]; - static const char *time_name[Space2DSW::ELAPSED_TIME_MAX] = { - "integrate_forces", - "generate_islands", - "setup_constraints", - "solve_constraints", - "integrate_velocities" - }; - - for (int i = 0; i < Space2DSW::ELAPSED_TIME_MAX; i++) { - total_time[i] = 0; - } - - for (Set<const Space2DSW *>::Element *E = active_spaces.front(); E; E = E->next()) { - for (int i = 0; i < Space2DSW::ELAPSED_TIME_MAX; i++) { - total_time[i] += E->get()->get_elapsed_time(Space2DSW::ElapsedTime(i)); - } - } - - Array values; - values.resize(Space2DSW::ELAPSED_TIME_MAX * 2); - for (int i = 0; i < Space2DSW::ELAPSED_TIME_MAX; i++) { - values[i * 2 + 0] = time_name[i]; - values[i * 2 + 1] = USEC_TO_SEC(total_time[i]); - } - values.push_back("flush_queries"); - values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg)); - - values.push_front("physics_2d"); - EngineDebugger::profiler_add_frame_data("servers", values); - } -} - -void PhysicsServer2DSW::end_sync() { - doing_sync = false; -} - -void PhysicsServer2DSW::finish() { - memdelete(stepper); -}; - -void PhysicsServer2DSW::_update_shapes() { - while (pending_shape_update_list.first()) { - pending_shape_update_list.first()->self()->_shape_changed(); - pending_shape_update_list.remove(pending_shape_update_list.first()); - } -} - -int PhysicsServer2DSW::get_process_info(ProcessInfo p_info) { - switch (p_info) { - case INFO_ACTIVE_OBJECTS: { - return active_objects; - } break; - case INFO_COLLISION_PAIRS: { - return collision_pairs; - } break; - case INFO_ISLAND_COUNT: { - return island_count; - } break; - } - - return 0; -} - -PhysicsServer2DSW *PhysicsServer2DSW::singletonsw = nullptr; - -PhysicsServer2DSW::PhysicsServer2DSW(bool p_using_threads) { - singletonsw = this; - BroadPhase2DSW::create_func = BroadPhase2DBVH::_create; - - using_threads = p_using_threads; -}; diff --git a/servers/physics_3d/gjk_epa.cpp b/servers/physics_3d/gjk_epa.cpp index a1dbdd0a70..ef6535a878 100644 --- a/servers/physics_3d/gjk_epa.cpp +++ b/servers/physics_3d/gjk_epa.cpp @@ -105,7 +105,7 @@ typedef unsigned char U1; // MinkowskiDiff struct MinkowskiDiff { - const Shape3DSW* m_shapes[2]; + const GodotShape3D* m_shapes[2]; Transform3D transform_A; Transform3D transform_B; @@ -113,10 +113,10 @@ struct MinkowskiDiff { real_t margin_A = 0.0; real_t margin_B = 0.0; - Vector3 (*get_support)(const Shape3DSW*, const Vector3&, real_t); + Vector3 (*get_support)(const GodotShape3D*, const Vector3&, real_t); - void Initialize(const Shape3DSW* shape0, const Transform3D& wtrs0, const real_t margin0, - const Shape3DSW* shape1, const Transform3D& wtrs1, const real_t margin1) { + void Initialize(const GodotShape3D* shape0, const Transform3D& wtrs0, const real_t margin0, + const GodotShape3D* shape1, const Transform3D& wtrs1, const real_t margin1) { m_shapes[0] = shape0; m_shapes[1] = shape1; transform_A = wtrs0; @@ -131,11 +131,11 @@ struct MinkowskiDiff { } } - static Vector3 get_support_without_margin(const Shape3DSW* p_shape, const Vector3& p_dir, real_t p_margin) { + static Vector3 get_support_without_margin(const GodotShape3D* p_shape, const Vector3& p_dir, real_t p_margin) { return p_shape->get_support(p_dir.normalized()); } - static Vector3 get_support_with_margin(const Shape3DSW* p_shape, const Vector3& p_dir, real_t p_margin) { + static Vector3 get_support_with_margin(const GodotShape3D* p_shape, const Vector3& p_dir, real_t p_margin) { Vector3 local_dir_norm = p_dir; if (local_dir_norm.length_squared() < CMP_EPSILON2) { local_dir_norm = Vector3(-1.0, -1.0, -1.0); @@ -862,8 +862,8 @@ struct GJK }; // - static void Initialize( const Shape3DSW* shape0, const Transform3D& wtrs0, real_t margin0, - const Shape3DSW* shape1, const Transform3D& wtrs1, real_t margin1, + static void Initialize( const GodotShape3D* shape0, const Transform3D& wtrs0, real_t margin0, + const GodotShape3D* shape1, const Transform3D& wtrs1, real_t margin1, sResults& results, tShape& shape) { @@ -884,10 +884,10 @@ struct GJK // // -bool Distance( const Shape3DSW* shape0, +bool Distance( const GodotShape3D* shape0, const Transform3D& wtrs0, real_t margin0, - const Shape3DSW* shape1, + const GodotShape3D* shape1, const Transform3D& wtrs1, real_t margin1, const Vector3& guess, @@ -925,10 +925,10 @@ bool Distance( const Shape3DSW* shape0, // -bool Penetration( const Shape3DSW* shape0, +bool Penetration( const GodotShape3D* shape0, const Transform3D& wtrs0, real_t margin0, - const Shape3DSW* shape1, + const GodotShape3D* shape1, const Transform3D& wtrs1, real_t margin1, const Vector3& guess, @@ -993,7 +993,7 @@ bool Penetration( const Shape3DSW* shape0, /* clang-format on */ -bool gjk_epa_calculate_distance(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_result_A, Vector3 &r_result_B) { +bool gjk_epa_calculate_distance(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_result_A, Vector3 &r_result_B) { GjkEpa2::sResults res; if (GjkEpa2::Distance(p_shape_A, p_transform_A, 0.0, p_shape_B, p_transform_B, 0.0, p_transform_B.origin - p_transform_A.origin, res)) { @@ -1005,7 +1005,7 @@ bool gjk_epa_calculate_distance(const Shape3DSW *p_shape_A, const Transform3D &p return false; } -bool gjk_epa_calculate_penetration(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap, real_t p_margin_A, real_t p_margin_B) { +bool gjk_epa_calculate_penetration(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, GodotCollisionSolver3D::CallbackResult p_result_callback, void *p_userdata, bool p_swap, real_t p_margin_A, real_t p_margin_B) { GjkEpa2::sResults res; if (GjkEpa2::Penetration(p_shape_A, p_transform_A, p_margin_A, p_shape_B, p_transform_B, p_margin_B, p_transform_B.origin - p_transform_A.origin, res)) { diff --git a/servers/physics_3d/gjk_epa.h b/servers/physics_3d/gjk_epa.h index 69e85d2bc0..39a7d03435 100644 --- a/servers/physics_3d/gjk_epa.h +++ b/servers/physics_3d/gjk_epa.h @@ -31,10 +31,10 @@ #ifndef GJK_EPA_H #define GJK_EPA_H -#include "collision_solver_3d_sw.h" -#include "shape_3d_sw.h" +#include "godot_collision_solver_3d.h" +#include "godot_shape_3d.h" -bool gjk_epa_calculate_penetration(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, real_t p_margin_A = 0.0, real_t p_margin_B = 0.0); -bool gjk_epa_calculate_distance(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_result_A, Vector3 &r_result_B); +bool gjk_epa_calculate_penetration(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, GodotCollisionSolver3D::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, real_t p_margin_A = 0.0, real_t p_margin_B = 0.0); +bool gjk_epa_calculate_distance(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_result_A, Vector3 &r_result_B); #endif diff --git a/servers/physics_3d/area_3d_sw.cpp b/servers/physics_3d/godot_area_3d.cpp index 630ab7e229..e115e17061 100644 --- a/servers/physics_3d/area_3d_sw.cpp +++ b/servers/physics_3d/godot_area_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* area_3d_sw.cpp */ +/* godot_area_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,39 +28,40 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "area_3d_sw.h" -#include "body_3d_sw.h" -#include "soft_body_3d_sw.h" -#include "space_3d_sw.h" +#include "godot_area_3d.h" -Area3DSW::BodyKey::BodyKey(SoftBody3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { +#include "godot_body_3d.h" +#include "godot_soft_body_3d.h" +#include "godot_space_3d.h" + +GodotArea3D::BodyKey::BodyKey(GodotSoftBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { rid = p_body->get_self(); instance_id = p_body->get_instance_id(); body_shape = p_body_shape; area_shape = p_area_shape; } -Area3DSW::BodyKey::BodyKey(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { +GodotArea3D::BodyKey::BodyKey(GodotBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { rid = p_body->get_self(); instance_id = p_body->get_instance_id(); body_shape = p_body_shape; area_shape = p_area_shape; } -Area3DSW::BodyKey::BodyKey(Area3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { +GodotArea3D::BodyKey::BodyKey(GodotArea3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { rid = p_body->get_self(); instance_id = p_body->get_instance_id(); body_shape = p_body_shape; area_shape = p_area_shape; } -void Area3DSW::_shapes_changed() { +void GodotArea3D::_shapes_changed() { if (!moved_list.in_list() && get_space()) { get_space()->area_add_to_moved_list(&moved_list); } } -void Area3DSW::set_transform(const Transform3D &p_transform) { +void GodotArea3D::set_transform(const Transform3D &p_transform) { if (!moved_list.in_list() && get_space()) { get_space()->area_add_to_moved_list(&moved_list); } @@ -69,7 +70,7 @@ void Area3DSW::set_transform(const Transform3D &p_transform) { _set_inv_transform(p_transform.affine_inverse()); } -void Area3DSW::set_space(Space3DSW *p_space) { +void GodotArea3D::set_space(GodotSpace3D *p_space) { if (get_space()) { if (monitor_query_list.in_list()) { get_space()->area_remove_from_monitor_query_list(&monitor_query_list); @@ -85,7 +86,7 @@ void Area3DSW::set_space(Space3DSW *p_space) { _set_space(p_space); } -void Area3DSW::set_monitor_callback(ObjectID p_id, const StringName &p_method) { +void GodotArea3D::set_monitor_callback(ObjectID p_id, const StringName &p_method) { if (p_id == monitor_callback_id) { monitor_callback_method = p_method; return; @@ -106,7 +107,7 @@ void Area3DSW::set_monitor_callback(ObjectID p_id, const StringName &p_method) { } } -void Area3DSW::set_area_monitor_callback(ObjectID p_id, const StringName &p_method) { +void GodotArea3D::set_area_monitor_callback(ObjectID p_id, const StringName &p_method) { if (p_id == area_monitor_callback_id) { area_monitor_callback_method = p_method; return; @@ -127,7 +128,7 @@ void Area3DSW::set_area_monitor_callback(ObjectID p_id, const StringName &p_meth } } -void Area3DSW::set_space_override_mode(PhysicsServer3D::AreaSpaceOverrideMode p_mode) { +void GodotArea3D::set_space_override_mode(PhysicsServer3D::AreaSpaceOverrideMode p_mode) { bool do_override = p_mode != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED; if (do_override == (space_override_mode != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED)) { return; @@ -137,7 +138,7 @@ void Area3DSW::set_space_override_mode(PhysicsServer3D::AreaSpaceOverrideMode p_ _shape_changed(); } -void Area3DSW::set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value) { +void GodotArea3D::set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value) { switch (p_param) { case PhysicsServer3D::AREA_PARAM_GRAVITY: gravity = p_value; @@ -180,7 +181,7 @@ void Area3DSW::set_param(PhysicsServer3D::AreaParameter p_param, const Variant & } } -Variant Area3DSW::get_param(PhysicsServer3D::AreaParameter p_param) const { +Variant GodotArea3D::get_param(PhysicsServer3D::AreaParameter p_param) const { switch (p_param) { case PhysicsServer3D::AREA_PARAM_GRAVITY: return gravity; @@ -211,7 +212,7 @@ Variant Area3DSW::get_param(PhysicsServer3D::AreaParameter p_param) const { return Variant(); } -void Area3DSW::_queue_monitor_update() { +void GodotArea3D::_queue_monitor_update() { ERR_FAIL_COND(!get_space()); if (!monitor_query_list.in_list()) { @@ -219,7 +220,7 @@ void Area3DSW::_queue_monitor_update() { } } -void Area3DSW::set_monitorable(bool p_monitorable) { +void GodotArea3D::set_monitorable(bool p_monitorable) { if (monitorable == p_monitorable) { return; } @@ -228,7 +229,7 @@ void Area3DSW::set_monitorable(bool p_monitorable) { _set_static(!monitorable); } -void Area3DSW::call_queries() { +void GodotArea3D::call_queries() { if (monitor_callback_id.is_valid() && !monitored_bodies.is_empty()) { Variant res[5]; Variant *resptr[5]; @@ -304,7 +305,7 @@ void Area3DSW::call_queries() { } } -void Area3DSW::compute_gravity(const Vector3 &p_position, Vector3 &r_gravity) const { +void GodotArea3D::compute_gravity(const Vector3 &p_position, Vector3 &r_gravity) const { if (is_gravity_point()) { const real_t gravity_distance_scale = get_gravity_distance_scale(); Vector3 v = get_transform().xform(get_gravity_vector()) - p_position; @@ -324,13 +325,13 @@ void Area3DSW::compute_gravity(const Vector3 &p_position, Vector3 &r_gravity) co } } -Area3DSW::Area3DSW() : - CollisionObject3DSW(TYPE_AREA), +GodotArea3D::GodotArea3D() : + GodotCollisionObject3D(TYPE_AREA), monitor_query_list(this), moved_list(this) { _set_static(true); //areas are never active set_ray_pickable(false); } -Area3DSW::~Area3DSW() { +GodotArea3D::~GodotArea3D() { } diff --git a/servers/physics_3d/area_3d_sw.h b/servers/physics_3d/godot_area_3d.h index af5c23949c..e8caa9221b 100644 --- a/servers/physics_3d/area_3d_sw.h +++ b/servers/physics_3d/godot_area_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* area_3d_sw.h */ +/* godot_area_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,19 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AREA_SW_H -#define AREA_SW_H +#ifndef GODOT_AREA_3D_H +#define GODOT_AREA_3D_H + +#include "godot_collision_object_3d.h" -#include "collision_object_3d_sw.h" #include "core/templates/self_list.h" #include "servers/physics_server_3d.h" -class Space3DSW; -class Body3DSW; -class SoftBody3DSW; -class Constraint3DSW; +class GodotSpace3D; +class GodotBody3D; +class GodotSoftBody3D; +class GodotConstraint3D; -class Area3DSW : public CollisionObject3DSW { +class GodotArea3D : public GodotCollisionObject3D { PhysicsServer3D::AreaSpaceOverrideMode space_override_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED; real_t gravity = 9.80665; Vector3 gravity_vector = Vector3(0, -1, 0); @@ -62,8 +63,8 @@ class Area3DSW : public CollisionObject3DSW { ObjectID area_monitor_callback_id; StringName area_monitor_callback_method; - SelfList<Area3DSW> monitor_query_list; - SelfList<Area3DSW> moved_list; + SelfList<GodotArea3D> monitor_query_list; + SelfList<GodotArea3D> moved_list; struct BodyKey { RID rid; @@ -84,9 +85,9 @@ class Area3DSW : public CollisionObject3DSW { } _FORCE_INLINE_ BodyKey() {} - BodyKey(SoftBody3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape); - BodyKey(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape); - BodyKey(Area3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape); + BodyKey(GodotSoftBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape); + BodyKey(GodotBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape); + BodyKey(GodotArea3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape); }; struct BodyState { @@ -99,7 +100,7 @@ class Area3DSW : public CollisionObject3DSW { Map<BodyKey, BodyState> monitored_bodies; Map<BodyKey, BodyState> monitored_areas; - Set<Constraint3DSW *> constraints; + Set<GodotConstraint3D *> constraints; virtual void _shapes_changed(); void _queue_monitor_update(); @@ -111,14 +112,14 @@ public: void set_area_monitor_callback(ObjectID p_id, const StringName &p_method); _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id.is_valid(); } - _FORCE_INLINE_ void add_body_to_query(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape); - _FORCE_INLINE_ void remove_body_from_query(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape); + _FORCE_INLINE_ void add_body_to_query(GodotBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape); + _FORCE_INLINE_ void remove_body_from_query(GodotBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape); - _FORCE_INLINE_ void add_soft_body_to_query(SoftBody3DSW *p_soft_body, uint32_t p_soft_body_shape, uint32_t p_area_shape); - _FORCE_INLINE_ void remove_soft_body_from_query(SoftBody3DSW *p_soft_body, uint32_t p_soft_body_shape, uint32_t p_area_shape); + _FORCE_INLINE_ void add_soft_body_to_query(GodotSoftBody3D *p_soft_body, uint32_t p_soft_body_shape, uint32_t p_area_shape); + _FORCE_INLINE_ void remove_soft_body_from_query(GodotSoftBody3D *p_soft_body, uint32_t p_soft_body_shape, uint32_t p_area_shape); - _FORCE_INLINE_ void add_area_to_query(Area3DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape); - _FORCE_INLINE_ void remove_area_from_query(Area3DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape); + _FORCE_INLINE_ void add_area_to_query(GodotArea3D *p_area, uint32_t p_area_shape, uint32_t p_self_shape); + _FORCE_INLINE_ void remove_area_from_query(GodotArea3D *p_area, uint32_t p_area_shape, uint32_t p_self_shape); void set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value); Variant get_param(PhysicsServer3D::AreaParameter p_param) const; @@ -162,9 +163,9 @@ public: _FORCE_INLINE_ void set_wind_direction(const Vector3 &p_wind_direction) { wind_direction = p_wind_direction; } _FORCE_INLINE_ const Vector3 &get_wind_direction() const { return wind_direction; } - _FORCE_INLINE_ void add_constraint(Constraint3DSW *p_constraint) { constraints.insert(p_constraint); } - _FORCE_INLINE_ void remove_constraint(Constraint3DSW *p_constraint) { constraints.erase(p_constraint); } - _FORCE_INLINE_ const Set<Constraint3DSW *> &get_constraints() const { return constraints; } + _FORCE_INLINE_ void add_constraint(GodotConstraint3D *p_constraint) { constraints.insert(p_constraint); } + _FORCE_INLINE_ void remove_constraint(GodotConstraint3D *p_constraint) { constraints.erase(p_constraint); } + _FORCE_INLINE_ const Set<GodotConstraint3D *> &get_constraints() const { return constraints; } _FORCE_INLINE_ void clear_constraints() { constraints.clear(); } void set_monitorable(bool p_monitorable); @@ -172,17 +173,17 @@ public: void set_transform(const Transform3D &p_transform); - void set_space(Space3DSW *p_space); + void set_space(GodotSpace3D *p_space); void call_queries(); void compute_gravity(const Vector3 &p_position, Vector3 &r_gravity) const; - Area3DSW(); - ~Area3DSW(); + GodotArea3D(); + ~GodotArea3D(); }; -void Area3DSW::add_soft_body_to_query(SoftBody3DSW *p_soft_body, uint32_t p_soft_body_shape, uint32_t p_area_shape) { +void GodotArea3D::add_soft_body_to_query(GodotSoftBody3D *p_soft_body, uint32_t p_soft_body_shape, uint32_t p_area_shape) { BodyKey bk(p_soft_body, p_soft_body_shape, p_area_shape); monitored_soft_bodies[bk].inc(); if (!monitor_query_list.in_list()) { @@ -190,7 +191,7 @@ void Area3DSW::add_soft_body_to_query(SoftBody3DSW *p_soft_body, uint32_t p_soft } } -void Area3DSW::remove_soft_body_from_query(SoftBody3DSW *p_soft_body, uint32_t p_soft_body_shape, uint32_t p_area_shape) { +void GodotArea3D::remove_soft_body_from_query(GodotSoftBody3D *p_soft_body, uint32_t p_soft_body_shape, uint32_t p_area_shape) { BodyKey bk(p_soft_body, p_soft_body_shape, p_area_shape); monitored_soft_bodies[bk].dec(); if (!monitor_query_list.in_list()) { @@ -198,7 +199,7 @@ void Area3DSW::remove_soft_body_from_query(SoftBody3DSW *p_soft_body, uint32_t p } } -void Area3DSW::add_body_to_query(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { +void GodotArea3D::add_body_to_query(GodotBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { BodyKey bk(p_body, p_body_shape, p_area_shape); monitored_bodies[bk].inc(); if (!monitor_query_list.in_list()) { @@ -206,7 +207,7 @@ void Area3DSW::add_body_to_query(Body3DSW *p_body, uint32_t p_body_shape, uint32 } } -void Area3DSW::remove_body_from_query(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { +void GodotArea3D::remove_body_from_query(GodotBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { BodyKey bk(p_body, p_body_shape, p_area_shape); monitored_bodies[bk].dec(); if (!monitor_query_list.in_list()) { @@ -214,7 +215,7 @@ void Area3DSW::remove_body_from_query(Body3DSW *p_body, uint32_t p_body_shape, u } } -void Area3DSW::add_area_to_query(Area3DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { +void GodotArea3D::add_area_to_query(GodotArea3D *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { BodyKey bk(p_area, p_area_shape, p_self_shape); monitored_areas[bk].inc(); if (!monitor_query_list.in_list()) { @@ -222,7 +223,7 @@ void Area3DSW::add_area_to_query(Area3DSW *p_area, uint32_t p_area_shape, uint32 } } -void Area3DSW::remove_area_from_query(Area3DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { +void GodotArea3D::remove_area_from_query(GodotArea3D *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { BodyKey bk(p_area, p_area_shape, p_self_shape); monitored_areas[bk].dec(); if (!monitor_query_list.in_list()) { @@ -231,15 +232,15 @@ void Area3DSW::remove_area_from_query(Area3DSW *p_area, uint32_t p_area_shape, u } struct AreaCMP { - Area3DSW *area = nullptr; + GodotArea3D *area = nullptr; int refCount = 0; _FORCE_INLINE_ bool operator==(const AreaCMP &p_cmp) const { return area->get_self() == p_cmp.area->get_self(); } _FORCE_INLINE_ bool operator<(const AreaCMP &p_cmp) const { return area->get_priority() < p_cmp.area->get_priority(); } _FORCE_INLINE_ AreaCMP() {} - _FORCE_INLINE_ AreaCMP(Area3DSW *p_area) { + _FORCE_INLINE_ AreaCMP(GodotArea3D *p_area) { area = p_area; refCount = 1; } }; -#endif // AREA__SW_H +#endif // GODOT_AREA_3D_H diff --git a/servers/physics_3d/area_pair_3d_sw.cpp b/servers/physics_3d/godot_area_pair_3d.cpp index bf4f0035b4..7453153de6 100644 --- a/servers/physics_3d/area_pair_3d_sw.cpp +++ b/servers/physics_3d/godot_area_pair_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* area_pair_3d_sw.cpp */ +/* godot_area_pair_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,12 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "area_pair_3d_sw.h" -#include "collision_solver_3d_sw.h" +#include "godot_area_pair_3d.h" -bool AreaPair3DSW::setup(real_t p_step) { +#include "godot_collision_solver_3d.h" + +bool GodotAreaPair3D::setup(real_t p_step) { bool result = false; - if (area->collides_with(body) && CollisionSolver3DSW::solve_static(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), nullptr, this)) { + if (area->collides_with(body) && GodotCollisionSolver3D::solve_static(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), nullptr, this)) { result = true; } @@ -51,7 +52,7 @@ bool AreaPair3DSW::setup(real_t p_step) { return process_collision; } -bool AreaPair3DSW::pre_solve(real_t p_step) { +bool GodotAreaPair3D::pre_solve(real_t p_step) { if (!process_collision) { return false; } @@ -77,11 +78,11 @@ bool AreaPair3DSW::pre_solve(real_t p_step) { return false; // Never do any post solving. } -void AreaPair3DSW::solve(real_t p_step) { +void GodotAreaPair3D::solve(real_t p_step) { // Nothing to do. } -AreaPair3DSW::AreaPair3DSW(Body3DSW *p_body, int p_body_shape, Area3DSW *p_area, int p_area_shape) { +GodotAreaPair3D::GodotAreaPair3D(GodotBody3D *p_body, int p_body_shape, GodotArea3D *p_area, int p_area_shape) { body = p_body; area = p_area; body_shape = p_body_shape; @@ -93,7 +94,7 @@ AreaPair3DSW::AreaPair3DSW(Body3DSW *p_body, int p_body_shape, Area3DSW *p_area, } } -AreaPair3DSW::~AreaPair3DSW() { +GodotAreaPair3D::~GodotAreaPair3D() { if (colliding) { if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) { body->remove_area(area); @@ -108,10 +109,10 @@ AreaPair3DSW::~AreaPair3DSW() { //////////////////////////////////////////////////// -bool Area2Pair3DSW::setup(real_t p_step) { +bool GodotArea2Pair3D::setup(real_t p_step) { bool result_a = area_a->collides_with(area_b); bool result_b = area_b->collides_with(area_a); - if ((result_a || result_b) && !CollisionSolver3DSW::solve_static(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), nullptr, this)) { + if ((result_a || result_b) && !GodotCollisionSolver3D::solve_static(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), nullptr, this)) { result_a = false; result_b = false; } @@ -139,7 +140,7 @@ bool Area2Pair3DSW::setup(real_t p_step) { return process_collision; } -bool Area2Pair3DSW::pre_solve(real_t p_step) { +bool GodotArea2Pair3D::pre_solve(real_t p_step) { if (process_collision_a) { if (colliding_a) { area_a->add_area_to_query(area_b, shape_b, shape_a); @@ -159,11 +160,11 @@ bool Area2Pair3DSW::pre_solve(real_t p_step) { return false; // Never do any post solving. } -void Area2Pair3DSW::solve(real_t p_step) { +void GodotArea2Pair3D::solve(real_t p_step) { // Nothing to do. } -Area2Pair3DSW::Area2Pair3DSW(Area3DSW *p_area_a, int p_shape_a, Area3DSW *p_area_b, int p_shape_b) { +GodotArea2Pair3D::GodotArea2Pair3D(GodotArea3D *p_area_a, int p_shape_a, GodotArea3D *p_area_b, int p_shape_b) { area_a = p_area_a; area_b = p_area_b; shape_a = p_shape_a; @@ -172,7 +173,7 @@ Area2Pair3DSW::Area2Pair3DSW(Area3DSW *p_area_a, int p_shape_a, Area3DSW *p_area area_b->add_constraint(this); } -Area2Pair3DSW::~Area2Pair3DSW() { +GodotArea2Pair3D::~GodotArea2Pair3D() { if (colliding_a) { if (area_a->has_area_monitor_callback()) { area_a->remove_area_from_query(area_b, shape_b, shape_a); @@ -191,11 +192,11 @@ Area2Pair3DSW::~Area2Pair3DSW() { //////////////////////////////////////////////////// -bool AreaSoftBodyPair3DSW::setup(real_t p_step) { +bool GodotAreaSoftBodyPair3D::setup(real_t p_step) { bool result = false; if ( area->collides_with(soft_body) && - CollisionSolver3DSW::solve_static( + GodotCollisionSolver3D::solve_static( soft_body->get_shape(soft_body_shape), soft_body->get_transform() * soft_body->get_shape_transform(soft_body_shape), area->get_shape(area_shape), @@ -219,7 +220,7 @@ bool AreaSoftBodyPair3DSW::setup(real_t p_step) { return process_collision; } -bool AreaSoftBodyPair3DSW::pre_solve(real_t p_step) { +bool GodotAreaSoftBodyPair3D::pre_solve(real_t p_step) { if (!process_collision) { return false; } @@ -245,11 +246,11 @@ bool AreaSoftBodyPair3DSW::pre_solve(real_t p_step) { return false; // Never do any post solving. } -void AreaSoftBodyPair3DSW::solve(real_t p_step) { +void GodotAreaSoftBodyPair3D::solve(real_t p_step) { // Nothing to do. } -AreaSoftBodyPair3DSW::AreaSoftBodyPair3DSW(SoftBody3DSW *p_soft_body, int p_soft_body_shape, Area3DSW *p_area, int p_area_shape) { +GodotAreaSoftBodyPair3D::GodotAreaSoftBodyPair3D(GodotSoftBody3D *p_soft_body, int p_soft_body_shape, GodotArea3D *p_area, int p_area_shape) { soft_body = p_soft_body; area = p_area; soft_body_shape = p_soft_body_shape; @@ -258,7 +259,7 @@ AreaSoftBodyPair3DSW::AreaSoftBodyPair3DSW(SoftBody3DSW *p_soft_body, int p_soft area->add_constraint(this); } -AreaSoftBodyPair3DSW::~AreaSoftBodyPair3DSW() { +GodotAreaSoftBodyPair3D::~GodotAreaSoftBodyPair3D() { if (colliding) { if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) { soft_body->remove_area(area); diff --git a/servers/physics_3d/area_pair_3d_sw.h b/servers/physics_3d/godot_area_pair_3d.h index 4572dcbb23..f55c03be03 100644 --- a/servers/physics_3d/area_pair_3d_sw.h +++ b/servers/physics_3d/godot_area_pair_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* area_pair_3d_sw.h */ +/* godot_area_pair_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,17 +28,17 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AREA_PAIR_SW_H -#define AREA_PAIR_SW_H +#ifndef GODOT_AREA_PAIR_3D_H +#define GODOT_AREA_PAIR_3D_H -#include "area_3d_sw.h" -#include "body_3d_sw.h" -#include "constraint_3d_sw.h" -#include "soft_body_3d_sw.h" +#include "godot_area_3d.h" +#include "godot_body_3d.h" +#include "godot_constraint_3d.h" +#include "godot_soft_body_3d.h" -class AreaPair3DSW : public Constraint3DSW { - Body3DSW *body; - Area3DSW *area; +class GodotAreaPair3D : public GodotConstraint3D { + GodotBody3D *body; + GodotArea3D *area; int body_shape; int area_shape; bool colliding = false; @@ -49,13 +49,13 @@ public: virtual bool pre_solve(real_t p_step) override; virtual void solve(real_t p_step) override; - AreaPair3DSW(Body3DSW *p_body, int p_body_shape, Area3DSW *p_area, int p_area_shape); - ~AreaPair3DSW(); + GodotAreaPair3D(GodotBody3D *p_body, int p_body_shape, GodotArea3D *p_area, int p_area_shape); + ~GodotAreaPair3D(); }; -class Area2Pair3DSW : public Constraint3DSW { - Area3DSW *area_a; - Area3DSW *area_b; +class GodotArea2Pair3D : public GodotConstraint3D { + GodotArea3D *area_a; + GodotArea3D *area_b; int shape_a; int shape_b; bool colliding_a = false; @@ -68,13 +68,13 @@ public: virtual bool pre_solve(real_t p_step) override; virtual void solve(real_t p_step) override; - Area2Pair3DSW(Area3DSW *p_area_a, int p_shape_a, Area3DSW *p_area_b, int p_shape_b); - ~Area2Pair3DSW(); + GodotArea2Pair3D(GodotArea3D *p_area_a, int p_shape_a, GodotArea3D *p_area_b, int p_shape_b); + ~GodotArea2Pair3D(); }; -class AreaSoftBodyPair3DSW : public Constraint3DSW { - SoftBody3DSW *soft_body; - Area3DSW *area; +class GodotAreaSoftBodyPair3D : public GodotConstraint3D { + GodotSoftBody3D *soft_body; + GodotArea3D *area; int soft_body_shape; int area_shape; bool colliding = false; @@ -85,8 +85,8 @@ public: virtual bool pre_solve(real_t p_step) override; virtual void solve(real_t p_step) override; - AreaSoftBodyPair3DSW(SoftBody3DSW *p_sof_body, int p_soft_body_shape, Area3DSW *p_area, int p_area_shape); - ~AreaSoftBodyPair3DSW(); + GodotAreaSoftBodyPair3D(GodotSoftBody3D *p_sof_body, int p_soft_body_shape, GodotArea3D *p_area, int p_area_shape); + ~GodotAreaSoftBodyPair3D(); }; -#endif // AREA_PAIR__SW_H +#endif // GODOT_AREA_PAIR_3D_H diff --git a/servers/physics_3d/body_3d_sw.cpp b/servers/physics_3d/godot_body_3d.cpp index 069374d122..6df6a0c45b 100644 --- a/servers/physics_3d/body_3d_sw.cpp +++ b/servers/physics_3d/godot_body_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_3d_sw.cpp */ +/* godot_body_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,19 +28,19 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "body_3d_sw.h" +#include "godot_body_3d.h" -#include "area_3d_sw.h" -#include "body_direct_state_3d_sw.h" -#include "space_3d_sw.h" +#include "godot_area_3d.h" +#include "godot_body_direct_state_3d.h" +#include "godot_space_3d.h" -void Body3DSW::_mass_properties_changed() { +void GodotBody3D::_mass_properties_changed() { if (get_space() && !mass_properties_update_list.in_list() && (calculate_inertia || calculate_center_of_mass)) { get_space()->body_add_to_mass_properties_update_list(&mass_properties_update_list); } } -void Body3DSW::_update_transform_dependant() { +void GodotBody3D::_update_transform_dependant() { center_of_mass = get_transform().basis.xform(center_of_mass_local); principal_inertia_axes = get_transform().basis * principal_inertia_axes_local; @@ -52,7 +52,7 @@ void Body3DSW::_update_transform_dependant() { _inv_inertia_tensor = tb * diag * tbt; } -void Body3DSW::update_mass_properties() { +void GodotBody3D::update_mass_properties() { // Update shapes and motions. switch (mode) { @@ -106,7 +106,7 @@ void Body3DSW::update_mass_properties() { inertia_set = true; - const Shape3DSW *shape = get_shape(i); + const GodotShape3D *shape = get_shape(i); real_t mass = area * this->mass / total_area; @@ -164,13 +164,13 @@ void Body3DSW::update_mass_properties() { _update_transform_dependant(); } -void Body3DSW::reset_mass_properties() { +void GodotBody3D::reset_mass_properties() { calculate_inertia = true; calculate_center_of_mass = true; _mass_properties_changed(); } -void Body3DSW::set_active(bool p_active) { +void GodotBody3D::set_active(bool p_active) { if (active == p_active) { return; } @@ -189,7 +189,7 @@ void Body3DSW::set_active(bool p_active) { } } -void Body3DSW::set_param(PhysicsServer3D::BodyParameter p_param, const Variant &p_value) { +void GodotBody3D::set_param(PhysicsServer3D::BodyParameter p_param, const Variant &p_value) { switch (p_param) { case PhysicsServer3D::BODY_PARAM_BOUNCE: { bounce = p_value; @@ -240,7 +240,7 @@ void Body3DSW::set_param(PhysicsServer3D::BodyParameter p_param, const Variant & } } -Variant Body3DSW::get_param(PhysicsServer3D::BodyParameter p_param) const { +Variant GodotBody3D::get_param(PhysicsServer3D::BodyParameter p_param) const { switch (p_param) { case PhysicsServer3D::BODY_PARAM_BOUNCE: { return bounce; @@ -278,7 +278,7 @@ Variant Body3DSW::get_param(PhysicsServer3D::BodyParameter p_param) const { return 0; } -void Body3DSW::set_mode(PhysicsServer3D::BodyMode p_mode) { +void GodotBody3D::set_mode(PhysicsServer3D::BodyMode p_mode) { PhysicsServer3D::BodyMode prev = mode; mode = p_mode; @@ -321,15 +321,15 @@ void Body3DSW::set_mode(PhysicsServer3D::BodyMode p_mode) { } } -PhysicsServer3D::BodyMode Body3DSW::get_mode() const { +PhysicsServer3D::BodyMode GodotBody3D::get_mode() const { return mode; } -void Body3DSW::_shapes_changed() { +void GodotBody3D::_shapes_changed() { _mass_properties_changed(); } -void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) { +void GodotBody3D::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) { switch (p_state) { case PhysicsServer3D::BODY_STATE_TRANSFORM: { if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { @@ -395,7 +395,7 @@ void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_va } } -Variant Body3DSW::get_state(PhysicsServer3D::BodyState p_state) const { +Variant GodotBody3D::get_state(PhysicsServer3D::BodyState p_state) const { switch (p_state) { case PhysicsServer3D::BODY_STATE_TRANSFORM: { return get_transform(); @@ -417,7 +417,7 @@ Variant Body3DSW::get_state(PhysicsServer3D::BodyState p_state) const { return Variant(); } -void Body3DSW::set_space(Space3DSW *p_space) { +void GodotBody3D::set_space(GodotSpace3D *p_space) { if (get_space()) { if (mass_properties_update_list.in_list()) { get_space()->body_remove_from_mass_properties_update_list(&mass_properties_update_list); @@ -440,7 +440,7 @@ void Body3DSW::set_space(Space3DSW *p_space) { } } -void Body3DSW::_compute_area_gravity_and_damping(const Area3DSW *p_area) { +void GodotBody3D::_compute_area_gravity_and_damping(const GodotArea3D *p_area) { Vector3 area_gravity; p_area->compute_gravity(get_transform().get_origin(), area_gravity); gravity += area_gravity; @@ -449,7 +449,7 @@ void Body3DSW::_compute_area_gravity_and_damping(const Area3DSW *p_area) { area_angular_damp += p_area->get_angular_damp(); } -void Body3DSW::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool lock) { +void GodotBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool lock) { if (lock) { locked_axis |= p_axis; } else { @@ -457,17 +457,16 @@ void Body3DSW::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool lock) { } } -bool Body3DSW::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const { +bool GodotBody3D::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const { return locked_axis & p_axis; } -void Body3DSW::integrate_forces(real_t p_step) { +void GodotBody3D::integrate_forces(real_t p_step) { if (mode == PhysicsServer3D::BODY_MODE_STATIC) { return; } - Area3DSW *def_area = get_space()->get_default_area(); - // AreaSW *damp_area = def_area; + GodotArea3D *def_area = get_space()->get_default_area(); ERR_FAIL_COND(!def_area); @@ -591,7 +590,7 @@ void Body3DSW::integrate_forces(real_t p_step) { contact_count = 0; } -void Body3DSW::integrate_velocities(real_t p_step) { +void GodotBody3D::integrate_velocities(real_t p_step) { if (mode == PhysicsServer3D::BODY_MODE_STATIC) { return; } @@ -655,49 +654,17 @@ void Body3DSW::integrate_velocities(real_t p_step) { _update_transform_dependant(); } -/* -void BodySW::simulate_motion(const Transform3D& p_xform,real_t p_step) { - Transform3D inv_xform = p_xform.affine_inverse(); - if (!get_space()) { - _set_transform(p_xform); - _set_inv_transform(inv_xform); - - return; - } - - //compute a FAKE linear velocity - this is easy - - linear_velocity=(p_xform.origin - get_transform().origin)/p_step; - - //compute a FAKE angular velocity, not so easy - Basis rot=get_transform().basis.orthonormalized().transposed() * p_xform.basis.orthonormalized(); - Vector3 axis; - real_t angle; - - rot.get_axis_angle(axis,angle); - axis.normalize(); - angular_velocity=axis.normalized() * (angle/p_step); - linear_velocity = (p_xform.origin - get_transform().origin)/p_step; - - if (!direct_state_query_list.in_list())// - callalways, so lv and av are cleared && (state_query || direct_state_query)) - get_space()->body_add_to_state_query_list(&direct_state_query_list); - simulated_motion=true; - _set_transform(p_xform); -} - -*/ - -void Body3DSW::wakeup_neighbours() { - for (const KeyValue<Constraint3DSW *, int> &E : constraint_map) { - const Constraint3DSW *c = E.key; - Body3DSW **n = c->get_body_ptr(); +void GodotBody3D::wakeup_neighbours() { + for (const KeyValue<GodotConstraint3D *, int> &E : constraint_map) { + const GodotConstraint3D *c = E.key; + GodotBody3D **n = c->get_body_ptr(); int bc = c->get_body_count(); for (int i = 0; i < bc; i++) { if (i == E.value) { continue; } - Body3DSW *b = n[i]; + GodotBody3D *b = n[i]; if (b->mode < PhysicsServer3D::BODY_MODE_DYNAMIC) { continue; } @@ -709,7 +676,7 @@ void Body3DSW::wakeup_neighbours() { } } -void Body3DSW::call_queries() { +void GodotBody3D::call_queries() { if (fi_callback_data) { if (!fi_callback_data->callable.get_object()) { set_force_integration_callback(Callable()); @@ -729,7 +696,7 @@ void Body3DSW::call_queries() { } } -bool Body3DSW::sleep_test(real_t p_step) { +bool GodotBody3D::sleep_test(real_t p_step) { if (mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { return true; } else if (!can_sleep) { @@ -746,12 +713,12 @@ bool Body3DSW::sleep_test(real_t p_step) { } } -void Body3DSW::set_state_sync_callback(void *p_instance, PhysicsServer3D::BodyStateCallback p_callback) { +void GodotBody3D::set_state_sync_callback(void *p_instance, PhysicsServer3D::BodyStateCallback p_callback) { body_state_callback_instance = p_instance; body_state_callback = p_callback; } -void Body3DSW::set_force_integration_callback(const Callable &p_callable, const Variant &p_udata) { +void GodotBody3D::set_force_integration_callback(const Callable &p_callable, const Variant &p_udata) { if (p_callable.get_object()) { if (!fi_callback_data) { fi_callback_data = memnew(ForceIntegrationCallbackData); @@ -764,23 +731,23 @@ void Body3DSW::set_force_integration_callback(const Callable &p_callable, const } } -PhysicsDirectBodyState3DSW *Body3DSW::get_direct_state() { +GodotPhysicsDirectBodyState3D *GodotBody3D::get_direct_state() { if (!direct_state) { - direct_state = memnew(PhysicsDirectBodyState3DSW); + direct_state = memnew(GodotPhysicsDirectBodyState3D); direct_state->body = this; } return direct_state; } -Body3DSW::Body3DSW() : - CollisionObject3DSW(TYPE_BODY), +GodotBody3D::GodotBody3D() : + GodotCollisionObject3D(TYPE_BODY), active_list(this), mass_properties_update_list(this), direct_state_query_list(this) { _set_static(false); } -Body3DSW::~Body3DSW() { +GodotBody3D::~GodotBody3D() { if (fi_callback_data) { memdelete(fi_callback_data); } diff --git a/servers/physics_3d/body_3d_sw.h b/servers/physics_3d/godot_body_3d.h index fc47040389..1151a22c96 100644 --- a/servers/physics_3d/body_3d_sw.h +++ b/servers/physics_3d/godot_body_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_3d_sw.h */ +/* godot_body_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,17 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BODY_3D_SW_H -#define BODY_3D_SW_H +#ifndef GODOT_BODY_3D_H +#define GODOT_BODY_3D_H + +#include "godot_area_3d.h" +#include "godot_collision_object_3d.h" -#include "area_3d_sw.h" -#include "collision_object_3d_sw.h" #include "core/templates/vset.h" -class Constraint3DSW; -class PhysicsDirectBodyState3DSW; +class GodotConstraint3D; +class GodotPhysicsDirectBodyState3D; -class Body3DSW : public CollisionObject3DSW { +class GodotBody3D : public GodotCollisionObject3D { PhysicsServer3D::BodyMode mode = PhysicsServer3D::BODY_MODE_DYNAMIC; Vector3 linear_velocity; @@ -85,9 +86,9 @@ class Body3DSW : public CollisionObject3DSW { real_t area_angular_damp = 0.0; real_t area_linear_damp = 0.0; - SelfList<Body3DSW> active_list; - SelfList<Body3DSW> mass_properties_update_list; - SelfList<Body3DSW> direct_state_query_list; + SelfList<GodotBody3D> active_list; + SelfList<GodotBody3D> mass_properties_update_list; + SelfList<GodotBody3D> direct_state_query_list; VSet<RID> exceptions; bool omit_force_integration = false; @@ -101,7 +102,7 @@ class Body3DSW : public CollisionObject3DSW { virtual void _shapes_changed(); Transform3D new_transform; - Map<Constraint3DSW *, int> constraint_map; + Map<GodotConstraint3D *, int> constraint_map; Vector<AreaCMP> areas; @@ -130,23 +131,23 @@ class Body3DSW : public CollisionObject3DSW { ForceIntegrationCallbackData *fi_callback_data = nullptr; - PhysicsDirectBodyState3DSW *direct_state = nullptr; + GodotPhysicsDirectBodyState3D *direct_state = nullptr; uint64_t island_step = 0; - _FORCE_INLINE_ void _compute_area_gravity_and_damping(const Area3DSW *p_area); + _FORCE_INLINE_ void _compute_area_gravity_and_damping(const GodotArea3D *p_area); _FORCE_INLINE_ void _update_transform_dependant(); - friend class PhysicsDirectBodyState3DSW; // i give up, too many functions to expose + friend class GodotPhysicsDirectBodyState3D; // i give up, too many functions to expose public: void set_state_sync_callback(void *p_instance, PhysicsServer3D::BodyStateCallback p_callback); void set_force_integration_callback(const Callable &p_callable, const Variant &p_udata = Variant()); - PhysicsDirectBodyState3DSW *get_direct_state(); + GodotPhysicsDirectBodyState3D *get_direct_state(); - _FORCE_INLINE_ void add_area(Area3DSW *p_area) { + _FORCE_INLINE_ void add_area(GodotArea3D *p_area) { int index = areas.find(AreaCMP(p_area)); if (index > -1) { areas.write[index].refCount += 1; @@ -155,7 +156,7 @@ public: } } - _FORCE_INLINE_ void remove_area(Area3DSW *p_area) { + _FORCE_INLINE_ void remove_area(GodotArea3D *p_area) { int index = areas.find(AreaCMP(p_area)); if (index > -1) { areas.write[index].refCount -= 1; @@ -185,9 +186,9 @@ public: _FORCE_INLINE_ uint64_t get_island_step() const { return island_step; } _FORCE_INLINE_ void set_island_step(uint64_t p_step) { island_step = p_step; } - _FORCE_INLINE_ void add_constraint(Constraint3DSW *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; } - _FORCE_INLINE_ void remove_constraint(Constraint3DSW *p_constraint) { constraint_map.erase(p_constraint); } - const Map<Constraint3DSW *, int> &get_constraint_map() const { return constraint_map; } + _FORCE_INLINE_ void add_constraint(GodotConstraint3D *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; } + _FORCE_INLINE_ void remove_constraint(GodotConstraint3D *p_constraint) { constraint_map.erase(p_constraint); } + const Map<GodotConstraint3D *, int> &get_constraint_map() const { return constraint_map; } _FORCE_INLINE_ void clear_constraint_map() { constraint_map.clear(); } _FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; } @@ -275,7 +276,7 @@ public: _FORCE_INLINE_ void set_continuous_collision_detection(bool p_enable) { continuous_cd = p_enable; } _FORCE_INLINE_ bool is_continuous_collision_detection_enabled() const { return continuous_cd; } - void set_space(Space3DSW *p_space); + void set_space(GodotSpace3D *p_space); void update_mass_properties(); void reset_mass_properties(); @@ -317,13 +318,13 @@ public: bool sleep_test(real_t p_step); - Body3DSW(); - ~Body3DSW(); + GodotBody3D(); + ~GodotBody3D(); }; //add contact inline -void Body3DSW::add_contact(const Vector3 &p_local_pos, const Vector3 &p_local_normal, real_t p_depth, int p_local_shape, const Vector3 &p_collider_pos, int p_collider_shape, ObjectID p_collider_instance_id, const RID &p_collider, const Vector3 &p_collider_velocity_at_pos) { +void GodotBody3D::add_contact(const Vector3 &p_local_pos, const Vector3 &p_local_normal, real_t p_depth, int p_local_shape, const Vector3 &p_collider_pos, int p_collider_shape, ObjectID p_collider_instance_id, const RID &p_collider, const Vector3 &p_collider_velocity_at_pos) { int c_max = contacts.size(); if (c_max == 0) { @@ -365,4 +366,4 @@ void Body3DSW::add_contact(const Vector3 &p_local_pos, const Vector3 &p_local_no c[idx].collider_velocity_at_pos = p_collider_velocity_at_pos; } -#endif // BODY_3D_SW_H +#endif // GODOT_BODY_3D_H diff --git a/servers/physics_3d/body_direct_state_3d_sw.cpp b/servers/physics_3d/godot_body_direct_state_3d.cpp index d61a6ac8e4..db09657f8a 100644 --- a/servers/physics_3d/body_direct_state_3d_sw.cpp +++ b/servers/physics_3d/godot_body_direct_state_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_direct_state_3d_sw.cpp */ +/* godot_body_direct_state_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,163 +28,163 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "body_direct_state_3d_sw.h" +#include "godot_body_direct_state_3d.h" -#include "body_3d_sw.h" -#include "space_3d_sw.h" +#include "godot_body_3d.h" +#include "godot_space_3d.h" -Vector3 PhysicsDirectBodyState3DSW::get_total_gravity() const { +Vector3 GodotPhysicsDirectBodyState3D::get_total_gravity() const { return body->gravity; } -real_t PhysicsDirectBodyState3DSW::get_total_angular_damp() const { +real_t GodotPhysicsDirectBodyState3D::get_total_angular_damp() const { return body->area_angular_damp; } -real_t PhysicsDirectBodyState3DSW::get_total_linear_damp() const { +real_t GodotPhysicsDirectBodyState3D::get_total_linear_damp() const { return body->area_linear_damp; } -Vector3 PhysicsDirectBodyState3DSW::get_center_of_mass() const { +Vector3 GodotPhysicsDirectBodyState3D::get_center_of_mass() const { return body->get_center_of_mass(); } -Basis PhysicsDirectBodyState3DSW::get_principal_inertia_axes() const { +Basis GodotPhysicsDirectBodyState3D::get_principal_inertia_axes() const { return body->get_principal_inertia_axes(); } -real_t PhysicsDirectBodyState3DSW::get_inverse_mass() const { +real_t GodotPhysicsDirectBodyState3D::get_inverse_mass() const { return body->get_inv_mass(); } -Vector3 PhysicsDirectBodyState3DSW::get_inverse_inertia() const { +Vector3 GodotPhysicsDirectBodyState3D::get_inverse_inertia() const { return body->get_inv_inertia(); } -Basis PhysicsDirectBodyState3DSW::get_inverse_inertia_tensor() const { +Basis GodotPhysicsDirectBodyState3D::get_inverse_inertia_tensor() const { return body->get_inv_inertia_tensor(); } -void PhysicsDirectBodyState3DSW::set_linear_velocity(const Vector3 &p_velocity) { +void GodotPhysicsDirectBodyState3D::set_linear_velocity(const Vector3 &p_velocity) { body->wakeup(); body->set_linear_velocity(p_velocity); } -Vector3 PhysicsDirectBodyState3DSW::get_linear_velocity() const { +Vector3 GodotPhysicsDirectBodyState3D::get_linear_velocity() const { return body->get_linear_velocity(); } -void PhysicsDirectBodyState3DSW::set_angular_velocity(const Vector3 &p_velocity) { +void GodotPhysicsDirectBodyState3D::set_angular_velocity(const Vector3 &p_velocity) { body->wakeup(); body->set_angular_velocity(p_velocity); } -Vector3 PhysicsDirectBodyState3DSW::get_angular_velocity() const { +Vector3 GodotPhysicsDirectBodyState3D::get_angular_velocity() const { return body->get_angular_velocity(); } -void PhysicsDirectBodyState3DSW::set_transform(const Transform3D &p_transform) { +void GodotPhysicsDirectBodyState3D::set_transform(const Transform3D &p_transform) { body->set_state(PhysicsServer3D::BODY_STATE_TRANSFORM, p_transform); } -Transform3D PhysicsDirectBodyState3DSW::get_transform() const { +Transform3D GodotPhysicsDirectBodyState3D::get_transform() const { return body->get_transform(); } -Vector3 PhysicsDirectBodyState3DSW::get_velocity_at_local_position(const Vector3 &p_position) const { +Vector3 GodotPhysicsDirectBodyState3D::get_velocity_at_local_position(const Vector3 &p_position) const { return body->get_velocity_in_local_point(p_position); } -void PhysicsDirectBodyState3DSW::add_central_force(const Vector3 &p_force) { +void GodotPhysicsDirectBodyState3D::add_central_force(const Vector3 &p_force) { body->wakeup(); body->add_central_force(p_force); } -void PhysicsDirectBodyState3DSW::add_force(const Vector3 &p_force, const Vector3 &p_position) { +void GodotPhysicsDirectBodyState3D::add_force(const Vector3 &p_force, const Vector3 &p_position) { body->wakeup(); body->add_force(p_force, p_position); } -void PhysicsDirectBodyState3DSW::add_torque(const Vector3 &p_torque) { +void GodotPhysicsDirectBodyState3D::add_torque(const Vector3 &p_torque) { body->wakeup(); body->add_torque(p_torque); } -void PhysicsDirectBodyState3DSW::apply_central_impulse(const Vector3 &p_impulse) { +void GodotPhysicsDirectBodyState3D::apply_central_impulse(const Vector3 &p_impulse) { body->wakeup(); body->apply_central_impulse(p_impulse); } -void PhysicsDirectBodyState3DSW::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) { +void GodotPhysicsDirectBodyState3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) { body->wakeup(); body->apply_impulse(p_impulse, p_position); } -void PhysicsDirectBodyState3DSW::apply_torque_impulse(const Vector3 &p_impulse) { +void GodotPhysicsDirectBodyState3D::apply_torque_impulse(const Vector3 &p_impulse) { body->wakeup(); body->apply_torque_impulse(p_impulse); } -void PhysicsDirectBodyState3DSW::set_sleep_state(bool p_sleep) { +void GodotPhysicsDirectBodyState3D::set_sleep_state(bool p_sleep) { body->set_active(!p_sleep); } -bool PhysicsDirectBodyState3DSW::is_sleeping() const { +bool GodotPhysicsDirectBodyState3D::is_sleeping() const { return !body->is_active(); } -int PhysicsDirectBodyState3DSW::get_contact_count() const { +int GodotPhysicsDirectBodyState3D::get_contact_count() const { return body->contact_count; } -Vector3 PhysicsDirectBodyState3DSW::get_contact_local_position(int p_contact_idx) const { +Vector3 GodotPhysicsDirectBodyState3D::get_contact_local_position(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Vector3()); return body->contacts[p_contact_idx].local_pos; } -Vector3 PhysicsDirectBodyState3DSW::get_contact_local_normal(int p_contact_idx) const { +Vector3 GodotPhysicsDirectBodyState3D::get_contact_local_normal(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Vector3()); return body->contacts[p_contact_idx].local_normal; } -real_t PhysicsDirectBodyState3DSW::get_contact_impulse(int p_contact_idx) const { +real_t GodotPhysicsDirectBodyState3D::get_contact_impulse(int p_contact_idx) const { return 0.0f; // Only implemented for bullet } -int PhysicsDirectBodyState3DSW::get_contact_local_shape(int p_contact_idx) const { +int GodotPhysicsDirectBodyState3D::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; } -RID PhysicsDirectBodyState3DSW::get_contact_collider(int p_contact_idx) const { +RID GodotPhysicsDirectBodyState3D::get_contact_collider(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, RID()); return body->contacts[p_contact_idx].collider; } -Vector3 PhysicsDirectBodyState3DSW::get_contact_collider_position(int p_contact_idx) const { +Vector3 GodotPhysicsDirectBodyState3D::get_contact_collider_position(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Vector3()); return body->contacts[p_contact_idx].collider_pos; } -ObjectID PhysicsDirectBodyState3DSW::get_contact_collider_id(int p_contact_idx) const { +ObjectID GodotPhysicsDirectBodyState3D::get_contact_collider_id(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, ObjectID()); return body->contacts[p_contact_idx].collider_instance_id; } -int PhysicsDirectBodyState3DSW::get_contact_collider_shape(int p_contact_idx) const { +int GodotPhysicsDirectBodyState3D::get_contact_collider_shape(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, 0); return body->contacts[p_contact_idx].collider_shape; } -Vector3 PhysicsDirectBodyState3DSW::get_contact_collider_velocity_at_position(int p_contact_idx) const { +Vector3 GodotPhysicsDirectBodyState3D::get_contact_collider_velocity_at_position(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Vector3()); return body->contacts[p_contact_idx].collider_velocity_at_pos; } -PhysicsDirectSpaceState3D *PhysicsDirectBodyState3DSW::get_space_state() { +PhysicsDirectSpaceState3D *GodotPhysicsDirectBodyState3D::get_space_state() { return body->get_space()->get_direct_state(); } -real_t PhysicsDirectBodyState3DSW::get_step() const { +real_t GodotPhysicsDirectBodyState3D::get_step() const { return body->get_space()->get_last_step(); } diff --git a/servers/physics_3d/body_direct_state_3d_sw.h b/servers/physics_3d/godot_body_direct_state_3d.h index 5132376715..6c584a2634 100644 --- a/servers/physics_3d/body_direct_state_3d_sw.h +++ b/servers/physics_3d/godot_body_direct_state_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_direct_state_3d_sw.h */ +/* godot_body_direct_state_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,18 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BODY_DIRECT_STATE_3D_SW_H -#define BODY_DIRECT_STATE_3D_SW_H +#ifndef GODOT_BODY_DIRECT_STATE_3D_H +#define GODOT_BODY_DIRECT_STATE_3D_H #include "servers/physics_server_3d.h" -class Body3DSW; +class GodotBody3D; -class PhysicsDirectBodyState3DSW : public PhysicsDirectBodyState3D { - GDCLASS(PhysicsDirectBodyState3DSW, PhysicsDirectBodyState3D); +class GodotPhysicsDirectBodyState3D : public PhysicsDirectBodyState3D { + GDCLASS(GodotPhysicsDirectBodyState3D, PhysicsDirectBodyState3D); public: - Body3DSW *body = nullptr; + GodotBody3D *body = nullptr; virtual Vector3 get_total_gravity() const override; virtual real_t get_total_angular_damp() const override; @@ -91,4 +91,4 @@ public: virtual real_t get_step() const override; }; -#endif // BODY_DIRECT_STATE_3D_SW_H +#endif // GODOT_BODY_DIRECT_STATE_3D_H diff --git a/servers/physics_3d/body_pair_3d_sw.cpp b/servers/physics_3d/godot_body_pair_3d.cpp index c27a2ecced..457abfb71a 100644 --- a/servers/physics_3d/body_pair_3d_sw.cpp +++ b/servers/physics_3d/godot_body_pair_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_pair_3d_sw.cpp */ +/* godot_body_pair_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "body_pair_3d_sw.h" +#include "godot_body_pair_3d.h" + +#include "godot_collision_solver_3d.h" +#include "godot_space_3d.h" -#include "collision_solver_3d_sw.h" #include "core/os/os.h" -#include "space_3d_sw.h" /* #define NO_ACCUMULATE_IMPULSES @@ -49,12 +50,12 @@ #define MIN_VELOCITY 0.0001 #define MAX_BIAS_ROTATION (Math_PI / 8) -void BodyPair3DSW::_contact_added_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B, void *p_userdata) { - BodyPair3DSW *pair = (BodyPair3DSW *)p_userdata; +void GodotBodyPair3D::_contact_added_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B, void *p_userdata) { + GodotBodyPair3D *pair = (GodotBodyPair3D *)p_userdata; pair->contact_added_callback(p_point_A, p_index_A, p_point_B, p_index_B); } -void BodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B) { +void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B) { // check if we already have the contact //Vector3 local_A = A->get_inv_transform().xform(p_point_A); @@ -135,7 +136,7 @@ void BodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, int p_index_ } } -void BodyPair3DSW::validate_contacts() { +void GodotBodyPair3D::validate_contacts() { //make sure to erase contacts that are no longer valid real_t contact_max_separation = space->get_contact_max_separation(); @@ -161,7 +162,7 @@ void BodyPair3DSW::validate_contacts() { } } -bool BodyPair3DSW::_test_ccd(real_t p_step, Body3DSW *p_A, int p_shape_A, const Transform3D &p_xform_A, Body3DSW *p_B, int p_shape_B, const Transform3D &p_xform_B) { +bool GodotBodyPair3D::_test_ccd(real_t p_step, GodotBody3D *p_A, int p_shape_A, const Transform3D &p_xform_A, GodotBody3D *p_B, int p_shape_B, const Transform3D &p_xform_B) { Vector3 motion = p_A->get_linear_velocity() * p_step; real_t mlen = motion.length(); if (mlen < CMP_EPSILON) { @@ -203,15 +204,15 @@ bool BodyPair3DSW::_test_ccd(real_t p_step, Body3DSW *p_A, int p_shape_A, const return true; } -real_t combine_bounce(Body3DSW *A, Body3DSW *B) { +real_t combine_bounce(GodotBody3D *A, GodotBody3D *B) { return CLAMP(A->get_bounce() + B->get_bounce(), 0, 1); } -real_t combine_friction(Body3DSW *A, Body3DSW *B) { +real_t combine_friction(GodotBody3D *A, GodotBody3D *B) { return ABS(MIN(A->get_friction(), B->get_friction())); } -bool BodyPair3DSW::setup(real_t p_step) { +bool GodotBodyPair3D::setup(real_t p_step) { if (!A->interacts_with(B) || A->has_exception(B->get_self()) || B->has_exception(A->get_self())) { collided = false; return false; @@ -242,10 +243,10 @@ bool BodyPair3DSW::setup(real_t p_step) { xform_Bu.origin -= offset_A; Transform3D xform_B = xform_Bu * B->get_shape_transform(shape_B); - Shape3DSW *shape_A_ptr = A->get_shape(shape_A); - Shape3DSW *shape_B_ptr = B->get_shape(shape_B); + GodotShape3D *shape_A_ptr = A->get_shape(shape_A); + GodotShape3D *shape_B_ptr = B->get_shape(shape_B); - collided = CollisionSolver3DSW::solve_static(shape_A_ptr, xform_A, shape_B_ptr, xform_B, _contact_added_callback, this, &sep_axis); + collided = GodotCollisionSolver3D::solve_static(shape_A_ptr, xform_A, shape_B_ptr, xform_B, _contact_added_callback, this, &sep_axis); if (!collided) { //test ccd (currently just a raycast) @@ -264,7 +265,7 @@ bool BodyPair3DSW::setup(real_t p_step) { return true; } -bool BodyPair3DSW::pre_solve(real_t p_step) { +bool GodotBodyPair3D::pre_solve(real_t p_step) { if (!collided) { return false; } @@ -273,8 +274,8 @@ bool BodyPair3DSW::pre_solve(real_t p_step) { real_t bias = (real_t)0.3; - Shape3DSW *shape_A_ptr = A->get_shape(shape_A); - Shape3DSW *shape_B_ptr = B->get_shape(shape_B); + GodotShape3D *shape_A_ptr = A->get_shape(shape_A); + GodotShape3D *shape_B_ptr = B->get_shape(shape_B); if (shape_A_ptr->get_custom_bias() || shape_B_ptr->get_custom_bias()) { if (shape_A_ptr->get_custom_bias() == 0) { @@ -380,7 +381,7 @@ bool BodyPair3DSW::pre_solve(real_t p_step) { return do_process; } -void BodyPair3DSW::solve(real_t p_step) { +void GodotBodyPair3D::solve(real_t p_step) { if (!collided) { return; } @@ -523,8 +524,8 @@ void BodyPair3DSW::solve(real_t p_step) { } } -BodyPair3DSW::BodyPair3DSW(Body3DSW *p_A, int p_shape_A, Body3DSW *p_B, int p_shape_B) : - BodyContact3DSW(_arr, 2) { +GodotBodyPair3D::GodotBodyPair3D(GodotBody3D *p_A, int p_shape_A, GodotBody3D *p_B, int p_shape_B) : + GodotBodyContact3D(_arr, 2) { A = p_A; B = p_B; shape_A = p_shape_A; @@ -534,17 +535,17 @@ BodyPair3DSW::BodyPair3DSW(Body3DSW *p_A, int p_shape_A, Body3DSW *p_B, int p_sh B->add_constraint(this, 1); } -BodyPair3DSW::~BodyPair3DSW() { +GodotBodyPair3D::~GodotBodyPair3D() { A->remove_constraint(this); B->remove_constraint(this); } -void BodySoftBodyPair3DSW::_contact_added_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B, void *p_userdata) { - BodySoftBodyPair3DSW *pair = (BodySoftBodyPair3DSW *)p_userdata; +void GodotBodySoftBodyPair3D::_contact_added_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B, void *p_userdata) { + GodotBodySoftBodyPair3D *pair = (GodotBodySoftBodyPair3D *)p_userdata; pair->contact_added_callback(p_point_A, p_index_A, p_point_B, p_index_B); } -void BodySoftBodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B) { +void GodotBodySoftBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B) { Vector3 local_A = body->get_inv_transform().xform(p_point_A); Vector3 local_B = p_point_B - soft_body->get_node_position(p_index_B); @@ -582,7 +583,7 @@ void BodySoftBodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, int contacts.push_back(contact); } -void BodySoftBodyPair3DSW::validate_contacts() { +void GodotBodySoftBodyPair3D::validate_contacts() { // Make sure to erase contacts that are no longer valid. const Transform3D &transform_A = body->get_transform(); @@ -612,7 +613,7 @@ void BodySoftBodyPair3DSW::validate_contacts() { contacts.resize(contact_count); } -bool BodySoftBodyPair3DSW::setup(real_t p_step) { +bool GodotBodySoftBodyPair3D::setup(real_t p_step) { if (!body->interacts_with(soft_body) || body->has_exception(soft_body->get_self()) || soft_body->has_exception(body->get_self())) { collided = false; return false; @@ -638,15 +639,15 @@ bool BodySoftBodyPair3DSW::setup(real_t p_step) { validate_contacts(); - Shape3DSW *shape_A_ptr = body->get_shape(body_shape); - Shape3DSW *shape_B_ptr = soft_body->get_shape(0); + GodotShape3D *shape_A_ptr = body->get_shape(body_shape); + GodotShape3D *shape_B_ptr = soft_body->get_shape(0); - collided = CollisionSolver3DSW::solve_static(shape_A_ptr, xform_A, shape_B_ptr, xform_B, _contact_added_callback, this, &sep_axis); + collided = GodotCollisionSolver3D::solve_static(shape_A_ptr, xform_A, shape_B_ptr, xform_B, _contact_added_callback, this, &sep_axis); return collided; } -bool BodySoftBodyPair3DSW::pre_solve(real_t p_step) { +bool GodotBodySoftBodyPair3D::pre_solve(real_t p_step) { if (!collided) { return false; } @@ -655,7 +656,7 @@ bool BodySoftBodyPair3DSW::pre_solve(real_t p_step) { real_t bias = (real_t)0.3; - Shape3DSW *shape_A_ptr = body->get_shape(body_shape); + GodotShape3D *shape_A_ptr = body->get_shape(body_shape); if (shape_A_ptr->get_custom_bias()) { bias = shape_A_ptr->get_custom_bias(); @@ -753,7 +754,7 @@ bool BodySoftBodyPair3DSW::pre_solve(real_t p_step) { return do_process; } -void BodySoftBodyPair3DSW::solve(real_t p_step) { +void GodotBodySoftBodyPair3D::solve(real_t p_step) { if (!collided) { return; } @@ -891,8 +892,8 @@ void BodySoftBodyPair3DSW::solve(real_t p_step) { } } -BodySoftBodyPair3DSW::BodySoftBodyPair3DSW(Body3DSW *p_A, int p_shape_A, SoftBody3DSW *p_B) : - BodyContact3DSW(&body, 1) { +GodotBodySoftBodyPair3D::GodotBodySoftBodyPair3D(GodotBody3D *p_A, int p_shape_A, GodotSoftBody3D *p_B) : + GodotBodyContact3D(&body, 1) { body = p_A; soft_body = p_B; body_shape = p_shape_A; @@ -901,7 +902,7 @@ BodySoftBodyPair3DSW::BodySoftBodyPair3DSW(Body3DSW *p_A, int p_shape_A, SoftBod soft_body->add_constraint(this); } -BodySoftBodyPair3DSW::~BodySoftBodyPair3DSW() { +GodotBodySoftBodyPair3D::~GodotBodySoftBodyPair3D() { body->remove_constraint(this); soft_body->remove_constraint(this); } diff --git a/servers/physics_3d/body_pair_3d_sw.h b/servers/physics_3d/godot_body_pair_3d.h index 01afb07e13..c0a2424e05 100644 --- a/servers/physics_3d/body_pair_3d_sw.h +++ b/servers/physics_3d/godot_body_pair_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_pair_3d_sw.h */ +/* godot_body_pair_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,15 +28,16 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BODY_PAIR_3D_SW_H -#define BODY_PAIR_3D_SW_H +#ifndef GODOT_BODY_PAIR_3D_H +#define GODOT_BODY_PAIR_3D_H + +#include "godot_body_3d.h" +#include "godot_constraint_3d.h" +#include "godot_soft_body_3d.h" -#include "body_3d_sw.h" -#include "constraint_3d_sw.h" #include "core/templates/local_vector.h" -#include "soft_body_3d_sw.h" -class BodyContact3DSW : public Constraint3DSW { +class GodotBodyContact3D : public GodotConstraint3D { protected: struct Contact { Vector3 position; @@ -59,25 +60,25 @@ protected: Vector3 sep_axis; bool collided = false; - Space3DSW *space = nullptr; + GodotSpace3D *space = nullptr; - BodyContact3DSW(Body3DSW **p_body_ptr = nullptr, int p_body_count = 0) : - Constraint3DSW(p_body_ptr, p_body_count) { + GodotBodyContact3D(GodotBody3D **p_body_ptr = nullptr, int p_body_count = 0) : + GodotConstraint3D(p_body_ptr, p_body_count) { } }; -class BodyPair3DSW : public BodyContact3DSW { +class GodotBodyPair3D : public GodotBodyContact3D { enum { MAX_CONTACTS = 4 }; union { struct { - Body3DSW *A; - Body3DSW *B; + GodotBody3D *A; + GodotBody3D *B; }; - Body3DSW *_arr[2] = { nullptr, nullptr }; + GodotBody3D *_arr[2] = { nullptr, nullptr }; }; int shape_A = 0; @@ -98,20 +99,20 @@ class BodyPair3DSW : public BodyContact3DSW { void contact_added_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B); void validate_contacts(); - bool _test_ccd(real_t p_step, Body3DSW *p_A, int p_shape_A, const Transform3D &p_xform_A, Body3DSW *p_B, int p_shape_B, const Transform3D &p_xform_B); + bool _test_ccd(real_t p_step, GodotBody3D *p_A, int p_shape_A, const Transform3D &p_xform_A, GodotBody3D *p_B, int p_shape_B, const Transform3D &p_xform_B); public: virtual bool setup(real_t p_step) override; virtual bool pre_solve(real_t p_step) override; virtual void solve(real_t p_step) override; - BodyPair3DSW(Body3DSW *p_A, int p_shape_A, Body3DSW *p_B, int p_shape_B); - ~BodyPair3DSW(); + GodotBodyPair3D(GodotBody3D *p_A, int p_shape_A, GodotBody3D *p_B, int p_shape_B); + ~GodotBodyPair3D(); }; -class BodySoftBodyPair3DSW : public BodyContact3DSW { - Body3DSW *body = nullptr; - SoftBody3DSW *soft_body = nullptr; +class GodotBodySoftBodyPair3D : public GodotBodyContact3D { + GodotBody3D *body = nullptr; + GodotSoftBody3D *soft_body = nullptr; int body_shape = 0; @@ -133,11 +134,11 @@ public: virtual bool pre_solve(real_t p_step) override; virtual void solve(real_t p_step) override; - virtual SoftBody3DSW *get_soft_body_ptr(int p_index) const override { return soft_body; } + virtual GodotSoftBody3D *get_soft_body_ptr(int p_index) const override { return soft_body; } virtual int get_soft_body_count() const override { return 1; } - BodySoftBodyPair3DSW(Body3DSW *p_A, int p_shape_A, SoftBody3DSW *p_B); - ~BodySoftBodyPair3DSW(); + GodotBodySoftBodyPair3D(GodotBody3D *p_A, int p_shape_A, GodotSoftBody3D *p_B); + ~GodotBodySoftBodyPair3D(); }; -#endif // BODY_PAIR_3D_SW_H +#endif // GODOT_BODY_PAIR_3D_H diff --git a/servers/physics_3d/broad_phase_3d_sw.cpp b/servers/physics_3d/godot_broad_phase_3d.cpp index 8aa64034ec..db51dfb2b6 100644 --- a/servers/physics_3d/broad_phase_3d_sw.cpp +++ b/servers/physics_3d/godot_broad_phase_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* broad_phase_3d_sw.cpp */ +/* godot_broad_phase_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,9 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "broad_phase_3d_sw.h" +#include "godot_broad_phase_3d.h" -BroadPhase3DSW::CreateFunction BroadPhase3DSW::create_func = nullptr; +GodotBroadPhase3D::CreateFunction GodotBroadPhase3D::create_func = nullptr; -BroadPhase3DSW::~BroadPhase3DSW() { +GodotBroadPhase3D::~GodotBroadPhase3D() { } diff --git a/servers/physics_3d/broad_phase_3d_sw.h b/servers/physics_3d/godot_broad_phase_3d.h index 98313cb216..65423f293c 100644 --- a/servers/physics_3d/broad_phase_3d_sw.h +++ b/servers/physics_3d/godot_broad_phase_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* broad_phase_3d_sw.h */ +/* godot_broad_phase_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,45 +28,45 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BROAD_PHASE_SW_H -#define BROAD_PHASE_SW_H +#ifndef GODOT_BROAD_PHASE_3D_H +#define GODOT_BROAD_PHASE_3D_H #include "core/math/aabb.h" #include "core/math/math_funcs.h" -class CollisionObject3DSW; +class GodotCollisionObject3D; -class BroadPhase3DSW { +class GodotBroadPhase3D { public: - typedef BroadPhase3DSW *(*CreateFunction)(); + typedef GodotBroadPhase3D *(*CreateFunction)(); static CreateFunction create_func; typedef uint32_t ID; - typedef void *(*PairCallback)(CollisionObject3DSW *A, int p_subindex_A, CollisionObject3DSW *B, int p_subindex_B, void *p_userdata); - typedef void (*UnpairCallback)(CollisionObject3DSW *A, int p_subindex_A, CollisionObject3DSW *B, int p_subindex_B, void *p_data, void *p_userdata); + typedef void *(*PairCallback)(GodotCollisionObject3D *A, int p_subindex_A, GodotCollisionObject3D *B, int p_subindex_B, void *p_userdata); + typedef void (*UnpairCallback)(GodotCollisionObject3D *A, int p_subindex_A, GodotCollisionObject3D *B, int p_subindex_B, void *p_data, void *p_userdata); // 0 is an invalid ID - virtual ID create(CollisionObject3DSW *p_object_, int p_subindex = 0, const AABB &p_aabb = AABB(), bool p_static = false) = 0; + virtual ID create(GodotCollisionObject3D *p_object_, int p_subindex = 0, const AABB &p_aabb = AABB(), bool p_static = false) = 0; virtual void move(ID p_id, const AABB &p_aabb) = 0; virtual void set_static(ID p_id, bool p_static) = 0; virtual void remove(ID p_id) = 0; - virtual CollisionObject3DSW *get_object(ID p_id) const = 0; + virtual GodotCollisionObject3D *get_object(ID p_id) const = 0; virtual bool is_static(ID p_id) const = 0; virtual int get_subindex(ID p_id) const = 0; - virtual int cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; - virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; - virtual int cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; + virtual int cull_point(const Vector3 &p_point, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; + virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; + virtual int cull_aabb(const AABB &p_aabb, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata) = 0; virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) = 0; virtual void update() = 0; - virtual ~BroadPhase3DSW(); + virtual ~GodotBroadPhase3D(); }; -#endif // BROAD_PHASE__SW_H +#endif // GODOT_BROAD_PHASE_3D_H diff --git a/servers/physics_3d/broad_phase_3d_bvh.cpp b/servers/physics_3d/godot_broad_phase_3d_bvh.cpp index d89e0e1f6d..0f2061a1ea 100644 --- a/servers/physics_3d/broad_phase_3d_bvh.cpp +++ b/servers/physics_3d/godot_broad_phase_3d_bvh.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* broad_phase_3d_bvh.cpp */ +/* godot_broad_phase_3d_bvh.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,55 +28,56 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "broad_phase_3d_bvh.h" -#include "collision_object_3d_sw.h" +#include "godot_broad_phase_3d_bvh.h" -BroadPhase3DBVH::ID BroadPhase3DBVH::create(CollisionObject3DSW *p_object, int p_subindex, const AABB &p_aabb, bool p_static) { +#include "godot_collision_object_3d.h" + +GodotBroadPhase3DBVH::ID GodotBroadPhase3DBVH::create(GodotCollisionObject3D *p_object, int p_subindex, const AABB &p_aabb, bool p_static) { ID oid = bvh.create(p_object, true, p_aabb, p_subindex, !p_static, 1 << p_object->get_type(), p_static ? 0 : 0xFFFFF); // Pair everything, don't care? return oid + 1; } -void BroadPhase3DBVH::move(ID p_id, const AABB &p_aabb) { +void GodotBroadPhase3DBVH::move(ID p_id, const AABB &p_aabb) { bvh.move(p_id - 1, p_aabb); } -void BroadPhase3DBVH::set_static(ID p_id, bool p_static) { - CollisionObject3DSW *it = bvh.get(p_id - 1); +void GodotBroadPhase3DBVH::set_static(ID p_id, bool p_static) { + GodotCollisionObject3D *it = bvh.get(p_id - 1); bvh.set_pairable(p_id - 1, !p_static, 1 << it->get_type(), p_static ? 0 : 0xFFFFF, false); // Pair everything, don't care? } -void BroadPhase3DBVH::remove(ID p_id) { +void GodotBroadPhase3DBVH::remove(ID p_id) { bvh.erase(p_id - 1); } -CollisionObject3DSW *BroadPhase3DBVH::get_object(ID p_id) const { - CollisionObject3DSW *it = bvh.get(p_id - 1); +GodotCollisionObject3D *GodotBroadPhase3DBVH::get_object(ID p_id) const { + GodotCollisionObject3D *it = bvh.get(p_id - 1); ERR_FAIL_COND_V(!it, nullptr); return it; } -bool BroadPhase3DBVH::is_static(ID p_id) const { +bool GodotBroadPhase3DBVH::is_static(ID p_id) const { return !bvh.is_pairable(p_id - 1); } -int BroadPhase3DBVH::get_subindex(ID p_id) const { +int GodotBroadPhase3DBVH::get_subindex(ID p_id) const { return bvh.get_subindex(p_id - 1); } -int BroadPhase3DBVH::cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { +int GodotBroadPhase3DBVH::cull_point(const Vector3 &p_point, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices) { return bvh.cull_point(p_point, p_results, p_max_results, p_result_indices); } -int BroadPhase3DBVH::cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { +int GodotBroadPhase3DBVH::cull_segment(const Vector3 &p_from, const Vector3 &p_to, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices) { return bvh.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices); } -int BroadPhase3DBVH::cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { +int GodotBroadPhase3DBVH::cull_aabb(const AABB &p_aabb, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices) { return bvh.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices); } -void *BroadPhase3DBVH::_pair_callback(void *self, uint32_t p_A, CollisionObject3DSW *p_object_A, int subindex_A, uint32_t p_B, CollisionObject3DSW *p_object_B, int subindex_B) { - BroadPhase3DBVH *bpo = (BroadPhase3DBVH *)(self); +void *GodotBroadPhase3DBVH::_pair_callback(void *self, uint32_t p_A, GodotCollisionObject3D *p_object_A, int subindex_A, uint32_t p_B, GodotCollisionObject3D *p_object_B, int subindex_B) { + GodotBroadPhase3DBVH *bpo = (GodotBroadPhase3DBVH *)(self); if (!bpo->pair_callback) { return nullptr; } @@ -84,8 +85,8 @@ void *BroadPhase3DBVH::_pair_callback(void *self, uint32_t p_A, CollisionObject3 return bpo->pair_callback(p_object_A, subindex_A, p_object_B, subindex_B, bpo->pair_userdata); } -void BroadPhase3DBVH::_unpair_callback(void *self, uint32_t p_A, CollisionObject3DSW *p_object_A, int subindex_A, uint32_t p_B, CollisionObject3DSW *p_object_B, int subindex_B, void *pairdata) { - BroadPhase3DBVH *bpo = (BroadPhase3DBVH *)(self); +void GodotBroadPhase3DBVH::_unpair_callback(void *self, uint32_t p_A, GodotCollisionObject3D *p_object_A, int subindex_A, uint32_t p_B, GodotCollisionObject3D *p_object_B, int subindex_B, void *pairdata) { + GodotBroadPhase3DBVH *bpo = (GodotBroadPhase3DBVH *)(self); if (!bpo->unpair_callback) { return; } @@ -93,25 +94,25 @@ void BroadPhase3DBVH::_unpair_callback(void *self, uint32_t p_A, CollisionObject bpo->unpair_callback(p_object_A, subindex_A, p_object_B, subindex_B, pairdata, bpo->unpair_userdata); } -void BroadPhase3DBVH::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { +void GodotBroadPhase3DBVH::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { pair_callback = p_pair_callback; pair_userdata = p_userdata; } -void BroadPhase3DBVH::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { +void GodotBroadPhase3DBVH::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { unpair_callback = p_unpair_callback; unpair_userdata = p_userdata; } -void BroadPhase3DBVH::update() { +void GodotBroadPhase3DBVH::update() { bvh.update(); } -BroadPhase3DSW *BroadPhase3DBVH::_create() { - return memnew(BroadPhase3DBVH); +GodotBroadPhase3D *GodotBroadPhase3DBVH::_create() { + return memnew(GodotBroadPhase3DBVH); } -BroadPhase3DBVH::BroadPhase3DBVH() { +GodotBroadPhase3DBVH::GodotBroadPhase3DBVH() { bvh.set_pair_callback(_pair_callback, this); bvh.set_unpair_callback(_unpair_callback, this); } diff --git a/servers/physics_3d/broad_phase_3d_bvh.h b/servers/physics_3d/godot_broad_phase_3d_bvh.h index 03131c9db2..61127e52c1 100644 --- a/servers/physics_3d/broad_phase_3d_bvh.h +++ b/servers/physics_3d/godot_broad_phase_3d_bvh.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* broad_phase_3d_bvh.h */ +/* godot_broad_phase_3d_bvh.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,17 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BROAD_PHASE_3D_BVH_H -#define BROAD_PHASE_3D_BVH_H +#ifndef GODOT_BROAD_PHASE_3D_BVH_H +#define GODOT_BROAD_PHASE_3D_BVH_H + +#include "godot_broad_phase_3d.h" -#include "broad_phase_3d_sw.h" #include "core/math/bvh.h" -class BroadPhase3DBVH : public BroadPhase3DSW { - BVH_Manager<CollisionObject3DSW, true, 128> bvh; +class GodotBroadPhase3DBVH : public GodotBroadPhase3D { + BVH_Manager<GodotCollisionObject3D, true, 128> bvh; - static void *_pair_callback(void *, uint32_t, CollisionObject3DSW *, int, uint32_t, CollisionObject3DSW *, int); - static void _unpair_callback(void *, uint32_t, CollisionObject3DSW *, int, uint32_t, CollisionObject3DSW *, int, void *); + static void *_pair_callback(void *, uint32_t, GodotCollisionObject3D *, int, uint32_t, GodotCollisionObject3D *, int); + static void _unpair_callback(void *, uint32_t, GodotCollisionObject3D *, int, uint32_t, GodotCollisionObject3D *, int, void *); PairCallback pair_callback = nullptr; void *pair_userdata = nullptr; @@ -47,26 +48,26 @@ class BroadPhase3DBVH : public BroadPhase3DSW { public: // 0 is an invalid ID - virtual ID create(CollisionObject3DSW *p_object, int p_subindex = 0, const AABB &p_aabb = AABB(), bool p_static = false); + virtual ID create(GodotCollisionObject3D *p_object, int p_subindex = 0, const AABB &p_aabb = AABB(), bool p_static = false); virtual void move(ID p_id, const AABB &p_aabb); virtual void set_static(ID p_id, bool p_static); virtual void remove(ID p_id); - virtual CollisionObject3DSW *get_object(ID p_id) const; + virtual GodotCollisionObject3D *get_object(ID p_id) const; virtual bool is_static(ID p_id) const; virtual int get_subindex(ID p_id) const; - virtual int cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr); - virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr); - virtual int cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr); + virtual int cull_point(const Vector3 &p_point, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices = nullptr); + virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices = nullptr); + virtual int cull_aabb(const AABB &p_aabb, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices = nullptr); virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata); virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata); virtual void update(); - static BroadPhase3DSW *_create(); - BroadPhase3DBVH(); + static GodotBroadPhase3D *_create(); + GodotBroadPhase3DBVH(); }; -#endif // BROAD_PHASE_3D_BVH_H +#endif // GODOT_BROAD_PHASE_3D_BVH_H diff --git a/servers/physics_3d/collision_object_3d_sw.cpp b/servers/physics_3d/godot_collision_object_3d.cpp index 098f627d11..80a3d18ce0 100644 --- a/servers/physics_3d/collision_object_3d_sw.cpp +++ b/servers/physics_3d/godot_collision_object_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_object_3d_sw.cpp */ +/* godot_collision_object_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "collision_object_3d_sw.h" -#include "servers/physics_3d/physics_server_3d_sw.h" -#include "space_3d_sw.h" +#include "godot_collision_object_3d.h" -void CollisionObject3DSW::add_shape(Shape3DSW *p_shape, const Transform3D &p_transform, bool p_disabled) { +#include "godot_physics_server_3d.h" +#include "godot_space_3d.h" + +void GodotCollisionObject3D::add_shape(GodotShape3D *p_shape, const Transform3D &p_transform, bool p_disabled) { Shape s; s.shape = p_shape; s.xform = p_transform; @@ -43,35 +44,35 @@ void CollisionObject3DSW::add_shape(Shape3DSW *p_shape, const Transform3D &p_tra p_shape->add_owner(this); if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); + GodotPhysicsServer3D::godot_singleton->pending_shape_update_list.add(&pending_shape_update_list); } } -void CollisionObject3DSW::set_shape(int p_index, Shape3DSW *p_shape) { +void GodotCollisionObject3D::set_shape(int p_index, GodotShape3D *p_shape) { ERR_FAIL_INDEX(p_index, shapes.size()); shapes[p_index].shape->remove_owner(this); shapes.write[p_index].shape = p_shape; p_shape->add_owner(this); if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); + GodotPhysicsServer3D::godot_singleton->pending_shape_update_list.add(&pending_shape_update_list); } } -void CollisionObject3DSW::set_shape_transform(int p_index, const Transform3D &p_transform) { +void GodotCollisionObject3D::set_shape_transform(int p_index, const Transform3D &p_transform) { ERR_FAIL_INDEX(p_index, shapes.size()); shapes.write[p_index].xform = p_transform; shapes.write[p_index].xform_inv = p_transform.affine_inverse(); if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); + GodotPhysicsServer3D::godot_singleton->pending_shape_update_list.add(&pending_shape_update_list); } } -void CollisionObject3DSW::set_shape_disabled(int p_idx, bool p_disabled) { +void GodotCollisionObject3D::set_shape_disabled(int p_idx, bool p_disabled) { ERR_FAIL_INDEX(p_idx, shapes.size()); - CollisionObject3DSW::Shape &shape = shapes.write[p_idx]; + GodotCollisionObject3D::Shape &shape = shapes.write[p_idx]; if (shape.disabled == p_disabled) { return; } @@ -86,16 +87,16 @@ void CollisionObject3DSW::set_shape_disabled(int p_idx, bool p_disabled) { space->get_broadphase()->remove(shape.bpid); shape.bpid = 0; if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); + GodotPhysicsServer3D::godot_singleton->pending_shape_update_list.add(&pending_shape_update_list); } } else if (!p_disabled && shape.bpid == 0) { if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); + GodotPhysicsServer3D::godot_singleton->pending_shape_update_list.add(&pending_shape_update_list); } } } -void CollisionObject3DSW::remove_shape(Shape3DSW *p_shape) { +void GodotCollisionObject3D::remove_shape(GodotShape3D *p_shape) { //remove a shape, all the times it appears for (int i = 0; i < shapes.size(); i++) { if (shapes[i].shape == p_shape) { @@ -105,7 +106,7 @@ void CollisionObject3DSW::remove_shape(Shape3DSW *p_shape) { } } -void CollisionObject3DSW::remove_shape(int p_index) { +void GodotCollisionObject3D::remove_shape(int p_index) { //remove anything from shape to be erased to end, so subindices don't change ERR_FAIL_INDEX(p_index, shapes.size()); for (int i = p_index; i < shapes.size(); i++) { @@ -120,11 +121,11 @@ void CollisionObject3DSW::remove_shape(int p_index) { shapes.remove(p_index); if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); + GodotPhysicsServer3D::godot_singleton->pending_shape_update_list.add(&pending_shape_update_list); } } -void CollisionObject3DSW::_set_static(bool p_static) { +void GodotCollisionObject3D::_set_static(bool p_static) { if (_static == p_static) { return; } @@ -141,7 +142,7 @@ void CollisionObject3DSW::_set_static(bool p_static) { } } -void CollisionObject3DSW::_unregister_shapes() { +void GodotCollisionObject3D::_unregister_shapes() { for (int i = 0; i < shapes.size(); i++) { Shape &s = shapes.write[i]; if (s.bpid > 0) { @@ -151,7 +152,7 @@ void CollisionObject3DSW::_unregister_shapes() { } } -void CollisionObject3DSW::_update_shapes() { +void GodotCollisionObject3D::_update_shapes() { if (!space) { return; } @@ -181,7 +182,7 @@ void CollisionObject3DSW::_update_shapes() { } } -void CollisionObject3DSW::_update_shapes_with_motion(const Vector3 &p_motion) { +void GodotCollisionObject3D::_update_shapes_with_motion(const Vector3 &p_motion) { if (!space) { return; } @@ -208,7 +209,7 @@ void CollisionObject3DSW::_update_shapes_with_motion(const Vector3 &p_motion) { } } -void CollisionObject3DSW::_set_space(Space3DSW *p_space) { +void GodotCollisionObject3D::_set_space(GodotSpace3D *p_space) { if (space) { space->remove_object(this); @@ -229,12 +230,12 @@ void CollisionObject3DSW::_set_space(Space3DSW *p_space) { } } -void CollisionObject3DSW::_shape_changed() { +void GodotCollisionObject3D::_shape_changed() { _update_shapes(); _shapes_changed(); } -CollisionObject3DSW::CollisionObject3DSW(Type p_type) : +GodotCollisionObject3D::GodotCollisionObject3D(Type p_type) : pending_shape_update_list(this) { type = p_type; } diff --git a/servers/physics_3d/collision_object_3d_sw.h b/servers/physics_3d/godot_collision_object_3d.h index 3aa48946b7..43558034e0 100644 --- a/servers/physics_3d/collision_object_3d_sw.h +++ b/servers/physics_3d/godot_collision_object_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_object_3d_sw.h */ +/* godot_collision_object_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef COLLISION_OBJECT_SW_H -#define COLLISION_OBJECT_SW_H +#ifndef GODOT_COLLISION_OBJECT_3D_H +#define GODOT_COLLISION_OBJECT_3D_H + +#include "godot_broad_phase_3d.h" +#include "godot_shape_3d.h" -#include "broad_phase_3d_sw.h" #include "core/templates/self_list.h" #include "servers/physics_server_3d.h" -#include "shape_3d_sw.h" #ifdef DEBUG_ENABLED #define MAX_OBJECT_DISTANCE 3.1622776601683791e+18 @@ -42,9 +43,9 @@ #define MAX_OBJECT_DISTANCE_X2 (MAX_OBJECT_DISTANCE * MAX_OBJECT_DISTANCE) #endif -class Space3DSW; +class GodotSpace3D; -class CollisionObject3DSW : public ShapeOwner3DSW { +class GodotCollisionObject3D : public GodotShapeOwner3D { public: enum Type { TYPE_AREA, @@ -62,20 +63,20 @@ private: struct Shape { Transform3D xform; Transform3D xform_inv; - BroadPhase3DSW::ID bpid; + GodotBroadPhase3D::ID bpid; AABB aabb_cache; //for rayqueries real_t area_cache = 0.0; - Shape3DSW *shape = nullptr; + GodotShape3D *shape = nullptr; bool disabled = false; }; Vector<Shape> shapes; - Space3DSW *space = nullptr; + GodotSpace3D *space = nullptr; Transform3D transform; Transform3D inv_transform; bool _static = true; - SelfList<CollisionObject3DSW> pending_shape_update_list; + SelfList<GodotCollisionObject3D> pending_shape_update_list; void _update_shapes(); @@ -98,11 +99,11 @@ protected: void _set_static(bool p_static); virtual void _shapes_changed() = 0; - void _set_space(Space3DSW *p_space); + void _set_space(GodotSpace3D *p_space); bool ray_pickable = true; - CollisionObject3DSW(Type p_type); + GodotCollisionObject3D(Type p_type); public: _FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; } @@ -114,11 +115,11 @@ public: void _shape_changed(); _FORCE_INLINE_ Type get_type() const { return type; } - void add_shape(Shape3DSW *p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false); - void set_shape(int p_index, Shape3DSW *p_shape); + void add_shape(GodotShape3D *p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false); + void set_shape(int p_index, GodotShape3D *p_shape); void set_shape_transform(int p_index, const Transform3D &p_transform); _FORCE_INLINE_ int get_shape_count() const { return shapes.size(); } - _FORCE_INLINE_ Shape3DSW *get_shape(int p_index) const { + _FORCE_INLINE_ GodotShape3D *get_shape(int p_index) const { CRASH_BAD_INDEX(p_index, shapes.size()); return shapes[p_index].shape; } @@ -141,7 +142,7 @@ public: _FORCE_INLINE_ const Transform3D &get_transform() const { return transform; } _FORCE_INLINE_ const Transform3D &get_inv_transform() const { return inv_transform; } - _FORCE_INLINE_ Space3DSW *get_space() const { return space; } + _FORCE_INLINE_ GodotSpace3D *get_space() const { return space; } _FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable = p_enable; } _FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; } @@ -164,22 +165,22 @@ public: } _FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; } - _FORCE_INLINE_ bool collides_with(CollisionObject3DSW *p_other) const { + _FORCE_INLINE_ bool collides_with(GodotCollisionObject3D *p_other) const { return p_other->collision_layer & collision_mask; } - _FORCE_INLINE_ bool interacts_with(CollisionObject3DSW *p_other) const { + _FORCE_INLINE_ bool interacts_with(GodotCollisionObject3D *p_other) const { return collision_layer & p_other->collision_mask || p_other->collision_layer & collision_mask; } - void remove_shape(Shape3DSW *p_shape); + void remove_shape(GodotShape3D *p_shape); void remove_shape(int p_index); - virtual void set_space(Space3DSW *p_space) = 0; + virtual void set_space(GodotSpace3D *p_space) = 0; _FORCE_INLINE_ bool is_static() const { return _static; } - virtual ~CollisionObject3DSW() {} + virtual ~GodotCollisionObject3D() {} }; -#endif // COLLISION_OBJECT_SW_H +#endif // GODOT_COLLISION_OBJECT_3D_H diff --git a/servers/physics_3d/collision_solver_3d_sw.cpp b/servers/physics_3d/godot_collision_solver_3d.cpp index 96f1936668..b9f2f7506b 100644 --- a/servers/physics_3d/collision_solver_3d_sw.cpp +++ b/servers/physics_3d/godot_collision_solver_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_solver_3d_sw.cpp */ +/* godot_collision_solver_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,17 +28,17 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "collision_solver_3d_sw.h" -#include "collision_solver_3d_sat.h" -#include "soft_body_3d_sw.h" +#include "godot_collision_solver_3d.h" +#include "godot_collision_solver_3d_sat.h" +#include "godot_soft_body_3d.h" #include "gjk_epa.h" #define collision_solver sat_calculate_penetration //#define collision_solver gjk_epa_calculate_penetration -bool CollisionSolver3DSW::solve_static_world_boundary(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { - const WorldBoundaryShape3DSW *world_boundary = static_cast<const WorldBoundaryShape3DSW *>(p_shape_A); +bool GodotCollisionSolver3D::solve_static_world_boundary(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { + const GodotWorldBoundaryShape3D *world_boundary = static_cast<const GodotWorldBoundaryShape3D *>(p_shape_A); if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_WORLD_BOUNDARY) { return false; } @@ -47,10 +47,10 @@ bool CollisionSolver3DSW::solve_static_world_boundary(const Shape3DSW *p_shape_A static const int max_supports = 16; Vector3 supports[max_supports]; int support_count; - Shape3DSW::FeatureType support_type; + GodotShape3D::FeatureType support_type; p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count, support_type); - if (support_type == Shape3DSW::FEATURE_CIRCLE) { + if (support_type == GodotShape3D::FEATURE_CIRCLE) { ERR_FAIL_COND_V(support_count != 3, false); Vector3 circle_pos = supports[0]; @@ -89,8 +89,8 @@ bool CollisionSolver3DSW::solve_static_world_boundary(const Shape3DSW *p_shape_A return found; } -bool CollisionSolver3DSW::solve_separation_ray(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin) { - const SeparationRayShape3DSW *ray = static_cast<const SeparationRayShape3DSW *>(p_shape_A); +bool GodotCollisionSolver3D::solve_separation_ray(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin) { + const GodotSeparationRayShape3D *ray = static_cast<const GodotSeparationRayShape3D *>(p_shape_A); Vector3 from = p_transform_A.origin; Vector3 to = from + p_transform_A.basis.get_axis(2) * (ray->get_length() + p_margin); @@ -134,13 +134,13 @@ bool CollisionSolver3DSW::solve_separation_ray(const Shape3DSW *p_shape_A, const struct _SoftBodyContactCollisionInfo { int node_index = 0; - CollisionSolver3DSW::CallbackResult result_callback = nullptr; + GodotCollisionSolver3D::CallbackResult result_callback = nullptr; void *userdata = nullptr; bool swap_result = false; int contact_count = 0; }; -void CollisionSolver3DSW::soft_body_contact_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B, void *p_userdata) { +void GodotCollisionSolver3D::soft_body_contact_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B, void *p_userdata) { _SoftBodyContactCollisionInfo &cinfo = *(_SoftBodyContactCollisionInfo *)(p_userdata); ++cinfo.contact_count; @@ -157,9 +157,9 @@ void CollisionSolver3DSW::soft_body_contact_callback(const Vector3 &p_point_A, i } struct _SoftBodyQueryInfo { - SoftBody3DSW *soft_body = nullptr; - const Shape3DSW *shape_A = nullptr; - const Shape3DSW *shape_B = nullptr; + GodotSoftBody3D *soft_body = nullptr; + const GodotShape3D *shape_A = nullptr; + const GodotShape3D *shape_B = nullptr; Transform3D transform_A; Transform3D node_transform; _SoftBodyContactCollisionInfo contact_info; @@ -169,7 +169,7 @@ struct _SoftBodyQueryInfo { #endif }; -bool CollisionSolver3DSW::soft_body_query_callback(uint32_t p_node_index, void *p_userdata) { +bool GodotCollisionSolver3D::soft_body_query_callback(uint32_t p_node_index, void *p_userdata) { _SoftBodyQueryInfo &query_cinfo = *(_SoftBodyQueryInfo *)(p_userdata); Vector3 node_position = query_cinfo.soft_body->get_node_position(p_node_index); @@ -188,7 +188,7 @@ bool CollisionSolver3DSW::soft_body_query_callback(uint32_t p_node_index, void * return (collided && !query_cinfo.contact_info.result_callback); } -bool CollisionSolver3DSW::soft_body_concave_callback(void *p_userdata, Shape3DSW *p_convex) { +bool GodotCollisionSolver3D::soft_body_concave_callback(void *p_userdata, GodotShape3D *p_convex) { _SoftBodyQueryInfo &query_cinfo = *(_SoftBodyQueryInfo *)(p_userdata); query_cinfo.shape_A = p_convex; @@ -220,15 +220,15 @@ bool CollisionSolver3DSW::soft_body_concave_callback(void *p_userdata, Shape3DSW return (collided && !query_cinfo.contact_info.result_callback); } -bool CollisionSolver3DSW::solve_soft_body(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { - const SoftBodyShape3DSW *soft_body_shape_B = static_cast<const SoftBodyShape3DSW *>(p_shape_B); +bool GodotCollisionSolver3D::solve_soft_body(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { + const GodotSoftBodyShape3D *soft_body_shape_B = static_cast<const GodotSoftBodyShape3D *>(p_shape_B); - SoftBody3DSW *soft_body = soft_body_shape_B->get_soft_body(); + GodotSoftBody3D *soft_body = soft_body_shape_B->get_soft_body(); const Transform3D &world_to_local = soft_body->get_inv_transform(); const real_t collision_margin = soft_body->get_collision_margin(); - SphereShape3DSW sphere_shape; + GodotSphereShape3D sphere_shape; sphere_shape.set_data(collision_margin); _SoftBodyQueryInfo query_cinfo; @@ -243,7 +243,7 @@ bool CollisionSolver3DSW::solve_soft_body(const Shape3DSW *p_shape_A, const Tran if (p_shape_A->is_concave()) { // In case of concave shape, query convex shapes first. - const ConcaveShape3DSW *concave_shape_A = static_cast<const ConcaveShape3DSW *>(p_shape_A); + const GodotConcaveShape3D *concave_shape_A = static_cast<const GodotConcaveShape3D *>(p_shape_A); AABB soft_body_aabb = soft_body->get_bounds(); soft_body_aabb.grow_by(collision_margin); @@ -277,9 +277,9 @@ bool CollisionSolver3DSW::solve_soft_body(const Shape3DSW *p_shape_A, const Tran struct _ConcaveCollisionInfo { const Transform3D *transform_A; - const Shape3DSW *shape_A; + const GodotShape3D *shape_A; const Transform3D *transform_B; - CollisionSolver3DSW::CallbackResult result_callback; + GodotCollisionSolver3D::CallbackResult result_callback; void *userdata; bool swap_result; bool collided; @@ -291,7 +291,7 @@ struct _ConcaveCollisionInfo { Vector3 close_A, close_B; }; -bool CollisionSolver3DSW::concave_callback(void *p_userdata, Shape3DSW *p_convex) { +bool GodotCollisionSolver3D::concave_callback(void *p_userdata, GodotShape3D *p_convex) { _ConcaveCollisionInfo &cinfo = *(_ConcaveCollisionInfo *)(p_userdata); cinfo.aabb_tests++; @@ -307,8 +307,8 @@ bool CollisionSolver3DSW::concave_callback(void *p_userdata, Shape3DSW *p_convex return !cinfo.result_callback; } -bool CollisionSolver3DSW::solve_concave(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin_A, real_t p_margin_B) { - const ConcaveShape3DSW *concave_B = static_cast<const ConcaveShape3DSW *>(p_shape_B); +bool GodotCollisionSolver3D::solve_concave(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin_A, real_t p_margin_B) { + const GodotConcaveShape3D *concave_B = static_cast<const GodotConcaveShape3D *>(p_shape_B); _ConcaveCollisionInfo cinfo; cinfo.transform_A = &p_transform_A; @@ -351,7 +351,7 @@ bool CollisionSolver3DSW::solve_concave(const Shape3DSW *p_shape_A, const Transf return cinfo.collided; } -bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis, real_t p_margin_A, real_t p_margin_B) { +bool GodotCollisionSolver3D::solve_static(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis, real_t p_margin_A, real_t p_margin_B) { PhysicsServer3D::ShapeType type_A = p_shape_A->get_type(); PhysicsServer3D::ShapeType type_B = p_shape_B->get_type(); bool concave_A = p_shape_A->is_concave(); @@ -421,7 +421,7 @@ bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transfo } } -bool CollisionSolver3DSW::concave_distance_callback(void *p_userdata, Shape3DSW *p_convex) { +bool GodotCollisionSolver3D::concave_distance_callback(void *p_userdata, GodotShape3D *p_convex) { _ConcaveCollisionInfo &cinfo = *(_ConcaveCollisionInfo *)(p_userdata); cinfo.aabb_tests++; @@ -443,8 +443,8 @@ bool CollisionSolver3DSW::concave_distance_callback(void *p_userdata, Shape3DSW return false; } -bool CollisionSolver3DSW::solve_distance_world_boundary(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B) { - const WorldBoundaryShape3DSW *world_boundary = static_cast<const WorldBoundaryShape3DSW *>(p_shape_A); +bool GodotCollisionSolver3D::solve_distance_world_boundary(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B) { + const GodotWorldBoundaryShape3D *world_boundary = static_cast<const GodotWorldBoundaryShape3D *>(p_shape_A); if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_WORLD_BOUNDARY) { return false; } @@ -453,11 +453,11 @@ bool CollisionSolver3DSW::solve_distance_world_boundary(const Shape3DSW *p_shape static const int max_supports = 16; Vector3 supports[max_supports]; int support_count; - Shape3DSW::FeatureType support_type; + GodotShape3D::FeatureType support_type; p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count, support_type); - if (support_type == Shape3DSW::FEATURE_CIRCLE) { + if (support_type == GodotShape3D::FEATURE_CIRCLE) { ERR_FAIL_COND_V(support_count != 3, false); Vector3 circle_pos = supports[0]; @@ -495,7 +495,7 @@ bool CollisionSolver3DSW::solve_distance_world_boundary(const Shape3DSW *p_shape return collided; } -bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis) { +bool GodotCollisionSolver3D::solve_distance(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis) { if (p_shape_A->is_concave()) { return false; } @@ -512,7 +512,7 @@ bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Trans return false; } - const ConcaveShape3DSW *concave_B = static_cast<const ConcaveShape3DSW *>(p_shape_B); + const GodotConcaveShape3D *concave_B = static_cast<const GodotConcaveShape3D *>(p_shape_B); _ConcaveCollisionInfo cinfo; cinfo.transform_A = &p_transform_A; diff --git a/servers/physics_3d/collision_solver_3d_sw.h b/servers/physics_3d/godot_collision_solver_3d.h index 0a9ea7c0eb..133635ca7e 100644 --- a/servers/physics_3d/collision_solver_3d_sw.h +++ b/servers/physics_3d/godot_collision_solver_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_solver_3d_sw.h */ +/* godot_collision_solver_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,30 +28,30 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef COLLISION_SOLVER_SW_H -#define COLLISION_SOLVER_SW_H +#ifndef GODOT_COLLISION_SOLVER_3D_H +#define GODOT_COLLISION_SOLVER_3D_H -#include "shape_3d_sw.h" +#include "godot_shape_3d.h" -class CollisionSolver3DSW { +class GodotCollisionSolver3D { public: typedef void (*CallbackResult)(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B, void *p_userdata); private: static bool soft_body_query_callback(uint32_t p_node_index, void *p_userdata); static void soft_body_contact_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B, void *p_userdata); - static bool soft_body_concave_callback(void *p_userdata, Shape3DSW *p_convex); - static bool concave_callback(void *p_userdata, Shape3DSW *p_convex); - static bool solve_static_world_boundary(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); - static bool solve_separation_ray(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin = 0); - static bool solve_soft_body(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); - static bool solve_concave(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin_A = 0, real_t p_margin_B = 0); - static bool concave_distance_callback(void *p_userdata, Shape3DSW *p_convex); - static bool solve_distance_world_boundary(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B); + static bool soft_body_concave_callback(void *p_userdata, GodotShape3D *p_convex); + static bool concave_callback(void *p_userdata, GodotShape3D *p_convex); + static bool solve_static_world_boundary(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); + static bool solve_separation_ray(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin = 0); + static bool solve_soft_body(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); + static bool solve_concave(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin_A = 0, real_t p_margin_B = 0); + static bool concave_distance_callback(void *p_userdata, GodotShape3D *p_convex); + static bool solve_distance_world_boundary(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B); public: - static bool solve_static(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); - static bool solve_distance(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis = nullptr); + static bool solve_static(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); + static bool solve_distance(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis = nullptr); }; -#endif // COLLISION_SOLVER__SW_H +#endif // GODOT_COLLISION_SOLVER_3D_H diff --git a/servers/physics_3d/collision_solver_3d_sat.cpp b/servers/physics_3d/godot_collision_solver_3d_sat.cpp index 86150f41a0..0790333f65 100644 --- a/servers/physics_3d/collision_solver_3d_sat.cpp +++ b/servers/physics_3d/godot_collision_solver_3d_sat.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_solver_3d_sat.cpp */ +/* godot_collision_solver_3d_sat.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "collision_solver_3d_sat.h" -#include "core/math/geometry_3d.h" +#include "godot_collision_solver_3d_sat.h" #include "gjk_epa.h" +#include "core/math/geometry_3d.h" + #define fallback_collision_solver gjk_epa_calculate_penetration // Cylinder SAT analytic methods and face-circle contact points for cylinder-trimesh and cylinder-box collision are based on ODE colliders. @@ -65,7 +66,7 @@ *************************************************************************/ struct _CollectorCallback { - CollisionSolver3DSW::CallbackResult callback; + GodotCollisionSolver3D::CallbackResult callback; void *userdata = nullptr; bool swap = false; bool collided = false; @@ -539,7 +540,7 @@ static void _generate_contacts_circle_circle(const Vector3 *p_points_A, int p_po } } -static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_point_count_A, Shape3DSW::FeatureType p_feature_type_A, const Vector3 *p_points_B, int p_point_count_B, Shape3DSW::FeatureType p_feature_type_B, _CollectorCallback *p_callback) { +static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_point_count_A, GodotShape3D::FeatureType p_feature_type_A, const Vector3 *p_points_B, int p_point_count_B, GodotShape3D::FeatureType p_feature_type_B, _CollectorCallback *p_callback) { #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A < 1); ERR_FAIL_COND(p_point_count_B < 1); @@ -713,7 +714,7 @@ public: Vector3 supports_A[max_supports]; int support_count_A; - Shape3DSW::FeatureType support_type_A; + GodotShape3D::FeatureType support_type_A; shape_A->get_supports(transform_A->basis.xform_inv(-best_axis).normalized(), max_supports, supports_A, support_count_A, support_type_A); for (int i = 0; i < support_count_A; i++) { supports_A[i] = transform_A->xform(supports_A[i]); @@ -727,7 +728,7 @@ public: Vector3 supports_B[max_supports]; int support_count_B; - Shape3DSW::FeatureType support_type_B; + GodotShape3D::FeatureType support_type_B; shape_B->get_supports(transform_B->basis.xform_inv(best_axis).normalized(), max_supports, supports_B, support_count_B, support_type_B); for (int i = 0; i < support_count_B; i++) { supports_B[i] = transform_B->xform(supports_B[i]); @@ -761,14 +762,14 @@ public: /****** SAT TESTS *******/ -typedef void (*CollisionFunc)(const Shape3DSW *, const Transform3D &, const Shape3DSW *, const Transform3D &, _CollectorCallback *p_callback, real_t, real_t); +typedef void (*CollisionFunc)(const GodotShape3D *, const Transform3D &, const GodotShape3D *, const Transform3D &, _CollectorCallback *p_callback, real_t, real_t); template <bool withMargin> -static void _collision_sphere_sphere(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); - const SphereShape3DSW *sphere_B = static_cast<const SphereShape3DSW *>(p_b); +static void _collision_sphere_sphere(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotSphereShape3D *sphere_A = static_cast<const GodotSphereShape3D *>(p_a); + const GodotSphereShape3D *sphere_B = static_cast<const GodotSphereShape3D *>(p_b); - SeparatorAxisTest<SphereShape3DSW, SphereShape3DSW, withMargin> separator(sphere_A, p_transform_a, sphere_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotSphereShape3D, GodotSphereShape3D, withMargin> separator(sphere_A, p_transform_a, sphere_B, p_transform_b, p_collector, p_margin_a, p_margin_b); // previous axis @@ -784,11 +785,11 @@ static void _collision_sphere_sphere(const Shape3DSW *p_a, const Transform3D &p_ } template <bool withMargin> -static void _collision_sphere_box(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); - const BoxShape3DSW *box_B = static_cast<const BoxShape3DSW *>(p_b); +static void _collision_sphere_box(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotSphereShape3D *sphere_A = static_cast<const GodotSphereShape3D *>(p_a); + const GodotBoxShape3D *box_B = static_cast<const GodotBoxShape3D *>(p_b); - SeparatorAxisTest<SphereShape3DSW, BoxShape3DSW, withMargin> separator(sphere_A, p_transform_a, box_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotSphereShape3D, GodotBoxShape3D, withMargin> separator(sphere_A, p_transform_a, box_B, p_transform_b, p_collector, p_margin_a, p_margin_b); if (!separator.test_previous_axis()) { return; @@ -835,11 +836,11 @@ static void _collision_sphere_box(const Shape3DSW *p_a, const Transform3D &p_tra } template <bool withMargin> -static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); - const CapsuleShape3DSW *capsule_B = static_cast<const CapsuleShape3DSW *>(p_b); +static void _collision_sphere_capsule(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotSphereShape3D *sphere_A = static_cast<const GodotSphereShape3D *>(p_a); + const GodotCapsuleShape3D *capsule_B = static_cast<const GodotCapsuleShape3D *>(p_b); - SeparatorAxisTest<SphereShape3DSW, CapsuleShape3DSW, withMargin> separator(sphere_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotSphereShape3D, GodotCapsuleShape3D, withMargin> separator(sphere_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_margin_a, p_margin_b); if (!separator.test_previous_axis()) { return; @@ -877,11 +878,11 @@ static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform3D &p } template <bool withMargin> -static void _collision_sphere_cylinder(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); - const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); +static void _collision_sphere_cylinder(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotSphereShape3D *sphere_A = static_cast<const GodotSphereShape3D *>(p_a); + const GodotCylinderShape3D *cylinder_B = static_cast<const GodotCylinderShape3D *>(p_b); - SeparatorAxisTest<SphereShape3DSW, CylinderShape3DSW, withMargin> separator(sphere_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotSphereShape3D, GodotCylinderShape3D, withMargin> separator(sphere_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); if (!separator.test_previous_axis()) { return; @@ -936,11 +937,11 @@ static void _collision_sphere_cylinder(const Shape3DSW *p_a, const Transform3D & } template <bool withMargin> -static void _collision_sphere_convex_polygon(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); - const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); +static void _collision_sphere_convex_polygon(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotSphereShape3D *sphere_A = static_cast<const GodotSphereShape3D *>(p_a); + const GodotConvexPolygonShape3D *convex_polygon_B = static_cast<const GodotConvexPolygonShape3D *>(p_b); - SeparatorAxisTest<SphereShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(sphere_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotSphereShape3D, GodotConvexPolygonShape3D, withMargin> separator(sphere_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); if (!separator.test_previous_axis()) { return; @@ -999,11 +1000,11 @@ static void _collision_sphere_convex_polygon(const Shape3DSW *p_a, const Transfo } template <bool withMargin> -static void _collision_sphere_face(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); - const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); +static void _collision_sphere_face(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotSphereShape3D *sphere_A = static_cast<const GodotSphereShape3D *>(p_a); + const GodotFaceShape3D *face_B = static_cast<const GodotFaceShape3D *>(p_b); - SeparatorAxisTest<SphereShape3DSW, FaceShape3DSW, withMargin> separator(sphere_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotSphereShape3D, GodotFaceShape3D, withMargin> separator(sphere_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b); Vector3 vertex[3] = { p_transform_b.xform(face_B->vertex[0]), @@ -1044,11 +1045,11 @@ static void _collision_sphere_face(const Shape3DSW *p_a, const Transform3D &p_tr } template <bool withMargin> -static void _collision_box_box(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); - const BoxShape3DSW *box_B = static_cast<const BoxShape3DSW *>(p_b); +static void _collision_box_box(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotBoxShape3D *box_A = static_cast<const GodotBoxShape3D *>(p_a); + const GodotBoxShape3D *box_B = static_cast<const GodotBoxShape3D *>(p_b); - SeparatorAxisTest<BoxShape3DSW, BoxShape3DSW, withMargin> separator(box_A, p_transform_a, box_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotBoxShape3D, GodotBoxShape3D, withMargin> separator(box_A, p_transform_a, box_B, p_transform_b, p_collector, p_margin_a, p_margin_b); if (!separator.test_previous_axis()) { return; @@ -1142,11 +1143,11 @@ static void _collision_box_box(const Shape3DSW *p_a, const Transform3D &p_transf } template <bool withMargin> -static void _collision_box_capsule(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); - const CapsuleShape3DSW *capsule_B = static_cast<const CapsuleShape3DSW *>(p_b); +static void _collision_box_capsule(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotBoxShape3D *box_A = static_cast<const GodotBoxShape3D *>(p_a); + const GodotCapsuleShape3D *capsule_B = static_cast<const GodotCapsuleShape3D *>(p_b); - SeparatorAxisTest<BoxShape3DSW, CapsuleShape3DSW, withMargin> separator(box_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotBoxShape3D, GodotCapsuleShape3D, withMargin> separator(box_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_margin_a, p_margin_b); if (!separator.test_previous_axis()) { return; @@ -1240,11 +1241,11 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform3D &p_tr } template <bool withMargin> -static void _collision_box_cylinder(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); - const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); +static void _collision_box_cylinder(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotBoxShape3D *box_A = static_cast<const GodotBoxShape3D *>(p_a); + const GodotCylinderShape3D *cylinder_B = static_cast<const GodotCylinderShape3D *>(p_b); - SeparatorAxisTest<BoxShape3DSW, CylinderShape3DSW, withMargin> separator(box_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotBoxShape3D, GodotCylinderShape3D, withMargin> separator(box_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); if (!separator.test_previous_axis()) { return; @@ -1353,11 +1354,11 @@ static void _collision_box_cylinder(const Shape3DSW *p_a, const Transform3D &p_t } template <bool withMargin> -static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); - const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); +static void _collision_box_convex_polygon(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotBoxShape3D *box_A = static_cast<const GodotBoxShape3D *>(p_a); + const GodotConvexPolygonShape3D *convex_polygon_B = static_cast<const GodotConvexPolygonShape3D *>(p_b); - SeparatorAxisTest<BoxShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(box_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotBoxShape3D, GodotConvexPolygonShape3D, withMargin> separator(box_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); if (!separator.test_previous_axis()) { return; @@ -1471,11 +1472,11 @@ static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform3 } template <bool withMargin> -static void _collision_box_face(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); - const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); +static void _collision_box_face(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotBoxShape3D *box_A = static_cast<const GodotBoxShape3D *>(p_a); + const GodotFaceShape3D *face_B = static_cast<const GodotFaceShape3D *>(p_b); - SeparatorAxisTest<BoxShape3DSW, FaceShape3DSW, withMargin> separator(box_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotBoxShape3D, GodotFaceShape3D, withMargin> separator(box_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b); Vector3 vertex[3] = { p_transform_b.xform(face_B->vertex[0]), @@ -1594,11 +1595,11 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform3D &p_trans } template <bool withMargin> -static void _collision_capsule_capsule(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a); - const CapsuleShape3DSW *capsule_B = static_cast<const CapsuleShape3DSW *>(p_b); +static void _collision_capsule_capsule(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotCapsuleShape3D *capsule_A = static_cast<const GodotCapsuleShape3D *>(p_a); + const GodotCapsuleShape3D *capsule_B = static_cast<const GodotCapsuleShape3D *>(p_b); - SeparatorAxisTest<CapsuleShape3DSW, CapsuleShape3DSW, withMargin> separator(capsule_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotCapsuleShape3D, GodotCapsuleShape3D, withMargin> separator(capsule_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_margin_a, p_margin_b); if (!separator.test_previous_axis()) { return; @@ -1658,11 +1659,11 @@ static void _collision_capsule_capsule(const Shape3DSW *p_a, const Transform3D & } template <bool withMargin> -static void _collision_capsule_cylinder(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a); - const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); +static void _collision_capsule_cylinder(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotCapsuleShape3D *capsule_A = static_cast<const GodotCapsuleShape3D *>(p_a); + const GodotCylinderShape3D *cylinder_B = static_cast<const GodotCylinderShape3D *>(p_b); - SeparatorAxisTest<CapsuleShape3DSW, CylinderShape3DSW, withMargin> separator(capsule_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotCapsuleShape3D, GodotCylinderShape3D, withMargin> separator(capsule_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); if (!separator.test_previous_axis()) { return; @@ -1709,7 +1710,7 @@ static void _collision_capsule_cylinder(const Shape3DSW *p_a, const Transform3D return; } - CollisionSolver3DSW::CallbackResult callback = SeparatorAxisTest<CapsuleShape3DSW, CylinderShape3DSW, withMargin>::test_contact_points; + GodotCollisionSolver3D::CallbackResult callback = SeparatorAxisTest<GodotCapsuleShape3D, GodotCylinderShape3D, withMargin>::test_contact_points; // Fallback to generic algorithm to find the best separating axis. if (!fallback_collision_solver(p_a, p_transform_a, p_b, p_transform_b, callback, &separator, false, p_margin_a, p_margin_b)) { @@ -1720,11 +1721,11 @@ static void _collision_capsule_cylinder(const Shape3DSW *p_a, const Transform3D } template <bool withMargin> -static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a); - const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); +static void _collision_capsule_convex_polygon(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotCapsuleShape3D *capsule_A = static_cast<const GodotCapsuleShape3D *>(p_a); + const GodotConvexPolygonShape3D *convex_polygon_B = static_cast<const GodotConvexPolygonShape3D *>(p_b); - SeparatorAxisTest<CapsuleShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(capsule_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotCapsuleShape3D, GodotConvexPolygonShape3D, withMargin> separator(capsule_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); if (!separator.test_previous_axis()) { return; @@ -1787,11 +1788,11 @@ static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transf } template <bool withMargin> -static void _collision_capsule_face(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a); - const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); +static void _collision_capsule_face(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotCapsuleShape3D *capsule_A = static_cast<const GodotCapsuleShape3D *>(p_a); + const GodotFaceShape3D *face_B = static_cast<const GodotFaceShape3D *>(p_b); - SeparatorAxisTest<CapsuleShape3DSW, FaceShape3DSW, withMargin> separator(capsule_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotCapsuleShape3D, GodotFaceShape3D, withMargin> separator(capsule_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b); Vector3 vertex[3] = { p_transform_b.xform(face_B->vertex[0]), @@ -1861,11 +1862,11 @@ static void _collision_capsule_face(const Shape3DSW *p_a, const Transform3D &p_t } template <bool withMargin> -static void _collision_cylinder_cylinder(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a); - const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); +static void _collision_cylinder_cylinder(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotCylinderShape3D *cylinder_A = static_cast<const GodotCylinderShape3D *>(p_a); + const GodotCylinderShape3D *cylinder_B = static_cast<const GodotCylinderShape3D *>(p_b); - SeparatorAxisTest<CylinderShape3DSW, CylinderShape3DSW, withMargin> separator(cylinder_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotCylinderShape3D, GodotCylinderShape3D, withMargin> separator(cylinder_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); Vector3 cylinder_A_axis = p_transform_a.basis.get_axis(1); Vector3 cylinder_B_axis = p_transform_b.basis.get_axis(1); @@ -1904,7 +1905,7 @@ static void _collision_cylinder_cylinder(const Shape3DSW *p_a, const Transform3D return; } - CollisionSolver3DSW::CallbackResult callback = SeparatorAxisTest<CylinderShape3DSW, CylinderShape3DSW, withMargin>::test_contact_points; + GodotCollisionSolver3D::CallbackResult callback = SeparatorAxisTest<GodotCylinderShape3D, GodotCylinderShape3D, withMargin>::test_contact_points; // Fallback to generic algorithm to find the best separating axis. if (!fallback_collision_solver(p_a, p_transform_a, p_b, p_transform_b, callback, &separator, false, p_margin_a, p_margin_b)) { @@ -1915,13 +1916,13 @@ static void _collision_cylinder_cylinder(const Shape3DSW *p_a, const Transform3D } template <bool withMargin> -static void _collision_cylinder_convex_polygon(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a); - const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); +static void _collision_cylinder_convex_polygon(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotCylinderShape3D *cylinder_A = static_cast<const GodotCylinderShape3D *>(p_a); + const GodotConvexPolygonShape3D *convex_polygon_B = static_cast<const GodotConvexPolygonShape3D *>(p_b); - SeparatorAxisTest<CylinderShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(cylinder_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotCylinderShape3D, GodotConvexPolygonShape3D, withMargin> separator(cylinder_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); - CollisionSolver3DSW::CallbackResult callback = SeparatorAxisTest<CylinderShape3DSW, ConvexPolygonShape3DSW, withMargin>::test_contact_points; + GodotCollisionSolver3D::CallbackResult callback = SeparatorAxisTest<GodotCylinderShape3D, GodotConvexPolygonShape3D, withMargin>::test_contact_points; // Fallback to generic algorithm to find the best separating axis. if (!fallback_collision_solver(p_a, p_transform_a, p_b, p_transform_b, callback, &separator, false, p_margin_a, p_margin_b)) { @@ -1932,11 +1933,11 @@ static void _collision_cylinder_convex_polygon(const Shape3DSW *p_a, const Trans } template <bool withMargin> -static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a); - const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); +static void _collision_cylinder_face(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotCylinderShape3D *cylinder_A = static_cast<const GodotCylinderShape3D *>(p_a); + const GodotFaceShape3D *face_B = static_cast<const GodotFaceShape3D *>(p_b); - SeparatorAxisTest<CylinderShape3DSW, FaceShape3DSW, withMargin> separator(cylinder_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotCylinderShape3D, GodotFaceShape3D, withMargin> separator(cylinder_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b); if (!separator.test_previous_axis()) { return; @@ -2037,11 +2038,11 @@ static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform3D &p_ } template <bool withMargin> -static void _collision_convex_polygon_convex_polygon(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const ConvexPolygonShape3DSW *convex_polygon_A = static_cast<const ConvexPolygonShape3DSW *>(p_a); - const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); +static void _collision_convex_polygon_convex_polygon(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotConvexPolygonShape3D *convex_polygon_A = static_cast<const GodotConvexPolygonShape3D *>(p_a); + const GodotConvexPolygonShape3D *convex_polygon_B = static_cast<const GodotConvexPolygonShape3D *>(p_b); - SeparatorAxisTest<ConvexPolygonShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(convex_polygon_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotConvexPolygonShape3D, GodotConvexPolygonShape3D, withMargin> separator(convex_polygon_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); if (!separator.test_previous_axis()) { return; @@ -2150,11 +2151,11 @@ static void _collision_convex_polygon_convex_polygon(const Shape3DSW *p_a, const } template <bool withMargin> -static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const ConvexPolygonShape3DSW *convex_polygon_A = static_cast<const ConvexPolygonShape3DSW *>(p_a); - const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); +static void _collision_convex_polygon_face(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const GodotConvexPolygonShape3D *convex_polygon_A = static_cast<const GodotConvexPolygonShape3D *>(p_a); + const GodotFaceShape3D *face_B = static_cast<const GodotFaceShape3D *>(p_b); - SeparatorAxisTest<ConvexPolygonShape3DSW, FaceShape3DSW, withMargin> separator(convex_polygon_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + SeparatorAxisTest<GodotConvexPolygonShape3D, GodotFaceShape3D, withMargin> separator(convex_polygon_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b); const Geometry3D::MeshData &mesh = convex_polygon_A->get_mesh(); @@ -2268,7 +2269,7 @@ static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform separator.generate_contacts(); } -bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap, Vector3 *r_prev_axis, real_t p_margin_a, real_t p_margin_b) { +bool sat_calculate_penetration(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, GodotCollisionSolver3D::CallbackResult p_result_callback, void *p_userdata, bool p_swap, Vector3 *r_prev_axis, real_t p_margin_a, real_t p_margin_b) { PhysicsServer3D::ShapeType type_A = p_shape_A->get_type(); ERR_FAIL_COND_V(type_A == PhysicsServer3D::SHAPE_WORLD_BOUNDARY, false); @@ -2366,8 +2367,8 @@ bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform3D &p_ callback.collided = false; callback.prev_axis = r_prev_axis; - const Shape3DSW *A = p_shape_A; - const Shape3DSW *B = p_shape_B; + const GodotShape3D *A = p_shape_A; + const GodotShape3D *B = p_shape_B; const Transform3D *transform_A = &p_transform_A; const Transform3D *transform_B = &p_transform_B; real_t margin_A = p_margin_a; diff --git a/servers/physics_3d/collision_solver_3d_sat.h b/servers/physics_3d/godot_collision_solver_3d_sat.h index e50da7b101..069a701cba 100644 --- a/servers/physics_3d/collision_solver_3d_sat.h +++ b/servers/physics_3d/godot_collision_solver_3d_sat.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_solver_3d_sat.h */ +/* godot_collision_solver_3d_sat.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef COLLISION_SOLVER_SAT_H -#define COLLISION_SOLVER_SAT_H +#ifndef GODOT_COLLISION_SOLVER_SAT_H +#define GODOT_COLLISION_SOLVER_SAT_H -#include "collision_solver_3d_sw.h" +#include "godot_collision_solver_3d.h" -bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, Vector3 *r_prev_axis = nullptr, real_t p_margin_a = 0, real_t p_margin_b = 0); +bool sat_calculate_penetration(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, GodotCollisionSolver3D::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, Vector3 *r_prev_axis = nullptr, real_t p_margin_a = 0, real_t p_margin_b = 0); -#endif // COLLISION_SOLVER_SAT_H +#endif // GODOT_COLLISION_SOLVER_SAT_H diff --git a/servers/physics_3d/constraint_3d_sw.h b/servers/physics_3d/godot_constraint_3d.h index 7b44726ef5..840c81716c 100644 --- a/servers/physics_3d/constraint_3d_sw.h +++ b/servers/physics_3d/godot_constraint_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* constraint_3d_sw.h */ +/* godot_constraint_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CONSTRAINT_SW_H -#define CONSTRAINT_SW_H +#ifndef GODOT_CONSTRAINT_3D_H +#define GODOT_CONSTRAINT_3D_H -class Body3DSW; -class SoftBody3DSW; +class GodotBody3D; +class GodotSoftBody3D; -class Constraint3DSW { - Body3DSW **_body_ptr; +class GodotConstraint3D { + GodotBody3D **_body_ptr; int _body_count; uint64_t island_step; int priority; @@ -44,7 +44,7 @@ class Constraint3DSW { RID self; protected: - Constraint3DSW(Body3DSW **p_body_ptr = nullptr, int p_body_count = 0) { + GodotConstraint3D(GodotBody3D **p_body_ptr = nullptr, int p_body_count = 0) { _body_ptr = p_body_ptr; _body_count = p_body_count; island_step = 0; @@ -59,10 +59,10 @@ public: _FORCE_INLINE_ uint64_t get_island_step() const { return island_step; } _FORCE_INLINE_ void set_island_step(uint64_t p_step) { island_step = p_step; } - _FORCE_INLINE_ Body3DSW **get_body_ptr() const { return _body_ptr; } + _FORCE_INLINE_ GodotBody3D **get_body_ptr() const { return _body_ptr; } _FORCE_INLINE_ int get_body_count() const { return _body_count; } - virtual SoftBody3DSW *get_soft_body_ptr(int p_index) const { return nullptr; } + virtual GodotSoftBody3D *get_soft_body_ptr(int p_index) const { return nullptr; } virtual int get_soft_body_count() const { return 0; } _FORCE_INLINE_ void set_priority(int p_priority) { priority = p_priority; } @@ -75,7 +75,7 @@ public: virtual bool pre_solve(real_t p_step) = 0; virtual void solve(real_t p_step) = 0; - virtual ~Constraint3DSW() {} + virtual ~GodotConstraint3D() {} }; -#endif // CONSTRAINT__SW_H +#endif // GODOT_CONSTRAINT_3D_H diff --git a/servers/physics_3d/joints_3d_sw.h b/servers/physics_3d/godot_joint_3d.h index e2514674ea..4086bb53e1 100644 --- a/servers/physics_3d/joints_3d_sw.h +++ b/servers/physics_3d/godot_joint_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* joints_3d_sw.h */ +/* godot_joint_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef JOINTS_SW_H -#define JOINTS_SW_H +#ifndef GODOT_JOINT_3D_H +#define GODOT_JOINT_3D_H -#include "body_3d_sw.h" -#include "constraint_3d_sw.h" +#include "godot_body_3d.h" +#include "godot_constraint_3d.h" -class Joint3DSW : public Constraint3DSW { +class GodotJoint3D : public GodotConstraint3D { protected: bool dynamic_A = false; bool dynamic_B = false; @@ -44,20 +44,20 @@ public: virtual bool pre_solve(real_t p_step) override { return true; } virtual void solve(real_t p_step) override {} - void copy_settings_from(Joint3DSW *p_joint) { + void copy_settings_from(GodotJoint3D *p_joint) { set_self(p_joint->get_self()); set_priority(p_joint->get_priority()); disable_collisions_between_bodies(p_joint->is_disabled_collisions_between_bodies()); } virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_MAX; } - _FORCE_INLINE_ Joint3DSW(Body3DSW **p_body_ptr = nullptr, int p_body_count = 0) : - Constraint3DSW(p_body_ptr, p_body_count) { + _FORCE_INLINE_ GodotJoint3D(GodotBody3D **p_body_ptr = nullptr, int p_body_count = 0) : + GodotConstraint3D(p_body_ptr, p_body_count) { } - virtual ~Joint3DSW() { + virtual ~GodotJoint3D() { for (int i = 0; i < get_body_count(); i++) { - Body3DSW *body = get_body_ptr()[i]; + GodotBody3D *body = get_body_ptr()[i]; if (body) { body->remove_constraint(this); } @@ -65,4 +65,4 @@ public: } }; -#endif // JOINTS_SW_H +#endif // GODOT_JOINT_3D_H diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp new file mode 100644 index 0000000000..34b56e733e --- /dev/null +++ b/servers/physics_3d/godot_physics_server_3d.cpp @@ -0,0 +1,1749 @@ +/*************************************************************************/ +/* godot_physics_server_3d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "godot_physics_server_3d.h" + +#include "godot_body_direct_state_3d.h" +#include "godot_broad_phase_3d_bvh.h" +#include "joints/godot_cone_twist_joint_3d.h" +#include "joints/godot_generic_6dof_joint_3d.h" +#include "joints/godot_hinge_joint_3d.h" +#include "joints/godot_pin_joint_3d.h" +#include "joints/godot_slider_joint_3d.h" + +#include "core/debugger/engine_debugger.h" +#include "core/os/os.h" + +#define FLUSH_QUERY_CHECK(m_object) \ + ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead."); + +RID GodotPhysicsServer3D::world_boundary_shape_create() { + GodotShape3D *shape = memnew(GodotWorldBoundaryShape3D); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID GodotPhysicsServer3D::separation_ray_shape_create() { + GodotShape3D *shape = memnew(GodotSeparationRayShape3D); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID GodotPhysicsServer3D::sphere_shape_create() { + GodotShape3D *shape = memnew(GodotSphereShape3D); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID GodotPhysicsServer3D::box_shape_create() { + GodotShape3D *shape = memnew(GodotBoxShape3D); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID GodotPhysicsServer3D::capsule_shape_create() { + GodotShape3D *shape = memnew(GodotCapsuleShape3D); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID GodotPhysicsServer3D::cylinder_shape_create() { + GodotShape3D *shape = memnew(GodotCylinderShape3D); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID GodotPhysicsServer3D::convex_polygon_shape_create() { + GodotShape3D *shape = memnew(GodotConvexPolygonShape3D); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID GodotPhysicsServer3D::concave_polygon_shape_create() { + GodotShape3D *shape = memnew(GodotConcavePolygonShape3D); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID GodotPhysicsServer3D::heightmap_shape_create() { + GodotShape3D *shape = memnew(GodotHeightMapShape3D); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID GodotPhysicsServer3D::custom_shape_create() { + ERR_FAIL_V(RID()); +} + +void GodotPhysicsServer3D::shape_set_data(RID p_shape, const Variant &p_data) { + GodotShape3D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND(!shape); + shape->set_data(p_data); +}; + +void GodotPhysicsServer3D::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) { + GodotShape3D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND(!shape); + shape->set_custom_bias(p_bias); +} + +PhysicsServer3D::ShapeType GodotPhysicsServer3D::shape_get_type(RID p_shape) const { + const GodotShape3D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND_V(!shape, SHAPE_CUSTOM); + return shape->get_type(); +}; + +Variant GodotPhysicsServer3D::shape_get_data(RID p_shape) const { + const GodotShape3D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND_V(!shape, Variant()); + ERR_FAIL_COND_V(!shape->is_configured(), Variant()); + return shape->get_data(); +}; + +void GodotPhysicsServer3D::shape_set_margin(RID p_shape, real_t p_margin) { +} + +real_t GodotPhysicsServer3D::shape_get_margin(RID p_shape) const { + return 0.0; +} + +real_t GodotPhysicsServer3D::shape_get_custom_solver_bias(RID p_shape) const { + const GodotShape3D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND_V(!shape, 0); + return shape->get_custom_bias(); +} + +RID GodotPhysicsServer3D::space_create() { + GodotSpace3D *space = memnew(GodotSpace3D); + RID id = space_owner.make_rid(space); + space->set_self(id); + RID area_id = area_create(); + GodotArea3D *area = area_owner.get_or_null(area_id); + ERR_FAIL_COND_V(!area, RID()); + space->set_default_area(area); + area->set_space(space); + area->set_priority(-1); + RID sgb = body_create(); + body_set_space(sgb, id); + body_set_mode(sgb, BODY_MODE_STATIC); + space->set_static_global_body(sgb); + + return id; +}; + +void GodotPhysicsServer3D::space_set_active(RID p_space, bool p_active) { + GodotSpace3D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND(!space); + if (p_active) { + active_spaces.insert(space); + } else { + active_spaces.erase(space); + } +} + +bool GodotPhysicsServer3D::space_is_active(RID p_space) const { + const GodotSpace3D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND_V(!space, false); + + return active_spaces.has(space); +} + +void GodotPhysicsServer3D::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) { + GodotSpace3D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND(!space); + + space->set_param(p_param, p_value); +} + +real_t GodotPhysicsServer3D::space_get_param(RID p_space, SpaceParameter p_param) const { + const GodotSpace3D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND_V(!space, 0); + return space->get_param(p_param); +} + +PhysicsDirectSpaceState3D *GodotPhysicsServer3D::space_get_direct_state(RID p_space) { + GodotSpace3D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND_V(!space, nullptr); + ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); + + return space->get_direct_state(); +} + +void GodotPhysicsServer3D::space_set_debug_contacts(RID p_space, int p_max_contacts) { + GodotSpace3D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND(!space); + space->set_debug_contacts(p_max_contacts); +} + +Vector<Vector3> GodotPhysicsServer3D::space_get_contacts(RID p_space) const { + GodotSpace3D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND_V(!space, Vector<Vector3>()); + return space->get_debug_contacts(); +} + +int GodotPhysicsServer3D::space_get_contact_count(RID p_space) const { + GodotSpace3D *space = space_owner.get_or_null(p_space); + ERR_FAIL_COND_V(!space, 0); + return space->get_debug_contact_count(); +} + +RID GodotPhysicsServer3D::area_create() { + GodotArea3D *area = memnew(GodotArea3D); + RID rid = area_owner.make_rid(area); + area->set_self(rid); + return rid; +}; + +void GodotPhysicsServer3D::area_set_space(RID p_area, RID p_space) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + GodotSpace3D *space = nullptr; + if (p_space.is_valid()) { + space = space_owner.get_or_null(p_space); + ERR_FAIL_COND(!space); + } + + if (area->get_space() == space) { + return; //pointless + } + + area->clear_constraints(); + area->set_space(space); +}; + +RID GodotPhysicsServer3D::area_get_space(RID p_area) const { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, RID()); + + GodotSpace3D *space = area->get_space(); + if (!space) { + return RID(); + } + return space->get_self(); +}; + +void GodotPhysicsServer3D::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_space_override_mode(p_mode); +} + +PhysicsServer3D::AreaSpaceOverrideMode GodotPhysicsServer3D::area_get_space_override_mode(RID p_area) const { + const GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, AREA_SPACE_OVERRIDE_DISABLED); + + return area->get_space_override_mode(); +} + +void GodotPhysicsServer3D::area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform, bool p_disabled) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + GodotShape3D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND(!shape); + + area->add_shape(shape, p_transform, p_disabled); +} + +void GodotPhysicsServer3D::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + GodotShape3D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND(!shape); + ERR_FAIL_COND(!shape->is_configured()); + + area->set_shape(p_shape_idx, shape); +} + +void GodotPhysicsServer3D::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_shape_transform(p_shape_idx, p_transform); +} + +int GodotPhysicsServer3D::area_get_shape_count(RID p_area) const { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, -1); + + return area->get_shape_count(); +} + +RID GodotPhysicsServer3D::area_get_shape(RID p_area, int p_shape_idx) const { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, RID()); + + GodotShape3D *shape = area->get_shape(p_shape_idx); + ERR_FAIL_COND_V(!shape, RID()); + + return shape->get_self(); +} + +Transform3D GodotPhysicsServer3D::area_get_shape_transform(RID p_area, int p_shape_idx) const { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, Transform3D()); + + return area->get_shape_transform(p_shape_idx); +} + +void GodotPhysicsServer3D::area_remove_shape(RID p_area, int p_shape_idx) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->remove_shape(p_shape_idx); +} + +void GodotPhysicsServer3D::area_clear_shapes(RID p_area) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + while (area->get_shape_count()) { + area->remove_shape(0); + } +} + +void GodotPhysicsServer3D::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + ERR_FAIL_INDEX(p_shape_idx, area->get_shape_count()); + FLUSH_QUERY_CHECK(area); + area->set_shape_disabled(p_shape_idx, p_disabled); +} + +void GodotPhysicsServer3D::area_attach_object_instance_id(RID p_area, ObjectID p_id) { + if (space_owner.owns(p_area)) { + GodotSpace3D *space = space_owner.get_or_null(p_area); + p_area = space->get_default_area()->get_self(); + } + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + area->set_instance_id(p_id); +} + +ObjectID GodotPhysicsServer3D::area_get_object_instance_id(RID p_area) const { + if (space_owner.owns(p_area)) { + GodotSpace3D *space = space_owner.get_or_null(p_area); + p_area = space->get_default_area()->get_self(); + } + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, ObjectID()); + return area->get_instance_id(); +} + +void GodotPhysicsServer3D::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) { + if (space_owner.owns(p_area)) { + GodotSpace3D *space = space_owner.get_or_null(p_area); + p_area = space->get_default_area()->get_self(); + } + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + area->set_param(p_param, p_value); +}; + +void GodotPhysicsServer3D::area_set_transform(RID p_area, const Transform3D &p_transform) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + area->set_transform(p_transform); +}; + +Variant GodotPhysicsServer3D::area_get_param(RID p_area, AreaParameter p_param) const { + if (space_owner.owns(p_area)) { + GodotSpace3D *space = space_owner.get_or_null(p_area); + p_area = space->get_default_area()->get_self(); + } + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, Variant()); + + return area->get_param(p_param); +}; + +Transform3D GodotPhysicsServer3D::area_get_transform(RID p_area) const { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, Transform3D()); + + return area->get_transform(); +}; + +void GodotPhysicsServer3D::area_set_collision_layer(RID p_area, uint32_t p_layer) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_collision_layer(p_layer); +} + +void GodotPhysicsServer3D::area_set_collision_mask(RID p_area, uint32_t p_mask) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_collision_mask(p_mask); +} + +void GodotPhysicsServer3D::area_set_monitorable(RID p_area, bool p_monitorable) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + FLUSH_QUERY_CHECK(area); + + area->set_monitorable(p_monitorable); +} + +void GodotPhysicsServer3D::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); +} + +void GodotPhysicsServer3D::area_set_ray_pickable(RID p_area, bool p_enable) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_ray_pickable(p_enable); +} + +void GodotPhysicsServer3D::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); +} + +/* BODY API */ + +RID GodotPhysicsServer3D::body_create() { + GodotBody3D *body = memnew(GodotBody3D); + RID rid = body_owner.make_rid(body); + body->set_self(rid); + return rid; +}; + +void GodotPhysicsServer3D::body_set_space(RID p_body, RID p_space) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + GodotSpace3D *space = nullptr; + if (p_space.is_valid()) { + space = space_owner.get_or_null(p_space); + ERR_FAIL_COND(!space); + } + + if (body->get_space() == space) { + return; //pointless + } + + body->clear_constraint_map(); + body->set_space(space); +}; + +RID GodotPhysicsServer3D::body_get_space(RID p_body) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, RID()); + + GodotSpace3D *space = body->get_space(); + if (!space) { + return RID(); + } + return space->get_self(); +}; + +void GodotPhysicsServer3D::body_set_mode(RID p_body, BodyMode p_mode) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_mode(p_mode); +}; + +PhysicsServer3D::BodyMode GodotPhysicsServer3D::body_get_mode(RID p_body) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, BODY_MODE_STATIC); + + return body->get_mode(); +}; + +void GodotPhysicsServer3D::body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform, bool p_disabled) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + GodotShape3D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND(!shape); + + body->add_shape(shape, p_transform, p_disabled); +} + +void GodotPhysicsServer3D::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + GodotShape3D *shape = shape_owner.get_or_null(p_shape); + ERR_FAIL_COND(!shape); + ERR_FAIL_COND(!shape->is_configured()); + + body->set_shape(p_shape_idx, shape); +} +void GodotPhysicsServer3D::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_shape_transform(p_shape_idx, p_transform); +} + +int GodotPhysicsServer3D::body_get_shape_count(RID p_body) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, -1); + + return body->get_shape_count(); +} + +RID GodotPhysicsServer3D::body_get_shape(RID p_body, int p_shape_idx) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, RID()); + + GodotShape3D *shape = body->get_shape(p_shape_idx); + ERR_FAIL_COND_V(!shape, RID()); + + return shape->get_self(); +} + +void GodotPhysicsServer3D::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); + FLUSH_QUERY_CHECK(body); + + body->set_shape_disabled(p_shape_idx, p_disabled); +} + +Transform3D GodotPhysicsServer3D::body_get_shape_transform(RID p_body, int p_shape_idx) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, Transform3D()); + + return body->get_shape_transform(p_shape_idx); +} + +void GodotPhysicsServer3D::body_remove_shape(RID p_body, int p_shape_idx) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->remove_shape(p_shape_idx); +} + +void GodotPhysicsServer3D::body_clear_shapes(RID p_body) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + while (body->get_shape_count()) { + body->remove_shape(0); + } +} + +void GodotPhysicsServer3D::body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_continuous_collision_detection(p_enable); +} + +bool GodotPhysicsServer3D::body_is_continuous_collision_detection_enabled(RID p_body) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, false); + + return body->is_continuous_collision_detection_enabled(); +} + +void GodotPhysicsServer3D::body_set_collision_layer(RID p_body, uint32_t p_layer) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_collision_layer(p_layer); + body->wakeup(); +} + +uint32_t GodotPhysicsServer3D::body_get_collision_layer(RID p_body) const { + const GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, 0); + + return body->get_collision_layer(); +} + +void GodotPhysicsServer3D::body_set_collision_mask(RID p_body, uint32_t p_mask) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_collision_mask(p_mask); + body->wakeup(); +} + +uint32_t GodotPhysicsServer3D::body_get_collision_mask(RID p_body) const { + const GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, 0); + + return body->get_collision_mask(); +} + +void GodotPhysicsServer3D::body_attach_object_instance_id(RID p_body, ObjectID p_id) { + GodotBody3D *body = body_owner.get_or_null(p_body); + if (body) { + body->set_instance_id(p_id); + return; + } + + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + if (soft_body) { + soft_body->set_instance_id(p_id); + return; + } + + ERR_FAIL_MSG("Invalid ID."); +}; + +ObjectID GodotPhysicsServer3D::body_get_object_instance_id(RID p_body) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, ObjectID()); + + return body->get_instance_id(); +}; + +void GodotPhysicsServer3D::body_set_user_flags(RID p_body, uint32_t p_flags) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); +}; + +uint32_t GodotPhysicsServer3D::body_get_user_flags(RID p_body) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, 0); + + return 0; +}; + +void GodotPhysicsServer3D::body_set_param(RID p_body, BodyParameter p_param, const Variant &p_value) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_param(p_param, p_value); +}; + +Variant GodotPhysicsServer3D::body_get_param(RID p_body, BodyParameter p_param) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, 0); + + return body->get_param(p_param); +}; + +void GodotPhysicsServer3D::body_reset_mass_properties(RID p_body) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + return body->reset_mass_properties(); +} + +void GodotPhysicsServer3D::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_state(p_state, p_variant); +}; + +Variant GodotPhysicsServer3D::body_get_state(RID p_body, BodyState p_state) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, Variant()); + + return body->get_state(p_state); +}; + +void GodotPhysicsServer3D::body_set_applied_force(RID p_body, const Vector3 &p_force) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_applied_force(p_force); + body->wakeup(); +}; + +Vector3 GodotPhysicsServer3D::body_get_applied_force(RID p_body) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, Vector3()); + return body->get_applied_force(); +}; + +void GodotPhysicsServer3D::body_set_applied_torque(RID p_body, const Vector3 &p_torque) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_applied_torque(p_torque); + body->wakeup(); +}; + +Vector3 GodotPhysicsServer3D::body_get_applied_torque(RID p_body) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, Vector3()); + + return body->get_applied_torque(); +}; + +void GodotPhysicsServer3D::body_add_central_force(RID p_body, const Vector3 &p_force) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->add_central_force(p_force); + body->wakeup(); +} + +void GodotPhysicsServer3D::body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->add_force(p_force, p_position); + body->wakeup(); +}; + +void GodotPhysicsServer3D::body_add_torque(RID p_body, const Vector3 &p_torque) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->add_torque(p_torque); + body->wakeup(); +}; + +void GodotPhysicsServer3D::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + _update_shapes(); + + body->apply_central_impulse(p_impulse); + body->wakeup(); +} + +void GodotPhysicsServer3D::body_apply_impulse(RID p_body, const Vector3 &p_impulse, const Vector3 &p_position) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + _update_shapes(); + + body->apply_impulse(p_impulse, p_position); + body->wakeup(); +}; + +void GodotPhysicsServer3D::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + _update_shapes(); + + body->apply_torque_impulse(p_impulse); + body->wakeup(); +}; + +void GodotPhysicsServer3D::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + _update_shapes(); + + Vector3 v = body->get_linear_velocity(); + Vector3 axis = p_axis_velocity.normalized(); + v -= axis * axis.dot(v); + v += p_axis_velocity; + body->set_linear_velocity(v); + body->wakeup(); +}; + +void GodotPhysicsServer3D::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_axis_lock(p_axis, p_lock); + body->wakeup(); +} + +bool GodotPhysicsServer3D::body_is_axis_locked(RID p_body, BodyAxis p_axis) const { + const GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, 0); + return body->is_axis_locked(p_axis); +} + +void GodotPhysicsServer3D::body_add_collision_exception(RID p_body, RID p_body_b) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->add_exception(p_body_b); + body->wakeup(); +}; + +void GodotPhysicsServer3D::body_remove_collision_exception(RID p_body, RID p_body_b) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->remove_exception(p_body_b); + body->wakeup(); +}; + +void GodotPhysicsServer3D::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + for (int i = 0; i < body->get_exceptions().size(); i++) { + p_exceptions->push_back(body->get_exceptions()[i]); + } +}; + +void GodotPhysicsServer3D::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); +}; + +real_t GodotPhysicsServer3D::body_get_contacts_reported_depth_threshold(RID p_body) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, 0); + return 0; +}; + +void GodotPhysicsServer3D::body_set_omit_force_integration(RID p_body, bool p_omit) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + + body->set_omit_force_integration(p_omit); +}; + +bool GodotPhysicsServer3D::body_is_omitting_force_integration(RID p_body) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, false); + return body->get_omit_force_integration(); +}; + +void GodotPhysicsServer3D::body_set_max_contacts_reported(RID p_body, int p_contacts) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + body->set_max_contacts_reported(p_contacts); +} + +int GodotPhysicsServer3D::body_get_max_contacts_reported(RID p_body) const { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, -1); + return body->get_max_contacts_reported(); +} + +void GodotPhysicsServer3D::body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + body->set_state_sync_callback(p_instance, p_callback); +} + +void GodotPhysicsServer3D::body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + body->set_force_integration_callback(p_callable, p_udata); +} + +void GodotPhysicsServer3D::body_set_ray_pickable(RID p_body, bool p_enable) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND(!body); + body->set_ray_pickable(p_enable); +} + +bool GodotPhysicsServer3D::body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result) { + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!body, false); + ERR_FAIL_COND_V(!body->get_space(), false); + ERR_FAIL_COND_V(body->get_space()->is_locked(), false); + + _update_shapes(); + + return body->get_space()->test_body_motion(body, p_parameters, r_result); +} + +PhysicsDirectBodyState3D *GodotPhysicsServer3D::body_get_direct_state(RID p_body) { + ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); + + GodotBody3D *body = body_owner.get_or_null(p_body); + ERR_FAIL_NULL_V(body, nullptr); + + ERR_FAIL_NULL_V(body->get_space(), nullptr); + ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); + + return body->get_direct_state(); +} + +/* SOFT BODY */ + +RID GodotPhysicsServer3D::soft_body_create() { + GodotSoftBody3D *soft_body = memnew(GodotSoftBody3D); + RID rid = soft_body_owner.make_rid(soft_body); + soft_body->set_self(rid); + return rid; +} + +void GodotPhysicsServer3D::soft_body_update_rendering_server(RID p_body, RenderingServerHandler *p_rendering_server_handler) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->update_rendering_server(p_rendering_server_handler); +} + +void GodotPhysicsServer3D::soft_body_set_space(RID p_body, RID p_space) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + GodotSpace3D *space = nullptr; + if (p_space.is_valid()) { + space = space_owner.get_or_null(p_space); + ERR_FAIL_COND(!space); + } + + if (soft_body->get_space() == space) { + return; + } + + soft_body->set_space(space); +} + +RID GodotPhysicsServer3D::soft_body_get_space(RID p_body) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!soft_body, RID()); + + GodotSpace3D *space = soft_body->get_space(); + if (!space) { + return RID(); + } + return space->get_self(); +} + +void GodotPhysicsServer3D::soft_body_set_collision_layer(RID p_body, uint32_t p_layer) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->set_collision_layer(p_layer); +} + +uint32_t GodotPhysicsServer3D::soft_body_get_collision_layer(RID p_body) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!soft_body, 0); + + return soft_body->get_collision_layer(); +} + +void GodotPhysicsServer3D::soft_body_set_collision_mask(RID p_body, uint32_t p_mask) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->set_collision_mask(p_mask); +} + +uint32_t GodotPhysicsServer3D::soft_body_get_collision_mask(RID p_body) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!soft_body, 0); + + return soft_body->get_collision_mask(); +} + +void GodotPhysicsServer3D::soft_body_add_collision_exception(RID p_body, RID p_body_b) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->add_exception(p_body_b); +} + +void GodotPhysicsServer3D::soft_body_remove_collision_exception(RID p_body, RID p_body_b) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->remove_exception(p_body_b); +} + +void GodotPhysicsServer3D::soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + for (int i = 0; i < soft_body->get_exceptions().size(); i++) { + p_exceptions->push_back(soft_body->get_exceptions()[i]); + } +} + +void GodotPhysicsServer3D::soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->set_state(p_state, p_variant); +} + +Variant GodotPhysicsServer3D::soft_body_get_state(RID p_body, BodyState p_state) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!soft_body, Variant()); + + return soft_body->get_state(p_state); +} + +void GodotPhysicsServer3D::soft_body_set_transform(RID p_body, const Transform3D &p_transform) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->set_state(BODY_STATE_TRANSFORM, p_transform); +} + +void GodotPhysicsServer3D::soft_body_set_ray_pickable(RID p_body, bool p_enable) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->set_ray_pickable(p_enable); +} + +void GodotPhysicsServer3D::soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->set_iteration_count(p_simulation_precision); +} + +int GodotPhysicsServer3D::soft_body_get_simulation_precision(RID p_body) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!soft_body, 0.f); + + return soft_body->get_iteration_count(); +} + +void GodotPhysicsServer3D::soft_body_set_total_mass(RID p_body, real_t p_total_mass) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->set_total_mass(p_total_mass); +} + +real_t GodotPhysicsServer3D::soft_body_get_total_mass(RID p_body) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!soft_body, 0.f); + + return soft_body->get_total_mass(); +} + +void GodotPhysicsServer3D::soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->set_linear_stiffness(p_stiffness); +} + +real_t GodotPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!soft_body, 0.f); + + return soft_body->get_linear_stiffness(); +} + +void GodotPhysicsServer3D::soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->set_pressure_coefficient(p_pressure_coefficient); +} + +real_t GodotPhysicsServer3D::soft_body_get_pressure_coefficient(RID p_body) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!soft_body, 0.f); + + return soft_body->get_pressure_coefficient(); +} + +void GodotPhysicsServer3D::soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->set_damping_coefficient(p_damping_coefficient); +} + +real_t GodotPhysicsServer3D::soft_body_get_damping_coefficient(RID p_body) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!soft_body, 0.f); + + return soft_body->get_damping_coefficient(); +} + +void GodotPhysicsServer3D::soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->set_drag_coefficient(p_drag_coefficient); +} + +real_t GodotPhysicsServer3D::soft_body_get_drag_coefficient(RID p_body) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!soft_body, 0.f); + + return soft_body->get_drag_coefficient(); +} + +void GodotPhysicsServer3D::soft_body_set_mesh(RID p_body, RID p_mesh) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->set_mesh(p_mesh); +} + +AABB GodotPhysicsServer3D::soft_body_get_bounds(RID p_body) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!soft_body, AABB()); + + return soft_body->get_bounds(); +} + +void GodotPhysicsServer3D::soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->set_vertex_position(p_point_index, p_global_position); +} + +Vector3 GodotPhysicsServer3D::soft_body_get_point_global_position(RID p_body, int p_point_index) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!soft_body, Vector3()); + + return soft_body->get_vertex_position(p_point_index); +} + +void GodotPhysicsServer3D::soft_body_remove_all_pinned_points(RID p_body) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + soft_body->unpin_all_vertices(); +} + +void GodotPhysicsServer3D::soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND(!soft_body); + + if (p_pin) { + soft_body->pin_vertex(p_point_index); + } else { + soft_body->unpin_vertex(p_point_index); + } +} + +bool GodotPhysicsServer3D::soft_body_is_point_pinned(RID p_body, int p_point_index) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_COND_V(!soft_body, false); + + return soft_body->is_vertex_pinned(p_point_index); +} + +/* JOINT API */ + +RID GodotPhysicsServer3D::joint_create() { + GodotJoint3D *joint = memnew(GodotJoint3D); + RID rid = joint_owner.make_rid(joint); + joint->set_self(rid); + return rid; +} + +void GodotPhysicsServer3D::joint_clear(RID p_joint) { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + if (joint->get_type() != JOINT_TYPE_MAX) { + GodotJoint3D *empty_joint = memnew(GodotJoint3D); + empty_joint->copy_settings_from(joint); + + joint_owner.replace(p_joint, empty_joint); + memdelete(joint); + } +} + +void GodotPhysicsServer3D::joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) { + GodotBody3D *body_A = body_owner.get_or_null(p_body_A); + ERR_FAIL_COND(!body_A); + + if (!p_body_B.is_valid()) { + ERR_FAIL_COND(!body_A->get_space()); + p_body_B = body_A->get_space()->get_static_global_body(); + } + + GodotBody3D *body_B = body_owner.get_or_null(p_body_B); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); + + GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); + + GodotJoint3D *joint = memnew(GodotPinJoint3D(body_A, p_local_A, body_B, p_local_B)); + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); +} + +void GodotPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!joint); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); + GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint); + pin_joint->set_param(p_param, p_value); +} + +real_t GodotPhysicsServer3D::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, 0); + GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint); + return pin_joint->get_param(p_param); +} + +void GodotPhysicsServer3D::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!joint); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); + GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint); + pin_joint->set_pos_a(p_A); +} + +Vector3 GodotPhysicsServer3D::pin_joint_get_local_a(RID p_joint) const { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, Vector3()); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3()); + GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint); + return pin_joint->get_position_a(); +} + +void GodotPhysicsServer3D::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!joint); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); + GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint); + pin_joint->set_pos_b(p_B); +} + +Vector3 GodotPhysicsServer3D::pin_joint_get_local_b(RID p_joint) const { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, Vector3()); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3()); + GodotPinJoint3D *pin_joint = static_cast<GodotPinJoint3D *>(joint); + return pin_joint->get_position_b(); +} + +void GodotPhysicsServer3D::joint_make_hinge(RID p_joint, RID p_body_A, const Transform3D &p_frame_A, RID p_body_B, const Transform3D &p_frame_B) { + GodotBody3D *body_A = body_owner.get_or_null(p_body_A); + ERR_FAIL_COND(!body_A); + + if (!p_body_B.is_valid()) { + ERR_FAIL_COND(!body_A->get_space()); + p_body_B = body_A->get_space()->get_static_global_body(); + } + + GodotBody3D *body_B = body_owner.get_or_null(p_body_B); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); + + GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); + + GodotJoint3D *joint = memnew(GodotHingeJoint3D(body_A, body_B, p_frame_A, p_frame_B)); + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); +} + +void GodotPhysicsServer3D::joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) { + GodotBody3D *body_A = body_owner.get_or_null(p_body_A); + ERR_FAIL_COND(!body_A); + + if (!p_body_B.is_valid()) { + ERR_FAIL_COND(!body_A->get_space()); + p_body_B = body_A->get_space()->get_static_global_body(); + } + + GodotBody3D *body_B = body_owner.get_or_null(p_body_B); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); + + GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); + + GodotJoint3D *joint = memnew(GodotHingeJoint3D(body_A, body_B, p_pivot_A, p_pivot_B, p_axis_A, p_axis_B)); + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); +} + +void GodotPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!joint); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE); + GodotHingeJoint3D *hinge_joint = static_cast<GodotHingeJoint3D *>(joint); + hinge_joint->set_param(p_param, p_value); +} + +real_t GodotPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, 0); + GodotHingeJoint3D *hinge_joint = static_cast<GodotHingeJoint3D *>(joint); + return hinge_joint->get_param(p_param); +} + +void GodotPhysicsServer3D::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!joint); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE); + GodotHingeJoint3D *hinge_joint = static_cast<GodotHingeJoint3D *>(joint); + hinge_joint->set_flag(p_flag, p_value); +} + +bool GodotPhysicsServer3D::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, false); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, false); + GodotHingeJoint3D *hinge_joint = static_cast<GodotHingeJoint3D *>(joint); + return hinge_joint->get_flag(p_flag); +} + +void GodotPhysicsServer3D::joint_set_solver_priority(RID p_joint, int p_priority) { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!joint); + joint->set_priority(p_priority); +} + +int GodotPhysicsServer3D::joint_get_solver_priority(RID p_joint) const { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, 0); + return joint->get_priority(); +} + +void GodotPhysicsServer3D::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!joint); + + joint->disable_collisions_between_bodies(p_disable); + + if (2 == joint->get_body_count()) { + GodotBody3D *body_a = *joint->get_body_ptr(); + GodotBody3D *body_b = *(joint->get_body_ptr() + 1); + + if (p_disable) { + body_add_collision_exception(body_a->get_self(), body_b->get_self()); + body_add_collision_exception(body_b->get_self(), body_a->get_self()); + } else { + body_remove_collision_exception(body_a->get_self(), body_b->get_self()); + body_remove_collision_exception(body_b->get_self(), body_a->get_self()); + } + } +} + +bool GodotPhysicsServer3D::joint_is_disabled_collisions_between_bodies(RID p_joint) const { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, true); + + return joint->is_disabled_collisions_between_bodies(); +} + +GodotPhysicsServer3D::JointType GodotPhysicsServer3D::joint_get_type(RID p_joint) const { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, JOINT_TYPE_PIN); + return joint->get_type(); +} + +void GodotPhysicsServer3D::joint_make_slider(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { + GodotBody3D *body_A = body_owner.get_or_null(p_body_A); + ERR_FAIL_COND(!body_A); + + if (!p_body_B.is_valid()) { + ERR_FAIL_COND(!body_A->get_space()); + p_body_B = body_A->get_space()->get_static_global_body(); + } + + GodotBody3D *body_B = body_owner.get_or_null(p_body_B); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); + + GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); + + GodotJoint3D *joint = memnew(GodotSliderJoint3D(body_A, body_B, p_local_frame_A, p_local_frame_B)); + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); +} + +void GodotPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!joint); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_SLIDER); + GodotSliderJoint3D *slider_joint = static_cast<GodotSliderJoint3D *>(joint); + slider_joint->set_param(p_param, p_value); +} + +real_t GodotPhysicsServer3D::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0); + GodotSliderJoint3D *slider_joint = static_cast<GodotSliderJoint3D *>(joint); + return slider_joint->get_param(p_param); +} + +void GodotPhysicsServer3D::joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { + GodotBody3D *body_A = body_owner.get_or_null(p_body_A); + ERR_FAIL_COND(!body_A); + + if (!p_body_B.is_valid()) { + ERR_FAIL_COND(!body_A->get_space()); + p_body_B = body_A->get_space()->get_static_global_body(); + } + + GodotBody3D *body_B = body_owner.get_or_null(p_body_B); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); + + GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); + + GodotJoint3D *joint = memnew(GodotConeTwistJoint3D(body_A, body_B, p_local_frame_A, p_local_frame_B)); + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); +} + +void GodotPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!joint); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_CONE_TWIST); + GodotConeTwistJoint3D *cone_twist_joint = static_cast<GodotConeTwistJoint3D *>(joint); + cone_twist_joint->set_param(p_param, p_value); +} + +real_t GodotPhysicsServer3D::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0); + GodotConeTwistJoint3D *cone_twist_joint = static_cast<GodotConeTwistJoint3D *>(joint); + return cone_twist_joint->get_param(p_param); +} + +void GodotPhysicsServer3D::joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { + GodotBody3D *body_A = body_owner.get_or_null(p_body_A); + ERR_FAIL_COND(!body_A); + + if (!p_body_B.is_valid()) { + ERR_FAIL_COND(!body_A->get_space()); + p_body_B = body_A->get_space()->get_static_global_body(); + } + + GodotBody3D *body_B = body_owner.get_or_null(p_body_B); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); + + GodotJoint3D *prev_joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); + + GodotJoint3D *joint = memnew(GodotGeneric6DOFJoint3D(body_A, body_B, p_local_frame_A, p_local_frame_B, true)); + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); +} + +void GodotPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!joint); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF); + GodotGeneric6DOFJoint3D *generic_6dof_joint = static_cast<GodotGeneric6DOFJoint3D *>(joint); + generic_6dof_joint->set_param(p_axis, p_param, p_value); +} + +real_t GodotPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) const { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, 0); + GodotGeneric6DOFJoint3D *generic_6dof_joint = static_cast<GodotGeneric6DOFJoint3D *>(joint); + return generic_6dof_joint->get_param(p_axis, p_param); +} + +void GodotPhysicsServer3D::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND(!joint); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF); + GodotGeneric6DOFJoint3D *generic_6dof_joint = static_cast<GodotGeneric6DOFJoint3D *>(joint); + generic_6dof_joint->set_flag(p_axis, p_flag, p_enable); +} + +bool GodotPhysicsServer3D::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) const { + GodotJoint3D *joint = joint_owner.get_or_null(p_joint); + ERR_FAIL_COND_V(!joint, false); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, false); + GodotGeneric6DOFJoint3D *generic_6dof_joint = static_cast<GodotGeneric6DOFJoint3D *>(joint); + return generic_6dof_joint->get_flag(p_axis, p_flag); +} + +void GodotPhysicsServer3D::free(RID p_rid) { + _update_shapes(); //just in case + + if (shape_owner.owns(p_rid)) { + GodotShape3D *shape = shape_owner.get_or_null(p_rid); + + while (shape->get_owners().size()) { + GodotShapeOwner3D *so = shape->get_owners().front()->key(); + so->remove_shape(shape); + } + + shape_owner.free(p_rid); + memdelete(shape); + } else if (body_owner.owns(p_rid)) { + GodotBody3D *body = body_owner.get_or_null(p_rid); + + /* + if (body->get_state_query()) + _clear_query(body->get_state_query()); + + if (body->get_direct_state_query()) + _clear_query(body->get_direct_state_query()); + */ + + body->set_space(nullptr); + + while (body->get_shape_count()) { + body->remove_shape(0); + } + + body_owner.free(p_rid); + memdelete(body); + } else if (soft_body_owner.owns(p_rid)) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_rid); + + soft_body->set_space(nullptr); + + soft_body_owner.free(p_rid); + memdelete(soft_body); + } else if (area_owner.owns(p_rid)) { + GodotArea3D *area = area_owner.get_or_null(p_rid); + + /* + if (area->get_monitor_query()) + _clear_query(area->get_monitor_query()); + */ + + area->set_space(nullptr); + + while (area->get_shape_count()) { + area->remove_shape(0); + } + + area_owner.free(p_rid); + memdelete(area); + } else if (space_owner.owns(p_rid)) { + GodotSpace3D *space = space_owner.get_or_null(p_rid); + + while (space->get_objects().size()) { + GodotCollisionObject3D *co = (GodotCollisionObject3D *)space->get_objects().front()->get(); + co->set_space(nullptr); + } + + active_spaces.erase(space); + free(space->get_default_area()->get_self()); + free(space->get_static_global_body()); + + space_owner.free(p_rid); + memdelete(space); + } else if (joint_owner.owns(p_rid)) { + GodotJoint3D *joint = joint_owner.get_or_null(p_rid); + + joint_owner.free(p_rid); + memdelete(joint); + + } else { + ERR_FAIL_MSG("Invalid ID."); + } +}; + +void GodotPhysicsServer3D::set_active(bool p_active) { + active = p_active; +}; + +void GodotPhysicsServer3D::set_collision_iterations(int p_iterations) { + iterations = p_iterations; +}; + +void GodotPhysicsServer3D::init() { + iterations = 8; // 8? + stepper = memnew(GodotStep3D); +}; + +void GodotPhysicsServer3D::step(real_t p_step) { +#ifndef _3D_DISABLED + + if (!active) { + return; + } + + _update_shapes(); + + island_count = 0; + active_objects = 0; + collision_pairs = 0; + for (Set<const GodotSpace3D *>::Element *E = active_spaces.front(); E; E = E->next()) { + stepper->step((GodotSpace3D *)E->get(), p_step, iterations); + island_count += E->get()->get_island_count(); + active_objects += E->get()->get_active_objects(); + collision_pairs += E->get()->get_collision_pairs(); + } +#endif +} + +void GodotPhysicsServer3D::sync() { + doing_sync = true; +}; + +void GodotPhysicsServer3D::flush_queries() { +#ifndef _3D_DISABLED + + if (!active) { + return; + } + + flushing_queries = true; + + uint64_t time_beg = OS::get_singleton()->get_ticks_usec(); + + for (Set<const GodotSpace3D *>::Element *E = active_spaces.front(); E; E = E->next()) { + GodotSpace3D *space = (GodotSpace3D *)E->get(); + space->call_queries(); + } + + flushing_queries = false; + + if (EngineDebugger::is_profiling("servers")) { + uint64_t total_time[GodotSpace3D::ELAPSED_TIME_MAX]; + static const char *time_name[GodotSpace3D::ELAPSED_TIME_MAX] = { + "integrate_forces", + "generate_islands", + "setup_constraints", + "solve_constraints", + "integrate_velocities" + }; + + for (int i = 0; i < GodotSpace3D::ELAPSED_TIME_MAX; i++) { + total_time[i] = 0; + } + + for (Set<const GodotSpace3D *>::Element *E = active_spaces.front(); E; E = E->next()) { + for (int i = 0; i < GodotSpace3D::ELAPSED_TIME_MAX; i++) { + total_time[i] += E->get()->get_elapsed_time(GodotSpace3D::ElapsedTime(i)); + } + } + + Array values; + values.resize(GodotSpace3D::ELAPSED_TIME_MAX * 2); + for (int i = 0; i < GodotSpace3D::ELAPSED_TIME_MAX; i++) { + values[i * 2 + 0] = time_name[i]; + values[i * 2 + 1] = USEC_TO_SEC(total_time[i]); + } + values.push_back("flush_queries"); + values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg)); + + values.push_front("physics"); + EngineDebugger::profiler_add_frame_data("servers", values); + } +#endif +}; + +void GodotPhysicsServer3D::end_sync() { + doing_sync = false; +}; + +void GodotPhysicsServer3D::finish() { + memdelete(stepper); +}; + +int GodotPhysicsServer3D::get_process_info(ProcessInfo p_info) { + switch (p_info) { + case INFO_ACTIVE_OBJECTS: { + return active_objects; + } break; + case INFO_COLLISION_PAIRS: { + return collision_pairs; + } break; + case INFO_ISLAND_COUNT: { + return island_count; + } break; + } + + return 0; +} + +void GodotPhysicsServer3D::_update_shapes() { + while (pending_shape_update_list.first()) { + pending_shape_update_list.first()->self()->_shape_changed(); + pending_shape_update_list.remove(pending_shape_update_list.first()); + } +} + +void GodotPhysicsServer3D::_shape_col_cbk(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B, void *p_userdata) { + CollCbkData *cbk = (CollCbkData *)p_userdata; + + if (cbk->max == 0) { + return; + } + + if (cbk->amount == cbk->max) { + //find least deep + real_t min_depth = 1e20; + int min_depth_idx = 0; + for (int i = 0; i < cbk->amount; i++) { + real_t d = cbk->ptr[i * 2 + 0].distance_squared_to(cbk->ptr[i * 2 + 1]); + if (d < min_depth) { + min_depth = d; + min_depth_idx = i; + } + } + + real_t d = p_point_A.distance_squared_to(p_point_B); + if (d < min_depth) { + return; + } + cbk->ptr[min_depth_idx * 2 + 0] = p_point_A; + cbk->ptr[min_depth_idx * 2 + 1] = p_point_B; + + } else { + cbk->ptr[cbk->amount * 2 + 0] = p_point_A; + cbk->ptr[cbk->amount * 2 + 1] = p_point_B; + cbk->amount++; + } +} + +GodotPhysicsServer3D *GodotPhysicsServer3D::godot_singleton = nullptr; +GodotPhysicsServer3D::GodotPhysicsServer3D(bool p_using_threads) { + godot_singleton = this; + GodotBroadPhase3D::create_func = GodotBroadPhase3DBVH::_create; + + using_threads = p_using_threads; +}; diff --git a/servers/physics_3d/physics_server_3d_sw.h b/servers/physics_3d/godot_physics_server_3d.h index 54a787198d..3ed9e320dc 100644 --- a/servers/physics_3d/physics_server_3d_sw.h +++ b/servers/physics_3d/godot_physics_server_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* physics_server_3d_sw.h */ +/* godot_physics_server_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,20 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PHYSICS_SERVER_SW -#define PHYSICS_SERVER_SW +#ifndef GODOT_PHYSICS_SERVER_3D_H +#define GODOT_PHYSICS_SERVER_3D_H + +#include "godot_joint_3d.h" +#include "godot_shape_3d.h" +#include "godot_space_3d.h" +#include "godot_step_3d.h" #include "core/templates/rid_owner.h" -#include "joints_3d_sw.h" #include "servers/physics_server_3d.h" -#include "shape_3d_sw.h" -#include "space_3d_sw.h" -#include "step_3d_sw.h" -class PhysicsServer3DSW : public PhysicsServer3D { - GDCLASS(PhysicsServer3DSW, PhysicsServer3D); +class GodotPhysicsServer3D : public PhysicsServer3D { + GDCLASS(GodotPhysicsServer3D, PhysicsServer3D); - friend class PhysicsDirectSpaceState3DSW; + friend class GodotPhysicsDirectSpaceState3D; bool active = true; int iterations = 0; @@ -53,22 +54,22 @@ class PhysicsServer3DSW : public PhysicsServer3D { bool doing_sync = false; bool flushing_queries = false; - Step3DSW *stepper = nullptr; - Set<const Space3DSW *> active_spaces; + GodotStep3D *stepper = nullptr; + Set<const GodotSpace3D *> active_spaces; - mutable RID_PtrOwner<Shape3DSW, true> shape_owner; - mutable RID_PtrOwner<Space3DSW, true> space_owner; - mutable RID_PtrOwner<Area3DSW, true> area_owner; - mutable RID_PtrOwner<Body3DSW, true> body_owner; - mutable RID_PtrOwner<SoftBody3DSW, true> soft_body_owner; - mutable RID_PtrOwner<Joint3DSW, true> joint_owner; + mutable RID_PtrOwner<GodotShape3D, true> shape_owner; + mutable RID_PtrOwner<GodotSpace3D, true> space_owner; + mutable RID_PtrOwner<GodotArea3D, true> area_owner; + mutable RID_PtrOwner<GodotBody3D, true> body_owner; + mutable RID_PtrOwner<GodotSoftBody3D, true> soft_body_owner; + mutable RID_PtrOwner<GodotJoint3D, true> joint_owner; //void _clear_query(QuerySW *p_query); - friend class CollisionObject3DSW; - SelfList<CollisionObject3DSW>::List pending_shape_update_list; + friend class GodotCollisionObject3D; + SelfList<GodotCollisionObject3D>::List pending_shape_update_list; void _update_shapes(); - static PhysicsServer3DSW *singletonsw; + static GodotPhysicsServer3D *godot_singleton; public: struct CollCbkData { @@ -372,8 +373,8 @@ public: int get_process_info(ProcessInfo p_info) override; - PhysicsServer3DSW(bool p_using_threads = false); - ~PhysicsServer3DSW() {} + GodotPhysicsServer3D(bool p_using_threads = false); + ~GodotPhysicsServer3D() {} }; -#endif +#endif // GODOT_PHYSICS_SERVER_3D_H diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/godot_shape_3d.cpp index 789fc6ab33..4c12a5a948 100644 --- a/servers/physics_3d/shape_3d_sw.cpp +++ b/servers/physics_3d/godot_shape_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* shape_3d_sw.cpp */ +/* godot_shape_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "shape_3d_sw.h" +#include "godot_shape_3d.h" #include "core/io/image.h" #include "core/math/convex_hull.h" #include "core/math/geometry_3d.h" #include "core/templates/sort_array.h" -// HeightMapShape3DSW is based on Bullet btHeightfieldTerrainShape. +// GodotHeightMapShape3D is based on Bullet btHeightfieldTerrainShape. /* Bullet Continuous Collision Detection and Physics Library @@ -58,16 +58,16 @@ subject to the following restrictions: #define _CYLINDER_EDGE_IS_VALID_SUPPORT_THRESHOLD 0.002 #define _CYLINDER_FACE_IS_VALID_SUPPORT_THRESHOLD 0.999 -void Shape3DSW::configure(const AABB &p_aabb) { +void GodotShape3D::configure(const AABB &p_aabb) { aabb = p_aabb; configured = true; - for (const KeyValue<ShapeOwner3DSW *, int> &E : owners) { - ShapeOwner3DSW *co = (ShapeOwner3DSW *)E.key; + for (const KeyValue<GodotShapeOwner3D *, int> &E : owners) { + GodotShapeOwner3D *co = (GodotShapeOwner3D *)E.key; co->_shape_changed(); } } -Vector3 Shape3DSW::get_support(const Vector3 &p_normal) const { +Vector3 GodotShape3D::get_support(const Vector3 &p_normal) const { Vector3 res; int amnt; FeatureType type; @@ -75,8 +75,8 @@ Vector3 Shape3DSW::get_support(const Vector3 &p_normal) const { return res; } -void Shape3DSW::add_owner(ShapeOwner3DSW *p_owner) { - Map<ShapeOwner3DSW *, int>::Element *E = owners.find(p_owner); +void GodotShape3D::add_owner(GodotShapeOwner3D *p_owner) { + Map<GodotShapeOwner3D *, int>::Element *E = owners.find(p_owner); if (E) { E->get()++; } else { @@ -84,8 +84,8 @@ void Shape3DSW::add_owner(ShapeOwner3DSW *p_owner) { } } -void Shape3DSW::remove_owner(ShapeOwner3DSW *p_owner) { - Map<ShapeOwner3DSW *, int>::Element *E = owners.find(p_owner); +void GodotShape3D::remove_owner(GodotShapeOwner3D *p_owner) { + Map<GodotShapeOwner3D *, int>::Element *E = owners.find(p_owner); ERR_FAIL_COND(!E); E->get()--; if (E->get() == 0) { @@ -93,33 +93,33 @@ void Shape3DSW::remove_owner(ShapeOwner3DSW *p_owner) { } } -bool Shape3DSW::is_owner(ShapeOwner3DSW *p_owner) const { +bool GodotShape3D::is_owner(GodotShapeOwner3D *p_owner) const { return owners.has(p_owner); } -const Map<ShapeOwner3DSW *, int> &Shape3DSW::get_owners() const { +const Map<GodotShapeOwner3D *, int> &GodotShape3D::get_owners() const { return owners; } -Shape3DSW::~Shape3DSW() { +GodotShape3D::~GodotShape3D() { ERR_FAIL_COND(owners.size()); } -Plane WorldBoundaryShape3DSW::get_plane() const { +Plane GodotWorldBoundaryShape3D::get_plane() const { return plane; } -void WorldBoundaryShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { +void GodotWorldBoundaryShape3D::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { // gibberish, a plane is infinity r_min = -1e7; r_max = 1e7; } -Vector3 WorldBoundaryShape3DSW::get_support(const Vector3 &p_normal) const { +Vector3 GodotWorldBoundaryShape3D::get_support(const Vector3 &p_normal) const { return p_normal * 1e15; } -bool WorldBoundaryShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { +bool GodotWorldBoundaryShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { bool inters = plane.intersects_segment(p_begin, p_end, &r_result); if (inters) { r_normal = plane.normal; @@ -127,11 +127,11 @@ bool WorldBoundaryShape3DSW::intersect_segment(const Vector3 &p_begin, const Vec return inters; } -bool WorldBoundaryShape3DSW::intersect_point(const Vector3 &p_point) const { +bool GodotWorldBoundaryShape3D::intersect_point(const Vector3 &p_point) const { return plane.distance_to(p_point) < 0; } -Vector3 WorldBoundaryShape3DSW::get_closest_point_to(const Vector3 &p_point) const { +Vector3 GodotWorldBoundaryShape3D::get_closest_point_to(const Vector3 &p_point) const { if (plane.is_point_over(p_point)) { return plane.project(p_point); } else { @@ -139,43 +139,43 @@ Vector3 WorldBoundaryShape3DSW::get_closest_point_to(const Vector3 &p_point) con } } -Vector3 WorldBoundaryShape3DSW::get_moment_of_inertia(real_t p_mass) const { +Vector3 GodotWorldBoundaryShape3D::get_moment_of_inertia(real_t p_mass) const { return Vector3(); // not applicable. } -void WorldBoundaryShape3DSW::_setup(const Plane &p_plane) { +void GodotWorldBoundaryShape3D::_setup(const Plane &p_plane) { plane = p_plane; configure(AABB(Vector3(-1e4, -1e4, -1e4), Vector3(1e4 * 2, 1e4 * 2, 1e4 * 2))); } -void WorldBoundaryShape3DSW::set_data(const Variant &p_data) { +void GodotWorldBoundaryShape3D::set_data(const Variant &p_data) { _setup(p_data); } -Variant WorldBoundaryShape3DSW::get_data() const { +Variant GodotWorldBoundaryShape3D::get_data() const { return plane; } -WorldBoundaryShape3DSW::WorldBoundaryShape3DSW() { +GodotWorldBoundaryShape3D::GodotWorldBoundaryShape3D() { } // -real_t SeparationRayShape3DSW::get_length() const { +real_t GodotSeparationRayShape3D::get_length() const { return length; } -bool SeparationRayShape3DSW::get_slide_on_slope() const { +bool GodotSeparationRayShape3D::get_slide_on_slope() const { return slide_on_slope; } -void SeparationRayShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { +void GodotSeparationRayShape3D::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { // don't think this will be even used r_min = 0; r_max = 1; } -Vector3 SeparationRayShape3DSW::get_support(const Vector3 &p_normal) const { +Vector3 GodotSeparationRayShape3D::get_support(const Vector3 &p_normal) const { if (p_normal.z > 0) { return Vector3(0, 0, length); } else { @@ -183,7 +183,7 @@ Vector3 SeparationRayShape3DSW::get_support(const Vector3 &p_normal) const { } } -void SeparationRayShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { +void GodotSeparationRayShape3D::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { if (Math::abs(p_normal.z) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { r_amount = 2; r_type = FEATURE_EDGE; @@ -200,15 +200,15 @@ void SeparationRayShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve } } -bool SeparationRayShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { +bool GodotSeparationRayShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { return false; //simply not possible } -bool SeparationRayShape3DSW::intersect_point(const Vector3 &p_point) const { +bool GodotSeparationRayShape3D::intersect_point(const Vector3 &p_point) const { return false; //simply not possible } -Vector3 SeparationRayShape3DSW::get_closest_point_to(const Vector3 &p_point) const { +Vector3 GodotSeparationRayShape3D::get_closest_point_to(const Vector3 &p_point) const { Vector3 s[2] = { Vector3(0, 0, 0), Vector3(0, 0, length) @@ -217,37 +217,37 @@ Vector3 SeparationRayShape3DSW::get_closest_point_to(const Vector3 &p_point) con return Geometry3D::get_closest_point_to_segment(p_point, s); } -Vector3 SeparationRayShape3DSW::get_moment_of_inertia(real_t p_mass) const { +Vector3 GodotSeparationRayShape3D::get_moment_of_inertia(real_t p_mass) const { return Vector3(); } -void SeparationRayShape3DSW::_setup(real_t p_length, bool p_slide_on_slope) { +void GodotSeparationRayShape3D::_setup(real_t p_length, bool p_slide_on_slope) { length = p_length; slide_on_slope = p_slide_on_slope; configure(AABB(Vector3(0, 0, 0), Vector3(0.1, 0.1, length))); } -void SeparationRayShape3DSW::set_data(const Variant &p_data) { +void GodotSeparationRayShape3D::set_data(const Variant &p_data) { Dictionary d = p_data; _setup(d["length"], d["slide_on_slope"]); } -Variant SeparationRayShape3DSW::get_data() const { +Variant GodotSeparationRayShape3D::get_data() const { Dictionary d; d["length"] = length; d["slide_on_slope"] = slide_on_slope; return d; } -SeparationRayShape3DSW::SeparationRayShape3DSW() {} +GodotSeparationRayShape3D::GodotSeparationRayShape3D() {} /********** SPHERE *************/ -real_t SphereShape3DSW::get_radius() const { +real_t GodotSphereShape3D::get_radius() const { return radius; } -void SphereShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { +void GodotSphereShape3D::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { real_t d = p_normal.dot(p_transform.origin); // figure out scale at point @@ -258,25 +258,25 @@ void SphereShape3DSW::project_range(const Vector3 &p_normal, const Transform3D & r_max = d + (radius)*scale; } -Vector3 SphereShape3DSW::get_support(const Vector3 &p_normal) const { +Vector3 GodotSphereShape3D::get_support(const Vector3 &p_normal) const { return p_normal * radius; } -void SphereShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { +void GodotSphereShape3D::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { *r_supports = p_normal * radius; r_amount = 1; r_type = FEATURE_POINT; } -bool SphereShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { +bool GodotSphereShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { return Geometry3D::segment_intersects_sphere(p_begin, p_end, Vector3(), radius, &r_result, &r_normal); } -bool SphereShape3DSW::intersect_point(const Vector3 &p_point) const { +bool GodotSphereShape3D::intersect_point(const Vector3 &p_point) const { return p_point.length() < radius; } -Vector3 SphereShape3DSW::get_closest_point_to(const Vector3 &p_point) const { +Vector3 GodotSphereShape3D::get_closest_point_to(const Vector3 &p_point) const { Vector3 p = p_point; real_t l = p.length(); if (l < radius) { @@ -285,29 +285,29 @@ Vector3 SphereShape3DSW::get_closest_point_to(const Vector3 &p_point) const { return (p / l) * radius; } -Vector3 SphereShape3DSW::get_moment_of_inertia(real_t p_mass) const { +Vector3 GodotSphereShape3D::get_moment_of_inertia(real_t p_mass) const { real_t s = 0.4 * p_mass * radius * radius; return Vector3(s, s, s); } -void SphereShape3DSW::_setup(real_t p_radius) { +void GodotSphereShape3D::_setup(real_t p_radius) { radius = p_radius; configure(AABB(Vector3(-radius, -radius, -radius), Vector3(radius * 2.0, radius * 2.0, radius * 2.0))); } -void SphereShape3DSW::set_data(const Variant &p_data) { +void GodotSphereShape3D::set_data(const Variant &p_data) { _setup(p_data); } -Variant SphereShape3DSW::get_data() const { +Variant GodotSphereShape3D::get_data() const { return radius; } -SphereShape3DSW::SphereShape3DSW() {} +GodotSphereShape3D::GodotSphereShape3D() {} /********** BOX *************/ -void BoxShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { +void GodotBoxShape3D::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { // no matter the angle, the box is mirrored anyway Vector3 local_normal = p_transform.basis.xform_inv(p_normal); @@ -318,7 +318,7 @@ void BoxShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_t r_max = distance + length; } -Vector3 BoxShape3DSW::get_support(const Vector3 &p_normal) const { +Vector3 GodotBoxShape3D::get_support(const Vector3 &p_normal) const { Vector3 point( (p_normal.x < 0) ? -half_extents.x : half_extents.x, (p_normal.y < 0) ? -half_extents.y : half_extents.y, @@ -327,7 +327,7 @@ Vector3 BoxShape3DSW::get_support(const Vector3 &p_normal) const { return point; } -void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { +void GodotBoxShape3D::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { static const int next[3] = { 1, 2, 0 }; static const int next2[3] = { 2, 0, 1 }; @@ -410,17 +410,17 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s r_supports[0] = point; } -bool BoxShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { +bool GodotBoxShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { AABB aabb(-half_extents, half_extents * 2.0); return aabb.intersects_segment(p_begin, p_end, &r_result, &r_normal); } -bool BoxShape3DSW::intersect_point(const Vector3 &p_point) const { +bool GodotBoxShape3D::intersect_point(const Vector3 &p_point) const { return (Math::abs(p_point.x) < half_extents.x && Math::abs(p_point.y) < half_extents.y && Math::abs(p_point.z) < half_extents.z); } -Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const { +Vector3 GodotBoxShape3D::get_closest_point_to(const Vector3 &p_point) const { int outside = 0; Vector3 min_point; @@ -470,7 +470,7 @@ Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const { return min_point; } -Vector3 BoxShape3DSW::get_moment_of_inertia(real_t p_mass) const { +Vector3 GodotBoxShape3D::get_moment_of_inertia(real_t p_mass) const { real_t lx = half_extents.x; real_t ly = half_extents.y; real_t lz = half_extents.z; @@ -478,25 +478,25 @@ Vector3 BoxShape3DSW::get_moment_of_inertia(real_t p_mass) const { return Vector3((p_mass / 3.0) * (ly * ly + lz * lz), (p_mass / 3.0) * (lx * lx + lz * lz), (p_mass / 3.0) * (lx * lx + ly * ly)); } -void BoxShape3DSW::_setup(const Vector3 &p_half_extents) { +void GodotBoxShape3D::_setup(const Vector3 &p_half_extents) { half_extents = p_half_extents.abs(); configure(AABB(-half_extents, half_extents * 2)); } -void BoxShape3DSW::set_data(const Variant &p_data) { +void GodotBoxShape3D::set_data(const Variant &p_data) { _setup(p_data); } -Variant BoxShape3DSW::get_data() const { +Variant GodotBoxShape3D::get_data() const { return half_extents; } -BoxShape3DSW::BoxShape3DSW() {} +GodotBoxShape3D::GodotBoxShape3D() {} /********** CAPSULE *************/ -void CapsuleShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { +void GodotCapsuleShape3D::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { Vector3 n = p_transform.basis.xform_inv(p_normal).normalized(); real_t h = height * 0.5 - radius; @@ -507,7 +507,7 @@ void CapsuleShape3DSW::project_range(const Vector3 &p_normal, const Transform3D r_min = p_normal.dot(p_transform.xform(-n)); } -Vector3 CapsuleShape3DSW::get_support(const Vector3 &p_normal) const { +Vector3 GodotCapsuleShape3D::get_support(const Vector3 &p_normal) const { Vector3 n = p_normal; real_t h = height * 0.5 - radius; @@ -517,7 +517,7 @@ Vector3 CapsuleShape3DSW::get_support(const Vector3 &p_normal) const { return n; } -void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { +void GodotCapsuleShape3D::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { Vector3 n = p_normal; real_t d = n.y; @@ -546,7 +546,7 @@ void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 } } -bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { +bool GodotCapsuleShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { Vector3 norm = (p_end - p_begin).normalized(); real_t min_d = 1e20; @@ -602,7 +602,7 @@ bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 & return collision; } -bool CapsuleShape3DSW::intersect_point(const Vector3 &p_point) const { +bool GodotCapsuleShape3D::intersect_point(const Vector3 &p_point) const { if (Math::abs(p_point.y) < height * 0.5 - radius) { return Vector3(p_point.x, 0, p_point.z).length() < radius; } else { @@ -612,7 +612,7 @@ bool CapsuleShape3DSW::intersect_point(const Vector3 &p_point) const { } } -Vector3 CapsuleShape3DSW::get_closest_point_to(const Vector3 &p_point) const { +Vector3 GodotCapsuleShape3D::get_closest_point_to(const Vector3 &p_point) const { Vector3 s[2] = { Vector3(0, -height * 0.5 + radius, 0), Vector3(0, height * 0.5 - radius, 0), @@ -627,7 +627,7 @@ Vector3 CapsuleShape3DSW::get_closest_point_to(const Vector3 &p_point) const { return p + (p_point - p).normalized() * radius; } -Vector3 CapsuleShape3DSW::get_moment_of_inertia(real_t p_mass) const { +Vector3 GodotCapsuleShape3D::get_moment_of_inertia(real_t p_mass) const { // use bad AABB approximation Vector3 extents = get_aabb().size * 0.5; @@ -637,31 +637,31 @@ Vector3 CapsuleShape3DSW::get_moment_of_inertia(real_t p_mass) const { (p_mass / 3.0) * (extents.x * extents.x + extents.y * extents.y)); } -void CapsuleShape3DSW::_setup(real_t p_height, real_t p_radius) { +void GodotCapsuleShape3D::_setup(real_t p_height, real_t p_radius) { height = p_height; radius = p_radius; configure(AABB(Vector3(-radius, -height * 0.5, -radius), Vector3(radius * 2, height, radius * 2))); } -void CapsuleShape3DSW::set_data(const Variant &p_data) { +void GodotCapsuleShape3D::set_data(const Variant &p_data) { Dictionary d = p_data; ERR_FAIL_COND(!d.has("radius")); ERR_FAIL_COND(!d.has("height")); _setup(d["height"], d["radius"]); } -Variant CapsuleShape3DSW::get_data() const { +Variant GodotCapsuleShape3D::get_data() const { Dictionary d; d["radius"] = radius; d["height"] = height; return d; } -CapsuleShape3DSW::CapsuleShape3DSW() {} +GodotCapsuleShape3D::GodotCapsuleShape3D() {} /********** CYLINDER *************/ -void CylinderShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { +void GodotCylinderShape3D::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { Vector3 cylinder_axis = p_transform.basis.get_axis(1).normalized(); real_t axis_dot = cylinder_axis.dot(p_normal); @@ -683,7 +683,7 @@ void CylinderShape3DSW::project_range(const Vector3 &p_normal, const Transform3D r_max = distance + length; } -Vector3 CylinderShape3DSW::get_support(const Vector3 &p_normal) const { +Vector3 GodotCylinderShape3D::get_support(const Vector3 &p_normal) const { Vector3 n = p_normal; real_t h = (n.y > 0) ? height : -height; real_t s = Math::sqrt(n.x * n.x + n.z * n.z); @@ -701,7 +701,7 @@ Vector3 CylinderShape3DSW::get_support(const Vector3 &p_normal) const { return n; } -void CylinderShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { +void GodotCylinderShape3D::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { real_t d = p_normal.y; if (Math::abs(d) > _CYLINDER_FACE_IS_VALID_SUPPORT_THRESHOLD) { real_t h = (d > 0) ? height : -height; @@ -761,18 +761,18 @@ void CylinderShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 } } -bool CylinderShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { +bool GodotCylinderShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { return Geometry3D::segment_intersects_cylinder(p_begin, p_end, height, radius, &r_result, &r_normal, 1); } -bool CylinderShape3DSW::intersect_point(const Vector3 &p_point) const { +bool GodotCylinderShape3D::intersect_point(const Vector3 &p_point) const { if (Math::abs(p_point.y) < height * 0.5) { return Vector3(p_point.x, 0, p_point.z).length() < radius; } return false; } -Vector3 CylinderShape3DSW::get_closest_point_to(const Vector3 &p_point) const { +Vector3 GodotCylinderShape3D::get_closest_point_to(const Vector3 &p_point) const { if (Math::absf(p_point.y) > height * 0.5) { // Project point to top disk. real_t dir = p_point.y > 0.0 ? 1.0 : -1.0; @@ -805,7 +805,7 @@ Vector3 CylinderShape3DSW::get_closest_point_to(const Vector3 &p_point) const { } } -Vector3 CylinderShape3DSW::get_moment_of_inertia(real_t p_mass) const { +Vector3 GodotCylinderShape3D::get_moment_of_inertia(real_t p_mass) const { // use bad AABB approximation Vector3 extents = get_aabb().size * 0.5; @@ -815,31 +815,31 @@ Vector3 CylinderShape3DSW::get_moment_of_inertia(real_t p_mass) const { (p_mass / 3.0) * (extents.x * extents.x + extents.y * extents.y)); } -void CylinderShape3DSW::_setup(real_t p_height, real_t p_radius) { +void GodotCylinderShape3D::_setup(real_t p_height, real_t p_radius) { height = p_height; radius = p_radius; configure(AABB(Vector3(-radius, -height * 0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0))); } -void CylinderShape3DSW::set_data(const Variant &p_data) { +void GodotCylinderShape3D::set_data(const Variant &p_data) { Dictionary d = p_data; ERR_FAIL_COND(!d.has("radius")); ERR_FAIL_COND(!d.has("height")); _setup(d["height"], d["radius"]); } -Variant CylinderShape3DSW::get_data() const { +Variant GodotCylinderShape3D::get_data() const { Dictionary d; d["radius"] = radius; d["height"] = height; return d; } -CylinderShape3DSW::CylinderShape3DSW() {} +GodotCylinderShape3D::GodotCylinderShape3D() {} /********** CONVEX POLYGON *************/ -void ConvexPolygonShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { +void GodotConvexPolygonShape3D::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { int vertex_count = mesh.vertices.size(); if (vertex_count == 0) { return; @@ -859,7 +859,7 @@ void ConvexPolygonShape3DSW::project_range(const Vector3 &p_normal, const Transf } } -Vector3 ConvexPolygonShape3DSW::get_support(const Vector3 &p_normal) const { +Vector3 GodotConvexPolygonShape3D::get_support(const Vector3 &p_normal) const { Vector3 n = p_normal; int vert_support_idx = -1; @@ -884,7 +884,7 @@ Vector3 ConvexPolygonShape3DSW::get_support(const Vector3 &p_normal) const { return vrts[vert_support_idx]; } -void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { +void GodotConvexPolygonShape3D::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int fc = mesh.faces.size(); @@ -954,7 +954,7 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve r_type = FEATURE_POINT; } -bool ConvexPolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { +bool GodotConvexPolygonShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int fc = mesh.faces.size(); @@ -992,7 +992,7 @@ bool ConvexPolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vec return col; } -bool ConvexPolygonShape3DSW::intersect_point(const Vector3 &p_point) const { +bool GodotConvexPolygonShape3D::intersect_point(const Vector3 &p_point) const { const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int fc = mesh.faces.size(); @@ -1005,7 +1005,7 @@ bool ConvexPolygonShape3DSW::intersect_point(const Vector3 &p_point) const { return true; } -Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) const { +Vector3 GodotConvexPolygonShape3D::get_closest_point_to(const Vector3 &p_point) const { const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int fc = mesh.faces.size(); const Vector3 *vertices = mesh.vertices.ptr(); @@ -1063,7 +1063,7 @@ Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) con return min_point; } -Vector3 ConvexPolygonShape3DSW::get_moment_of_inertia(real_t p_mass) const { +Vector3 GodotConvexPolygonShape3D::get_moment_of_inertia(real_t p_mass) const { // use bad AABB approximation Vector3 extents = get_aabb().size * 0.5; @@ -1073,7 +1073,7 @@ Vector3 ConvexPolygonShape3DSW::get_moment_of_inertia(real_t p_mass) const { (p_mass / 3.0) * (extents.x * extents.x + extents.y * extents.y)); } -void ConvexPolygonShape3DSW::_setup(const Vector<Vector3> &p_vertices) { +void GodotConvexPolygonShape3D::_setup(const Vector<Vector3> &p_vertices) { Error err = ConvexHullComputer::convex_hull(p_vertices, mesh); if (err != OK) { ERR_PRINT("Failed to build convex hull"); @@ -1092,20 +1092,20 @@ void ConvexPolygonShape3DSW::_setup(const Vector<Vector3> &p_vertices) { configure(_aabb); } -void ConvexPolygonShape3DSW::set_data(const Variant &p_data) { +void GodotConvexPolygonShape3D::set_data(const Variant &p_data) { _setup(p_data); } -Variant ConvexPolygonShape3DSW::get_data() const { +Variant GodotConvexPolygonShape3D::get_data() const { return mesh.vertices; } -ConvexPolygonShape3DSW::ConvexPolygonShape3DSW() { +GodotConvexPolygonShape3D::GodotConvexPolygonShape3D() { } /********** FACE POLYGON *************/ -void FaceShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { +void GodotFaceShape3D::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { for (int i = 0; i < 3; i++) { Vector3 v = p_transform.xform(vertex[i]); real_t d = p_normal.dot(v); @@ -1120,7 +1120,7 @@ void FaceShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_ } } -Vector3 FaceShape3DSW::get_support(const Vector3 &p_normal) const { +Vector3 GodotFaceShape3D::get_support(const Vector3 &p_normal) const { int vert_support_idx = -1; real_t support_max = 0; @@ -1136,7 +1136,7 @@ Vector3 FaceShape3DSW::get_support(const Vector3 &p_normal) const { return vertex[vert_support_idx]; } -void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { +void GodotFaceShape3D::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { Vector3 n = p_normal; /** TEST FACE AS SUPPORT **/ @@ -1188,7 +1188,7 @@ void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_ r_supports[0] = vertex[vert_support_idx]; } -bool FaceShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { +bool GodotFaceShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { bool c = Geometry3D::segment_intersects_triangle(p_begin, p_end, vertex[0], vertex[1], vertex[2], &r_result); if (c) { r_normal = Plane(vertex[0], vertex[1], vertex[2]).normal; @@ -1204,23 +1204,23 @@ bool FaceShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_e return c; } -bool FaceShape3DSW::intersect_point(const Vector3 &p_point) const { +bool GodotFaceShape3D::intersect_point(const Vector3 &p_point) const { return false; //face is flat } -Vector3 FaceShape3DSW::get_closest_point_to(const Vector3 &p_point) const { +Vector3 GodotFaceShape3D::get_closest_point_to(const Vector3 &p_point) const { return Face3(vertex[0], vertex[1], vertex[2]).get_closest_point_to(p_point); } -Vector3 FaceShape3DSW::get_moment_of_inertia(real_t p_mass) const { +Vector3 GodotFaceShape3D::get_moment_of_inertia(real_t p_mass) const { return Vector3(); // Sorry, but i don't think anyone cares, FaceShape! } -FaceShape3DSW::FaceShape3DSW() { +GodotFaceShape3D::GodotFaceShape3D() { configure(AABB()); } -Vector<Vector3> ConcavePolygonShape3DSW::get_faces() const { +Vector<Vector3> GodotConcavePolygonShape3D::get_faces() const { Vector<Vector3> rfaces; rfaces.resize(faces.size() * 3); @@ -1235,7 +1235,7 @@ Vector<Vector3> ConcavePolygonShape3DSW::get_faces() const { return rfaces; } -void ConcavePolygonShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { +void GodotConcavePolygonShape3D::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { int count = vertices.size(); if (count == 0) { r_min = 0; @@ -1256,7 +1256,7 @@ void ConcavePolygonShape3DSW::project_range(const Vector3 &p_normal, const Trans } } -Vector3 ConcavePolygonShape3DSW::get_support(const Vector3 &p_normal) const { +Vector3 GodotConcavePolygonShape3D::get_support(const Vector3 &p_normal) const { int count = vertices.size(); if (count == 0) { return Vector3(); @@ -1281,7 +1281,7 @@ Vector3 ConcavePolygonShape3DSW::get_support(const Vector3 &p_normal) const { return vptr[vert_support_idx]; } -void ConcavePolygonShape3DSW::_cull_segment(int p_idx, _SegmentCullParams *p_params) const { +void GodotConcavePolygonShape3D::_cull_segment(int p_idx, _SegmentCullParams *p_params) const { const BVH *bvh = &p_params->bvh[p_idx]; /* @@ -1296,7 +1296,7 @@ void ConcavePolygonShape3DSW::_cull_segment(int p_idx, _SegmentCullParams *p_par if (bvh->face_index >= 0) { const Face *f = &p_params->faces[bvh->face_index]; - FaceShape3DSW *face = p_params->face; + GodotFaceShape3D *face = p_params->face; face->normal = f->normal; face->vertex[0] = p_params->vertices[f->indices[0]]; face->vertex[1] = p_params->vertices[f->indices[1]]; @@ -1323,7 +1323,7 @@ void ConcavePolygonShape3DSW::_cull_segment(int p_idx, _SegmentCullParams *p_par } } -bool ConcavePolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { +bool GodotConcavePolygonShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { if (faces.size() == 0) { return false; } @@ -1333,7 +1333,7 @@ bool ConcavePolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Ve const Vector3 *vr = vertices.ptr(); const BVH *br = bvh.ptr(); - FaceShape3DSW face; + GodotFaceShape3D face; face.backface_collision = backface_collision; _SegmentCullParams params; @@ -1359,15 +1359,15 @@ bool ConcavePolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Ve } } -bool ConcavePolygonShape3DSW::intersect_point(const Vector3 &p_point) const { +bool GodotConcavePolygonShape3D::intersect_point(const Vector3 &p_point) const { return false; //face is flat } -Vector3 ConcavePolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) const { +Vector3 GodotConcavePolygonShape3D::get_closest_point_to(const Vector3 &p_point) const { return Vector3(); } -bool ConcavePolygonShape3DSW::_cull(int p_idx, _CullParams *p_params) const { +bool GodotConcavePolygonShape3D::_cull(int p_idx, _CullParams *p_params) const { const BVH *bvh = &p_params->bvh[p_idx]; if (!p_params->aabb.intersects(bvh->aabb)) { @@ -1376,7 +1376,7 @@ bool ConcavePolygonShape3DSW::_cull(int p_idx, _CullParams *p_params) const { if (bvh->face_index >= 0) { const Face *f = &p_params->faces[bvh->face_index]; - FaceShape3DSW *face = p_params->face; + GodotFaceShape3D *face = p_params->face; face->normal = f->normal; face->vertex[0] = p_params->vertices[f->indices[0]]; face->vertex[1] = p_params->vertices[f->indices[1]]; @@ -1401,7 +1401,7 @@ bool ConcavePolygonShape3DSW::_cull(int p_idx, _CullParams *p_params) const { return false; } -void ConcavePolygonShape3DSW::cull(const AABB &p_local_aabb, QueryCallback p_callback, void *p_userdata) const { +void GodotConcavePolygonShape3D::cull(const AABB &p_local_aabb, QueryCallback p_callback, void *p_userdata) const { // make matrix local to concave if (faces.size() == 0) { return; @@ -1414,7 +1414,7 @@ void ConcavePolygonShape3DSW::cull(const AABB &p_local_aabb, QueryCallback p_cal const Vector3 *vr = vertices.ptr(); const BVH *br = bvh.ptr(); - FaceShape3DSW face; // use this to send in the callback + GodotFaceShape3D face; // use this to send in the callback face.backface_collision = backface_collision; _CullParams params; @@ -1430,7 +1430,7 @@ void ConcavePolygonShape3DSW::cull(const AABB &p_local_aabb, QueryCallback p_cal _cull(0, ¶ms); } -Vector3 ConcavePolygonShape3DSW::get_moment_of_inertia(real_t p_mass) const { +Vector3 GodotConcavePolygonShape3D::get_moment_of_inertia(real_t p_mass) const { // use bad AABB approximation Vector3 extents = get_aabb().size * 0.5; @@ -1440,40 +1440,40 @@ Vector3 ConcavePolygonShape3DSW::get_moment_of_inertia(real_t p_mass) const { (p_mass / 3.0) * (extents.x * extents.x + extents.y * extents.y)); } -struct _VolumeSW_BVH_Element { +struct _Volume_BVH_Element { AABB aabb; Vector3 center; int face_index; }; -struct _VolumeSW_BVH_CompareX { - _FORCE_INLINE_ bool operator()(const _VolumeSW_BVH_Element &a, const _VolumeSW_BVH_Element &b) const { +struct _Volume_BVH_CompareX { + _FORCE_INLINE_ bool operator()(const _Volume_BVH_Element &a, const _Volume_BVH_Element &b) const { return a.center.x < b.center.x; } }; -struct _VolumeSW_BVH_CompareY { - _FORCE_INLINE_ bool operator()(const _VolumeSW_BVH_Element &a, const _VolumeSW_BVH_Element &b) const { +struct _Volume_BVH_CompareY { + _FORCE_INLINE_ bool operator()(const _Volume_BVH_Element &a, const _Volume_BVH_Element &b) const { return a.center.y < b.center.y; } }; -struct _VolumeSW_BVH_CompareZ { - _FORCE_INLINE_ bool operator()(const _VolumeSW_BVH_Element &a, const _VolumeSW_BVH_Element &b) const { +struct _Volume_BVH_CompareZ { + _FORCE_INLINE_ bool operator()(const _Volume_BVH_Element &a, const _Volume_BVH_Element &b) const { return a.center.z < b.center.z; } }; -struct _VolumeSW_BVH { +struct _Volume_BVH { AABB aabb; - _VolumeSW_BVH *left; - _VolumeSW_BVH *right; + _Volume_BVH *left; + _Volume_BVH *right; int face_index; }; -_VolumeSW_BVH *_volume_sw_build_bvh(_VolumeSW_BVH_Element *p_elements, int p_size, int &count) { - _VolumeSW_BVH *bvh = memnew(_VolumeSW_BVH); +_Volume_BVH *_volume_build_bvh(_Volume_BVH_Element *p_elements, int p_size, int &count) { + _Volume_BVH *bvh = memnew(_Volume_BVH); if (p_size == 1) { //leaf @@ -1498,30 +1498,30 @@ _VolumeSW_BVH *_volume_sw_build_bvh(_VolumeSW_BVH_Element *p_elements, int p_siz bvh->aabb = aabb; switch (aabb.get_longest_axis_index()) { case 0: { - SortArray<_VolumeSW_BVH_Element, _VolumeSW_BVH_CompareX> sort_x; + SortArray<_Volume_BVH_Element, _Volume_BVH_CompareX> sort_x; sort_x.sort(p_elements, p_size); } break; case 1: { - SortArray<_VolumeSW_BVH_Element, _VolumeSW_BVH_CompareY> sort_y; + SortArray<_Volume_BVH_Element, _Volume_BVH_CompareY> sort_y; sort_y.sort(p_elements, p_size); } break; case 2: { - SortArray<_VolumeSW_BVH_Element, _VolumeSW_BVH_CompareZ> sort_z; + SortArray<_Volume_BVH_Element, _Volume_BVH_CompareZ> sort_z; sort_z.sort(p_elements, p_size); } break; } int split = p_size / 2; - bvh->left = _volume_sw_build_bvh(p_elements, split, count); - bvh->right = _volume_sw_build_bvh(&p_elements[split], p_size - split, count); + bvh->left = _volume_build_bvh(p_elements, split, count); + bvh->right = _volume_build_bvh(&p_elements[split], p_size - split, count); //printf("branch at %p - %i: %i\n",bvh,count,bvh->face_index); count++; return bvh; } -void ConcavePolygonShape3DSW::_fill_bvh(_VolumeSW_BVH *p_bvh_tree, BVH *p_bvh_array, int &p_idx) { +void GodotConcavePolygonShape3D::_fill_bvh(_Volume_BVH *p_bvh_tree, BVH *p_bvh_array, int &p_idx) { int idx = p_idx; p_bvh_array[idx].aabb = p_bvh_tree->aabb; @@ -1547,7 +1547,7 @@ void ConcavePolygonShape3DSW::_fill_bvh(_VolumeSW_BVH *p_bvh_tree, BVH *p_bvh_ar memdelete(p_bvh_tree); } -void ConcavePolygonShape3DSW::_setup(const Vector<Vector3> &p_faces, bool p_backface_collision) { +void GodotConcavePolygonShape3D::_setup(const Vector<Vector3> &p_faces, bool p_backface_collision) { int src_face_count = p_faces.size(); if (src_face_count == 0) { configure(AABB()); @@ -1558,10 +1558,10 @@ void ConcavePolygonShape3DSW::_setup(const Vector<Vector3> &p_faces, bool p_back const Vector3 *facesr = p_faces.ptr(); - Vector<_VolumeSW_BVH_Element> bvh_array; + Vector<_Volume_BVH_Element> bvh_array; bvh_array.resize(src_face_count); - _VolumeSW_BVH_Element *bvh_arrayw = bvh_array.ptrw(); + _Volume_BVH_Element *bvh_arrayw = bvh_array.ptrw(); faces.resize(src_face_count); Face *facesw = faces.ptrw(); @@ -1593,7 +1593,7 @@ void ConcavePolygonShape3DSW::_setup(const Vector<Vector3> &p_faces, bool p_back } int count = 0; - _VolumeSW_BVH *bvh_tree = _volume_sw_build_bvh(bvh_arrayw, src_face_count, count); + _Volume_BVH *bvh_tree = _volume_build_bvh(bvh_arrayw, src_face_count, count); bvh.resize(count + 1); @@ -1607,14 +1607,14 @@ void ConcavePolygonShape3DSW::_setup(const Vector<Vector3> &p_faces, bool p_back configure(_aabb); // this type of shape has no margin } -void ConcavePolygonShape3DSW::set_data(const Variant &p_data) { +void GodotConcavePolygonShape3D::set_data(const Variant &p_data) { Dictionary d = p_data; ERR_FAIL_COND(!d.has("faces")); _setup(d["faces"], d["backface_collision"]); } -Variant ConcavePolygonShape3DSW::get_data() const { +Variant GodotConcavePolygonShape3D::get_data() const { Dictionary d; d["faces"] = get_faces(); d["backface_collision"] = backface_collision; @@ -1622,29 +1622,29 @@ Variant ConcavePolygonShape3DSW::get_data() const { return d; } -ConcavePolygonShape3DSW::ConcavePolygonShape3DSW() { +GodotConcavePolygonShape3D::GodotConcavePolygonShape3D() { } /* HEIGHT MAP SHAPE */ -Vector<real_t> HeightMapShape3DSW::get_heights() const { +Vector<real_t> GodotHeightMapShape3D::get_heights() const { return heights; } -int HeightMapShape3DSW::get_width() const { +int GodotHeightMapShape3D::get_width() const { return width; } -int HeightMapShape3DSW::get_depth() const { +int GodotHeightMapShape3D::get_depth() const { return depth; } -void HeightMapShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { +void GodotHeightMapShape3D::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { //not very useful, but not very used either p_transform.xform(get_aabb()).project_range_in_plane(Plane(p_normal), r_min, r_max); } -Vector3 HeightMapShape3DSW::get_support(const Vector3 &p_normal) const { +Vector3 GodotHeightMapShape3D::get_support(const Vector3 &p_normal) const { //not very useful, but not very used either return get_aabb().get_support(p_normal); } @@ -1657,8 +1657,8 @@ struct _HeightmapSegmentCullParams { Vector3 result; Vector3 normal; - const HeightMapShape3DSW *heightmap = nullptr; - FaceShape3DSW *face = nullptr; + const GodotHeightMapShape3D *heightmap = nullptr; + GodotFaceShape3D *face = nullptr; }; struct _HeightmapGridCullState { @@ -1706,7 +1706,7 @@ _FORCE_INLINE_ bool _heightmap_cell_cull_segment(_HeightmapSegmentCullParams &p_ } _FORCE_INLINE_ bool _heightmap_chunk_cull_segment(_HeightmapSegmentCullParams &p_params, const _HeightmapGridCullState &p_state) { - const HeightMapShape3DSW::Range &chunk = p_params.heightmap->_get_bounds_chunk(p_state.x, p_state.z); + const GodotHeightMapShape3D::Range &chunk = p_params.heightmap->_get_bounds_chunk(p_state.x, p_state.z); Vector3 enter_pos; Vector3 exit_pos; @@ -1725,8 +1725,8 @@ _FORCE_INLINE_ bool _heightmap_chunk_cull_segment(_HeightmapSegmentCullParams &p } // Transform positions to heightmap space. - enter_pos *= HeightMapShape3DSW::BOUNDS_CHUNK_SIZE; - exit_pos *= HeightMapShape3DSW::BOUNDS_CHUNK_SIZE; + enter_pos *= GodotHeightMapShape3D::BOUNDS_CHUNK_SIZE; + exit_pos *= GodotHeightMapShape3D::BOUNDS_CHUNK_SIZE; // We did enter the flat projection of the AABB, // but we have to check if we intersect it on the vertical axis. @@ -1741,7 +1741,7 @@ _FORCE_INLINE_ bool _heightmap_chunk_cull_segment(_HeightmapSegmentCullParams &p } template <typename ProcessFunction> -bool HeightMapShape3DSW::_intersect_grid_segment(ProcessFunction &p_process, const Vector3 &p_begin, const Vector3 &p_end, int p_width, int p_depth, const Vector3 &offset, Vector3 &r_point, Vector3 &r_normal) const { +bool GodotHeightMapShape3D::_intersect_grid_segment(ProcessFunction &p_process, const Vector3 &p_begin, const Vector3 &p_end, int p_width, int p_depth, const Vector3 &offset, Vector3 &r_point, Vector3 &r_normal) const { Vector3 delta = (p_end - p_begin); real_t length = delta.length(); @@ -1751,7 +1751,7 @@ bool HeightMapShape3DSW::_intersect_grid_segment(ProcessFunction &p_process, con Vector3 local_begin = p_begin + offset; - FaceShape3DSW face; + GodotFaceShape3D face; face.backface_collision = false; _HeightmapSegmentCullParams params; @@ -1881,7 +1881,7 @@ bool HeightMapShape3DSW::_intersect_grid_segment(ProcessFunction &p_process, con return false; } -bool HeightMapShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const { +bool GodotHeightMapShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const { if (heights.is_empty()) { return false; } @@ -1898,7 +1898,7 @@ bool HeightMapShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 if ((begin_x == end_x) && (begin_z == end_z)) { // Simple case for rays that don't traverse the grid horizontally. // Just perform a test on the given cell. - FaceShape3DSW face; + GodotFaceShape3D face; face.backface_collision = false; _HeightmapSegmentCullParams params; @@ -1938,15 +1938,15 @@ bool HeightMapShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 return false; } -bool HeightMapShape3DSW::intersect_point(const Vector3 &p_point) const { +bool GodotHeightMapShape3D::intersect_point(const Vector3 &p_point) const { return false; } -Vector3 HeightMapShape3DSW::get_closest_point_to(const Vector3 &p_point) const { +Vector3 GodotHeightMapShape3D::get_closest_point_to(const Vector3 &p_point) const { return Vector3(); } -void HeightMapShape3DSW::_get_cell(const Vector3 &p_point, int &r_x, int &r_y, int &r_z) const { +void GodotHeightMapShape3D::_get_cell(const Vector3 &p_point, int &r_x, int &r_y, int &r_z) const { const AABB &aabb = get_aabb(); Vector3 pos_local = aabb.position + local_origin; @@ -1961,7 +1961,7 @@ void HeightMapShape3DSW::_get_cell(const Vector3 &p_point, int &r_x, int &r_y, i r_z = (clamped_point.z < 0.0) ? (clamped_point.z - 0.5) : (clamped_point.z + 0.5); } -void HeightMapShape3DSW::cull(const AABB &p_local_aabb, QueryCallback p_callback, void *p_userdata) const { +void GodotHeightMapShape3D::cull(const AABB &p_local_aabb, QueryCallback p_callback, void *p_userdata) const { if (heights.is_empty()) { return; } @@ -1987,7 +1987,7 @@ void HeightMapShape3DSW::cull(const AABB &p_local_aabb, QueryCallback p_callback int start_z = MAX(0, aabb_min[2]); int end_z = MIN(depth - 1, aabb_max[2]); - FaceShape3DSW face; + GodotFaceShape3D face; face.backface_collision = true; for (int z = start_z; z < end_z; z++) { @@ -2012,7 +2012,7 @@ void HeightMapShape3DSW::cull(const AABB &p_local_aabb, QueryCallback p_callback } } -Vector3 HeightMapShape3DSW::get_moment_of_inertia(real_t p_mass) const { +Vector3 GodotHeightMapShape3D::get_moment_of_inertia(real_t p_mass) const { // use bad AABB approximation Vector3 extents = get_aabb().size * 0.5; @@ -2022,7 +2022,7 @@ Vector3 HeightMapShape3DSW::get_moment_of_inertia(real_t p_mass) const { (p_mass / 3.0) * (extents.x * extents.x + extents.y * extents.y)); } -void HeightMapShape3DSW::_build_accelerator() { +void GodotHeightMapShape3D::_build_accelerator() { bounds_grid.clear(); bounds_grid_width = width / BOUNDS_CHUNK_SIZE; @@ -2091,7 +2091,7 @@ void HeightMapShape3DSW::_build_accelerator() { } } -void HeightMapShape3DSW::_setup(const Vector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height) { +void GodotHeightMapShape3D::_setup(const Vector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height) { heights = p_heights; width = p_width; depth = p_depth; @@ -2112,7 +2112,7 @@ void HeightMapShape3DSW::_setup(const Vector<real_t> &p_heights, int p_width, in configure(aabb); } -void HeightMapShape3DSW::set_data(const Variant &p_data) { +void GodotHeightMapShape3D::set_data(const Variant &p_data) { ERR_FAIL_COND(p_data.get_type() != Variant::DICTIONARY); Dictionary d = p_data; @@ -2184,7 +2184,7 @@ void HeightMapShape3DSW::set_data(const Variant &p_data) { _setup(heights_buffer, width, depth, min_height, max_height); } -Variant HeightMapShape3DSW::get_data() const { +Variant GodotHeightMapShape3D::get_data() const { Dictionary d; d["width"] = width; d["depth"] = depth; @@ -2198,5 +2198,5 @@ Variant HeightMapShape3DSW::get_data() const { return d; } -HeightMapShape3DSW::HeightMapShape3DSW() { +GodotHeightMapShape3D::GodotHeightMapShape3D() { } diff --git a/servers/physics_3d/shape_3d_sw.h b/servers/physics_3d/godot_shape_3d.h index 061d66a085..8822d9487b 100644 --- a/servers/physics_3d/shape_3d_sw.h +++ b/servers/physics_3d/godot_shape_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* shape_3d_sw.h */ +/* godot_shape_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,30 +28,30 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SHAPE_SW_H -#define SHAPE_SW_H +#ifndef GODOT_SHAPE_3D_H +#define GODOT_SHAPE_3D_H #include "core/math/geometry_3d.h" #include "core/templates/local_vector.h" #include "servers/physics_server_3d.h" -class Shape3DSW; +class GodotShape3D; -class ShapeOwner3DSW { +class GodotShapeOwner3D { public: virtual void _shape_changed() = 0; - virtual void remove_shape(Shape3DSW *p_shape) = 0; + virtual void remove_shape(GodotShape3D *p_shape) = 0; - virtual ~ShapeOwner3DSW() {} + virtual ~GodotShapeOwner3D() {} }; -class Shape3DSW { +class GodotShape3D { RID self; AABB aabb; bool configured = false; real_t custom_bias = 0.0; - Map<ShapeOwner3DSW *, int> owners; + Map<GodotShapeOwner3D *, int> owners; protected: void configure(const AABB &p_aabb); @@ -90,29 +90,29 @@ public: _FORCE_INLINE_ void set_custom_bias(real_t p_bias) { custom_bias = p_bias; } _FORCE_INLINE_ real_t get_custom_bias() const { return custom_bias; } - void add_owner(ShapeOwner3DSW *p_owner); - void remove_owner(ShapeOwner3DSW *p_owner); - bool is_owner(ShapeOwner3DSW *p_owner) const; - const Map<ShapeOwner3DSW *, int> &get_owners() const; + void add_owner(GodotShapeOwner3D *p_owner); + void remove_owner(GodotShapeOwner3D *p_owner); + bool is_owner(GodotShapeOwner3D *p_owner) const; + const Map<GodotShapeOwner3D *, int> &get_owners() const; - Shape3DSW() {} - virtual ~Shape3DSW(); + GodotShape3D() {} + virtual ~GodotShape3D(); }; -class ConcaveShape3DSW : public Shape3DSW { +class GodotConcaveShape3D : public GodotShape3D { public: virtual bool is_concave() const override { return true; } virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override { r_amount = 0; } // Returns true to stop the query. - typedef bool (*QueryCallback)(void *p_userdata, Shape3DSW *p_convex); + typedef bool (*QueryCallback)(void *p_userdata, GodotShape3D *p_convex); virtual void cull(const AABB &p_local_aabb, QueryCallback p_callback, void *p_userdata) const = 0; - ConcaveShape3DSW() {} + GodotConcaveShape3D() {} }; -class WorldBoundaryShape3DSW : public Shape3DSW { +class GodotWorldBoundaryShape3D : public GodotShape3D { Plane plane; void _setup(const Plane &p_plane); @@ -134,10 +134,10 @@ public: virtual void set_data(const Variant &p_data) override; virtual Variant get_data() const override; - WorldBoundaryShape3DSW(); + GodotWorldBoundaryShape3D(); }; -class SeparationRayShape3DSW : public Shape3DSW { +class GodotSeparationRayShape3D : public GodotShape3D { real_t length = 1.0; bool slide_on_slope = false; @@ -162,10 +162,10 @@ public: virtual void set_data(const Variant &p_data) override; virtual Variant get_data() const override; - SeparationRayShape3DSW(); + GodotSeparationRayShape3D(); }; -class SphereShape3DSW : public Shape3DSW { +class GodotSphereShape3D : public GodotShape3D { real_t radius = 0.0; void _setup(real_t p_radius); @@ -189,10 +189,10 @@ public: virtual void set_data(const Variant &p_data) override; virtual Variant get_data() const override; - SphereShape3DSW(); + GodotSphereShape3D(); }; -class BoxShape3DSW : public Shape3DSW { +class GodotBoxShape3D : public GodotShape3D { Vector3 half_extents; void _setup(const Vector3 &p_half_extents); @@ -214,10 +214,10 @@ public: virtual void set_data(const Variant &p_data) override; virtual Variant get_data() const override; - BoxShape3DSW(); + GodotBoxShape3D(); }; -class CapsuleShape3DSW : public Shape3DSW { +class GodotCapsuleShape3D : public GodotShape3D { real_t height = 0.0; real_t radius = 0.0; @@ -243,10 +243,10 @@ public: virtual void set_data(const Variant &p_data) override; virtual Variant get_data() const override; - CapsuleShape3DSW(); + GodotCapsuleShape3D(); }; -class CylinderShape3DSW : public Shape3DSW { +class GodotCylinderShape3D : public GodotShape3D { real_t height = 0.0; real_t radius = 0.0; @@ -272,10 +272,10 @@ public: virtual void set_data(const Variant &p_data) override; virtual Variant get_data() const override; - CylinderShape3DSW(); + GodotCylinderShape3D(); }; -struct ConvexPolygonShape3DSW : public Shape3DSW { +struct GodotConvexPolygonShape3D : public GodotShape3D { Geometry3D::MeshData mesh; void _setup(const Vector<Vector3> &p_vertices); @@ -297,13 +297,13 @@ public: virtual void set_data(const Variant &p_data) override; virtual Variant get_data() const override; - ConvexPolygonShape3DSW(); + GodotConvexPolygonShape3D(); }; -struct _VolumeSW_BVH; -struct FaceShape3DSW; +struct _Volume_BVH; +struct GodotFaceShape3D; -struct ConcavePolygonShape3DSW : public ConcaveShape3DSW { +struct GodotConcavePolygonShape3D : public GodotConcaveShape3D { // always a trimesh struct Face { @@ -331,7 +331,7 @@ struct ConcavePolygonShape3DSW : public ConcaveShape3DSW { const Face *faces = nullptr; const Vector3 *vertices = nullptr; const BVH *bvh = nullptr; - FaceShape3DSW *face = nullptr; + GodotFaceShape3D *face = nullptr; }; struct _SegmentCullParams { @@ -341,7 +341,7 @@ struct ConcavePolygonShape3DSW : public ConcaveShape3DSW { const Face *faces = nullptr; const Vector3 *vertices = nullptr; const BVH *bvh = nullptr; - FaceShape3DSW *face = nullptr; + GodotFaceShape3D *face = nullptr; Vector3 result; Vector3 normal; @@ -354,7 +354,7 @@ struct ConcavePolygonShape3DSW : public ConcaveShape3DSW { void _cull_segment(int p_idx, _SegmentCullParams *p_params) const; bool _cull(int p_idx, _CullParams *p_params) const; - void _fill_bvh(_VolumeSW_BVH *p_bvh_tree, BVH *p_bvh_array, int &p_idx); + void _fill_bvh(_Volume_BVH *p_bvh_tree, BVH *p_bvh_array, int &p_idx); void _setup(const Vector<Vector3> &p_faces, bool p_backface_collision); @@ -377,10 +377,10 @@ public: virtual void set_data(const Variant &p_data) override; virtual Variant get_data() const override; - ConcavePolygonShape3DSW(); + GodotConcavePolygonShape3D(); }; -struct HeightMapShape3DSW : public ConcaveShape3DSW { +struct GodotHeightMapShape3D : public GodotConcaveShape3D { Vector<real_t> heights; int width = 0; int depth = 0; @@ -440,11 +440,11 @@ public: virtual void set_data(const Variant &p_data) override; virtual Variant get_data() const override; - HeightMapShape3DSW(); + GodotHeightMapShape3D(); }; //used internally -struct FaceShape3DSW : public Shape3DSW { +struct GodotFaceShape3D : public GodotShape3D { Vector3 normal; //cache Vector3 vertex[3]; bool backface_collision = false; @@ -465,11 +465,11 @@ struct FaceShape3DSW : public Shape3DSW { virtual void set_data(const Variant &p_data) override {} virtual Variant get_data() const override { return Variant(); } - FaceShape3DSW(); + GodotFaceShape3D(); }; -struct MotionShape3DSW : public Shape3DSW { - Shape3DSW *shape = nullptr; +struct GodotMotionShape3D : public GodotShape3D { + GodotShape3D *shape = nullptr; Vector3 motion; virtual PhysicsServer3D::ShapeType get_type() const override { return PhysicsServer3D::SHAPE_CONVEX_POLYGON; } @@ -504,7 +504,7 @@ struct MotionShape3DSW : public Shape3DSW { virtual void set_data(const Variant &p_data) override {} virtual Variant get_data() const override { return Variant(); } - MotionShape3DSW() { configure(AABB()); } + GodotMotionShape3D() { configure(AABB()); } }; -#endif // SHAPE_SW_H +#endif // GODOT_SHAPE_3D_H diff --git a/servers/physics_3d/soft_body_3d_sw.cpp b/servers/physics_3d/godot_soft_body_3d.cpp index c9166810fe..d15235d27c 100644 --- a/servers/physics_3d/soft_body_3d_sw.cpp +++ b/servers/physics_3d/godot_soft_body_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* soft_body_3d_sw.cpp */ +/* godot_soft_body_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "soft_body_3d_sw.h" -#include "space_3d_sw.h" +#include "godot_soft_body_3d.h" + +#include "godot_space_3d.h" #include "core/math/geometry_3d.h" #include "core/templates/map.h" @@ -53,16 +54,16 @@ subject to the following restrictions: */ ///btSoftBody implementation by Nathanael Presson -SoftBody3DSW::SoftBody3DSW() : - CollisionObject3DSW(TYPE_SOFT_BODY), +GodotSoftBody3D::GodotSoftBody3D() : + GodotCollisionObject3D(TYPE_SOFT_BODY), active_list(this) { _set_static(false); } -void SoftBody3DSW::_shapes_changed() { +void GodotSoftBody3D::_shapes_changed() { } -void SoftBody3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) { +void GodotSoftBody3D::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) { switch (p_state) { case PhysicsServer3D::BODY_STATE_TRANSFORM: { _set_transform(p_variant); @@ -87,7 +88,7 @@ void SoftBody3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant & } } -Variant SoftBody3DSW::get_state(PhysicsServer3D::BodyState p_state) const { +Variant GodotSoftBody3D::get_state(PhysicsServer3D::BodyState p_state) const { switch (p_state) { case PhysicsServer3D::BODY_STATE_TRANSFORM: { return get_transform(); @@ -110,7 +111,7 @@ Variant SoftBody3DSW::get_state(PhysicsServer3D::BodyState p_state) const { return Variant(); } -void SoftBody3DSW::set_space(Space3DSW *p_space) { +void GodotSoftBody3D::set_space(GodotSpace3D *p_space) { if (get_space()) { get_space()->soft_body_remove_from_active_list(&active_list); @@ -128,7 +129,7 @@ void SoftBody3DSW::set_space(Space3DSW *p_space) { } } -void SoftBody3DSW::set_mesh(RID p_mesh) { +void GodotSoftBody3D::set_mesh(RID p_mesh) { destroy(); soft_mesh = p_mesh; @@ -145,7 +146,7 @@ void SoftBody3DSW::set_mesh(RID p_mesh) { } } -void SoftBody3DSW::update_rendering_server(RenderingServerHandler *p_rendering_server_handler) { +void GodotSoftBody3D::update_rendering_server(RenderingServerHandler *p_rendering_server_handler) { if (soft_mesh.is_null()) { return; } @@ -164,7 +165,7 @@ void SoftBody3DSW::update_rendering_server(RenderingServerHandler *p_rendering_s p_rendering_server_handler->set_aabb(bounds); } -void SoftBody3DSW::update_normals_and_centroids() { +void GodotSoftBody3D::update_normals_and_centroids() { uint32_t i, ni; for (i = 0, ni = nodes.size(); i < ni; ++i) { @@ -191,7 +192,7 @@ void SoftBody3DSW::update_normals_and_centroids() { } } -void SoftBody3DSW::update_bounds() { +void GodotSoftBody3D::update_bounds() { AABB prev_bounds = bounds; prev_bounds.grow_by(collision_margin); @@ -223,13 +224,13 @@ void SoftBody3DSW::update_bounds() { } } -void SoftBody3DSW::update_constants() { +void GodotSoftBody3D::update_constants() { reset_link_rest_lengths(); update_link_constants(); update_area(); } -void SoftBody3DSW::update_area() { +void GodotSoftBody3D::update_area() { int i, ni; // Face area. @@ -275,7 +276,7 @@ void SoftBody3DSW::update_area() { } } -void SoftBody3DSW::reset_link_rest_lengths() { +void GodotSoftBody3D::reset_link_rest_lengths() { for (uint32_t i = 0, ni = links.size(); i < ni; ++i) { Link &link = links[i]; link.rl = (link.n[0]->x - link.n[1]->x).length(); @@ -283,7 +284,7 @@ void SoftBody3DSW::reset_link_rest_lengths() { } } -void SoftBody3DSW::update_link_constants() { +void GodotSoftBody3D::update_link_constants() { real_t inv_linear_stiffness = 1.0 / linear_stiffness; for (uint32_t i = 0, ni = links.size(); i < ni; ++i) { Link &link = links[i]; @@ -291,7 +292,7 @@ void SoftBody3DSW::update_link_constants() { } } -void SoftBody3DSW::apply_nodes_transform(const Transform3D &p_transform) { +void GodotSoftBody3D::apply_nodes_transform(const Transform3D &p_transform) { if (soft_mesh.is_null()) { return; } @@ -317,7 +318,7 @@ void SoftBody3DSW::apply_nodes_transform(const Transform3D &p_transform) { update_constants(); } -Vector3 SoftBody3DSW::get_vertex_position(int p_index) const { +Vector3 GodotSoftBody3D::get_vertex_position(int p_index) const { ERR_FAIL_COND_V(p_index < 0, Vector3()); if (soft_mesh.is_null()) { @@ -331,7 +332,7 @@ Vector3 SoftBody3DSW::get_vertex_position(int p_index) const { return nodes[node_index].x; } -void SoftBody3DSW::set_vertex_position(int p_index, const Vector3 &p_position) { +void GodotSoftBody3D::set_vertex_position(int p_index, const Vector3 &p_position) { ERR_FAIL_COND(p_index < 0); if (soft_mesh.is_null()) { @@ -347,7 +348,7 @@ void SoftBody3DSW::set_vertex_position(int p_index, const Vector3 &p_position) { node.x = p_position; } -void SoftBody3DSW::pin_vertex(int p_index) { +void GodotSoftBody3D::pin_vertex(int p_index) { ERR_FAIL_COND(p_index < 0); if (is_vertex_pinned(p_index)) { @@ -366,7 +367,7 @@ void SoftBody3DSW::pin_vertex(int p_index) { } } -void SoftBody3DSW::unpin_vertex(int p_index) { +void GodotSoftBody3D::unpin_vertex(int p_index) { ERR_FAIL_COND(p_index < 0); uint32_t pinned_count = pinned_vertices.size(); @@ -390,7 +391,7 @@ void SoftBody3DSW::unpin_vertex(int p_index) { } } -void SoftBody3DSW::unpin_all_vertices() { +void GodotSoftBody3D::unpin_all_vertices() { if (!soft_mesh.is_null()) { real_t inv_node_mass = nodes.size() * inv_total_mass; uint32_t pinned_count = pinned_vertices.size(); @@ -409,7 +410,7 @@ void SoftBody3DSW::unpin_all_vertices() { pinned_vertices.clear(); } -bool SoftBody3DSW::is_vertex_pinned(int p_index) const { +bool GodotSoftBody3D::is_vertex_pinned(int p_index) const { ERR_FAIL_COND_V(p_index < 0, false); uint32_t pinned_count = pinned_vertices.size(); @@ -422,47 +423,47 @@ bool SoftBody3DSW::is_vertex_pinned(int p_index) const { return false; } -uint32_t SoftBody3DSW::get_node_count() const { +uint32_t GodotSoftBody3D::get_node_count() const { return nodes.size(); } -real_t SoftBody3DSW::get_node_inv_mass(uint32_t p_node_index) const { +real_t GodotSoftBody3D::get_node_inv_mass(uint32_t p_node_index) const { ERR_FAIL_COND_V(p_node_index >= nodes.size(), 0.0); return nodes[p_node_index].im; } -Vector3 SoftBody3DSW::get_node_position(uint32_t p_node_index) const { +Vector3 GodotSoftBody3D::get_node_position(uint32_t p_node_index) const { ERR_FAIL_COND_V(p_node_index >= nodes.size(), Vector3()); return nodes[p_node_index].x; } -Vector3 SoftBody3DSW::get_node_velocity(uint32_t p_node_index) const { +Vector3 GodotSoftBody3D::get_node_velocity(uint32_t p_node_index) const { ERR_FAIL_COND_V(p_node_index >= nodes.size(), Vector3()); return nodes[p_node_index].v; } -Vector3 SoftBody3DSW::get_node_biased_velocity(uint32_t p_node_index) const { +Vector3 GodotSoftBody3D::get_node_biased_velocity(uint32_t p_node_index) const { ERR_FAIL_COND_V(p_node_index >= nodes.size(), Vector3()); return nodes[p_node_index].bv; } -void SoftBody3DSW::apply_node_impulse(uint32_t p_node_index, const Vector3 &p_impulse) { +void GodotSoftBody3D::apply_node_impulse(uint32_t p_node_index, const Vector3 &p_impulse) { ERR_FAIL_COND(p_node_index >= nodes.size()); Node &node = nodes[p_node_index]; node.v += p_impulse * node.im; } -void SoftBody3DSW::apply_node_bias_impulse(uint32_t p_node_index, const Vector3 &p_impulse) { +void GodotSoftBody3D::apply_node_bias_impulse(uint32_t p_node_index, const Vector3 &p_impulse) { ERR_FAIL_COND(p_node_index >= nodes.size()); Node &node = nodes[p_node_index]; node.bv += p_impulse * node.im; } -uint32_t SoftBody3DSW::get_face_count() const { +uint32_t GodotSoftBody3D::get_face_count() const { return faces.size(); } -void SoftBody3DSW::get_face_points(uint32_t p_face_index, Vector3 &r_point_1, Vector3 &r_point_2, Vector3 &r_point_3) const { +void GodotSoftBody3D::get_face_points(uint32_t p_face_index, Vector3 &r_point_1, Vector3 &r_point_2, Vector3 &r_point_3) const { ERR_FAIL_COND(p_face_index >= faces.size()); const Face &face = faces[p_face_index]; r_point_1 = face.n[0]->x; @@ -470,12 +471,12 @@ void SoftBody3DSW::get_face_points(uint32_t p_face_index, Vector3 &r_point_1, Ve r_point_3 = face.n[2]->x; } -Vector3 SoftBody3DSW::get_face_normal(uint32_t p_face_index) const { +Vector3 GodotSoftBody3D::get_face_normal(uint32_t p_face_index) const { ERR_FAIL_COND_V(p_face_index >= faces.size(), Vector3()); return faces[p_face_index].normal; } -bool SoftBody3DSW::create_from_trimesh(const Vector<int> &p_indices, const Vector<Vector3> &p_vertices) { +bool GodotSoftBody3D::create_from_trimesh(const Vector<int> &p_indices, const Vector<Vector3> &p_vertices) { ERR_FAIL_COND_V(p_indices.is_empty(), false); ERR_FAIL_COND_V(p_vertices.is_empty(), false); @@ -595,7 +596,7 @@ bool SoftBody3DSW::create_from_trimesh(const Vector<int> &p_indices, const Vecto return true; } -void SoftBody3DSW::generate_bending_constraints(int p_distance) { +void GodotSoftBody3D::generate_bending_constraints(int p_distance) { uint32_t i, j; if (p_distance > 1) { @@ -714,7 +715,7 @@ public: }; typedef LinkDeps *LinkDepsPtr; -void SoftBody3DSW::reoptimize_link_order() { +void GodotSoftBody3D::reoptimize_link_order() { const int reop_not_dependent = -1; const int reop_node_complete = -2; @@ -823,7 +824,7 @@ void SoftBody3DSW::reoptimize_link_order() { memdelete_arr(link_buffer); } -void SoftBody3DSW::append_link(uint32_t p_node1, uint32_t p_node2) { +void GodotSoftBody3D::append_link(uint32_t p_node1, uint32_t p_node2) { if (p_node1 == p_node2) { return; } @@ -839,7 +840,7 @@ void SoftBody3DSW::append_link(uint32_t p_node1, uint32_t p_node2) { links.push_back(link); } -void SoftBody3DSW::append_face(uint32_t p_node1, uint32_t p_node2, uint32_t p_node3) { +void GodotSoftBody3D::append_face(uint32_t p_node1, uint32_t p_node2, uint32_t p_node3) { if (p_node1 == p_node2) { return; } @@ -864,11 +865,11 @@ void SoftBody3DSW::append_face(uint32_t p_node1, uint32_t p_node2, uint32_t p_no faces.push_back(face); } -void SoftBody3DSW::set_iteration_count(int p_val) { +void GodotSoftBody3D::set_iteration_count(int p_val) { iteration_count = p_val; } -void SoftBody3DSW::set_total_mass(real_t p_val) { +void GodotSoftBody3D::set_total_mass(real_t p_val) { ERR_FAIL_COND(p_val < 0.0); inv_total_mass = 1.0 / p_val; @@ -884,27 +885,27 @@ void SoftBody3DSW::set_total_mass(real_t p_val) { update_constants(); } -void SoftBody3DSW::set_collision_margin(real_t p_val) { +void GodotSoftBody3D::set_collision_margin(real_t p_val) { collision_margin = p_val; } -void SoftBody3DSW::set_linear_stiffness(real_t p_val) { +void GodotSoftBody3D::set_linear_stiffness(real_t p_val) { linear_stiffness = p_val; } -void SoftBody3DSW::set_pressure_coefficient(real_t p_val) { +void GodotSoftBody3D::set_pressure_coefficient(real_t p_val) { pressure_coefficient = p_val; } -void SoftBody3DSW::set_damping_coefficient(real_t p_val) { +void GodotSoftBody3D::set_damping_coefficient(real_t p_val) { damping_coefficient = p_val; } -void SoftBody3DSW::set_drag_coefficient(real_t p_val) { +void GodotSoftBody3D::set_drag_coefficient(real_t p_val) { drag_coefficient = p_val; } -void SoftBody3DSW::add_velocity(const Vector3 &p_velocity) { +void GodotSoftBody3D::add_velocity(const Vector3 &p_velocity) { for (uint32_t i = 0, ni = nodes.size(); i < ni; ++i) { Node &node = nodes[i]; if (node.im > 0) { @@ -913,7 +914,7 @@ void SoftBody3DSW::add_velocity(const Vector3 &p_velocity) { } } -void SoftBody3DSW::apply_forces(bool p_has_wind_forces) { +void GodotSoftBody3D::apply_forces(bool p_has_wind_forces) { int ac = areas.size(); if (nodes.is_empty()) { @@ -977,13 +978,13 @@ void SoftBody3DSW::apply_forces(bool p_has_wind_forces) { } } -void SoftBody3DSW::_compute_area_gravity(const Area3DSW *p_area) { +void GodotSoftBody3D::_compute_area_gravity(const GodotArea3D *p_area) { Vector3 area_gravity; p_area->compute_gravity(get_transform().get_origin(), area_gravity); gravity += area_gravity; } -Vector3 SoftBody3DSW::_compute_area_windforce(const Area3DSW *p_area, const Face *p_face) { +Vector3 GodotSoftBody3D::_compute_area_windforce(const GodotArea3D *p_area, const Face *p_face) { real_t wfm = p_area->get_wind_force_magnitude(); real_t waf = p_area->get_wind_attenuation_factor(); const Vector3 &wd = p_area->get_wind_direction(); @@ -995,12 +996,12 @@ Vector3 SoftBody3DSW::_compute_area_windforce(const Area3DSW *p_area, const Face return nodal_force_magnitude * p_face->normal; } -void SoftBody3DSW::predict_motion(real_t p_delta) { +void GodotSoftBody3D::predict_motion(real_t p_delta) { const real_t inv_delta = 1.0 / p_delta; ERR_FAIL_COND(!get_space()); - Area3DSW *def_area = get_space()->get_default_area(); + GodotArea3D *def_area = get_space()->get_default_area(); ERR_FAIL_COND(!def_area); gravity = def_area->get_gravity_vector() * def_area->get_gravity(); @@ -1083,7 +1084,7 @@ void SoftBody3DSW::predict_motion(real_t p_delta) { face_tree.optimize_incremental(1); } -void SoftBody3DSW::solve_constraints(real_t p_delta) { +void GodotSoftBody3D::solve_constraints(real_t p_delta) { const real_t inv_delta = 1.0 / p_delta; uint32_t i, ni; @@ -1120,7 +1121,7 @@ void SoftBody3DSW::solve_constraints(real_t p_delta) { update_normals_and_centroids(); } -void SoftBody3DSW::solve_links(real_t kst, real_t ti) { +void GodotSoftBody3D::solve_links(real_t kst, real_t ti) { for (uint32_t i = 0, ni = links.size(); i < ni; ++i) { Link &link = links[i]; if (link.c0 > 0) { @@ -1138,16 +1139,16 @@ void SoftBody3DSW::solve_links(real_t kst, real_t ti) { } struct AABBQueryResult { - const SoftBody3DSW *soft_body = nullptr; + const GodotSoftBody3D *soft_body = nullptr; void *userdata = nullptr; - SoftBody3DSW::QueryResultCallback result_callback = nullptr; + GodotSoftBody3D::QueryResultCallback result_callback = nullptr; _FORCE_INLINE_ bool operator()(void *p_data) { return result_callback(soft_body->get_node_index(p_data), userdata); }; }; -void SoftBody3DSW::query_aabb(const AABB &p_aabb, SoftBody3DSW::QueryResultCallback p_result_callback, void *p_userdata) { +void GodotSoftBody3D::query_aabb(const AABB &p_aabb, GodotSoftBody3D::QueryResultCallback p_result_callback, void *p_userdata) { AABBQueryResult query_result; query_result.soft_body = this; query_result.result_callback = p_result_callback; @@ -1157,16 +1158,16 @@ void SoftBody3DSW::query_aabb(const AABB &p_aabb, SoftBody3DSW::QueryResultCallb } struct RayQueryResult { - const SoftBody3DSW *soft_body = nullptr; + const GodotSoftBody3D *soft_body = nullptr; void *userdata = nullptr; - SoftBody3DSW::QueryResultCallback result_callback = nullptr; + GodotSoftBody3D::QueryResultCallback result_callback = nullptr; _FORCE_INLINE_ bool operator()(void *p_data) { return result_callback(soft_body->get_face_index(p_data), userdata); }; }; -void SoftBody3DSW::query_ray(const Vector3 &p_from, const Vector3 &p_to, SoftBody3DSW::QueryResultCallback p_result_callback, void *p_userdata) { +void GodotSoftBody3D::query_ray(const Vector3 &p_from, const Vector3 &p_to, GodotSoftBody3D::QueryResultCallback p_result_callback, void *p_userdata) { if (face_tree.is_empty()) { initialize_face_tree(); } @@ -1179,7 +1180,7 @@ void SoftBody3DSW::query_ray(const Vector3 &p_from, const Vector3 &p_to, SoftBod face_tree.ray_query(p_from, p_to, query_result); } -void SoftBody3DSW::initialize_face_tree() { +void GodotSoftBody3D::initialize_face_tree() { face_tree.clear(); for (uint32_t i = 0; i < faces.size(); ++i) { Face &face = faces[i]; @@ -1196,7 +1197,7 @@ void SoftBody3DSW::initialize_face_tree() { } } -void SoftBody3DSW::update_face_tree(real_t p_delta) { +void GodotSoftBody3D::update_face_tree(real_t p_delta) { for (uint32_t i = 0; i < faces.size(); ++i) { const Face &face = faces[i]; @@ -1220,25 +1221,25 @@ void SoftBody3DSW::update_face_tree(real_t p_delta) { } } -void SoftBody3DSW::initialize_shape(bool p_force_move) { +void GodotSoftBody3D::initialize_shape(bool p_force_move) { if (get_shape_count() == 0) { - SoftBodyShape3DSW *soft_body_shape = memnew(SoftBodyShape3DSW(this)); + GodotSoftBodyShape3D *soft_body_shape = memnew(GodotSoftBodyShape3D(this)); add_shape(soft_body_shape); } else if (p_force_move) { - SoftBodyShape3DSW *soft_body_shape = static_cast<SoftBodyShape3DSW *>(get_shape(0)); + GodotSoftBodyShape3D *soft_body_shape = static_cast<GodotSoftBodyShape3D *>(get_shape(0)); soft_body_shape->update_bounds(); } } -void SoftBody3DSW::deinitialize_shape() { +void GodotSoftBody3D::deinitialize_shape() { if (get_shape_count() > 0) { - Shape3DSW *shape = get_shape(0); + GodotShape3D *shape = get_shape(0); remove_shape(shape); memdelete(shape); } } -void SoftBody3DSW::destroy() { +void GodotSoftBody3D::destroy() { soft_mesh = RID(); map_visual_to_physics.clear(); @@ -1254,7 +1255,7 @@ void SoftBody3DSW::destroy() { deinitialize_shape(); } -void SoftBodyShape3DSW::update_bounds() { +void GodotSoftBodyShape3D::update_bounds() { ERR_FAIL_COND(!soft_body); AABB collision_aabb = soft_body->get_bounds(); @@ -1262,13 +1263,13 @@ void SoftBodyShape3DSW::update_bounds() { configure(collision_aabb); } -SoftBodyShape3DSW::SoftBodyShape3DSW(SoftBody3DSW *p_soft_body) { +GodotSoftBodyShape3D::GodotSoftBodyShape3D(GodotSoftBody3D *p_soft_body) { soft_body = p_soft_body; update_bounds(); } struct _SoftBodyIntersectSegmentInfo { - const SoftBody3DSW *soft_body = nullptr; + const GodotSoftBody3D *soft_body = nullptr; Vector3 from; Vector3 dir; Vector3 hit_position; @@ -1296,7 +1297,7 @@ struct _SoftBodyIntersectSegmentInfo { } }; -bool SoftBodyShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { +bool GodotSoftBodyShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { _SoftBodyIntersectSegmentInfo query_info; query_info.soft_body = soft_body; query_info.from = p_begin; @@ -1313,10 +1314,10 @@ bool SoftBodyShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 return false; } -bool SoftBodyShape3DSW::intersect_point(const Vector3 &p_point) const { +bool GodotSoftBodyShape3D::intersect_point(const Vector3 &p_point) const { return false; } -Vector3 SoftBodyShape3DSW::get_closest_point_to(const Vector3 &p_point) const { +Vector3 GodotSoftBodyShape3D::get_closest_point_to(const Vector3 &p_point) const { ERR_FAIL_V_MSG(Vector3(), "Get closest point is not supported for soft bodies."); } diff --git a/servers/physics_3d/soft_body_3d_sw.h b/servers/physics_3d/godot_soft_body_3d.h index 7d4b83d0ee..008d5dddb8 100644 --- a/servers/physics_3d/soft_body_3d_sw.h +++ b/servers/physics_3d/godot_soft_body_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* soft_body_3d_sw.h */ +/* godot_soft_body_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SOFT_BODY_3D_SW_H -#define SOFT_BODY_3D_SW_H +#ifndef GODOT_SOFT_BODY_3D_H +#define GODOT_SOFT_BODY_3D_H -#include "area_3d_sw.h" -#include "collision_object_3d_sw.h" +#include "godot_area_3d.h" +#include "godot_collision_object_3d.h" #include "core/math/aabb.h" #include "core/math/dynamic_bvh.h" @@ -41,9 +41,9 @@ #include "core/templates/set.h" #include "core/templates/vset.h" -class Constraint3DSW; +class GodotConstraint3D; -class SoftBody3DSW : public CollisionObject3DSW { +class GodotSoftBody3D : public GodotCollisionObject3D { RID soft_mesh; struct Node { @@ -103,9 +103,9 @@ class SoftBody3DSW : public CollisionObject3DSW { Vector3 gravity; - SelfList<SoftBody3DSW> active_list; + SelfList<GodotSoftBody3D> active_list; - Set<Constraint3DSW *> constraints; + Set<GodotConstraint3D *> constraints; Vector<AreaCMP> areas; @@ -113,20 +113,20 @@ class SoftBody3DSW : public CollisionObject3DSW { uint64_t island_step = 0; - _FORCE_INLINE_ void _compute_area_gravity(const Area3DSW *p_area); - _FORCE_INLINE_ Vector3 _compute_area_windforce(const Area3DSW *p_area, const Face *p_face); + _FORCE_INLINE_ void _compute_area_gravity(const GodotArea3D *p_area); + _FORCE_INLINE_ Vector3 _compute_area_windforce(const GodotArea3D *p_area, const Face *p_face); public: - SoftBody3DSW(); + GodotSoftBody3D(); const AABB &get_bounds() const { return bounds; } void set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant); Variant get_state(PhysicsServer3D::BodyState p_state) const; - _FORCE_INLINE_ void add_constraint(Constraint3DSW *p_constraint) { constraints.insert(p_constraint); } - _FORCE_INLINE_ void remove_constraint(Constraint3DSW *p_constraint) { constraints.erase(p_constraint); } - _FORCE_INLINE_ const Set<Constraint3DSW *> &get_constraints() const { return constraints; } + _FORCE_INLINE_ void add_constraint(GodotConstraint3D *p_constraint) { constraints.insert(p_constraint); } + _FORCE_INLINE_ void remove_constraint(GodotConstraint3D *p_constraint) { constraints.erase(p_constraint); } + _FORCE_INLINE_ const Set<GodotConstraint3D *> &get_constraints() const { return constraints; } _FORCE_INLINE_ void clear_constraints() { constraints.clear(); } _FORCE_INLINE_ void add_exception(const RID &p_exception) { exceptions.insert(p_exception); } @@ -137,7 +137,7 @@ public: _FORCE_INLINE_ uint64_t get_island_step() const { return island_step; } _FORCE_INLINE_ void set_island_step(uint64_t p_step) { island_step = p_step; } - _FORCE_INLINE_ void add_area(Area3DSW *p_area) { + _FORCE_INLINE_ void add_area(GodotArea3D *p_area) { int index = areas.find(AreaCMP(p_area)); if (index > -1) { areas.write[index].refCount += 1; @@ -146,7 +146,7 @@ public: } } - _FORCE_INLINE_ void remove_area(Area3DSW *p_area) { + _FORCE_INLINE_ void remove_area(GodotArea3D *p_area) { int index = areas.find(AreaCMP(p_area)); if (index > -1) { areas.write[index].refCount -= 1; @@ -156,7 +156,7 @@ public: } } - virtual void set_space(Space3DSW *p_space); + virtual void set_space(GodotSpace3D *p_space); void set_mesh(RID p_mesh); @@ -251,11 +251,11 @@ private: void destroy(); }; -class SoftBodyShape3DSW : public Shape3DSW { - SoftBody3DSW *soft_body = nullptr; +class GodotSoftBodyShape3D : public GodotShape3D { + GodotSoftBody3D *soft_body = nullptr; public: - SoftBody3DSW *get_soft_body() const { return soft_body; } + GodotSoftBody3D *get_soft_body() const { return soft_body; } virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_SOFT_BODY; } virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { r_min = r_max = 0.0; } @@ -272,8 +272,8 @@ public: void update_bounds(); - SoftBodyShape3DSW(SoftBody3DSW *p_soft_body); - ~SoftBodyShape3DSW() {} + GodotSoftBodyShape3D(GodotSoftBody3D *p_soft_body); + ~GodotSoftBodyShape3D() {} }; -#endif // SOFT_BODY_3D_SW_H +#endif // GODOT_SOFT_BODY_3D_H diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/godot_space_3d.cpp index c88747c017..750bf3a16d 100644 --- a/servers/physics_3d/space_3d_sw.cpp +++ b/servers/physics_3d/godot_space_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* space_3d_sw.cpp */ +/* godot_space_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,37 +28,38 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "space_3d_sw.h" +#include "godot_space_3d.h" + +#include "godot_collision_solver_3d.h" +#include "godot_physics_server_3d.h" -#include "collision_solver_3d_sw.h" #include "core/config/project_settings.h" -#include "physics_server_3d_sw.h" #define TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR 0.05 -_FORCE_INLINE_ static bool _can_collide_with(CollisionObject3DSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +_FORCE_INLINE_ static bool _can_collide_with(GodotCollisionObject3D *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (!(p_object->get_collision_layer() & p_collision_mask)) { return false; } - if (p_object->get_type() == CollisionObject3DSW::TYPE_AREA && !p_collide_with_areas) { + if (p_object->get_type() == GodotCollisionObject3D::TYPE_AREA && !p_collide_with_areas) { return false; } - if (p_object->get_type() == CollisionObject3DSW::TYPE_BODY && !p_collide_with_bodies) { + if (p_object->get_type() == GodotCollisionObject3D::TYPE_BODY && !p_collide_with_bodies) { return false; } - if (p_object->get_type() == CollisionObject3DSW::TYPE_SOFT_BODY && !p_collide_with_bodies) { + if (p_object->get_type() == GodotCollisionObject3D::TYPE_SOFT_BODY && !p_collide_with_bodies) { return false; } return true; } -int PhysicsDirectSpaceState3DSW::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +int GodotPhysicsDirectSpaceState3D::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { ERR_FAIL_COND_V(space->locked, false); - int amount = space->broadphase->cull_point(p_point, space->intersection_query_results, Space3DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); + int amount = space->broadphase->cull_point(p_point, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int cc = 0; //Transform3D ai = p_xform.affine_inverse(); @@ -78,7 +79,7 @@ int PhysicsDirectSpaceState3DSW::intersect_point(const Vector3 &p_point, ShapeRe continue; } - const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; + const GodotCollisionObject3D *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; Transform3D inv_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); @@ -103,7 +104,7 @@ int PhysicsDirectSpaceState3DSW::intersect_point(const Vector3 &p_point, ShapeRe return cc; } -bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_ray) { +bool GodotPhysicsDirectSpaceState3D::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_ray) { ERR_FAIL_COND_V(space->locked, false); Vector3 begin, end; @@ -112,14 +113,14 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec end = p_to; normal = (end - begin).normalized(); - int amount = space->broadphase->cull_segment(begin, end, space->intersection_query_results, Space3DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); + int amount = space->broadphase->cull_segment(begin, end, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); //todo, create another array that references results, compute AABBs and check closest point to ray origin, sort, and stop evaluating results when beyond first collision bool collided = false; Vector3 res_point, res_normal; int res_shape; - const CollisionObject3DSW *res_obj; + const GodotCollisionObject3D *res_obj; real_t min_d = 1e10; for (int i = 0; i < amount; i++) { @@ -135,7 +136,7 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec continue; } - const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; + const GodotCollisionObject3D *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; Transform3D inv_xform = col_obj->get_shape_inv_transform(shape_idx) * col_obj->get_inv_transform(); @@ -143,7 +144,7 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec Vector3 local_from = inv_xform.xform(begin); Vector3 local_to = inv_xform.xform(end); - const Shape3DSW *shape = col_obj->get_shape(shape_idx); + const GodotShape3D *shape = col_obj->get_shape(shape_idx); Vector3 shape_point, shape_normal; @@ -182,17 +183,17 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec return true; } -int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Transform3D &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +int GodotPhysicsDirectSpaceState3D::intersect_shape(const RID &p_shape, const Transform3D &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) { return 0; } - Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.get_or_null(p_shape); + GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); AABB aabb = p_xform.xform(shape->get_aabb()); - int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space3DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); + int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int cc = 0; @@ -213,10 +214,10 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans continue; } - const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; + const GodotCollisionObject3D *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; - if (!CollisionSolver3DSW::solve_static(shape, p_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), nullptr, nullptr, nullptr, p_margin, 0)) { + if (!GodotCollisionSolver3D::solve_static(shape, p_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), nullptr, nullptr, nullptr, p_margin, 0)) { continue; } @@ -237,21 +238,21 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans return cc; } -bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transform3D &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { - Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.get_or_null(p_shape); +bool GodotPhysicsDirectSpaceState3D::cast_motion(const RID &p_shape, const Transform3D &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { + GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, false); AABB aabb = p_xform.xform(shape->get_aabb()); aabb = aabb.merge(AABB(aabb.position + p_motion, aabb.size)); //motion aabb = aabb.grow(p_margin); - int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space3DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); + int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); real_t best_safe = 1; real_t best_unsafe = 1; Transform3D xform_inv = p_xform.affine_inverse(); - MotionShape3DSW mshape; + GodotMotionShape3D mshape; mshape.shape = shape; mshape.motion = xform_inv.basis.xform(p_motion); @@ -270,7 +271,7 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor continue; //ignore excluded } - const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; + const GodotCollisionObject3D *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; Vector3 point_A, point_B; @@ -278,14 +279,14 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor Transform3D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? - if (CollisionSolver3DSW::solve_distance(&mshape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) { + if (GodotCollisionSolver3D::solve_distance(&mshape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) { continue; } //test initial overlap, ignore objects it's inside of. sep_axis = motion_normal; - if (!CollisionSolver3DSW::solve_distance(shape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) { + if (!GodotCollisionSolver3D::solve_distance(shape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) { continue; } @@ -300,7 +301,7 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor Vector3 lA, lB; Vector3 sep = motion_normal; //important optimization for this to work fast enough - bool collided = !CollisionSolver3DSW::solve_distance(&mshape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, aabb, &sep); + bool collided = !GodotCollisionSolver3D::solve_distance(&mshape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, aabb, &sep); if (collided) { hi = fraction; @@ -342,8 +343,8 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor r_info->point = closest_B; r_info->normal = (closest_A - closest_B).normalized(); best_first = false; - if (col_obj->get_type() == CollisionObject3DSW::TYPE_BODY) { - const Body3DSW *body = static_cast<const Body3DSW *>(col_obj); + if (col_obj->get_type() == GodotCollisionObject3D::TYPE_BODY) { + const GodotBody3D *body = static_cast<const GodotBody3D *>(col_obj); Vector3 rel_vec = closest_B - (body->get_transform().origin + body->get_center_of_mass()); r_info->linear_velocity = body->get_linear_velocity() + (body->get_angular_velocity()).cross(rel_vec); } @@ -356,36 +357,36 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor return true; } -bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +bool GodotPhysicsDirectSpaceState3D::collide_shape(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) { return false; } - Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.get_or_null(p_shape); + GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); AABB aabb = p_shape_xform.xform(shape->get_aabb()); aabb = aabb.grow(p_margin); - int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space3DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); + int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); bool collided = false; r_result_count = 0; - PhysicsServer3DSW::CollCbkData cbk; + GodotPhysicsServer3D::CollCbkData cbk; cbk.max = p_result_max; cbk.amount = 0; cbk.ptr = r_results; - CollisionSolver3DSW::CallbackResult cbkres = PhysicsServer3DSW::_shape_col_cbk; + GodotCollisionSolver3D::CallbackResult cbkres = GodotPhysicsServer3D::_shape_col_cbk; - PhysicsServer3DSW::CollCbkData *cbkptr = &cbk; + GodotPhysicsServer3D::CollCbkData *cbkptr = &cbk; for (int i = 0; i < amount; i++) { if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { continue; } - const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; + const GodotCollisionObject3D *col_obj = space->intersection_query_results[i]; if (p_exclude.has(col_obj->get_self())) { continue; @@ -393,7 +394,7 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform3D & int shape_idx = space->intersection_query_subindex_results[i]; - if (CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_margin)) { + if (GodotCollisionSolver3D::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_margin)) { collided = true; } } @@ -404,7 +405,7 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform3D & } struct _RestResultData { - const CollisionObject3DSW *object = nullptr; + const GodotCollisionObject3D *object = nullptr; int local_shape = 0; int shape = 0; Vector3 contact; @@ -413,7 +414,7 @@ struct _RestResultData { }; struct _RestCallbackData { - const CollisionObject3DSW *object = nullptr; + const GodotCollisionObject3D *object = nullptr; int local_shape = 0; int shape = 0; @@ -486,8 +487,8 @@ static void _rest_cbk_result(const Vector3 &p_point_A, int p_index_A, const Vect rd->best_result.local_shape = rd->local_shape; } -bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.get_or_null(p_shape); +bool GodotPhysicsDirectSpaceState3D::rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { + GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR; @@ -495,7 +496,7 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform3D &p_sh AABB aabb = p_shape_xform.xform(shape->get_aabb()); aabb = aabb.grow(p_margin); - int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space3DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); + int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); _RestCallbackData rcd; rcd.min_allowed_depth = min_contact_depth; @@ -505,7 +506,7 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform3D &p_sh continue; } - const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; + const GodotCollisionObject3D *col_obj = space->intersection_query_results[i]; if (p_exclude.has(col_obj->get_self())) { continue; @@ -515,7 +516,7 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform3D &p_sh rcd.object = col_obj; rcd.shape = shape_idx; - bool sc = CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin); + bool sc = GodotCollisionSolver3D::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin); if (!sc) { continue; } @@ -530,8 +531,8 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform3D &p_sh r_info->normal = rcd.best_result.normal; r_info->point = rcd.best_result.contact; r_info->rid = rcd.best_result.object->get_self(); - if (rcd.best_result.object->get_type() == CollisionObject3DSW::TYPE_BODY) { - const Body3DSW *body = static_cast<const Body3DSW *>(rcd.best_result.object); + if (rcd.best_result.object->get_type() == GodotCollisionObject3D::TYPE_BODY) { + const GodotBody3D *body = static_cast<const GodotBody3D *>(rcd.best_result.object); Vector3 rel_vec = rcd.best_result.contact - (body->get_transform().origin + body->get_center_of_mass()); r_info->linear_velocity = body->get_linear_velocity() + (body->get_angular_velocity()).cross(rel_vec); @@ -542,10 +543,10 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform3D &p_sh return true; } -Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const { - CollisionObject3DSW *obj = PhysicsServer3DSW::singletonsw->area_owner.get_or_null(p_object); +Vector3 GodotPhysicsDirectSpaceState3D::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const { + GodotCollisionObject3D *obj = GodotPhysicsServer3D::godot_singleton->area_owner.get_or_null(p_object); if (!obj) { - obj = PhysicsServer3DSW::singletonsw->body_owner.get_or_null(p_object); + obj = GodotPhysicsServer3D::godot_singleton->body_owner.get_or_null(p_object); } ERR_FAIL_COND_V(!obj, Vector3()); @@ -562,7 +563,7 @@ Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_ob } Transform3D shape_xform = obj->get_transform() * obj->get_shape_transform(i); - Shape3DSW *shape = obj->get_shape(i); + GodotShape3D *shape = obj->get_shape(i); Vector3 point = shape->get_closest_point_to(shape_xform.affine_inverse().xform(p_point)); point = shape_xform.xform(point); @@ -582,13 +583,13 @@ Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_ob } } -PhysicsDirectSpaceState3DSW::PhysicsDirectSpaceState3DSW() { +GodotPhysicsDirectSpaceState3D::GodotPhysicsDirectSpaceState3D() { space = nullptr; } //////////////////////////////////////////////////////////////////////////////////////////////////////////// -int Space3DSW::_cull_aabb_for_body(Body3DSW *p_body, const AABB &p_aabb) { +int GodotSpace3D::_cull_aabb_for_body(GodotBody3D *p_body, const AABB &p_aabb) { int amount = broadphase->cull_aabb(p_aabb, intersection_query_results, INTERSECTION_QUERY_MAX, intersection_query_subindex_results); for (int i = 0; i < amount; i++) { @@ -596,13 +597,13 @@ int Space3DSW::_cull_aabb_for_body(Body3DSW *p_body, const AABB &p_aabb) { if (intersection_query_results[i] == p_body) { keep = false; - } else if (intersection_query_results[i]->get_type() == CollisionObject3DSW::TYPE_AREA) { + } else if (intersection_query_results[i]->get_type() == GodotCollisionObject3D::TYPE_AREA) { keep = false; - } else if (intersection_query_results[i]->get_type() == CollisionObject3DSW::TYPE_SOFT_BODY) { + } else if (intersection_query_results[i]->get_type() == GodotCollisionObject3D::TYPE_SOFT_BODY) { keep = false; - } else if (!p_body->collides_with(static_cast<Body3DSW *>(intersection_query_results[i]))) { + } else if (!p_body->collides_with(static_cast<GodotBody3D *>(intersection_query_results[i]))) { keep = false; - } else if (static_cast<Body3DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) { + } else if (static_cast<GodotBody3D *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) { keep = false; } @@ -620,7 +621,7 @@ int Space3DSW::_cull_aabb_for_body(Body3DSW *p_body, const AABB &p_aabb) { return amount; } -bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::MotionParameters &p_parameters, PhysicsServer3D::MotionResult *r_result) { +bool GodotSpace3D::test_body_motion(GodotBody3D *p_body, const PhysicsServer3D::MotionParameters &p_parameters, PhysicsServer3D::MotionResult *r_result) { //give me back regular physics engine logic //this is madness //and most people using this function will think @@ -679,13 +680,13 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion Vector3 sr[max_results * 2]; do { - PhysicsServer3DSW::CollCbkData cbk; + GodotPhysicsServer3D::CollCbkData cbk; cbk.max = max_results; cbk.amount = 0; cbk.ptr = sr; - PhysicsServer3DSW::CollCbkData *cbkptr = &cbk; - CollisionSolver3DSW::CallbackResult cbkres = PhysicsServer3DSW::_shape_col_cbk; + GodotPhysicsServer3D::CollCbkData *cbkptr = &cbk; + GodotCollisionSolver3D::CallbackResult cbkres = GodotPhysicsServer3D::_shape_col_cbk; bool collided = false; @@ -697,10 +698,10 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion } Transform3D body_shape_xform = body_transform * p_body->get_shape_transform(j); - Shape3DSW *body_shape = p_body->get_shape(j); + GodotShape3D *body_shape = p_body->get_shape(j); for (int i = 0; i < amount; i++) { - const CollisionObject3DSW *col_obj = intersection_query_results[i]; + const GodotCollisionObject3D *col_obj = intersection_query_results[i]; if (p_parameters.exclude_bodies.has(col_obj->get_self())) { continue; } @@ -710,7 +711,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion int shape_idx = intersection_query_subindex_results[i]; - if (CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_parameters.margin)) { + if (GodotCollisionSolver3D::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_parameters.margin)) { collided = cbk.amount > 0; } } @@ -770,13 +771,13 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion continue; } - Shape3DSW *body_shape = p_body->get_shape(j); + GodotShape3D *body_shape = p_body->get_shape(j); // Colliding separation rays allows to properly snap to the ground, // otherwise it's not needed in regular motion. if (!p_parameters.collide_separation_ray && (body_shape->get_type() == PhysicsServer3D::SHAPE_SEPARATION_RAY)) { // When slide on slope is on, separation ray shape acts like a regular shape. - if (!static_cast<SeparationRayShape3DSW *>(body_shape)->get_slide_on_slope()) { + if (!static_cast<GodotSeparationRayShape3D *>(body_shape)->get_slide_on_slope()) { continue; } } @@ -784,7 +785,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion Transform3D body_shape_xform = body_transform * p_body->get_shape_transform(j); Transform3D body_shape_xform_inv = body_shape_xform.affine_inverse(); - MotionShape3DSW mshape; + GodotMotionShape3D mshape; mshape.shape = body_shape; mshape.motion = body_shape_xform_inv.basis.xform(p_parameters.motion); @@ -794,7 +795,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion real_t best_unsafe = 1; for (int i = 0; i < amount; i++) { - const CollisionObject3DSW *col_obj = intersection_query_results[i]; + const GodotCollisionObject3D *col_obj = intersection_query_results[i]; if (p_parameters.exclude_bodies.has(col_obj->get_self())) { continue; } @@ -810,12 +811,12 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion Transform3D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? - if (CollisionSolver3DSW::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, motion_aabb, &sep_axis)) { + if (GodotCollisionSolver3D::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, motion_aabb, &sep_axis)) { continue; } sep_axis = motion_normal; - if (!CollisionSolver3DSW::solve_distance(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, motion_aabb, &sep_axis)) { + if (!GodotCollisionSolver3D::solve_distance(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, motion_aabb, &sep_axis)) { stuck = true; break; } @@ -831,7 +832,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion Vector3 lA, lB; Vector3 sep = motion_normal; //important optimization for this to work fast enough - bool collided = !CollisionSolver3DSW::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, motion_aabb, &sep); + bool collided = !GodotCollisionSolver3D::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, motion_aabb, &sep); if (collided) { hi = fraction; @@ -911,14 +912,14 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion } Transform3D body_shape_xform = ugt * p_body->get_shape_transform(j); - Shape3DSW *body_shape = p_body->get_shape(j); + GodotShape3D *body_shape = p_body->get_shape(j); body_aabb.position += p_parameters.motion * unsafe; int amount = _cull_aabb_for_body(p_body, body_aabb); for (int i = 0; i < amount; i++) { - const CollisionObject3DSW *col_obj = intersection_query_results[i]; + const GodotCollisionObject3D *col_obj = intersection_query_results[i]; if (p_parameters.exclude_bodies.has(col_obj->get_self())) { continue; } @@ -930,7 +931,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion rcd.object = col_obj; rcd.shape = shape_idx; - bool sc = CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_parameters.margin); + bool sc = GodotCollisionSolver3D::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_parameters.margin); if (!sc) { continue; } @@ -952,7 +953,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion collision.position = result.contact; collision.depth = result.len; - const Body3DSW *body = static_cast<const Body3DSW *>(result.object); + const GodotBody3D *body = static_cast<const GodotBody3D *>(result.object); Vector3 rel_vec = result.contact - (body->get_transform().origin + body->get_center_of_mass()); collision.collider_velocity = body->get_linear_velocity() + (body->get_angular_velocity()).cross(rel_vec); @@ -984,44 +985,44 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion return collided; } -void *Space3DSW::_broadphase_pair(CollisionObject3DSW *A, int p_subindex_A, CollisionObject3DSW *B, int p_subindex_B, void *p_self) { +void *GodotSpace3D::_broadphase_pair(GodotCollisionObject3D *A, int p_subindex_A, GodotCollisionObject3D *B, int p_subindex_B, void *p_self) { if (!A->interacts_with(B)) { return nullptr; } - CollisionObject3DSW::Type type_A = A->get_type(); - CollisionObject3DSW::Type type_B = B->get_type(); + GodotCollisionObject3D::Type type_A = A->get_type(); + GodotCollisionObject3D::Type type_B = B->get_type(); if (type_A > type_B) { SWAP(A, B); SWAP(p_subindex_A, p_subindex_B); SWAP(type_A, type_B); } - Space3DSW *self = (Space3DSW *)p_self; + GodotSpace3D *self = (GodotSpace3D *)p_self; self->collision_pairs++; - if (type_A == CollisionObject3DSW::TYPE_AREA) { - Area3DSW *area = static_cast<Area3DSW *>(A); - if (type_B == CollisionObject3DSW::TYPE_AREA) { - Area3DSW *area_b = static_cast<Area3DSW *>(B); - Area2Pair3DSW *area2_pair = memnew(Area2Pair3DSW(area_b, p_subindex_B, area, p_subindex_A)); + if (type_A == GodotCollisionObject3D::TYPE_AREA) { + GodotArea3D *area = static_cast<GodotArea3D *>(A); + if (type_B == GodotCollisionObject3D::TYPE_AREA) { + GodotArea3D *area_b = static_cast<GodotArea3D *>(B); + GodotArea2Pair3D *area2_pair = memnew(GodotArea2Pair3D(area_b, p_subindex_B, area, p_subindex_A)); return area2_pair; - } else if (type_B == CollisionObject3DSW::TYPE_SOFT_BODY) { - SoftBody3DSW *softbody = static_cast<SoftBody3DSW *>(B); - AreaSoftBodyPair3DSW *soft_area_pair = memnew(AreaSoftBodyPair3DSW(softbody, p_subindex_B, area, p_subindex_A)); + } else if (type_B == GodotCollisionObject3D::TYPE_SOFT_BODY) { + GodotSoftBody3D *softbody = static_cast<GodotSoftBody3D *>(B); + GodotAreaSoftBodyPair3D *soft_area_pair = memnew(GodotAreaSoftBodyPair3D(softbody, p_subindex_B, area, p_subindex_A)); return soft_area_pair; } else { - Body3DSW *body = static_cast<Body3DSW *>(B); - AreaPair3DSW *area_pair = memnew(AreaPair3DSW(body, p_subindex_B, area, p_subindex_A)); + GodotBody3D *body = static_cast<GodotBody3D *>(B); + GodotAreaPair3D *area_pair = memnew(GodotAreaPair3D(body, p_subindex_B, area, p_subindex_A)); return area_pair; } - } else if (type_A == CollisionObject3DSW::TYPE_BODY) { - if (type_B == CollisionObject3DSW::TYPE_SOFT_BODY) { - BodySoftBodyPair3DSW *soft_pair = memnew(BodySoftBodyPair3DSW((Body3DSW *)A, p_subindex_A, (SoftBody3DSW *)B)); + } else if (type_A == GodotCollisionObject3D::TYPE_BODY) { + if (type_B == GodotCollisionObject3D::TYPE_SOFT_BODY) { + GodotBodySoftBodyPair3D *soft_pair = memnew(GodotBodySoftBodyPair3D((GodotBody3D *)A, p_subindex_A, (GodotSoftBody3D *)B)); return soft_pair; } else { - BodyPair3DSW *b = memnew(BodyPair3DSW((Body3DSW *)A, p_subindex_A, (Body3DSW *)B, p_subindex_B)); + GodotBodyPair3D *b = memnew(GodotBodyPair3D((GodotBody3D *)A, p_subindex_A, (GodotBody3D *)B, p_subindex_B)); return b; } } else { @@ -1031,110 +1032,110 @@ void *Space3DSW::_broadphase_pair(CollisionObject3DSW *A, int p_subindex_A, Coll return nullptr; } -void Space3DSW::_broadphase_unpair(CollisionObject3DSW *A, int p_subindex_A, CollisionObject3DSW *B, int p_subindex_B, void *p_data, void *p_self) { +void GodotSpace3D::_broadphase_unpair(GodotCollisionObject3D *A, int p_subindex_A, GodotCollisionObject3D *B, int p_subindex_B, void *p_data, void *p_self) { if (!p_data) { return; } - Space3DSW *self = (Space3DSW *)p_self; + GodotSpace3D *self = (GodotSpace3D *)p_self; self->collision_pairs--; - Constraint3DSW *c = (Constraint3DSW *)p_data; + GodotConstraint3D *c = (GodotConstraint3D *)p_data; memdelete(c); } -const SelfList<Body3DSW>::List &Space3DSW::get_active_body_list() const { +const SelfList<GodotBody3D>::List &GodotSpace3D::get_active_body_list() const { return active_list; } -void Space3DSW::body_add_to_active_list(SelfList<Body3DSW> *p_body) { +void GodotSpace3D::body_add_to_active_list(SelfList<GodotBody3D> *p_body) { active_list.add(p_body); } -void Space3DSW::body_remove_from_active_list(SelfList<Body3DSW> *p_body) { +void GodotSpace3D::body_remove_from_active_list(SelfList<GodotBody3D> *p_body) { active_list.remove(p_body); } -void Space3DSW::body_add_to_mass_properties_update_list(SelfList<Body3DSW> *p_body) { +void GodotSpace3D::body_add_to_mass_properties_update_list(SelfList<GodotBody3D> *p_body) { mass_properties_update_list.add(p_body); } -void Space3DSW::body_remove_from_mass_properties_update_list(SelfList<Body3DSW> *p_body) { +void GodotSpace3D::body_remove_from_mass_properties_update_list(SelfList<GodotBody3D> *p_body) { mass_properties_update_list.remove(p_body); } -BroadPhase3DSW *Space3DSW::get_broadphase() { +GodotBroadPhase3D *GodotSpace3D::get_broadphase() { return broadphase; } -void Space3DSW::add_object(CollisionObject3DSW *p_object) { +void GodotSpace3D::add_object(GodotCollisionObject3D *p_object) { ERR_FAIL_COND(objects.has(p_object)); objects.insert(p_object); } -void Space3DSW::remove_object(CollisionObject3DSW *p_object) { +void GodotSpace3D::remove_object(GodotCollisionObject3D *p_object) { ERR_FAIL_COND(!objects.has(p_object)); objects.erase(p_object); } -const Set<CollisionObject3DSW *> &Space3DSW::get_objects() const { +const Set<GodotCollisionObject3D *> &GodotSpace3D::get_objects() const { return objects; } -void Space3DSW::body_add_to_state_query_list(SelfList<Body3DSW> *p_body) { +void GodotSpace3D::body_add_to_state_query_list(SelfList<GodotBody3D> *p_body) { state_query_list.add(p_body); } -void Space3DSW::body_remove_from_state_query_list(SelfList<Body3DSW> *p_body) { +void GodotSpace3D::body_remove_from_state_query_list(SelfList<GodotBody3D> *p_body) { state_query_list.remove(p_body); } -void Space3DSW::area_add_to_monitor_query_list(SelfList<Area3DSW> *p_area) { +void GodotSpace3D::area_add_to_monitor_query_list(SelfList<GodotArea3D> *p_area) { monitor_query_list.add(p_area); } -void Space3DSW::area_remove_from_monitor_query_list(SelfList<Area3DSW> *p_area) { +void GodotSpace3D::area_remove_from_monitor_query_list(SelfList<GodotArea3D> *p_area) { monitor_query_list.remove(p_area); } -void Space3DSW::area_add_to_moved_list(SelfList<Area3DSW> *p_area) { +void GodotSpace3D::area_add_to_moved_list(SelfList<GodotArea3D> *p_area) { area_moved_list.add(p_area); } -void Space3DSW::area_remove_from_moved_list(SelfList<Area3DSW> *p_area) { +void GodotSpace3D::area_remove_from_moved_list(SelfList<GodotArea3D> *p_area) { area_moved_list.remove(p_area); } -const SelfList<Area3DSW>::List &Space3DSW::get_moved_area_list() const { +const SelfList<GodotArea3D>::List &GodotSpace3D::get_moved_area_list() const { return area_moved_list; } -const SelfList<SoftBody3DSW>::List &Space3DSW::get_active_soft_body_list() const { +const SelfList<GodotSoftBody3D>::List &GodotSpace3D::get_active_soft_body_list() const { return active_soft_body_list; } -void Space3DSW::soft_body_add_to_active_list(SelfList<SoftBody3DSW> *p_soft_body) { +void GodotSpace3D::soft_body_add_to_active_list(SelfList<GodotSoftBody3D> *p_soft_body) { active_soft_body_list.add(p_soft_body); } -void Space3DSW::soft_body_remove_from_active_list(SelfList<SoftBody3DSW> *p_soft_body) { +void GodotSpace3D::soft_body_remove_from_active_list(SelfList<GodotSoftBody3D> *p_soft_body) { active_soft_body_list.remove(p_soft_body); } -void Space3DSW::call_queries() { +void GodotSpace3D::call_queries() { while (state_query_list.first()) { - Body3DSW *b = state_query_list.first()->self(); + GodotBody3D *b = state_query_list.first()->self(); state_query_list.remove(state_query_list.first()); b->call_queries(); } while (monitor_query_list.first()) { - Area3DSW *a = monitor_query_list.first()->self(); + GodotArea3D *a = monitor_query_list.first()->self(); monitor_query_list.remove(monitor_query_list.first()); a->call_queries(); } } -void Space3DSW::setup() { +void GodotSpace3D::setup() { contact_debug_count = 0; while (mass_properties_update_list.first()) { mass_properties_update_list.first()->self()->update_mass_properties(); @@ -1142,11 +1143,11 @@ void Space3DSW::setup() { } } -void Space3DSW::update() { +void GodotSpace3D::update() { broadphase->update(); } -void Space3DSW::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_value) { +void GodotSpace3D::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_value) { switch (p_param) { case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: contact_recycle_radius = p_value; @@ -1175,7 +1176,7 @@ void Space3DSW::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_valu } } -real_t Space3DSW::get_param(PhysicsServer3D::SpaceParameter p_param) const { +real_t GodotSpace3D::get_param(PhysicsServer3D::SpaceParameter p_param) const { switch (p_param) { case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: return contact_recycle_radius; @@ -1197,38 +1198,38 @@ real_t Space3DSW::get_param(PhysicsServer3D::SpaceParameter p_param) const { return 0; } -void Space3DSW::lock() { +void GodotSpace3D::lock() { locked = true; } -void Space3DSW::unlock() { +void GodotSpace3D::unlock() { locked = false; } -bool Space3DSW::is_locked() const { +bool GodotSpace3D::is_locked() const { return locked; } -PhysicsDirectSpaceState3DSW *Space3DSW::get_direct_state() { +GodotPhysicsDirectSpaceState3D *GodotSpace3D::get_direct_state() { return direct_access; } -Space3DSW::Space3DSW() { +GodotSpace3D::GodotSpace3D() { body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_linear", 0.1); body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_angular", Math::deg2rad(8.0)); body_time_to_sleep = GLOBAL_DEF("physics/3d/time_before_sleep", 0.5); ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/time_before_sleep", PropertyInfo(Variant::FLOAT, "physics/3d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); body_angular_velocity_damp_ratio = 10; - broadphase = BroadPhase3DSW::create_func(); + broadphase = GodotBroadPhase3D::create_func(); broadphase->set_pair_callback(_broadphase_pair, this); broadphase->set_unpair_callback(_broadphase_unpair, this); - direct_access = memnew(PhysicsDirectSpaceState3DSW); + direct_access = memnew(GodotPhysicsDirectSpaceState3D); direct_access->space = this; } -Space3DSW::~Space3DSW() { +GodotSpace3D::~GodotSpace3D() { memdelete(broadphase); memdelete(direct_access); } diff --git a/servers/physics_3d/space_3d_sw.h b/servers/physics_3d/godot_space_3d.h index 69cc3c4bbd..3b36dd346c 100644 --- a/servers/physics_3d/space_3d_sw.h +++ b/servers/physics_3d/godot_space_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* space_3d_sw.h */ +/* godot_space_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,25 +28,26 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SPACE_SW_H -#define SPACE_SW_H +#ifndef GODOT_SPACE_3D_H +#define GODOT_SPACE_3D_H + +#include "godot_area_3d.h" +#include "godot_area_pair_3d.h" +#include "godot_body_3d.h" +#include "godot_body_pair_3d.h" +#include "godot_broad_phase_3d.h" +#include "godot_collision_object_3d.h" +#include "godot_soft_body_3d.h" -#include "area_3d_sw.h" -#include "area_pair_3d_sw.h" -#include "body_3d_sw.h" -#include "body_pair_3d_sw.h" -#include "broad_phase_3d_sw.h" -#include "collision_object_3d_sw.h" #include "core/config/project_settings.h" #include "core/templates/hash_map.h" #include "core/typedefs.h" -#include "soft_body_3d_sw.h" -class PhysicsDirectSpaceState3DSW : public PhysicsDirectSpaceState3D { - GDCLASS(PhysicsDirectSpaceState3DSW, PhysicsDirectSpaceState3D); +class GodotPhysicsDirectSpaceState3D : public PhysicsDirectSpaceState3D { + GDCLASS(GodotPhysicsDirectSpaceState3D, PhysicsDirectSpaceState3D); public: - Space3DSW *space; + GodotSpace3D *space; virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false) override; @@ -56,10 +57,10 @@ public: virtual bool rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const override; - PhysicsDirectSpaceState3DSW(); + GodotPhysicsDirectSpaceState3D(); }; -class Space3DSW { +class GodotSpace3D { public: enum ElapsedTime { ELAPSED_TIME_INTEGRATE_FORCES, @@ -74,23 +75,23 @@ public: private: uint64_t elapsed_time[ELAPSED_TIME_MAX] = {}; - PhysicsDirectSpaceState3DSW *direct_access; + GodotPhysicsDirectSpaceState3D *direct_access; RID self; - BroadPhase3DSW *broadphase; - SelfList<Body3DSW>::List active_list; - SelfList<Body3DSW>::List mass_properties_update_list; - SelfList<Body3DSW>::List state_query_list; - SelfList<Area3DSW>::List monitor_query_list; - SelfList<Area3DSW>::List area_moved_list; - SelfList<SoftBody3DSW>::List active_soft_body_list; + GodotBroadPhase3D *broadphase; + SelfList<GodotBody3D>::List active_list; + SelfList<GodotBody3D>::List mass_properties_update_list; + SelfList<GodotBody3D>::List state_query_list; + SelfList<GodotArea3D>::List monitor_query_list; + SelfList<GodotArea3D>::List area_moved_list; + SelfList<GodotSoftBody3D>::List active_soft_body_list; - static void *_broadphase_pair(CollisionObject3DSW *A, int p_subindex_A, CollisionObject3DSW *B, int p_subindex_B, void *p_self); - static void _broadphase_unpair(CollisionObject3DSW *A, int p_subindex_A, CollisionObject3DSW *B, int p_subindex_B, void *p_data, void *p_self); + static void *_broadphase_pair(GodotCollisionObject3D *A, int p_subindex_A, GodotCollisionObject3D *B, int p_subindex_B, void *p_self); + static void _broadphase_unpair(GodotCollisionObject3D *A, int p_subindex_A, GodotCollisionObject3D *B, int p_subindex_B, void *p_data, void *p_self); - Set<CollisionObject3DSW *> objects; + Set<GodotCollisionObject3D *> objects; - Area3DSW *area = nullptr; + GodotArea3D *area = nullptr; real_t contact_recycle_radius = 0.01; real_t contact_max_separation = 0.05; @@ -101,7 +102,7 @@ private: INTERSECTION_QUERY_MAX = 2048 }; - CollisionObject3DSW *intersection_query_results[INTERSECTION_QUERY_MAX]; + GodotCollisionObject3D *intersection_query_results[INTERSECTION_QUERY_MAX]; int intersection_query_subindex_results[INTERSECTION_QUERY_MAX]; real_t body_linear_velocity_sleep_threshold; @@ -122,41 +123,41 @@ private: Vector<Vector3> contact_debug; int contact_debug_count = 0; - friend class PhysicsDirectSpaceState3DSW; + friend class GodotPhysicsDirectSpaceState3D; - int _cull_aabb_for_body(Body3DSW *p_body, const AABB &p_aabb); + int _cull_aabb_for_body(GodotBody3D *p_body, const AABB &p_aabb); public: _FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; } _FORCE_INLINE_ RID get_self() const { return self; } - void set_default_area(Area3DSW *p_area) { area = p_area; } - Area3DSW *get_default_area() const { return area; } + void set_default_area(GodotArea3D *p_area) { area = p_area; } + GodotArea3D *get_default_area() const { return area; } - const SelfList<Body3DSW>::List &get_active_body_list() const; - void body_add_to_active_list(SelfList<Body3DSW> *p_body); - void body_remove_from_active_list(SelfList<Body3DSW> *p_body); - void body_add_to_mass_properties_update_list(SelfList<Body3DSW> *p_body); - void body_remove_from_mass_properties_update_list(SelfList<Body3DSW> *p_body); + const SelfList<GodotBody3D>::List &get_active_body_list() const; + void body_add_to_active_list(SelfList<GodotBody3D> *p_body); + void body_remove_from_active_list(SelfList<GodotBody3D> *p_body); + void body_add_to_mass_properties_update_list(SelfList<GodotBody3D> *p_body); + void body_remove_from_mass_properties_update_list(SelfList<GodotBody3D> *p_body); - void body_add_to_state_query_list(SelfList<Body3DSW> *p_body); - void body_remove_from_state_query_list(SelfList<Body3DSW> *p_body); + void body_add_to_state_query_list(SelfList<GodotBody3D> *p_body); + void body_remove_from_state_query_list(SelfList<GodotBody3D> *p_body); - void area_add_to_monitor_query_list(SelfList<Area3DSW> *p_area); - void area_remove_from_monitor_query_list(SelfList<Area3DSW> *p_area); - void area_add_to_moved_list(SelfList<Area3DSW> *p_area); - void area_remove_from_moved_list(SelfList<Area3DSW> *p_area); - const SelfList<Area3DSW>::List &get_moved_area_list() const; + void area_add_to_monitor_query_list(SelfList<GodotArea3D> *p_area); + void area_remove_from_monitor_query_list(SelfList<GodotArea3D> *p_area); + void area_add_to_moved_list(SelfList<GodotArea3D> *p_area); + void area_remove_from_moved_list(SelfList<GodotArea3D> *p_area); + const SelfList<GodotArea3D>::List &get_moved_area_list() const; - const SelfList<SoftBody3DSW>::List &get_active_soft_body_list() const; - void soft_body_add_to_active_list(SelfList<SoftBody3DSW> *p_soft_body); - void soft_body_remove_from_active_list(SelfList<SoftBody3DSW> *p_soft_body); + const SelfList<GodotSoftBody3D>::List &get_active_soft_body_list() const; + void soft_body_add_to_active_list(SelfList<GodotSoftBody3D> *p_soft_body); + void soft_body_remove_from_active_list(SelfList<GodotSoftBody3D> *p_soft_body); - BroadPhase3DSW *get_broadphase(); + GodotBroadPhase3D *get_broadphase(); - void add_object(CollisionObject3DSW *p_object); - void remove_object(CollisionObject3DSW *p_object); - const Set<CollisionObject3DSW *> &get_objects() const; + void add_object(GodotCollisionObject3D *p_object); + void remove_object(GodotCollisionObject3D *p_object); + const Set<GodotCollisionObject3D *> &get_objects() const; _FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; } _FORCE_INLINE_ real_t get_contact_max_separation() const { return contact_max_separation; } @@ -189,7 +190,7 @@ public: int get_collision_pairs() const { return collision_pairs; } - PhysicsDirectSpaceState3DSW *get_direct_state(); + GodotPhysicsDirectSpaceState3D *get_direct_state(); void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); } _FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.is_empty(); } @@ -207,10 +208,10 @@ public: void set_elapsed_time(ElapsedTime p_time, uint64_t p_msec) { elapsed_time[p_time] = p_msec; } uint64_t get_elapsed_time(ElapsedTime p_time) const { return elapsed_time[p_time]; } - bool test_body_motion(Body3DSW *p_body, const PhysicsServer3D::MotionParameters &p_parameters, PhysicsServer3D::MotionResult *r_result); + bool test_body_motion(GodotBody3D *p_body, const PhysicsServer3D::MotionParameters &p_parameters, PhysicsServer3D::MotionResult *r_result); - Space3DSW(); - ~Space3DSW(); + GodotSpace3D(); + ~GodotSpace3D(); }; -#endif // SPACE__SW_H +#endif // GODOT_SPACE_3D_H diff --git a/servers/physics_3d/step_3d_sw.cpp b/servers/physics_3d/godot_step_3d.cpp index 6572d58c91..a8654c617b 100644 --- a/servers/physics_3d/step_3d_sw.cpp +++ b/servers/physics_3d/godot_step_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* step_3d_sw.cpp */ +/* godot_step_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "step_3d_sw.h" -#include "joints_3d_sw.h" +#include "godot_step_3d.h" + +#include "godot_joint_3d.h" #include "core/os/os.h" @@ -39,7 +40,7 @@ #define ISLAND_SIZE_RESERVE 512 #define CONSTRAINT_COUNT_RESERVE 1024 -void Step3DSW::_populate_island(Body3DSW *p_body, LocalVector<Body3DSW *> &p_body_island, LocalVector<Constraint3DSW *> &p_constraint_island) { +void GodotStep3D::_populate_island(GodotBody3D *p_body, LocalVector<GodotBody3D *> &p_body_island, LocalVector<GodotConstraint3D *> &p_constraint_island) { p_body->set_island_step(_step); if (p_body->get_mode() > PhysicsServer3D::BODY_MODE_KINEMATIC) { @@ -47,8 +48,8 @@ void Step3DSW::_populate_island(Body3DSW *p_body, LocalVector<Body3DSW *> &p_bod p_body_island.push_back(p_body); } - for (const KeyValue<Constraint3DSW *, int> &E : p_body->get_constraint_map()) { - Constraint3DSW *constraint = (Constraint3DSW *)E.key; + for (const KeyValue<GodotConstraint3D *, int> &E : p_body->get_constraint_map()) { + GodotConstraint3D *constraint = (GodotConstraint3D *)E.key; if (constraint->get_island_step() == _step) { continue; // Already processed. } @@ -62,7 +63,7 @@ void Step3DSW::_populate_island(Body3DSW *p_body, LocalVector<Body3DSW *> &p_bod if (i == E.value) { continue; } - Body3DSW *other_body = constraint->get_body_ptr()[i]; + GodotBody3D *other_body = constraint->get_body_ptr()[i]; if (other_body->get_island_step() == _step) { continue; // Already processed. } @@ -74,7 +75,7 @@ void Step3DSW::_populate_island(Body3DSW *p_body, LocalVector<Body3DSW *> &p_bod // Find connected soft bodies. for (int i = 0; i < constraint->get_soft_body_count(); i++) { - SoftBody3DSW *soft_body = constraint->get_soft_body_ptr(i); + GodotSoftBody3D *soft_body = constraint->get_soft_body_ptr(i); if (soft_body->get_island_step() == _step) { continue; // Already processed. } @@ -83,11 +84,11 @@ void Step3DSW::_populate_island(Body3DSW *p_body, LocalVector<Body3DSW *> &p_bod } } -void Step3DSW::_populate_island_soft_body(SoftBody3DSW *p_soft_body, LocalVector<Body3DSW *> &p_body_island, LocalVector<Constraint3DSW *> &p_constraint_island) { +void GodotStep3D::_populate_island_soft_body(GodotSoftBody3D *p_soft_body, LocalVector<GodotBody3D *> &p_body_island, LocalVector<GodotConstraint3D *> &p_constraint_island) { p_soft_body->set_island_step(_step); - for (Set<Constraint3DSW *>::Element *E = p_soft_body->get_constraints().front(); E; E = E->next()) { - Constraint3DSW *constraint = (Constraint3DSW *)E->get(); + for (Set<GodotConstraint3D *>::Element *E = p_soft_body->get_constraints().front(); E; E = E->next()) { + GodotConstraint3D *constraint = (GodotConstraint3D *)E->get(); if (constraint->get_island_step() == _step) { continue; // Already processed. } @@ -98,7 +99,7 @@ void Step3DSW::_populate_island_soft_body(SoftBody3DSW *p_soft_body, LocalVector // Find connected rigid bodies. for (int i = 0; i < constraint->get_body_count(); i++) { - Body3DSW *body = constraint->get_body_ptr()[i]; + GodotBody3D *body = constraint->get_body_ptr()[i]; if (body->get_island_step() == _step) { continue; // Already processed. } @@ -110,16 +111,16 @@ void Step3DSW::_populate_island_soft_body(SoftBody3DSW *p_soft_body, LocalVector } } -void Step3DSW::_setup_contraint(uint32_t p_constraint_index, void *p_userdata) { - Constraint3DSW *constraint = all_constraints[p_constraint_index]; +void GodotStep3D::_setup_contraint(uint32_t p_constraint_index, void *p_userdata) { + GodotConstraint3D *constraint = all_constraints[p_constraint_index]; constraint->setup(delta); } -void Step3DSW::_pre_solve_island(LocalVector<Constraint3DSW *> &p_constraint_island) const { +void GodotStep3D::_pre_solve_island(LocalVector<GodotConstraint3D *> &p_constraint_island) const { uint32_t constraint_count = p_constraint_island.size(); uint32_t valid_constraint_count = 0; for (uint32_t constraint_index = 0; constraint_index < constraint_count; ++constraint_index) { - Constraint3DSW *constraint = p_constraint_island[constraint_index]; + GodotConstraint3D *constraint = p_constraint_island[constraint_index]; if (p_constraint_island[constraint_index]->pre_solve(delta)) { // Keep this constraint for solving. p_constraint_island[valid_constraint_count++] = constraint; @@ -128,8 +129,8 @@ void Step3DSW::_pre_solve_island(LocalVector<Constraint3DSW *> &p_constraint_isl p_constraint_island.resize(valid_constraint_count); } -void Step3DSW::_solve_island(uint32_t p_island_index, void *p_userdata) { - LocalVector<Constraint3DSW *> &constraint_island = constraint_islands[p_island_index]; +void GodotStep3D::_solve_island(uint32_t p_island_index, void *p_userdata) { + LocalVector<GodotConstraint3D *> &constraint_island = constraint_islands[p_island_index]; int current_priority = 1; @@ -146,7 +147,7 @@ void Step3DSW::_solve_island(uint32_t p_island_index, void *p_userdata) { uint32_t priority_constraint_count = 0; ++current_priority; for (uint32_t constraint_index = 0; constraint_index < constraint_count; ++constraint_index) { - Constraint3DSW *constraint = constraint_island[constraint_index]; + GodotConstraint3D *constraint = constraint_island[constraint_index]; if (constraint->get_priority() >= current_priority) { // Keep this constraint for the next iteration. constraint_island[priority_constraint_count++] = constraint; @@ -156,12 +157,12 @@ void Step3DSW::_solve_island(uint32_t p_island_index, void *p_userdata) { } } -void Step3DSW::_check_suspend(const LocalVector<Body3DSW *> &p_body_island) const { +void GodotStep3D::_check_suspend(const LocalVector<GodotBody3D *> &p_body_island) const { bool can_sleep = true; uint32_t body_count = p_body_island.size(); for (uint32_t body_index = 0; body_index < body_count; ++body_index) { - Body3DSW *body = p_body_island[body_index]; + GodotBody3D *body = p_body_island[body_index]; if (!body->sleep_test(delta)) { can_sleep = false; @@ -170,7 +171,7 @@ void Step3DSW::_check_suspend(const LocalVector<Body3DSW *> &p_body_island) cons // Put all to sleep or wake up everyone. for (uint32_t body_index = 0; body_index < body_count; ++body_index) { - Body3DSW *body = p_body_island[body_index]; + GodotBody3D *body = p_body_island[body_index]; bool active = body->is_active(); @@ -180,7 +181,7 @@ void Step3DSW::_check_suspend(const LocalVector<Body3DSW *> &p_body_island) cons } } -void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { +void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta, int p_iterations) { p_space->lock(); // can't access space during this p_space->setup(); //update inertias, etc @@ -190,9 +191,9 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { iterations = p_iterations; delta = p_delta; - const SelfList<Body3DSW>::List *body_list = &p_space->get_active_body_list(); + const SelfList<GodotBody3D>::List *body_list = &p_space->get_active_body_list(); - const SelfList<SoftBody3DSW>::List *soft_body_list = &p_space->get_active_soft_body_list(); + const SelfList<GodotSoftBody3D>::List *soft_body_list = &p_space->get_active_soft_body_list(); /* INTEGRATE FORCES */ @@ -201,7 +202,7 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { int active_count = 0; - const SelfList<Body3DSW> *b = body_list->first(); + const SelfList<GodotBody3D> *b = body_list->first(); while (b) { b->self()->integrate_forces(p_delta); b = b->next(); @@ -210,7 +211,7 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { /* UPDATE SOFT BODY MOTION */ - const SelfList<SoftBody3DSW> *sb = soft_body_list->first(); + const SelfList<GodotSoftBody3D> *sb = soft_body_list->first(); while (sb) { sb->self()->predict_motion(p_delta); sb = sb->next(); @@ -221,7 +222,7 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); - p_space->set_elapsed_time(Space3DSW::ELAPSED_TIME_INTEGRATE_FORCES, profile_endtime - profile_begtime); + p_space->set_elapsed_time(GodotSpace3D::ELAPSED_TIME_INTEGRATE_FORCES, profile_endtime - profile_begtime); profile_begtime = profile_endtime; } @@ -229,11 +230,11 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { uint32_t island_count = 0; - const SelfList<Area3DSW>::List &aml = p_space->get_moved_area_list(); + const SelfList<GodotArea3D>::List &aml = p_space->get_moved_area_list(); while (aml.first()) { - for (const Set<Constraint3DSW *>::Element *E = aml.first()->self()->get_constraints().front(); E; E = E->next()) { - Constraint3DSW *constraint = E->get(); + for (const Set<GodotConstraint3D *>::Element *E = aml.first()->self()->get_constraints().front(); E; E = E->next()) { + GodotConstraint3D *constraint = E->get(); if (constraint->get_island_step() == _step) { continue; } @@ -244,13 +245,13 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { if (constraint_islands.size() < island_count) { constraint_islands.resize(island_count); } - LocalVector<Constraint3DSW *> &constraint_island = constraint_islands[island_count - 1]; + LocalVector<GodotConstraint3D *> &constraint_island = constraint_islands[island_count - 1]; constraint_island.clear(); all_constraints.push_back(constraint); constraint_island.push_back(constraint); } - p_space->area_remove_from_moved_list((SelfList<Area3DSW> *)aml.first()); //faster to remove here + p_space->area_remove_from_moved_list((SelfList<GodotArea3D> *)aml.first()); //faster to remove here } /* GENERATE CONSTRAINT ISLANDS FOR ACTIVE RIGID BODIES */ @@ -260,14 +261,14 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { uint32_t body_island_count = 0; while (b) { - Body3DSW *body = b->self(); + GodotBody3D *body = b->self(); if (body->get_island_step() != _step) { ++body_island_count; if (body_islands.size() < body_island_count) { body_islands.resize(body_island_count); } - LocalVector<Body3DSW *> &body_island = body_islands[body_island_count - 1]; + LocalVector<GodotBody3D *> &body_island = body_islands[body_island_count - 1]; body_island.clear(); body_island.reserve(BODY_ISLAND_SIZE_RESERVE); @@ -275,7 +276,7 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { if (constraint_islands.size() < island_count) { constraint_islands.resize(island_count); } - LocalVector<Constraint3DSW *> &constraint_island = constraint_islands[island_count - 1]; + LocalVector<GodotConstraint3D *> &constraint_island = constraint_islands[island_count - 1]; constraint_island.clear(); constraint_island.reserve(ISLAND_SIZE_RESERVE); @@ -296,14 +297,14 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { sb = soft_body_list->first(); while (sb) { - SoftBody3DSW *soft_body = sb->self(); + GodotSoftBody3D *soft_body = sb->self(); if (soft_body->get_island_step() != _step) { ++body_island_count; if (body_islands.size() < body_island_count) { body_islands.resize(body_island_count); } - LocalVector<Body3DSW *> &body_island = body_islands[body_island_count - 1]; + LocalVector<GodotBody3D *> &body_island = body_islands[body_island_count - 1]; body_island.clear(); body_island.reserve(BODY_ISLAND_SIZE_RESERVE); @@ -311,7 +312,7 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { if (constraint_islands.size() < island_count) { constraint_islands.resize(island_count); } - LocalVector<Constraint3DSW *> &constraint_island = constraint_islands[island_count - 1]; + LocalVector<GodotConstraint3D *> &constraint_island = constraint_islands[island_count - 1]; constraint_island.clear(); constraint_island.reserve(ISLAND_SIZE_RESERVE); @@ -332,18 +333,18 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); - p_space->set_elapsed_time(Space3DSW::ELAPSED_TIME_GENERATE_ISLANDS, profile_endtime - profile_begtime); + p_space->set_elapsed_time(GodotSpace3D::ELAPSED_TIME_GENERATE_ISLANDS, profile_endtime - profile_begtime); profile_begtime = profile_endtime; } /* SETUP CONSTRAINTS / PROCESS COLLISIONS */ uint32_t total_contraint_count = all_constraints.size(); - work_pool.do_work(total_contraint_count, this, &Step3DSW::_setup_contraint, nullptr); + work_pool.do_work(total_contraint_count, this, &GodotStep3D::_setup_contraint, nullptr); { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); - p_space->set_elapsed_time(Space3DSW::ELAPSED_TIME_SETUP_CONSTRAINTS, profile_endtime - profile_begtime); + p_space->set_elapsed_time(GodotSpace3D::ELAPSED_TIME_SETUP_CONSTRAINTS, profile_endtime - profile_begtime); profile_begtime = profile_endtime; } @@ -359,14 +360,14 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { // Warning: _solve_island modifies the constraint islands for optimization purpose, // their content is not reliable after these calls and shouldn't be used anymore. if (island_count > 1) { - work_pool.do_work(island_count, this, &Step3DSW::_solve_island, nullptr); + work_pool.do_work(island_count, this, &GodotStep3D::_solve_island, nullptr); } else if (island_count > 0) { _solve_island(0); } { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); - p_space->set_elapsed_time(Space3DSW::ELAPSED_TIME_SOLVE_CONSTRAINTS, profile_endtime - profile_begtime); + p_space->set_elapsed_time(GodotSpace3D::ELAPSED_TIME_SOLVE_CONSTRAINTS, profile_endtime - profile_begtime); profile_begtime = profile_endtime; } @@ -374,7 +375,7 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { b = body_list->first(); while (b) { - const SelfList<Body3DSW> *n = b->next(); + const SelfList<GodotBody3D> *n = b->next(); b->self()->integrate_velocities(p_delta); b = n; } @@ -395,7 +396,7 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); - p_space->set_elapsed_time(Space3DSW::ELAPSED_TIME_INTEGRATE_VELOCITIES, profile_endtime - profile_begtime); + p_space->set_elapsed_time(GodotSpace3D::ELAPSED_TIME_INTEGRATE_VELOCITIES, profile_endtime - profile_begtime); profile_begtime = profile_endtime; } @@ -406,7 +407,7 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { _step++; } -Step3DSW::Step3DSW() { +GodotStep3D::GodotStep3D() { body_islands.reserve(BODY_ISLAND_COUNT_RESERVE); constraint_islands.reserve(ISLAND_COUNT_RESERVE); all_constraints.reserve(CONSTRAINT_COUNT_RESERVE); @@ -414,6 +415,6 @@ Step3DSW::Step3DSW() { work_pool.init(); } -Step3DSW::~Step3DSW() { +GodotStep3D::~GodotStep3D() { work_pool.finish(); } diff --git a/servers/physics_3d/step_3d_sw.h b/servers/physics_3d/godot_step_3d.h index f2f879104a..23ede4feff 100644 --- a/servers/physics_3d/step_3d_sw.h +++ b/servers/physics_3d/godot_step_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* step_3d_sw.h */ +/* godot_step_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,15 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef STEP_SW_H -#define STEP_SW_H +#ifndef GODOT_STEP_3D_H +#define GODOT_STEP_3D_H -#include "space_3d_sw.h" +#include "godot_space_3d.h" #include "core/templates/local_vector.h" #include "core/templates/thread_work_pool.h" -class Step3DSW { +class GodotStep3D { uint64_t _step = 1; int iterations = 0; @@ -44,21 +44,21 @@ class Step3DSW { ThreadWorkPool work_pool; - LocalVector<LocalVector<Body3DSW *>> body_islands; - LocalVector<LocalVector<Constraint3DSW *>> constraint_islands; - LocalVector<Constraint3DSW *> all_constraints; + LocalVector<LocalVector<GodotBody3D *>> body_islands; + LocalVector<LocalVector<GodotConstraint3D *>> constraint_islands; + LocalVector<GodotConstraint3D *> all_constraints; - void _populate_island(Body3DSW *p_body, LocalVector<Body3DSW *> &p_body_island, LocalVector<Constraint3DSW *> &p_constraint_island); - void _populate_island_soft_body(SoftBody3DSW *p_soft_body, LocalVector<Body3DSW *> &p_body_island, LocalVector<Constraint3DSW *> &p_constraint_island); + void _populate_island(GodotBody3D *p_body, LocalVector<GodotBody3D *> &p_body_island, LocalVector<GodotConstraint3D *> &p_constraint_island); + void _populate_island_soft_body(GodotSoftBody3D *p_soft_body, LocalVector<GodotBody3D *> &p_body_island, LocalVector<GodotConstraint3D *> &p_constraint_island); void _setup_contraint(uint32_t p_constraint_index, void *p_userdata = nullptr); - void _pre_solve_island(LocalVector<Constraint3DSW *> &p_constraint_island) const; + void _pre_solve_island(LocalVector<GodotConstraint3D *> &p_constraint_island) const; void _solve_island(uint32_t p_island_index, void *p_userdata = nullptr); - void _check_suspend(const LocalVector<Body3DSW *> &p_body_island) const; + void _check_suspend(const LocalVector<GodotBody3D *> &p_body_island) const; public: - void step(Space3DSW *p_space, real_t p_delta, int p_iterations); - Step3DSW(); - ~Step3DSW(); + void step(GodotSpace3D *p_space, real_t p_delta, int p_iterations); + GodotStep3D(); + ~GodotStep3D(); }; -#endif // STEP__SW_H +#endif // GODOT_STEP_3D_H diff --git a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp b/servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp index bb9cc1bf67..31a87fc595 100644 --- a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* cone_twist_joint_3d_sw.cpp */ +/* godot_cone_twist_joint_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -49,7 +49,7 @@ subject to the following restrictions: Written by: Marcus Hennix */ -#include "cone_twist_joint_3d_sw.h" +#include "godot_cone_twist_joint_3d.h" static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) { if (Math::abs(n.z) > Math_SQRT12) { @@ -84,8 +84,8 @@ static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) { return (y < 0.0f) ? -angle : angle; } -ConeTwistJoint3DSW::ConeTwistJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame) : - Joint3DSW(_arr, 2) { +GodotConeTwistJoint3D::GodotConeTwistJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame) : + GodotJoint3D(_arr, 2) { A = rbA; B = rbB; @@ -96,7 +96,7 @@ ConeTwistJoint3DSW::ConeTwistJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Trans B->add_constraint(this, 1); } -bool ConeTwistJoint3DSW::setup(real_t p_timestep) { +bool GodotConeTwistJoint3D::setup(real_t p_timestep) { dynamic_A = (A->get_mode() > PhysicsServer3D::BODY_MODE_KINEMATIC); dynamic_B = (B->get_mode() > PhysicsServer3D::BODY_MODE_KINEMATIC); @@ -129,7 +129,7 @@ bool ConeTwistJoint3DSW::setup(real_t p_timestep) { plane_space(normal[0], normal[1], normal[2]); for (int i = 0; i < 3; i++) { - memnew_placement(&m_jac[i], JacobianEntry3DSW( + memnew_placement(&m_jac[i], GodotJacobianEntry3D( A->get_principal_inertia_axes().transposed(), B->get_principal_inertia_axes().transposed(), pivotAInW - A->get_transform().origin - A->get_center_of_mass(), @@ -230,7 +230,7 @@ bool ConeTwistJoint3DSW::setup(real_t p_timestep) { return true; } -void ConeTwistJoint3DSW::solve(real_t p_timestep) { +void GodotConeTwistJoint3D::solve(real_t p_timestep) { Vector3 pivotAInW = A->get_transform().xform(m_rbAFrame.origin); Vector3 pivotBInW = B->get_transform().xform(m_rbBFrame.origin); @@ -312,7 +312,7 @@ void ConeTwistJoint3DSW::solve(real_t p_timestep) { } } -void ConeTwistJoint3DSW::set_param(PhysicsServer3D::ConeTwistJointParam p_param, real_t p_value) { +void GodotConeTwistJoint3D::set_param(PhysicsServer3D::ConeTwistJointParam p_param, real_t p_value) { switch (p_param) { case PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN: { m_swingSpan1 = p_value; @@ -335,7 +335,7 @@ void ConeTwistJoint3DSW::set_param(PhysicsServer3D::ConeTwistJointParam p_param, } } -real_t ConeTwistJoint3DSW::get_param(PhysicsServer3D::ConeTwistJointParam p_param) const { +real_t GodotConeTwistJoint3D::get_param(PhysicsServer3D::ConeTwistJointParam p_param) const { switch (p_param) { case PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN: { return m_swingSpan1; diff --git a/servers/physics_3d/joints/cone_twist_joint_3d_sw.h b/servers/physics_3d/joints/godot_cone_twist_joint_3d.h index bf7e593820..999d0f0692 100644 --- a/servers/physics_3d/joints/cone_twist_joint_3d_sw.h +++ b/servers/physics_3d/joints/godot_cone_twist_joint_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* cone_twist_joint_3d_sw.h */ +/* godot_cone_twist_joint_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -34,7 +34,7 @@ Adapted to Godot from the Bullet library. /* Bullet Continuous Collision Detection and Physics Library -ConeTwistJointSW is Copyright (c) 2007 Starbreeze Studios +GodotConeTwistJoint3D is Copyright (c) 2007 Starbreeze Studios This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. @@ -49,28 +49,28 @@ subject to the following restrictions: Written by: Marcus Hennix */ -#ifndef CONE_TWIST_JOINT_SW_H -#define CONE_TWIST_JOINT_SW_H +#ifndef GODOT_CONE_TWIST_JOINT_3D_H +#define GODOT_CONE_TWIST_JOINT_3D_H -#include "servers/physics_3d/joints/jacobian_entry_3d_sw.h" -#include "servers/physics_3d/joints_3d_sw.h" +#include "servers/physics_3d/godot_joint_3d.h" +#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" -///ConeTwistJointSW can be used to simulate ragdoll joints (upper arm, leg etc) -class ConeTwistJoint3DSW : public Joint3DSW { +// GodotConeTwistJoint3D can be used to simulate ragdoll joints (upper arm, leg etc). +class GodotConeTwistJoint3D : public GodotJoint3D { #ifdef IN_PARALLELL_SOLVER public: #endif union { struct { - Body3DSW *A; - Body3DSW *B; + GodotBody3D *A; + GodotBody3D *B; }; - Body3DSW *_arr[2] = { nullptr, nullptr }; + GodotBody3D *_arr[2] = { nullptr, nullptr }; }; - JacobianEntry3DSW m_jac[3] = {}; //3 orthogonal linear constraints + GodotJacobianEntry3D m_jac[3] = {}; //3 orthogonal linear constraints real_t m_appliedImpulse = 0.0; Transform3D m_rbAFrame; @@ -107,7 +107,7 @@ public: virtual bool setup(real_t p_step) override; virtual void solve(real_t p_step) override; - ConeTwistJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame); + GodotConeTwistJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame); void setAngularOnly(bool angularOnly) { m_angularOnly = angularOnly; @@ -139,4 +139,4 @@ public: real_t get_param(PhysicsServer3D::ConeTwistJointParam p_param) const; }; -#endif // CONE_TWIST_JOINT_SW_H +#endif // GODOT_CONE_TWIST_JOINT_3D_H diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp b/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp index 56aba24b42..d7e0537439 100644 --- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* generic_6dof_joint_3d_sw.cpp */ +/* godot_generic_6dof_joint_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -49,18 +49,18 @@ subject to the following restrictions: /* 2007-09-09 -Generic6DOFJointSW Refactored by Francisco Le?n +GodotGeneric6DOFJoint3D Refactored by Francisco Le?n email: projectileman@yahoo.com http://gimpact.sf.net */ -#include "generic_6dof_joint_3d_sw.h" +#include "godot_generic_6dof_joint_3d.h" #define GENERIC_D6_DISABLE_WARMSTARTING 1 -//////////////////////////// G6DOFRotationalLimitMotorSW //////////////////////////////////// +//////////////////////////// GodotG6DOFRotationalLimitMotor3D //////////////////////////////////// -int G6DOFRotationalLimitMotor3DSW::testLimitValue(real_t test_value) { +int GodotG6DOFRotationalLimitMotor3D::testLimitValue(real_t test_value) { if (m_loLimit > m_hiLimit) { m_currentLimit = 0; //Free from violation return 0; @@ -80,9 +80,9 @@ int G6DOFRotationalLimitMotor3DSW::testLimitValue(real_t test_value) { return 0; } -real_t G6DOFRotationalLimitMotor3DSW::solveAngularLimits( +real_t GodotG6DOFRotationalLimitMotor3D::solveAngularLimits( real_t timeStep, Vector3 &axis, real_t jacDiagABInv, - Body3DSW *body0, Body3DSW *body1, bool p_body0_dynamic, bool p_body1_dynamic) { + GodotBody3D *body0, GodotBody3D *body1, bool p_body0_dynamic, bool p_body1_dynamic) { if (!needApplyTorques()) { return 0.0f; } @@ -148,14 +148,13 @@ real_t G6DOFRotationalLimitMotor3DSW::solveAngularLimits( return clippedMotorImpulse; } -//////////////////////////// End G6DOFRotationalLimitMotorSW //////////////////////////////////// +//////////////////////////// GodotG6DOFTranslationalLimitMotor3D //////////////////////////////////// -//////////////////////////// G6DOFTranslationalLimitMotorSW //////////////////////////////////// -real_t G6DOFTranslationalLimitMotor3DSW::solveLinearAxis( +real_t GodotG6DOFTranslationalLimitMotor3D::solveLinearAxis( real_t timeStep, real_t jacDiagABInv, - Body3DSW *body1, const Vector3 &pointInA, - Body3DSW *body2, const Vector3 &pointInB, + GodotBody3D *body1, const Vector3 &pointInA, + GodotBody3D *body2, const Vector3 &pointInB, bool p_body1_dynamic, bool p_body2_dynamic, int limit_index, const Vector3 &axis_normal_on_a, @@ -217,10 +216,10 @@ real_t G6DOFTranslationalLimitMotor3DSW::solveLinearAxis( return normalImpulse; } -//////////////////////////// G6DOFTranslationalLimitMotorSW //////////////////////////////////// +//////////////////////////// GodotGeneric6DOFJoint3D //////////////////////////////////// -Generic6DOFJoint3DSW::Generic6DOFJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &frameInA, const Transform3D &frameInB, bool useLinearReferenceFrameA) : - Joint3DSW(_arr, 2), +GodotGeneric6DOFJoint3D::GodotGeneric6DOFJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameInA, const Transform3D &frameInB, bool useLinearReferenceFrameA) : + GodotJoint3D(_arr, 2), m_frameInA(frameInA), m_frameInB(frameInB), m_useLinearReferenceFrameA(useLinearReferenceFrameA) { @@ -230,7 +229,7 @@ Generic6DOFJoint3DSW::Generic6DOFJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const T B->add_constraint(this, 1); } -void Generic6DOFJoint3DSW::calculateAngleInfo() { +void GodotGeneric6DOFJoint3D::calculateAngleInfo() { Basis relative_frame = m_calculatedTransformB.basis.inverse() * m_calculatedTransformA.basis; m_calculatedAxisAngleDiff = relative_frame.get_euler_xyz(); @@ -270,17 +269,17 @@ void Generic6DOFJoint3DSW::calculateAngleInfo() { */ } -void Generic6DOFJoint3DSW::calculateTransforms() { +void GodotGeneric6DOFJoint3D::calculateTransforms() { m_calculatedTransformA = A->get_transform() * m_frameInA; m_calculatedTransformB = B->get_transform() * m_frameInB; calculateAngleInfo(); } -void Generic6DOFJoint3DSW::buildLinearJacobian( - JacobianEntry3DSW &jacLinear, const Vector3 &normalWorld, +void GodotGeneric6DOFJoint3D::buildLinearJacobian( + GodotJacobianEntry3D &jacLinear, const Vector3 &normalWorld, const Vector3 &pivotAInW, const Vector3 &pivotBInW) { - memnew_placement(&jacLinear, JacobianEntry3DSW( + memnew_placement(&jacLinear, GodotJacobianEntry3D( A->get_principal_inertia_axes().transposed(), B->get_principal_inertia_axes().transposed(), pivotAInW - A->get_transform().origin - A->get_center_of_mass(), @@ -292,16 +291,16 @@ void Generic6DOFJoint3DSW::buildLinearJacobian( B->get_inv_mass())); } -void Generic6DOFJoint3DSW::buildAngularJacobian( - JacobianEntry3DSW &jacAngular, const Vector3 &jointAxisW) { - memnew_placement(&jacAngular, JacobianEntry3DSW(jointAxisW, +void GodotGeneric6DOFJoint3D::buildAngularJacobian( + GodotJacobianEntry3D &jacAngular, const Vector3 &jointAxisW) { + memnew_placement(&jacAngular, GodotJacobianEntry3D(jointAxisW, A->get_principal_inertia_axes().transposed(), B->get_principal_inertia_axes().transposed(), A->get_inv_inertia(), B->get_inv_inertia())); } -bool Generic6DOFJoint3DSW::testAngularLimitMotor(int axis_index) { +bool GodotGeneric6DOFJoint3D::testAngularLimitMotor(int axis_index) { real_t angle = m_calculatedAxisAngleDiff[axis_index]; //test limits @@ -309,7 +308,7 @@ bool Generic6DOFJoint3DSW::testAngularLimitMotor(int axis_index) { return m_angularLimits[axis_index].needApplyTorques(); } -bool Generic6DOFJoint3DSW::setup(real_t p_timestep) { +bool GodotGeneric6DOFJoint3D::setup(real_t p_timestep) { dynamic_A = (A->get_mode() > PhysicsServer3D::BODY_MODE_KINEMATIC); dynamic_B = (B->get_mode() > PhysicsServer3D::BODY_MODE_KINEMATIC); @@ -365,7 +364,7 @@ bool Generic6DOFJoint3DSW::setup(real_t p_timestep) { return true; } -void Generic6DOFJoint3DSW::solve(real_t p_timestep) { +void GodotGeneric6DOFJoint3D::solve(real_t p_timestep) { m_timeStep = p_timestep; //calculateTransforms(); @@ -414,19 +413,19 @@ void Generic6DOFJoint3DSW::solve(real_t p_timestep) { } } -void Generic6DOFJoint3DSW::updateRHS(real_t timeStep) { +void GodotGeneric6DOFJoint3D::updateRHS(real_t timeStep) { (void)timeStep; } -Vector3 Generic6DOFJoint3DSW::getAxis(int axis_index) const { +Vector3 GodotGeneric6DOFJoint3D::getAxis(int axis_index) const { return m_calculatedAxis[axis_index]; } -real_t Generic6DOFJoint3DSW::getAngle(int axis_index) const { +real_t GodotGeneric6DOFJoint3D::getAngle(int axis_index) const { return m_calculatedAxisAngleDiff[axis_index]; } -void Generic6DOFJoint3DSW::calcAnchorPos() { +void GodotGeneric6DOFJoint3D::calcAnchorPos() { real_t imA = A->get_inv_mass(); real_t imB = B->get_inv_mass(); real_t weight; @@ -438,9 +437,9 @@ void Generic6DOFJoint3DSW::calcAnchorPos() { const Vector3 &pA = m_calculatedTransformA.origin; const Vector3 &pB = m_calculatedTransformB.origin; m_AnchorPos = pA * weight + pB * (real_t(1.0) - weight); -} // Generic6DOFJointSW::calcAnchorPos() +} -void Generic6DOFJoint3DSW::set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param, real_t p_value) { +void GodotGeneric6DOFJoint3D::set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param, real_t p_value) { ERR_FAIL_INDEX(p_axis, 3); switch (p_param) { case PhysicsServer3D::G6DOF_JOINT_LINEAR_LOWER_LIMIT: { @@ -527,7 +526,7 @@ void Generic6DOFJoint3DSW::set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DO } } -real_t Generic6DOFJoint3DSW::get_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param) const { +real_t GodotGeneric6DOFJoint3D::get_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param) const { ERR_FAIL_INDEX_V(p_axis, 3, 0); switch (p_param) { case PhysicsServer3D::G6DOF_JOINT_LINEAR_LOWER_LIMIT: { @@ -615,7 +614,7 @@ real_t Generic6DOFJoint3DSW::get_param(Vector3::Axis p_axis, PhysicsServer3D::G6 return 0; } -void Generic6DOFJoint3DSW::set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag, bool p_value) { +void GodotGeneric6DOFJoint3D::set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag, bool p_value) { ERR_FAIL_INDEX(p_axis, 3); switch (p_flag) { @@ -642,7 +641,7 @@ void Generic6DOFJoint3DSW::set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOF } } -bool Generic6DOFJoint3DSW::get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const { +bool GodotGeneric6DOFJoint3D::get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const { ERR_FAIL_INDEX_V(p_axis, 3, 0); switch (p_flag) { case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT: { diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h b/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h index 6492e40393..729b3fa1f9 100644 --- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h +++ b/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* generic_6dof_joint_3d_sw.h */ +/* godot_generic_6dof_joint_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -32,11 +32,11 @@ Adapted to Godot from the Bullet library. */ -#ifndef GENERIC_6DOF_JOINT_SW_H -#define GENERIC_6DOF_JOINT_SW_H +#ifndef GODOT_GENERIC_6DOF_JOINT_3D_H +#define GODOT_GENERIC_6DOF_JOINT_3D_H -#include "servers/physics_3d/joints/jacobian_entry_3d_sw.h" -#include "servers/physics_3d/joints_3d_sw.h" +#include "servers/physics_3d/godot_joint_3d.h" +#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" /* Bullet Continuous Collision Detection and Physics Library @@ -55,13 +55,13 @@ subject to the following restrictions: /* 2007-09-09 -Generic6DOFJointSW Refactored by Francisco Le?n +GodotGeneric6DOFJoint3D Refactored by Francisco Le?n email: projectileman@yahoo.com http://gimpact.sf.net */ //! Rotation Limit structure for generic joints -class G6DOFRotationalLimitMotor3DSW { +class GodotG6DOFRotationalLimitMotor3D { public: //! limit_parameters //!@{ @@ -86,29 +86,25 @@ public: real_t m_accumulatedImpulse = 0.0; //!@} - G6DOFRotationalLimitMotor3DSW() {} + GodotG6DOFRotationalLimitMotor3D() {} - //! Is limited bool isLimited() { return (m_loLimit < m_hiLimit); } - //! Need apply correction + // Need apply correction. bool needApplyTorques() { return (m_enableMotor || m_currentLimit != 0); } - //! calculates error - /*! - calculates m_currentLimit and m_currentLimitError. - */ + // Calculates m_currentLimit and m_currentLimitError. int testLimitValue(real_t test_value); - //! apply the correction impulses for two bodies - real_t solveAngularLimits(real_t timeStep, Vector3 &axis, real_t jacDiagABInv, Body3DSW *body0, Body3DSW *body1, bool p_body0_dynamic, bool p_body1_dynamic); + // Apply the correction impulses for two bodies. + real_t solveAngularLimits(real_t timeStep, Vector3 &axis, real_t jacDiagABInv, GodotBody3D *body0, GodotBody3D *body1, bool p_body0_dynamic, bool p_body1_dynamic); }; -class G6DOFTranslationalLimitMotor3DSW { +class GodotG6DOFTranslationalLimitMotor3D { public: Vector3 m_lowerLimit = Vector3(0.0, 0.0, 0.0); //!< the constraint lower limits Vector3 m_upperLimit = Vector3(0.0, 0.0, 0.0); //!< the constraint upper limits @@ -135,23 +131,23 @@ public: real_t solveLinearAxis( real_t timeStep, real_t jacDiagABInv, - Body3DSW *body1, const Vector3 &pointInA, - Body3DSW *body2, const Vector3 &pointInB, + GodotBody3D *body1, const Vector3 &pointInA, + GodotBody3D *body2, const Vector3 &pointInB, bool p_body1_dynamic, bool p_body2_dynamic, int limit_index, const Vector3 &axis_normal_on_a, const Vector3 &anchorPos); }; -class Generic6DOFJoint3DSW : public Joint3DSW { +class GodotGeneric6DOFJoint3D : public GodotJoint3D { protected: union { struct { - Body3DSW *A; - Body3DSW *B; + GodotBody3D *A; + GodotBody3D *B; }; - Body3DSW *_arr[2] = { nullptr, nullptr }; + GodotBody3D *_arr[2] = { nullptr, nullptr }; }; //! relative_frames @@ -162,18 +158,18 @@ protected: //! Jacobians //!@{ - JacobianEntry3DSW m_jacLinear[3]; //!< 3 orthogonal linear constraints - JacobianEntry3DSW m_jacAng[3]; //!< 3 orthogonal angular constraints + GodotJacobianEntry3D m_jacLinear[3]; //!< 3 orthogonal linear constraints + GodotJacobianEntry3D m_jacAng[3]; //!< 3 orthogonal angular constraints //!@} //! Linear_Limit_parameters //!@{ - G6DOFTranslationalLimitMotor3DSW m_linearLimits; + GodotG6DOFTranslationalLimitMotor3D m_linearLimits; //!@} //! hinge_parameters //!@{ - G6DOFRotationalLimitMotor3DSW m_angularLimits[3]; + GodotG6DOFRotationalLimitMotor3D m_angularLimits[3]; //!@} protected: @@ -191,45 +187,35 @@ protected: //!@} - Generic6DOFJoint3DSW(Generic6DOFJoint3DSW const &) = delete; - void operator=(Generic6DOFJoint3DSW const &) = delete; + GodotGeneric6DOFJoint3D(GodotGeneric6DOFJoint3D const &) = delete; + void operator=(GodotGeneric6DOFJoint3D const &) = delete; void buildLinearJacobian( - JacobianEntry3DSW &jacLinear, const Vector3 &normalWorld, + GodotJacobianEntry3D &jacLinear, const Vector3 &normalWorld, const Vector3 &pivotAInW, const Vector3 &pivotBInW); - void buildAngularJacobian(JacobianEntry3DSW &jacAngular, const Vector3 &jointAxisW); + void buildAngularJacobian(GodotJacobianEntry3D &jacAngular, const Vector3 &jointAxisW); //! calcs the euler angles between the two bodies. void calculateAngleInfo(); public: - Generic6DOFJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &frameInA, const Transform3D &frameInB, bool useLinearReferenceFrameA); + GodotGeneric6DOFJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameInA, const Transform3D &frameInB, bool useLinearReferenceFrameA); virtual PhysicsServer3D::JointType get_type() const override { return PhysicsServer3D::JOINT_TYPE_6DOF; } virtual bool setup(real_t p_step) override; virtual void solve(real_t p_step) override; - //! Calcs global transform of the offsets - /*! - Calcs the global transform for the joint offset for body A an B, and also calcs the agle differences between the bodies. - \sa Generic6DOFJointSW.getCalculatedTransformA , Generic6DOFJointSW.getCalculatedTransformB, Generic6DOFJointSW.calculateAngleInfo - */ + // Calcs the global transform for the joint offset for body A an B, and also calcs the angle differences between the bodies. void calculateTransforms(); - //! Gets the global transform of the offset for body A - /*! - \sa Generic6DOFJointSW.getFrameOffsetA, Generic6DOFJointSW.getFrameOffsetB, Generic6DOFJointSW.calculateAngleInfo. - */ + // Gets the global transform of the offset for body A. const Transform3D &getCalculatedTransformA() const { return m_calculatedTransformA; } - //! Gets the global transform of the offset for body B - /*! - \sa Generic6DOFJointSW.getFrameOffsetA, Generic6DOFJointSW.getFrameOffsetB, Generic6DOFJointSW.calculateAngleInfo. - */ + // Gets the global transform of the offset for body B. const Transform3D &getCalculatedTransformB() const { return m_calculatedTransformB; } @@ -250,27 +236,16 @@ public: return m_frameInB; } - //! performs Jacobian calculation, and also calculates angle differences and axis - + // Performs Jacobian calculation, and also calculates angle differences and axis. void updateRHS(real_t timeStep); - //! Get the rotation axis in global coordinates - /*! - \pre Generic6DOFJointSW.buildJacobian must be called previously. - */ + // Get the rotation axis in global coordinates. Vector3 getAxis(int axis_index) const; - //! Get the relative Euler angle - /*! - \pre Generic6DOFJointSW.buildJacobian must be called previously. - */ + // Get the relative Euler angle. real_t getAngle(int axis_index) const; - //! Test angular limit. - /*! - Calculates angular correction and returns true if limit needs to be corrected. - \pre Generic6DOFJointSW.buildJacobian must be called previously. - */ + // Calculates angular correction and returns true if limit needs to be corrected. bool testAngularLimitMotor(int axis_index); void setLinearLowerLimit(const Vector3 &linearLower) { @@ -293,17 +268,17 @@ public: m_angularLimits[2].m_hiLimit = angularUpper.z; } - //! Retrieves the angular limit information. - G6DOFRotationalLimitMotor3DSW *getRotationalLimitMotor(int index) { + // Retrieves the angular limit information. + GodotG6DOFRotationalLimitMotor3D *getRotationalLimitMotor(int index) { return &m_angularLimits[index]; } - //! Retrieves the limit information. - G6DOFTranslationalLimitMotor3DSW *getTranslationalLimitMotor() { + // Retrieves the limit information. + GodotG6DOFTranslationalLimitMotor3D *getTranslationalLimitMotor() { return &m_linearLimits; } - //first 3 are linear, next 3 are angular + // First 3 are linear, next 3 are angular. void setLimit(int axis, real_t lo, real_t hi) { if (axis < 3) { m_linearLimits.m_lowerLimit[axis] = lo; @@ -328,10 +303,10 @@ public: return m_angularLimits[limitIndex - 3].isLimited(); } - const Body3DSW *getRigidBodyA() const { + const GodotBody3D *getRigidBodyA() const { return A; } - const Body3DSW *getRigidBodyB() const { + const GodotBody3D *getRigidBodyB() const { return B; } @@ -344,4 +319,4 @@ public: bool get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const; }; -#endif // GENERIC_6DOF_JOINT_SW_H +#endif // GODOT_GENERIC_6DOF_JOINT_3D_H diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.cpp b/servers/physics_3d/joints/godot_hinge_joint_3d.cpp index a45fcf7eb5..7b7ca1b3ac 100644 --- a/servers/physics_3d/joints/hinge_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/godot_hinge_joint_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* hinge_joint_3d_sw.cpp */ +/* godot_hinge_joint_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -47,7 +47,7 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#include "hinge_joint_3d_sw.h" +#include "godot_hinge_joint_3d.h" static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) { if (Math::abs(n.z) > Math_SQRT12) { @@ -67,8 +67,8 @@ static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) { } } -HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &frameA, const Transform3D &frameB) : - Joint3DSW(_arr, 2) { +GodotHingeJoint3D::GodotHingeJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameA, const Transform3D &frameB) : + GodotJoint3D(_arr, 2) { A = rbA; B = rbB; @@ -83,9 +83,9 @@ HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D & B->add_constraint(this, 1); } -HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB, +GodotHingeJoint3D::GodotHingeJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB, const Vector3 &axisInA, const Vector3 &axisInB) : - Joint3DSW(_arr, 2) { + GodotJoint3D(_arr, 2) { A = rbA; B = rbB; @@ -124,7 +124,7 @@ HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Vector3 &pivo B->add_constraint(this, 1); } -bool HingeJoint3DSW::setup(real_t p_step) { +bool GodotHingeJoint3D::setup(real_t p_step) { dynamic_A = (A->get_mode() > PhysicsServer3D::BODY_MODE_KINEMATIC); dynamic_B = (B->get_mode() > PhysicsServer3D::BODY_MODE_KINEMATIC); @@ -149,7 +149,7 @@ bool HingeJoint3DSW::setup(real_t p_step) { plane_space(normal[0], normal[1], normal[2]); for (int i = 0; i < 3; i++) { - memnew_placement(&m_jac[i], JacobianEntry3DSW( + memnew_placement(&m_jac[i], GodotJacobianEntry3D( A->get_principal_inertia_axes().transposed(), B->get_principal_inertia_axes().transposed(), pivotAInW - A->get_transform().origin - A->get_center_of_mass(), @@ -175,19 +175,19 @@ bool HingeJoint3DSW::setup(real_t p_step) { Vector3 jointAxis1 = A->get_transform().basis.xform(jointAxis1local); Vector3 hingeAxisWorld = A->get_transform().basis.xform(m_rbAFrame.basis.get_axis(2)); - memnew_placement(&m_jacAng[0], JacobianEntry3DSW(jointAxis0, + memnew_placement(&m_jacAng[0], GodotJacobianEntry3D(jointAxis0, A->get_principal_inertia_axes().transposed(), B->get_principal_inertia_axes().transposed(), A->get_inv_inertia(), B->get_inv_inertia())); - memnew_placement(&m_jacAng[1], JacobianEntry3DSW(jointAxis1, + memnew_placement(&m_jacAng[1], GodotJacobianEntry3D(jointAxis1, A->get_principal_inertia_axes().transposed(), B->get_principal_inertia_axes().transposed(), A->get_inv_inertia(), B->get_inv_inertia())); - memnew_placement(&m_jacAng[2], JacobianEntry3DSW(hingeAxisWorld, + memnew_placement(&m_jacAng[2], GodotJacobianEntry3D(hingeAxisWorld, A->get_principal_inertia_axes().transposed(), B->get_principal_inertia_axes().transposed(), A->get_inv_inertia(), @@ -226,7 +226,7 @@ bool HingeJoint3DSW::setup(real_t p_step) { return true; } -void HingeJoint3DSW::solve(real_t p_step) { +void GodotHingeJoint3D::solve(real_t p_step) { Vector3 pivotAInW = A->get_transform().xform(m_rbAFrame.origin); Vector3 pivotBInW = B->get_transform().xform(m_rbBFrame.origin); @@ -377,7 +377,7 @@ static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) { return (y < 0.0f) ? -angle : angle; } -real_t HingeJoint3DSW::get_hinge_angle() { +real_t GodotHingeJoint3D::get_hinge_angle() { const Vector3 refAxis0 = A->get_transform().basis.xform(m_rbAFrame.basis.get_axis(0)); const Vector3 refAxis1 = A->get_transform().basis.xform(m_rbAFrame.basis.get_axis(1)); const Vector3 swingAxis = B->get_transform().basis.xform(m_rbBFrame.basis.get_axis(1)); @@ -385,7 +385,7 @@ real_t HingeJoint3DSW::get_hinge_angle() { return atan2fast(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1)); } -void HingeJoint3DSW::set_param(PhysicsServer3D::HingeJointParam p_param, real_t p_value) { +void GodotHingeJoint3D::set_param(PhysicsServer3D::HingeJointParam p_param, real_t p_value) { switch (p_param) { case PhysicsServer3D::HINGE_JOINT_BIAS: tau = p_value; @@ -416,7 +416,7 @@ void HingeJoint3DSW::set_param(PhysicsServer3D::HingeJointParam p_param, real_t } } -real_t HingeJoint3DSW::get_param(PhysicsServer3D::HingeJointParam p_param) const { +real_t GodotHingeJoint3D::get_param(PhysicsServer3D::HingeJointParam p_param) const { switch (p_param) { case PhysicsServer3D::HINGE_JOINT_BIAS: return tau; @@ -441,7 +441,7 @@ real_t HingeJoint3DSW::get_param(PhysicsServer3D::HingeJointParam p_param) const return 0; } -void HingeJoint3DSW::set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_value) { +void GodotHingeJoint3D::set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_value) { switch (p_flag) { case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT: m_useLimit = p_value; @@ -454,7 +454,7 @@ void HingeJoint3DSW::set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_val } } -bool HingeJoint3DSW::get_flag(PhysicsServer3D::HingeJointFlag p_flag) const { +bool GodotHingeJoint3D::get_flag(PhysicsServer3D::HingeJointFlag p_flag) const { switch (p_flag) { case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT: return m_useLimit; diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.h b/servers/physics_3d/joints/godot_hinge_joint_3d.h index a4ceff9ffe..ff1fbe0f25 100644 --- a/servers/physics_3d/joints/hinge_joint_3d_sw.h +++ b/servers/physics_3d/joints/godot_hinge_joint_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* hinge_joint_3d_sw.h */ +/* godot_hinge_joint_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -32,11 +32,11 @@ Adapted to Godot from the Bullet library. */ -#ifndef HINGE_JOINT_SW_H -#define HINGE_JOINT_SW_H +#ifndef GODOT_HINGE_JOINT_3D_H +#define GODOT_HINGE_JOINT_3D_H -#include "servers/physics_3d/joints/jacobian_entry_3d_sw.h" -#include "servers/physics_3d/joints_3d_sw.h" +#include "servers/physics_3d/godot_joint_3d.h" +#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" /* Bullet Continuous Collision Detection and Physics Library @@ -53,18 +53,18 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -class HingeJoint3DSW : public Joint3DSW { +class GodotHingeJoint3D : public GodotJoint3D { union { struct { - Body3DSW *A; - Body3DSW *B; + GodotBody3D *A; + GodotBody3D *B; }; - Body3DSW *_arr[2] = {}; + GodotBody3D *_arr[2] = {}; }; - JacobianEntry3DSW m_jac[3]; //3 orthogonal linear constraints - JacobianEntry3DSW m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor + GodotJacobianEntry3D m_jac[3]; //3 orthogonal linear constraints + GodotJacobianEntry3D m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor Transform3D m_rbAFrame; // constraint axii. Assumes z is hinge axis. Transform3D m_rbBFrame; @@ -109,8 +109,8 @@ public: void set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_value); bool get_flag(PhysicsServer3D::HingeJointFlag p_flag) const; - HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &frameA, const Transform3D &frameB); - HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB, const Vector3 &axisInA, const Vector3 &axisInB); + GodotHingeJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameA, const Transform3D &frameB); + GodotHingeJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB, const Vector3 &axisInA, const Vector3 &axisInB); }; -#endif // HINGE_JOINT_SW_H +#endif // GODOT_HINGE_JOINT_3D_H diff --git a/servers/physics_3d/joints/jacobian_entry_3d_sw.h b/servers/physics_3d/joints/godot_jacobian_entry_3d.h index 7294ff78e3..90a77a9b61 100644 --- a/servers/physics_3d/joints/jacobian_entry_3d_sw.h +++ b/servers/physics_3d/joints/godot_jacobian_entry_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* jacobian_entry_3d_sw.h */ +/* godot_jacobian_entry_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -32,8 +32,8 @@ Adapted to Godot from the Bullet library. */ -#ifndef JACOBIAN_ENTRY_SW_H -#define JACOBIAN_ENTRY_SW_H +#ifndef GODOT_JACOBIAN_ENTRY_3D_H +#define GODOT_JACOBIAN_ENTRY_3D_H /* Bullet Continuous Collision Detection and Physics Library @@ -52,11 +52,11 @@ subject to the following restrictions: #include "core/math/transform_3d.h" -class JacobianEntry3DSW { +class GodotJacobianEntry3D { public: - JacobianEntry3DSW() {} + GodotJacobianEntry3D() {} //constraint between two different rigidbodies - JacobianEntry3DSW( + GodotJacobianEntry3D( const Basis &world2A, const Basis &world2B, const Vector3 &rel_pos1, const Vector3 &rel_pos2, @@ -76,7 +76,7 @@ public: } //angular constraint between two different rigidbodies - JacobianEntry3DSW(const Vector3 &jointAxis, + GodotJacobianEntry3D(const Vector3 &jointAxis, const Basis &world2A, const Basis &world2B, const Vector3 &inertiaInvA, @@ -92,7 +92,7 @@ public: } //angular constraint between two different rigidbodies - JacobianEntry3DSW(const Vector3 &axisInA, + GodotJacobianEntry3D(const Vector3 &axisInA, const Vector3 &axisInB, const Vector3 &inertiaInvA, const Vector3 &inertiaInvB) : @@ -107,7 +107,7 @@ public: } //constraint on one rigidbody - JacobianEntry3DSW( + GodotJacobianEntry3D( const Basis &world2A, const Vector3 &rel_pos1, const Vector3 &rel_pos2, const Vector3 &jointAxis, @@ -126,16 +126,16 @@ public: real_t getDiagonal() const { return m_Adiag; } // for two constraints on the same rigidbody (for example vehicle friction) - real_t getNonDiagonal(const JacobianEntry3DSW &jacB, const real_t massInvA) const { - const JacobianEntry3DSW &jacA = *this; + real_t getNonDiagonal(const GodotJacobianEntry3D &jacB, const real_t massInvA) const { + const GodotJacobianEntry3D &jacA = *this; real_t lin = massInvA * jacA.m_linearJointAxis.dot(jacB.m_linearJointAxis); real_t ang = jacA.m_0MinvJt.dot(jacB.m_aJ); return lin + ang; } // for two constraints on sharing two same rigidbodies (for example two contact points between two rigidbodies) - real_t getNonDiagonal(const JacobianEntry3DSW &jacB, const real_t massInvA, const real_t massInvB) const { - const JacobianEntry3DSW &jacA = *this; + real_t getNonDiagonal(const GodotJacobianEntry3D &jacB, const real_t massInvA, const real_t massInvB) const { + const GodotJacobianEntry3D &jacA = *this; Vector3 lin = jacA.m_linearJointAxis * jacB.m_linearJointAxis; Vector3 ang0 = jacA.m_0MinvJt * jacB.m_aJ; Vector3 ang1 = jacA.m_1MinvJt * jacB.m_bJ; @@ -166,4 +166,4 @@ public: real_t m_Adiag = 1.0; }; -#endif // JACOBIAN_ENTRY_SW_H +#endif // GODOT_JACOBIAN_ENTRY_3D_H diff --git a/servers/physics_3d/joints/pin_joint_3d_sw.cpp b/servers/physics_3d/joints/godot_pin_joint_3d.cpp index f41151ec0e..10d52ad5e9 100644 --- a/servers/physics_3d/joints/pin_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/godot_pin_joint_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* pin_joint_3d_sw.cpp */ +/* godot_pin_joint_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -47,9 +47,9 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#include "pin_joint_3d_sw.h" +#include "godot_pin_joint_3d.h" -bool PinJoint3DSW::setup(real_t p_step) { +bool GodotPinJoint3D::setup(real_t p_step) { dynamic_A = (A->get_mode() > PhysicsServer3D::BODY_MODE_KINEMATIC); dynamic_B = (B->get_mode() > PhysicsServer3D::BODY_MODE_KINEMATIC); @@ -63,7 +63,7 @@ bool PinJoint3DSW::setup(real_t p_step) { for (int i = 0; i < 3; i++) { normal[i] = 1; - memnew_placement(&m_jac[i], JacobianEntry3DSW( + memnew_placement(&m_jac[i], GodotJacobianEntry3D( A->get_principal_inertia_axes().transposed(), B->get_principal_inertia_axes().transposed(), A->get_transform().xform(m_pivotInA) - A->get_transform().origin - A->get_center_of_mass(), @@ -79,7 +79,7 @@ bool PinJoint3DSW::setup(real_t p_step) { return true; } -void PinJoint3DSW::solve(real_t p_step) { +void GodotPinJoint3D::solve(real_t p_step) { Vector3 pivotAInW = A->get_transform().xform(m_pivotInA); Vector3 pivotBInW = B->get_transform().xform(m_pivotInB); @@ -137,7 +137,7 @@ void PinJoint3DSW::solve(real_t p_step) { } } -void PinJoint3DSW::set_param(PhysicsServer3D::PinJointParam p_param, real_t p_value) { +void GodotPinJoint3D::set_param(PhysicsServer3D::PinJointParam p_param, real_t p_value) { switch (p_param) { case PhysicsServer3D::PIN_JOINT_BIAS: m_tau = p_value; @@ -151,7 +151,7 @@ void PinJoint3DSW::set_param(PhysicsServer3D::PinJointParam p_param, real_t p_va } } -real_t PinJoint3DSW::get_param(PhysicsServer3D::PinJointParam p_param) const { +real_t GodotPinJoint3D::get_param(PhysicsServer3D::PinJointParam p_param) const { switch (p_param) { case PhysicsServer3D::PIN_JOINT_BIAS: return m_tau; @@ -164,8 +164,8 @@ real_t PinJoint3DSW::get_param(PhysicsServer3D::PinJointParam p_param) const { return 0; } -PinJoint3DSW::PinJoint3DSW(Body3DSW *p_body_a, const Vector3 &p_pos_a, Body3DSW *p_body_b, const Vector3 &p_pos_b) : - Joint3DSW(_arr, 2) { +GodotPinJoint3D::GodotPinJoint3D(GodotBody3D *p_body_a, const Vector3 &p_pos_a, GodotBody3D *p_body_b, const Vector3 &p_pos_b) : + GodotJoint3D(_arr, 2) { A = p_body_a; B = p_body_b; m_pivotInA = p_pos_a; @@ -175,5 +175,5 @@ PinJoint3DSW::PinJoint3DSW(Body3DSW *p_body_a, const Vector3 &p_pos_a, Body3DSW B->add_constraint(this, 1); } -PinJoint3DSW::~PinJoint3DSW() { +GodotPinJoint3D::~GodotPinJoint3D() { } diff --git a/servers/physics_3d/joints/pin_joint_3d_sw.h b/servers/physics_3d/joints/godot_pin_joint_3d.h index 79af48f2a5..17e2e6e973 100644 --- a/servers/physics_3d/joints/pin_joint_3d_sw.h +++ b/servers/physics_3d/joints/godot_pin_joint_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* pin_joint_3d_sw.h */ +/* godot_pin_joint_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -32,11 +32,11 @@ Adapted to Godot from the Bullet library. */ -#ifndef PIN_JOINT_SW_H -#define PIN_JOINT_SW_H +#ifndef GODOT_PIN_JOINT_3D_H +#define GODOT_PIN_JOINT_3D_H -#include "servers/physics_3d/joints/jacobian_entry_3d_sw.h" -#include "servers/physics_3d/joints_3d_sw.h" +#include "servers/physics_3d/godot_joint_3d.h" +#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" /* Bullet Continuous Collision Detection and Physics Library @@ -53,14 +53,14 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -class PinJoint3DSW : public Joint3DSW { +class GodotPinJoint3D : public GodotJoint3D { union { struct { - Body3DSW *A; - Body3DSW *B; + GodotBody3D *A; + GodotBody3D *B; }; - Body3DSW *_arr[2] = {}; + GodotBody3D *_arr[2] = {}; }; real_t m_tau = 0.3; //bias @@ -68,7 +68,7 @@ class PinJoint3DSW : public Joint3DSW { real_t m_impulseClamp = 0.0; real_t m_appliedImpulse = 0.0; - JacobianEntry3DSW m_jac[3] = {}; //3 orthogonal linear constraints + GodotJacobianEntry3D m_jac[3] = {}; //3 orthogonal linear constraints Vector3 m_pivotInA; Vector3 m_pivotInB; @@ -88,8 +88,8 @@ public: Vector3 get_position_a() { return m_pivotInA; } Vector3 get_position_b() { return m_pivotInB; } - PinJoint3DSW(Body3DSW *p_body_a, const Vector3 &p_pos_a, Body3DSW *p_body_b, const Vector3 &p_pos_b); - ~PinJoint3DSW(); + GodotPinJoint3D(GodotBody3D *p_body_a, const Vector3 &p_pos_a, GodotBody3D *p_body_b, const Vector3 &p_pos_b); + ~GodotPinJoint3D(); }; -#endif // PIN_JOINT_SW_H +#endif // GODOT_PIN_JOINT_3D_H diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.cpp b/servers/physics_3d/joints/godot_slider_joint_3d.cpp index e10ed436d5..3be111ac92 100644 --- a/servers/physics_3d/joints/slider_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/godot_slider_joint_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* slider_joint_3d_sw.cpp */ +/* godot_slider_joint_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -53,7 +53,7 @@ April 04, 2008 */ -#include "slider_joint_3d_sw.h" +#include "godot_slider_joint_3d.h" //----------------------------------------------------------------------------- @@ -76,8 +76,8 @@ static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) { //----------------------------------------------------------------------------- -SliderJoint3DSW::SliderJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &frameInA, const Transform3D &frameInB) : - Joint3DSW(_arr, 2), +GodotSliderJoint3D::GodotSliderJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameInA, const Transform3D &frameInB) : + GodotJoint3D(_arr, 2), m_frameInA(frameInA), m_frameInB(frameInB) { A = rbA; @@ -85,11 +85,11 @@ SliderJoint3DSW::SliderJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D A->add_constraint(this, 0); B->add_constraint(this, 1); -} // SliderJointSW::SliderJointSW() +} //----------------------------------------------------------------------------- -bool SliderJoint3DSW::setup(real_t p_step) { +bool GodotSliderJoint3D::setup(real_t p_step) { dynamic_A = (A->get_mode() > PhysicsServer3D::BODY_MODE_KINEMATIC); dynamic_B = (B->get_mode() > PhysicsServer3D::BODY_MODE_KINEMATIC); @@ -112,7 +112,7 @@ bool SliderJoint3DSW::setup(real_t p_step) { //linear part for (i = 0; i < 3; i++) { normalWorld = m_calculatedTransformA.basis.get_axis(i); - memnew_placement(&m_jacLin[i], JacobianEntry3DSW( + memnew_placement(&m_jacLin[i], GodotJacobianEntry3D( A->get_principal_inertia_axes().transposed(), B->get_principal_inertia_axes().transposed(), m_relPosA - A->get_center_of_mass(), @@ -129,7 +129,7 @@ bool SliderJoint3DSW::setup(real_t p_step) { // angular part for (i = 0; i < 3; i++) { normalWorld = m_calculatedTransformA.basis.get_axis(i); - memnew_placement(&m_jacAng[i], JacobianEntry3DSW( + memnew_placement(&m_jacAng[i], GodotJacobianEntry3D( normalWorld, A->get_principal_inertia_axes().transposed(), B->get_principal_inertia_axes().transposed(), @@ -144,11 +144,11 @@ bool SliderJoint3DSW::setup(real_t p_step) { m_accumulatedAngMotorImpulse = real_t(0.0); return true; -} // SliderJointSW::buildJacobianInt() +} //----------------------------------------------------------------------------- -void SliderJoint3DSW::solve(real_t p_step) { +void GodotSliderJoint3D::solve(real_t p_step) { int i; // linear Vector3 velA = A->get_velocity_in_local_point(m_relPosA); @@ -284,13 +284,11 @@ void SliderJoint3DSW::solve(real_t p_step) { } } } -} // SliderJointSW::solveConstraint() - -//----------------------------------------------------------------------------- +} //----------------------------------------------------------------------------- -void SliderJoint3DSW::calculateTransforms() { +void GodotSliderJoint3D::calculateTransforms() { m_calculatedTransformA = A->get_transform() * m_frameInA; m_calculatedTransformB = B->get_transform() * m_frameInB; m_realPivotAInW = m_calculatedTransformA.origin; @@ -305,11 +303,11 @@ void SliderJoint3DSW::calculateTransforms() { normalWorld = m_calculatedTransformA.basis.get_axis(i); m_depth[i] = m_delta.dot(normalWorld); } -} // SliderJointSW::calculateTransforms() +} //----------------------------------------------------------------------------- -void SliderJoint3DSW::testLinLimits() { +void GodotSliderJoint3D::testLinLimits() { m_solveLinLim = false; m_linPos = m_depth[0]; if (m_lowerLinLimit <= m_upperLinLimit) { @@ -325,11 +323,11 @@ void SliderJoint3DSW::testLinLimits() { } else { m_depth[0] = real_t(0.); } -} // SliderJointSW::testLinLimits() +} //----------------------------------------------------------------------------- -void SliderJoint3DSW::testAngLimits() { +void GodotSliderJoint3D::testAngLimits() { m_angDepth = real_t(0.); m_solveAngLim = false; if (m_lowerAngLimit <= m_upperAngLimit) { @@ -345,26 +343,26 @@ void SliderJoint3DSW::testAngLimits() { m_solveAngLim = true; } } -} // SliderJointSW::testAngLimits() +} //----------------------------------------------------------------------------- -Vector3 SliderJoint3DSW::getAncorInA() { +Vector3 GodotSliderJoint3D::getAncorInA() { Vector3 ancorInA; ancorInA = m_realPivotAInW + (m_lowerLinLimit + m_upperLinLimit) * real_t(0.5) * m_sliderAxis; ancorInA = A->get_transform().inverse().xform(ancorInA); return ancorInA; -} // SliderJointSW::getAncorInA() +} //----------------------------------------------------------------------------- -Vector3 SliderJoint3DSW::getAncorInB() { +Vector3 GodotSliderJoint3D::getAncorInB() { Vector3 ancorInB; ancorInB = m_frameInB.origin; return ancorInB; -} // SliderJointSW::getAncorInB(); +} -void SliderJoint3DSW::set_param(PhysicsServer3D::SliderJointParam p_param, real_t p_value) { +void GodotSliderJoint3D::set_param(PhysicsServer3D::SliderJointParam p_param, real_t p_value) { switch (p_param) { case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: m_upperLinLimit = p_value; @@ -439,7 +437,7 @@ void SliderJoint3DSW::set_param(PhysicsServer3D::SliderJointParam p_param, real_ } } -real_t SliderJoint3DSW::get_param(PhysicsServer3D::SliderJointParam p_param) const { +real_t GodotSliderJoint3D::get_param(PhysicsServer3D::SliderJointParam p_param) const { switch (p_param) { case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: return m_upperLinLimit; diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.h b/servers/physics_3d/joints/godot_slider_joint_3d.h index d32ad9469e..9baaf1fa40 100644 --- a/servers/physics_3d/joints/slider_joint_3d_sw.h +++ b/servers/physics_3d/joints/godot_slider_joint_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* slider_joint_3d_sw.h */ +/* godot_slider_joint_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -32,11 +32,11 @@ Adapted to Godot from the Bullet library. */ -#ifndef SLIDER_JOINT_SW_H -#define SLIDER_JOINT_SW_H +#ifndef GODOT_SLIDER_JOINT_3D_H +#define GODOT_SLIDER_JOINT_3D_H -#include "servers/physics_3d/joints/jacobian_entry_3d_sw.h" -#include "servers/physics_3d/joints_3d_sw.h" +#include "servers/physics_3d/godot_joint_3d.h" +#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" /* Bullet Continuous Collision Detection and Physics Library @@ -65,15 +65,15 @@ April 04, 2008 //----------------------------------------------------------------------------- -class SliderJoint3DSW : public Joint3DSW { +class GodotSliderJoint3D : public GodotJoint3D { protected: union { struct { - Body3DSW *A; - Body3DSW *B; + GodotBody3D *A; + GodotBody3D *B; }; - Body3DSW *_arr[2] = { nullptr, nullptr }; + GodotBody3D *_arr[2] = { nullptr, nullptr }; }; Transform3D m_frameInA; @@ -114,10 +114,10 @@ protected: bool m_solveLinLim = false; bool m_solveAngLim = false; - JacobianEntry3DSW m_jacLin[3] = {}; + GodotJacobianEntry3D m_jacLin[3] = {}; real_t m_jacLinDiagABInv[3] = {}; - JacobianEntry3DSW m_jacAng[3] = {}; + GodotJacobianEntry3D m_jacAng[3] = {}; real_t m_timeStep = 0.0; Transform3D m_calculatedTransformA; @@ -149,13 +149,13 @@ protected: public: // constructors - SliderJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &frameInA, const Transform3D &frameInB); + GodotSliderJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameInA, const Transform3D &frameInB); //SliderJointSW(); // overrides // access - const Body3DSW *getRigidBodyA() const { return A; } - const Body3DSW *getRigidBodyB() const { return B; } + const GodotBody3D *getRigidBodyA() const { return A; } + const GodotBody3D *getRigidBodyB() const { return B; } const Transform3D &getCalculatedTransformA() const { return m_calculatedTransformA; } const Transform3D &getCalculatedTransformB() const { return m_calculatedTransformB; } const Transform3D &getFrameOffsetA() const { return m_frameInA; } @@ -243,4 +243,4 @@ public: virtual PhysicsServer3D::JointType get_type() const override { return PhysicsServer3D::JOINT_TYPE_SLIDER; } }; -#endif // SLIDER_JOINT_SW_H +#endif // GODOT_SLIDER_JOINT_3D_H diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp deleted file mode 100644 index b16e199a03..0000000000 --- a/servers/physics_3d/physics_server_3d_sw.cpp +++ /dev/null @@ -1,1748 +0,0 @@ -/*************************************************************************/ -/* physics_server_3d_sw.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "physics_server_3d_sw.h" - -#include "body_direct_state_3d_sw.h" -#include "broad_phase_3d_bvh.h" -#include "core/debugger/engine_debugger.h" -#include "core/os/os.h" -#include "joints/cone_twist_joint_3d_sw.h" -#include "joints/generic_6dof_joint_3d_sw.h" -#include "joints/hinge_joint_3d_sw.h" -#include "joints/pin_joint_3d_sw.h" -#include "joints/slider_joint_3d_sw.h" - -#define FLUSH_QUERY_CHECK(m_object) \ - ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead."); - -RID PhysicsServer3DSW::world_boundary_shape_create() { - Shape3DSW *shape = memnew(WorldBoundaryShape3DSW); - RID rid = shape_owner.make_rid(shape); - shape->set_self(rid); - return rid; -} -RID PhysicsServer3DSW::separation_ray_shape_create() { - Shape3DSW *shape = memnew(SeparationRayShape3DSW); - RID rid = shape_owner.make_rid(shape); - shape->set_self(rid); - return rid; -} -RID PhysicsServer3DSW::sphere_shape_create() { - Shape3DSW *shape = memnew(SphereShape3DSW); - RID rid = shape_owner.make_rid(shape); - shape->set_self(rid); - return rid; -} -RID PhysicsServer3DSW::box_shape_create() { - Shape3DSW *shape = memnew(BoxShape3DSW); - RID rid = shape_owner.make_rid(shape); - shape->set_self(rid); - return rid; -} -RID PhysicsServer3DSW::capsule_shape_create() { - Shape3DSW *shape = memnew(CapsuleShape3DSW); - RID rid = shape_owner.make_rid(shape); - shape->set_self(rid); - return rid; -} -RID PhysicsServer3DSW::cylinder_shape_create() { - Shape3DSW *shape = memnew(CylinderShape3DSW); - RID rid = shape_owner.make_rid(shape); - shape->set_self(rid); - return rid; -} -RID PhysicsServer3DSW::convex_polygon_shape_create() { - Shape3DSW *shape = memnew(ConvexPolygonShape3DSW); - RID rid = shape_owner.make_rid(shape); - shape->set_self(rid); - return rid; -} -RID PhysicsServer3DSW::concave_polygon_shape_create() { - Shape3DSW *shape = memnew(ConcavePolygonShape3DSW); - RID rid = shape_owner.make_rid(shape); - shape->set_self(rid); - return rid; -} -RID PhysicsServer3DSW::heightmap_shape_create() { - Shape3DSW *shape = memnew(HeightMapShape3DSW); - RID rid = shape_owner.make_rid(shape); - shape->set_self(rid); - return rid; -} -RID PhysicsServer3DSW::custom_shape_create() { - ERR_FAIL_V(RID()); -} - -void PhysicsServer3DSW::shape_set_data(RID p_shape, const Variant &p_data) { - Shape3DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - shape->set_data(p_data); -}; - -void PhysicsServer3DSW::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) { - Shape3DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - shape->set_custom_bias(p_bias); -} - -PhysicsServer3D::ShapeType PhysicsServer3DSW::shape_get_type(RID p_shape) const { - const Shape3DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND_V(!shape, SHAPE_CUSTOM); - return shape->get_type(); -}; - -Variant PhysicsServer3DSW::shape_get_data(RID p_shape) const { - const Shape3DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND_V(!shape, Variant()); - ERR_FAIL_COND_V(!shape->is_configured(), Variant()); - return shape->get_data(); -}; - -void PhysicsServer3DSW::shape_set_margin(RID p_shape, real_t p_margin) { -} - -real_t PhysicsServer3DSW::shape_get_margin(RID p_shape) const { - return 0.0; -} - -real_t PhysicsServer3DSW::shape_get_custom_solver_bias(RID p_shape) const { - const Shape3DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND_V(!shape, 0); - return shape->get_custom_bias(); -} - -RID PhysicsServer3DSW::space_create() { - Space3DSW *space = memnew(Space3DSW); - RID id = space_owner.make_rid(space); - space->set_self(id); - RID area_id = area_create(); - Area3DSW *area = area_owner.get_or_null(area_id); - ERR_FAIL_COND_V(!area, RID()); - space->set_default_area(area); - area->set_space(space); - area->set_priority(-1); - RID sgb = body_create(); - body_set_space(sgb, id); - body_set_mode(sgb, BODY_MODE_STATIC); - space->set_static_global_body(sgb); - - return id; -}; - -void PhysicsServer3DSW::space_set_active(RID p_space, bool p_active) { - Space3DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - if (p_active) { - active_spaces.insert(space); - } else { - active_spaces.erase(space); - } -} - -bool PhysicsServer3DSW::space_is_active(RID p_space) const { - const Space3DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, false); - - return active_spaces.has(space); -} - -void PhysicsServer3DSW::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) { - Space3DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - - space->set_param(p_param, p_value); -} - -real_t PhysicsServer3DSW::space_get_param(RID p_space, SpaceParameter p_param) const { - const Space3DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, 0); - return space->get_param(p_param); -} - -PhysicsDirectSpaceState3D *PhysicsServer3DSW::space_get_direct_state(RID p_space) { - Space3DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, nullptr); - ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); - - return space->get_direct_state(); -} - -void PhysicsServer3DSW::space_set_debug_contacts(RID p_space, int p_max_contacts) { - Space3DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - space->set_debug_contacts(p_max_contacts); -} - -Vector<Vector3> PhysicsServer3DSW::space_get_contacts(RID p_space) const { - Space3DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, Vector<Vector3>()); - return space->get_debug_contacts(); -} - -int PhysicsServer3DSW::space_get_contact_count(RID p_space) const { - Space3DSW *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, 0); - return space->get_debug_contact_count(); -} - -RID PhysicsServer3DSW::area_create() { - Area3DSW *area = memnew(Area3DSW); - RID rid = area_owner.make_rid(area); - area->set_self(rid); - return rid; -}; - -void PhysicsServer3DSW::area_set_space(RID p_area, RID p_space) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - Space3DSW *space = nullptr; - if (p_space.is_valid()) { - space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - } - - if (area->get_space() == space) { - return; //pointless - } - - area->clear_constraints(); - area->set_space(space); -}; - -RID PhysicsServer3DSW::area_get_space(RID p_area) const { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, RID()); - - Space3DSW *space = area->get_space(); - if (!space) { - return RID(); - } - return space->get_self(); -}; - -void PhysicsServer3DSW::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_space_override_mode(p_mode); -} - -PhysicsServer3D::AreaSpaceOverrideMode PhysicsServer3DSW::area_get_space_override_mode(RID p_area) const { - const Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, AREA_SPACE_OVERRIDE_DISABLED); - - return area->get_space_override_mode(); -} - -void PhysicsServer3DSW::area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform, bool p_disabled) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - Shape3DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - - area->add_shape(shape, p_transform, p_disabled); -} - -void PhysicsServer3DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - Shape3DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - ERR_FAIL_COND(!shape->is_configured()); - - area->set_shape(p_shape_idx, shape); -} - -void PhysicsServer3DSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_shape_transform(p_shape_idx, p_transform); -} - -int PhysicsServer3DSW::area_get_shape_count(RID p_area) const { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, -1); - - return area->get_shape_count(); -} - -RID PhysicsServer3DSW::area_get_shape(RID p_area, int p_shape_idx) const { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, RID()); - - Shape3DSW *shape = area->get_shape(p_shape_idx); - ERR_FAIL_COND_V(!shape, RID()); - - return shape->get_self(); -} - -Transform3D PhysicsServer3DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, Transform3D()); - - return area->get_shape_transform(p_shape_idx); -} - -void PhysicsServer3DSW::area_remove_shape(RID p_area, int p_shape_idx) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->remove_shape(p_shape_idx); -} - -void PhysicsServer3DSW::area_clear_shapes(RID p_area) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - while (area->get_shape_count()) { - area->remove_shape(0); - } -} - -void PhysicsServer3DSW::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - ERR_FAIL_INDEX(p_shape_idx, area->get_shape_count()); - FLUSH_QUERY_CHECK(area); - area->set_shape_disabled(p_shape_idx, p_disabled); -} - -void PhysicsServer3DSW::area_attach_object_instance_id(RID p_area, ObjectID p_id) { - if (space_owner.owns(p_area)) { - Space3DSW *space = space_owner.get_or_null(p_area); - p_area = space->get_default_area()->get_self(); - } - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - area->set_instance_id(p_id); -} - -ObjectID PhysicsServer3DSW::area_get_object_instance_id(RID p_area) const { - if (space_owner.owns(p_area)) { - Space3DSW *space = space_owner.get_or_null(p_area); - p_area = space->get_default_area()->get_self(); - } - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, ObjectID()); - return area->get_instance_id(); -} - -void PhysicsServer3DSW::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) { - if (space_owner.owns(p_area)) { - Space3DSW *space = space_owner.get_or_null(p_area); - p_area = space->get_default_area()->get_self(); - } - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - area->set_param(p_param, p_value); -}; - -void PhysicsServer3DSW::area_set_transform(RID p_area, const Transform3D &p_transform) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - area->set_transform(p_transform); -}; - -Variant PhysicsServer3DSW::area_get_param(RID p_area, AreaParameter p_param) const { - if (space_owner.owns(p_area)) { - Space3DSW *space = space_owner.get_or_null(p_area); - p_area = space->get_default_area()->get_self(); - } - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, Variant()); - - return area->get_param(p_param); -}; - -Transform3D PhysicsServer3DSW::area_get_transform(RID p_area) const { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, Transform3D()); - - return area->get_transform(); -}; - -void PhysicsServer3DSW::area_set_collision_layer(RID p_area, uint32_t p_layer) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_collision_layer(p_layer); -} - -void PhysicsServer3DSW::area_set_collision_mask(RID p_area, uint32_t p_mask) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_collision_mask(p_mask); -} - -void PhysicsServer3DSW::area_set_monitorable(RID p_area, bool p_monitorable) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - FLUSH_QUERY_CHECK(area); - - area->set_monitorable(p_monitorable); -} - -void PhysicsServer3DSW::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); -} - -void PhysicsServer3DSW::area_set_ray_pickable(RID p_area, bool p_enable) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_ray_pickable(p_enable); -} - -void PhysicsServer3DSW::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - Area3DSW *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); -} - -/* BODY API */ - -RID PhysicsServer3DSW::body_create() { - Body3DSW *body = memnew(Body3DSW); - RID rid = body_owner.make_rid(body); - body->set_self(rid); - return rid; -}; - -void PhysicsServer3DSW::body_set_space(RID p_body, RID p_space) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - Space3DSW *space = nullptr; - if (p_space.is_valid()) { - space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - } - - if (body->get_space() == space) { - return; //pointless - } - - body->clear_constraint_map(); - body->set_space(space); -}; - -RID PhysicsServer3DSW::body_get_space(RID p_body) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, RID()); - - Space3DSW *space = body->get_space(); - if (!space) { - return RID(); - } - return space->get_self(); -}; - -void PhysicsServer3DSW::body_set_mode(RID p_body, BodyMode p_mode) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_mode(p_mode); -}; - -PhysicsServer3D::BodyMode PhysicsServer3DSW::body_get_mode(RID p_body) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, BODY_MODE_STATIC); - - return body->get_mode(); -}; - -void PhysicsServer3DSW::body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform, bool p_disabled) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - Shape3DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - - body->add_shape(shape, p_transform, p_disabled); -} - -void PhysicsServer3DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - Shape3DSW *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - ERR_FAIL_COND(!shape->is_configured()); - - body->set_shape(p_shape_idx, shape); -} -void PhysicsServer3DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_shape_transform(p_shape_idx, p_transform); -} - -int PhysicsServer3DSW::body_get_shape_count(RID p_body) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, -1); - - return body->get_shape_count(); -} - -RID PhysicsServer3DSW::body_get_shape(RID p_body, int p_shape_idx) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, RID()); - - Shape3DSW *shape = body->get_shape(p_shape_idx); - ERR_FAIL_COND_V(!shape, RID()); - - return shape->get_self(); -} - -void PhysicsServer3DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); - FLUSH_QUERY_CHECK(body); - - body->set_shape_disabled(p_shape_idx, p_disabled); -} - -Transform3D PhysicsServer3DSW::body_get_shape_transform(RID p_body, int p_shape_idx) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, Transform3D()); - - return body->get_shape_transform(p_shape_idx); -} - -void PhysicsServer3DSW::body_remove_shape(RID p_body, int p_shape_idx) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->remove_shape(p_shape_idx); -} - -void PhysicsServer3DSW::body_clear_shapes(RID p_body) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - while (body->get_shape_count()) { - body->remove_shape(0); - } -} - -void PhysicsServer3DSW::body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_continuous_collision_detection(p_enable); -} - -bool PhysicsServer3DSW::body_is_continuous_collision_detection_enabled(RID p_body) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, false); - - return body->is_continuous_collision_detection_enabled(); -} - -void PhysicsServer3DSW::body_set_collision_layer(RID p_body, uint32_t p_layer) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_collision_layer(p_layer); - body->wakeup(); -} - -uint32_t PhysicsServer3DSW::body_get_collision_layer(RID p_body) const { - const Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_collision_layer(); -} - -void PhysicsServer3DSW::body_set_collision_mask(RID p_body, uint32_t p_mask) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_collision_mask(p_mask); - body->wakeup(); -} - -uint32_t PhysicsServer3DSW::body_get_collision_mask(RID p_body) const { - const Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_collision_mask(); -} - -void PhysicsServer3DSW::body_attach_object_instance_id(RID p_body, ObjectID p_id) { - Body3DSW *body = body_owner.get_or_null(p_body); - if (body) { - body->set_instance_id(p_id); - return; - } - - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - if (soft_body) { - soft_body->set_instance_id(p_id); - return; - } - - ERR_FAIL_MSG("Invalid ID."); -}; - -ObjectID PhysicsServer3DSW::body_get_object_instance_id(RID p_body) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, ObjectID()); - - return body->get_instance_id(); -}; - -void PhysicsServer3DSW::body_set_user_flags(RID p_body, uint32_t p_flags) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); -}; - -uint32_t PhysicsServer3DSW::body_get_user_flags(RID p_body) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return 0; -}; - -void PhysicsServer3DSW::body_set_param(RID p_body, BodyParameter p_param, const Variant &p_value) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_param(p_param, p_value); -}; - -Variant PhysicsServer3DSW::body_get_param(RID p_body, BodyParameter p_param) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_param(p_param); -}; - -void PhysicsServer3DSW::body_reset_mass_properties(RID p_body) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - return body->reset_mass_properties(); -} - -void PhysicsServer3DSW::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_state(p_state, p_variant); -}; - -Variant PhysicsServer3DSW::body_get_state(RID p_body, BodyState p_state) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, Variant()); - - return body->get_state(p_state); -}; - -void PhysicsServer3DSW::body_set_applied_force(RID p_body, const Vector3 &p_force) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_applied_force(p_force); - body->wakeup(); -}; - -Vector3 PhysicsServer3DSW::body_get_applied_force(RID p_body) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, Vector3()); - return body->get_applied_force(); -}; - -void PhysicsServer3DSW::body_set_applied_torque(RID p_body, const Vector3 &p_torque) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_applied_torque(p_torque); - body->wakeup(); -}; - -Vector3 PhysicsServer3DSW::body_get_applied_torque(RID p_body) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, Vector3()); - - return body->get_applied_torque(); -}; - -void PhysicsServer3DSW::body_add_central_force(RID p_body, const Vector3 &p_force) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->add_central_force(p_force); - body->wakeup(); -} - -void PhysicsServer3DSW::body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->add_force(p_force, p_position); - body->wakeup(); -}; - -void PhysicsServer3DSW::body_add_torque(RID p_body, const Vector3 &p_torque) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->add_torque(p_torque); - body->wakeup(); -}; - -void PhysicsServer3DSW::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - _update_shapes(); - - body->apply_central_impulse(p_impulse); - body->wakeup(); -} - -void PhysicsServer3DSW::body_apply_impulse(RID p_body, const Vector3 &p_impulse, const Vector3 &p_position) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - _update_shapes(); - - body->apply_impulse(p_impulse, p_position); - body->wakeup(); -}; - -void PhysicsServer3DSW::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - _update_shapes(); - - body->apply_torque_impulse(p_impulse); - body->wakeup(); -}; - -void PhysicsServer3DSW::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - _update_shapes(); - - Vector3 v = body->get_linear_velocity(); - Vector3 axis = p_axis_velocity.normalized(); - v -= axis * axis.dot(v); - v += p_axis_velocity; - body->set_linear_velocity(v); - body->wakeup(); -}; - -void PhysicsServer3DSW::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_axis_lock(p_axis, p_lock); - body->wakeup(); -} - -bool PhysicsServer3DSW::body_is_axis_locked(RID p_body, BodyAxis p_axis) const { - const Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - return body->is_axis_locked(p_axis); -} - -void PhysicsServer3DSW::body_add_collision_exception(RID p_body, RID p_body_b) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->add_exception(p_body_b); - body->wakeup(); -}; - -void PhysicsServer3DSW::body_remove_collision_exception(RID p_body, RID p_body_b) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->remove_exception(p_body_b); - body->wakeup(); -}; - -void PhysicsServer3DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - for (int i = 0; i < body->get_exceptions().size(); i++) { - p_exceptions->push_back(body->get_exceptions()[i]); - } -}; - -void PhysicsServer3DSW::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); -}; - -real_t PhysicsServer3DSW::body_get_contacts_reported_depth_threshold(RID p_body) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - return 0; -}; - -void PhysicsServer3DSW::body_set_omit_force_integration(RID p_body, bool p_omit) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_omit_force_integration(p_omit); -}; - -bool PhysicsServer3DSW::body_is_omitting_force_integration(RID p_body) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, false); - return body->get_omit_force_integration(); -}; - -void PhysicsServer3DSW::body_set_max_contacts_reported(RID p_body, int p_contacts) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_max_contacts_reported(p_contacts); -} - -int PhysicsServer3DSW::body_get_max_contacts_reported(RID p_body) const { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, -1); - return body->get_max_contacts_reported(); -} - -void PhysicsServer3DSW::body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_state_sync_callback(p_instance, p_callback); -} - -void PhysicsServer3DSW::body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_force_integration_callback(p_callable, p_udata); -} - -void PhysicsServer3DSW::body_set_ray_pickable(RID p_body, bool p_enable) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_ray_pickable(p_enable); -} - -bool PhysicsServer3DSW::body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result) { - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, false); - ERR_FAIL_COND_V(!body->get_space(), false); - ERR_FAIL_COND_V(body->get_space()->is_locked(), false); - - _update_shapes(); - - return body->get_space()->test_body_motion(body, p_parameters, r_result); -} - -PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) { - ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); - - Body3DSW *body = body_owner.get_or_null(p_body); - ERR_FAIL_NULL_V(body, nullptr); - - ERR_FAIL_NULL_V(body->get_space(), nullptr); - ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); - - return body->get_direct_state(); -} - -/* SOFT BODY */ - -RID PhysicsServer3DSW::soft_body_create() { - SoftBody3DSW *soft_body = memnew(SoftBody3DSW); - RID rid = soft_body_owner.make_rid(soft_body); - soft_body->set_self(rid); - return rid; -} - -void PhysicsServer3DSW::soft_body_update_rendering_server(RID p_body, RenderingServerHandler *p_rendering_server_handler) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->update_rendering_server(p_rendering_server_handler); -} - -void PhysicsServer3DSW::soft_body_set_space(RID p_body, RID p_space) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - Space3DSW *space = nullptr; - if (p_space.is_valid()) { - space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - } - - if (soft_body->get_space() == space) { - return; - } - - soft_body->set_space(space); -} - -RID PhysicsServer3DSW::soft_body_get_space(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!soft_body, RID()); - - Space3DSW *space = soft_body->get_space(); - if (!space) { - return RID(); - } - return space->get_self(); -} - -void PhysicsServer3DSW::soft_body_set_collision_layer(RID p_body, uint32_t p_layer) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->set_collision_layer(p_layer); -} - -uint32_t PhysicsServer3DSW::soft_body_get_collision_layer(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!soft_body, 0); - - return soft_body->get_collision_layer(); -} - -void PhysicsServer3DSW::soft_body_set_collision_mask(RID p_body, uint32_t p_mask) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->set_collision_mask(p_mask); -} - -uint32_t PhysicsServer3DSW::soft_body_get_collision_mask(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!soft_body, 0); - - return soft_body->get_collision_mask(); -} - -void PhysicsServer3DSW::soft_body_add_collision_exception(RID p_body, RID p_body_b) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->add_exception(p_body_b); -} - -void PhysicsServer3DSW::soft_body_remove_collision_exception(RID p_body, RID p_body_b) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->remove_exception(p_body_b); -} - -void PhysicsServer3DSW::soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - for (int i = 0; i < soft_body->get_exceptions().size(); i++) { - p_exceptions->push_back(soft_body->get_exceptions()[i]); - } -} - -void PhysicsServer3DSW::soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->set_state(p_state, p_variant); -} - -Variant PhysicsServer3DSW::soft_body_get_state(RID p_body, BodyState p_state) const { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!soft_body, Variant()); - - return soft_body->get_state(p_state); -} - -void PhysicsServer3DSW::soft_body_set_transform(RID p_body, const Transform3D &p_transform) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->set_state(BODY_STATE_TRANSFORM, p_transform); -} - -void PhysicsServer3DSW::soft_body_set_ray_pickable(RID p_body, bool p_enable) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->set_ray_pickable(p_enable); -} - -void PhysicsServer3DSW::soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->set_iteration_count(p_simulation_precision); -} - -int PhysicsServer3DSW::soft_body_get_simulation_precision(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!soft_body, 0.f); - - return soft_body->get_iteration_count(); -} - -void PhysicsServer3DSW::soft_body_set_total_mass(RID p_body, real_t p_total_mass) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->set_total_mass(p_total_mass); -} - -real_t PhysicsServer3DSW::soft_body_get_total_mass(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!soft_body, 0.f); - - return soft_body->get_total_mass(); -} - -void PhysicsServer3DSW::soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->set_linear_stiffness(p_stiffness); -} - -real_t PhysicsServer3DSW::soft_body_get_linear_stiffness(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!soft_body, 0.f); - - return soft_body->get_linear_stiffness(); -} - -void PhysicsServer3DSW::soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->set_pressure_coefficient(p_pressure_coefficient); -} - -real_t PhysicsServer3DSW::soft_body_get_pressure_coefficient(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!soft_body, 0.f); - - return soft_body->get_pressure_coefficient(); -} - -void PhysicsServer3DSW::soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->set_damping_coefficient(p_damping_coefficient); -} - -real_t PhysicsServer3DSW::soft_body_get_damping_coefficient(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!soft_body, 0.f); - - return soft_body->get_damping_coefficient(); -} - -void PhysicsServer3DSW::soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->set_drag_coefficient(p_drag_coefficient); -} - -real_t PhysicsServer3DSW::soft_body_get_drag_coefficient(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!soft_body, 0.f); - - return soft_body->get_drag_coefficient(); -} - -void PhysicsServer3DSW::soft_body_set_mesh(RID p_body, RID p_mesh) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->set_mesh(p_mesh); -} - -AABB PhysicsServer3DSW::soft_body_get_bounds(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!soft_body, AABB()); - - return soft_body->get_bounds(); -} - -void PhysicsServer3DSW::soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->set_vertex_position(p_point_index, p_global_position); -} - -Vector3 PhysicsServer3DSW::soft_body_get_point_global_position(RID p_body, int p_point_index) const { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!soft_body, Vector3()); - - return soft_body->get_vertex_position(p_point_index); -} - -void PhysicsServer3DSW::soft_body_remove_all_pinned_points(RID p_body) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - soft_body->unpin_all_vertices(); -} - -void PhysicsServer3DSW::soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!soft_body); - - if (p_pin) { - soft_body->pin_vertex(p_point_index); - } else { - soft_body->unpin_vertex(p_point_index); - } -} - -bool PhysicsServer3DSW::soft_body_is_point_pinned(RID p_body, int p_point_index) const { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!soft_body, false); - - return soft_body->is_vertex_pinned(p_point_index); -} - -/* JOINT API */ - -RID PhysicsServer3DSW::joint_create() { - Joint3DSW *joint = memnew(Joint3DSW); - RID rid = joint_owner.make_rid(joint); - joint->set_self(rid); - return rid; -} - -void PhysicsServer3DSW::joint_clear(RID p_joint) { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - if (joint->get_type() != JOINT_TYPE_MAX) { - Joint3DSW *empty_joint = memnew(Joint3DSW); - empty_joint->copy_settings_from(joint); - - joint_owner.replace(p_joint, empty_joint); - memdelete(joint); - } -} - -void PhysicsServer3DSW::joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) { - Body3DSW *body_A = body_owner.get_or_null(p_body_A); - ERR_FAIL_COND(!body_A); - - if (!p_body_B.is_valid()) { - ERR_FAIL_COND(!body_A->get_space()); - p_body_B = body_A->get_space()->get_static_global_body(); - } - - Body3DSW *body_B = body_owner.get_or_null(p_body_B); - ERR_FAIL_COND(!body_B); - - ERR_FAIL_COND(body_A == body_B); - - Joint3DSW *prev_joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(prev_joint == nullptr); - - Joint3DSW *joint = memnew(PinJoint3DSW(body_A, p_local_A, body_B, p_local_B)); - - joint->copy_settings_from(prev_joint); - joint_owner.replace(p_joint, joint); - memdelete(prev_joint); -} - -void PhysicsServer3DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); - PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); - pin_joint->set_param(p_param, p_value); -} - -real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, 0); - PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); - return pin_joint->get_param(p_param); -} - -void PhysicsServer3DSW::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); - PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); - pin_joint->set_pos_a(p_A); -} - -Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, Vector3()); - ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3()); - PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); - return pin_joint->get_position_a(); -} - -void PhysicsServer3DSW::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); - PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); - pin_joint->set_pos_b(p_B); -} - -Vector3 PhysicsServer3DSW::pin_joint_get_local_b(RID p_joint) const { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, Vector3()); - ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3()); - PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); - return pin_joint->get_position_b(); -} - -void PhysicsServer3DSW::joint_make_hinge(RID p_joint, RID p_body_A, const Transform3D &p_frame_A, RID p_body_B, const Transform3D &p_frame_B) { - Body3DSW *body_A = body_owner.get_or_null(p_body_A); - ERR_FAIL_COND(!body_A); - - if (!p_body_B.is_valid()) { - ERR_FAIL_COND(!body_A->get_space()); - p_body_B = body_A->get_space()->get_static_global_body(); - } - - Body3DSW *body_B = body_owner.get_or_null(p_body_B); - ERR_FAIL_COND(!body_B); - - ERR_FAIL_COND(body_A == body_B); - - Joint3DSW *prev_joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(prev_joint == nullptr); - - Joint3DSW *joint = memnew(HingeJoint3DSW(body_A, body_B, p_frame_A, p_frame_B)); - - joint->copy_settings_from(prev_joint); - joint_owner.replace(p_joint, joint); - memdelete(prev_joint); -} - -void PhysicsServer3DSW::joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) { - Body3DSW *body_A = body_owner.get_or_null(p_body_A); - ERR_FAIL_COND(!body_A); - - if (!p_body_B.is_valid()) { - ERR_FAIL_COND(!body_A->get_space()); - p_body_B = body_A->get_space()->get_static_global_body(); - } - - Body3DSW *body_B = body_owner.get_or_null(p_body_B); - ERR_FAIL_COND(!body_B); - - ERR_FAIL_COND(body_A == body_B); - - Joint3DSW *prev_joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(prev_joint == nullptr); - - Joint3DSW *joint = memnew(HingeJoint3DSW(body_A, body_B, p_pivot_A, p_pivot_B, p_axis_A, p_axis_B)); - - joint->copy_settings_from(prev_joint); - joint_owner.replace(p_joint, joint); - memdelete(prev_joint); -} - -void PhysicsServer3DSW::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE); - HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); - hinge_joint->set_param(p_param, p_value); -} - -real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, 0); - HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); - return hinge_joint->get_param(p_param); -} - -void PhysicsServer3DSW::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE); - HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); - hinge_joint->set_flag(p_flag, p_value); -} - -bool PhysicsServer3DSW::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, false); - ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, false); - HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); - return hinge_joint->get_flag(p_flag); -} - -void PhysicsServer3DSW::joint_set_solver_priority(RID p_joint, int p_priority) { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - joint->set_priority(p_priority); -} - -int PhysicsServer3DSW::joint_get_solver_priority(RID p_joint) const { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, 0); - return joint->get_priority(); -} - -void PhysicsServer3DSW::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - - joint->disable_collisions_between_bodies(p_disable); - - if (2 == joint->get_body_count()) { - Body3DSW *body_a = *joint->get_body_ptr(); - Body3DSW *body_b = *(joint->get_body_ptr() + 1); - - if (p_disable) { - body_add_collision_exception(body_a->get_self(), body_b->get_self()); - body_add_collision_exception(body_b->get_self(), body_a->get_self()); - } else { - body_remove_collision_exception(body_a->get_self(), body_b->get_self()); - body_remove_collision_exception(body_b->get_self(), body_a->get_self()); - } - } -} - -bool PhysicsServer3DSW::joint_is_disabled_collisions_between_bodies(RID p_joint) const { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, true); - - return joint->is_disabled_collisions_between_bodies(); -} - -PhysicsServer3DSW::JointType PhysicsServer3DSW::joint_get_type(RID p_joint) const { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, JOINT_TYPE_PIN); - return joint->get_type(); -} - -void PhysicsServer3DSW::joint_make_slider(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { - Body3DSW *body_A = body_owner.get_or_null(p_body_A); - ERR_FAIL_COND(!body_A); - - if (!p_body_B.is_valid()) { - ERR_FAIL_COND(!body_A->get_space()); - p_body_B = body_A->get_space()->get_static_global_body(); - } - - Body3DSW *body_B = body_owner.get_or_null(p_body_B); - ERR_FAIL_COND(!body_B); - - ERR_FAIL_COND(body_A == body_B); - - Joint3DSW *prev_joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(prev_joint == nullptr); - - Joint3DSW *joint = memnew(SliderJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B)); - - joint->copy_settings_from(prev_joint); - joint_owner.replace(p_joint, joint); - memdelete(prev_joint); -} - -void PhysicsServer3DSW::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_SLIDER); - SliderJoint3DSW *slider_joint = static_cast<SliderJoint3DSW *>(joint); - slider_joint->set_param(p_param, p_value); -} - -real_t PhysicsServer3DSW::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0); - SliderJoint3DSW *slider_joint = static_cast<SliderJoint3DSW *>(joint); - return slider_joint->get_param(p_param); -} - -void PhysicsServer3DSW::joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { - Body3DSW *body_A = body_owner.get_or_null(p_body_A); - ERR_FAIL_COND(!body_A); - - if (!p_body_B.is_valid()) { - ERR_FAIL_COND(!body_A->get_space()); - p_body_B = body_A->get_space()->get_static_global_body(); - } - - Body3DSW *body_B = body_owner.get_or_null(p_body_B); - ERR_FAIL_COND(!body_B); - - ERR_FAIL_COND(body_A == body_B); - - Joint3DSW *prev_joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(prev_joint == nullptr); - - Joint3DSW *joint = memnew(ConeTwistJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B)); - - joint->copy_settings_from(prev_joint); - joint_owner.replace(p_joint, joint); - memdelete(prev_joint); -} - -void PhysicsServer3DSW::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_CONE_TWIST); - ConeTwistJoint3DSW *cone_twist_joint = static_cast<ConeTwistJoint3DSW *>(joint); - cone_twist_joint->set_param(p_param, p_value); -} - -real_t PhysicsServer3DSW::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0); - ConeTwistJoint3DSW *cone_twist_joint = static_cast<ConeTwistJoint3DSW *>(joint); - return cone_twist_joint->get_param(p_param); -} - -void PhysicsServer3DSW::joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { - Body3DSW *body_A = body_owner.get_or_null(p_body_A); - ERR_FAIL_COND(!body_A); - - if (!p_body_B.is_valid()) { - ERR_FAIL_COND(!body_A->get_space()); - p_body_B = body_A->get_space()->get_static_global_body(); - } - - Body3DSW *body_B = body_owner.get_or_null(p_body_B); - ERR_FAIL_COND(!body_B); - - ERR_FAIL_COND(body_A == body_B); - - Joint3DSW *prev_joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(prev_joint == nullptr); - - Joint3DSW *joint = memnew(Generic6DOFJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B, true)); - - joint->copy_settings_from(prev_joint); - joint_owner.replace(p_joint, joint); - memdelete(prev_joint); -} - -void PhysicsServer3DSW::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF); - Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); - generic_6dof_joint->set_param(p_axis, p_param, p_value); -} - -real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) const { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, 0); - Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); - return generic_6dof_joint->get_param(p_axis, p_param); -} - -void PhysicsServer3DSW::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF); - Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); - generic_6dof_joint->set_flag(p_axis, p_flag, p_enable); -} - -bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) const { - Joint3DSW *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, false); - ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, false); - Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); - return generic_6dof_joint->get_flag(p_axis, p_flag); -} - -void PhysicsServer3DSW::free(RID p_rid) { - _update_shapes(); //just in case - - if (shape_owner.owns(p_rid)) { - Shape3DSW *shape = shape_owner.get_or_null(p_rid); - - while (shape->get_owners().size()) { - ShapeOwner3DSW *so = shape->get_owners().front()->key(); - so->remove_shape(shape); - } - - shape_owner.free(p_rid); - memdelete(shape); - } else if (body_owner.owns(p_rid)) { - Body3DSW *body = body_owner.get_or_null(p_rid); - - /* - if (body->get_state_query()) - _clear_query(body->get_state_query()); - - if (body->get_direct_state_query()) - _clear_query(body->get_direct_state_query()); - */ - - body->set_space(nullptr); - - while (body->get_shape_count()) { - body->remove_shape(0); - } - - body_owner.free(p_rid); - memdelete(body); - } else if (soft_body_owner.owns(p_rid)) { - SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_rid); - - soft_body->set_space(nullptr); - - soft_body_owner.free(p_rid); - memdelete(soft_body); - } else if (area_owner.owns(p_rid)) { - Area3DSW *area = area_owner.get_or_null(p_rid); - - /* - if (area->get_monitor_query()) - _clear_query(area->get_monitor_query()); - */ - - area->set_space(nullptr); - - while (area->get_shape_count()) { - area->remove_shape(0); - } - - area_owner.free(p_rid); - memdelete(area); - } else if (space_owner.owns(p_rid)) { - Space3DSW *space = space_owner.get_or_null(p_rid); - - while (space->get_objects().size()) { - CollisionObject3DSW *co = (CollisionObject3DSW *)space->get_objects().front()->get(); - co->set_space(nullptr); - } - - active_spaces.erase(space); - free(space->get_default_area()->get_self()); - free(space->get_static_global_body()); - - space_owner.free(p_rid); - memdelete(space); - } else if (joint_owner.owns(p_rid)) { - Joint3DSW *joint = joint_owner.get_or_null(p_rid); - - joint_owner.free(p_rid); - memdelete(joint); - - } else { - ERR_FAIL_MSG("Invalid ID."); - } -}; - -void PhysicsServer3DSW::set_active(bool p_active) { - active = p_active; -}; - -void PhysicsServer3DSW::set_collision_iterations(int p_iterations) { - iterations = p_iterations; -}; - -void PhysicsServer3DSW::init() { - iterations = 8; // 8? - stepper = memnew(Step3DSW); -}; - -void PhysicsServer3DSW::step(real_t p_step) { -#ifndef _3D_DISABLED - - if (!active) { - return; - } - - _update_shapes(); - - island_count = 0; - active_objects = 0; - collision_pairs = 0; - for (Set<const Space3DSW *>::Element *E = active_spaces.front(); E; E = E->next()) { - stepper->step((Space3DSW *)E->get(), p_step, iterations); - island_count += E->get()->get_island_count(); - active_objects += E->get()->get_active_objects(); - collision_pairs += E->get()->get_collision_pairs(); - } -#endif -} - -void PhysicsServer3DSW::sync() { - doing_sync = true; -}; - -void PhysicsServer3DSW::flush_queries() { -#ifndef _3D_DISABLED - - if (!active) { - return; - } - - flushing_queries = true; - - uint64_t time_beg = OS::get_singleton()->get_ticks_usec(); - - for (Set<const Space3DSW *>::Element *E = active_spaces.front(); E; E = E->next()) { - Space3DSW *space = (Space3DSW *)E->get(); - space->call_queries(); - } - - flushing_queries = false; - - if (EngineDebugger::is_profiling("servers")) { - uint64_t total_time[Space3DSW::ELAPSED_TIME_MAX]; - static const char *time_name[Space3DSW::ELAPSED_TIME_MAX] = { - "integrate_forces", - "generate_islands", - "setup_constraints", - "solve_constraints", - "integrate_velocities" - }; - - for (int i = 0; i < Space3DSW::ELAPSED_TIME_MAX; i++) { - total_time[i] = 0; - } - - for (Set<const Space3DSW *>::Element *E = active_spaces.front(); E; E = E->next()) { - for (int i = 0; i < Space3DSW::ELAPSED_TIME_MAX; i++) { - total_time[i] += E->get()->get_elapsed_time(Space3DSW::ElapsedTime(i)); - } - } - - Array values; - values.resize(Space3DSW::ELAPSED_TIME_MAX * 2); - for (int i = 0; i < Space3DSW::ELAPSED_TIME_MAX; i++) { - values[i * 2 + 0] = time_name[i]; - values[i * 2 + 1] = USEC_TO_SEC(total_time[i]); - } - values.push_back("flush_queries"); - values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg)); - - values.push_front("physics"); - EngineDebugger::profiler_add_frame_data("servers", values); - } -#endif -}; - -void PhysicsServer3DSW::end_sync() { - doing_sync = false; -}; - -void PhysicsServer3DSW::finish() { - memdelete(stepper); -}; - -int PhysicsServer3DSW::get_process_info(ProcessInfo p_info) { - switch (p_info) { - case INFO_ACTIVE_OBJECTS: { - return active_objects; - } break; - case INFO_COLLISION_PAIRS: { - return collision_pairs; - } break; - case INFO_ISLAND_COUNT: { - return island_count; - } break; - } - - return 0; -} - -void PhysicsServer3DSW::_update_shapes() { - while (pending_shape_update_list.first()) { - pending_shape_update_list.first()->self()->_shape_changed(); - pending_shape_update_list.remove(pending_shape_update_list.first()); - } -} - -void PhysicsServer3DSW::_shape_col_cbk(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B, void *p_userdata) { - CollCbkData *cbk = (CollCbkData *)p_userdata; - - if (cbk->max == 0) { - return; - } - - if (cbk->amount == cbk->max) { - //find least deep - real_t min_depth = 1e20; - int min_depth_idx = 0; - for (int i = 0; i < cbk->amount; i++) { - real_t d = cbk->ptr[i * 2 + 0].distance_squared_to(cbk->ptr[i * 2 + 1]); - if (d < min_depth) { - min_depth = d; - min_depth_idx = i; - } - } - - real_t d = p_point_A.distance_squared_to(p_point_B); - if (d < min_depth) { - return; - } - cbk->ptr[min_depth_idx * 2 + 0] = p_point_A; - cbk->ptr[min_depth_idx * 2 + 1] = p_point_B; - - } else { - cbk->ptr[cbk->amount * 2 + 0] = p_point_A; - cbk->ptr[cbk->amount * 2 + 1] = p_point_B; - cbk->amount++; - } -} - -PhysicsServer3DSW *PhysicsServer3DSW::singletonsw = nullptr; -PhysicsServer3DSW::PhysicsServer3DSW(bool p_using_threads) { - singletonsw = this; - BroadPhase3DSW::create_func = BroadPhase3DBVH::_create; - - using_threads = p_using_threads; -}; diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 26e1411111..f83c57407d 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PHYSICS_2D_SERVER_H -#define PHYSICS_2D_SERVER_H +#ifndef PHYSICS_SERVER_2D_H +#define PHYSICS_SERVER_2D_H #include "core/io/resource.h" #include "core/object/class_db.h" @@ -701,4 +701,4 @@ VARIANT_ENUM_CAST(PhysicsServer2D::DampedSpringParam); VARIANT_ENUM_CAST(PhysicsServer2D::AreaBodyStatus); VARIANT_ENUM_CAST(PhysicsServer2D::ProcessInfo); -#endif +#endif // PHYSICS_SERVER_2D_H diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.cpp b/servers/physics_server_2d_wrap_mt.cpp index 33070bf42d..33070bf42d 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.cpp +++ b/servers/physics_server_2d_wrap_mt.cpp diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_server_2d_wrap_mt.h index 8d9e366661..927ef5d57c 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.h +++ b/servers/physics_server_2d_wrap_mt.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PHYSICS2DSERVERWRAPMT_H -#define PHYSICS2DSERVERWRAPMT_H +#ifndef PHYSICS_SERVER_2D_WRAP_MT_H +#define PHYSICS_SERVER_2D_WRAP_MT_H #include "core/config/project_settings.h" #include "core/os/thread.h" @@ -330,4 +330,4 @@ public: #endif #undef SYNC_DEBUG -#endif // PHYSICS2DSERVERWRAPMT_H +#endif // PHYSICS_SERVER_2D_WRAP_MT_H diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index c609afc11e..6f55e287c9 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PHYSICS_SERVER_H -#define PHYSICS_SERVER_H +#ifndef PHYSICS_SERVER_3D_H +#define PHYSICS_SERVER_3D_H #include "core/io/resource.h" #include "core/object/class_db.h" @@ -903,4 +903,4 @@ VARIANT_ENUM_CAST(PhysicsServer3D::G6DOFJointAxisFlag); VARIANT_ENUM_CAST(PhysicsServer3D::AreaBodyStatus); VARIANT_ENUM_CAST(PhysicsServer3D::ProcessInfo); -#endif +#endif // PHYSICS_SERVER_3D_H diff --git a/servers/physics_3d/physics_server_3d_wrap_mt.cpp b/servers/physics_server_3d_wrap_mt.cpp index c424100bba..c424100bba 100644 --- a/servers/physics_3d/physics_server_3d_wrap_mt.cpp +++ b/servers/physics_server_3d_wrap_mt.cpp diff --git a/servers/physics_3d/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h index 17d02addda..bf936fd0fc 100644 --- a/servers/physics_3d/physics_server_3d_wrap_mt.h +++ b/servers/physics_server_3d_wrap_mt.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PHYSICS3DSERVERWRAPMT_H -#define PHYSICS3DSERVERWRAPMT_H +#ifndef PHYSICS_SERVER_3D_WRAP_MT_H +#define PHYSICS_SERVER_3D_WRAP_MT_H #include "core/config/project_settings.h" #include "core/os/thread.h" @@ -406,4 +406,4 @@ public: #endif #undef SYNC_DEBUG -#endif // PHYSICS3DSERVERWRAPMT_H +#endif // PHYSICS_SERVER_3D_WRAP_MT_H diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 28cd8374c0..8be9c2114f 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -59,12 +59,12 @@ #include "display_server.h" #include "navigation_server_2d.h" #include "navigation_server_3d.h" -#include "physics_2d/physics_server_2d_sw.h" -#include "physics_2d/physics_server_2d_wrap_mt.h" -#include "physics_3d/physics_server_3d_sw.h" -#include "physics_3d/physics_server_3d_wrap_mt.h" +#include "physics_2d/godot_physics_server_2d.h" +#include "physics_3d/godot_physics_server_3d.h" #include "physics_server_2d.h" +#include "physics_server_2d_wrap_mt.h" #include "physics_server_3d.h" +#include "physics_server_3d_wrap_mt.h" #include "rendering/renderer_compositor.h" #include "rendering/rendering_device.h" #include "rendering/rendering_device_binds.h" @@ -82,7 +82,7 @@ ShaderTypes *shader_types = nullptr; PhysicsServer3D *_createGodotPhysics3DCallback() { bool using_threads = GLOBAL_GET("physics/3d/run_on_thread"); - PhysicsServer3D *physics_server = memnew(PhysicsServer3DSW(using_threads)); + PhysicsServer3D *physics_server = memnew(GodotPhysicsServer3D(using_threads)); return memnew(PhysicsServer3DWrapMT(physics_server, using_threads)); } @@ -90,7 +90,7 @@ PhysicsServer3D *_createGodotPhysics3DCallback() { PhysicsServer2D *_createGodotPhysics2DCallback() { bool using_threads = GLOBAL_GET("physics/2d/run_on_thread"); - PhysicsServer2D *physics_server = memnew(PhysicsServer2DSW(using_threads)); + PhysicsServer2D *physics_server = memnew(GodotPhysicsServer2D(using_threads)); return memnew(PhysicsServer2DWrapMT(physics_server, using_threads)); } @@ -133,6 +133,7 @@ void register_server_types() { GDREGISTER_VIRTUAL_CLASS(XRInterface); GDREGISTER_CLASS(XRInterfaceExtension); // can't register this as virtual because we need a creation function for our extensions. + GDREGISTER_CLASS(XRPose); GDREGISTER_CLASS(XRPositionalTracker); GDREGISTER_CLASS(AudioStream); diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index 42d11d8bc1..215959bb6a 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -1421,7 +1421,7 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide } } - _err_print_error(nullptr, p_path.utf8().get_data(), parser.get_error_line(), parser.get_error_text().utf8().get_data(), ERR_HANDLER_SHADER); + _err_print_error(nullptr, p_path.utf8().get_data(), parser.get_error_line(), parser.get_error_text().utf8().get_data(), false, ERR_HANDLER_SHADER); return err; } diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 835d552fd4..347238cdaa 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -495,9 +495,6 @@ void RendererViewport::draw_viewports() { if (XRServer::get_singleton() != nullptr) { xr_interface = XRServer::get_singleton()->get_primary_interface(); - - // process all our active interfaces - XRServer::get_singleton()->_process(); } if (Engine::get_singleton()->is_editor_hint()) { diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp index bf54158905..ca11df439c 100644 --- a/servers/xr/xr_interface.cpp +++ b/servers/xr/xr_interface.cpp @@ -32,6 +32,8 @@ // #include "servers/rendering/renderer_compositor.h" void XRInterface::_bind_methods() { + ADD_SIGNAL(MethodInfo("play_area_changed", PropertyInfo(Variant::INT, "mode"))); + ClassDB::bind_method(D_METHOD("get_name"), &XRInterface::get_name); ClassDB::bind_method(D_METHOD("get_capabilities"), &XRInterface::get_capabilities); @@ -47,12 +49,21 @@ void XRInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("get_render_target_size"), &XRInterface::get_render_target_size); ClassDB::bind_method(D_METHOD("get_view_count"), &XRInterface::get_view_count); + ClassDB::bind_method(D_METHOD("trigger_haptic_pulse", "action_name", "tracker_name", "frequency", "amplitude", "duration_sec", "delay_sec"), &XRInterface::trigger_haptic_pulse); + ADD_GROUP("Interface", "interface_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interface_is_primary"), "set_primary", "is_primary"); - // we don't have any properties specific to VR yet.... + // methods and properties specific to VR... + ClassDB::bind_method(D_METHOD("supports_play_area_mode", "mode"), &XRInterface::supports_play_area_mode); + ClassDB::bind_method(D_METHOD("get_play_area_mode"), &XRInterface::get_play_area_mode); + ClassDB::bind_method(D_METHOD("set_play_area_mode", "mode"), &XRInterface::set_play_area_mode); + ClassDB::bind_method(D_METHOD("get_play_area"), &XRInterface::get_play_area); + + ADD_GROUP("XR", "xr_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "xr_play_area_mode", PROPERTY_HINT_ENUM, "Unknown,3DOF,Sitting,Roomscale,Stage"), "set_play_area_mode", "get_play_area_mode"); - // but we do have properties specific to AR.... + // methods and properties specific to AR.... ClassDB::bind_method(D_METHOD("get_anchor_detection_is_enabled"), &XRInterface::get_anchor_detection_is_enabled); ClassDB::bind_method(D_METHOD("set_anchor_detection_is_enabled", "enable"), &XRInterface::set_anchor_detection_is_enabled); ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &XRInterface::get_camera_feed_id); @@ -63,19 +74,23 @@ void XRInterface::_bind_methods() { BIND_ENUM_CONSTANT(XR_NONE); BIND_ENUM_CONSTANT(XR_MONO); BIND_ENUM_CONSTANT(XR_STEREO); + BIND_ENUM_CONSTANT(XR_QUAD); + BIND_ENUM_CONSTANT(XR_VR); BIND_ENUM_CONSTANT(XR_AR); BIND_ENUM_CONSTANT(XR_EXTERNAL); - BIND_ENUM_CONSTANT(EYE_MONO); - BIND_ENUM_CONSTANT(EYE_LEFT); - BIND_ENUM_CONSTANT(EYE_RIGHT); - BIND_ENUM_CONSTANT(XR_NORMAL_TRACKING); BIND_ENUM_CONSTANT(XR_EXCESSIVE_MOTION); BIND_ENUM_CONSTANT(XR_INSUFFICIENT_FEATURES); BIND_ENUM_CONSTANT(XR_UNKNOWN_TRACKING); BIND_ENUM_CONSTANT(XR_NOT_TRACKING); -} + + BIND_ENUM_CONSTANT(XR_PLAY_AREA_UNKNOWN); + BIND_ENUM_CONSTANT(XR_PLAY_AREA_3DOF); + BIND_ENUM_CONSTANT(XR_PLAY_AREA_SITTING); + BIND_ENUM_CONSTANT(XR_PLAY_AREA_ROOMSCALE); + BIND_ENUM_CONSTANT(XR_PLAY_AREA_STAGE); +}; bool XRInterface::is_primary() { XRServer *xr_server = XRServer::get_singleton(); @@ -101,6 +116,29 @@ XRInterface::XRInterface() {} XRInterface::~XRInterface() {} +// query if this interface supports this play area mode +bool XRInterface::supports_play_area_mode(XRInterface::PlayAreaMode p_mode) { + return p_mode == XR_PLAY_AREA_UNKNOWN; +} + +// get the current play area mode +XRInterface::PlayAreaMode XRInterface::get_play_area_mode() const { + return XR_PLAY_AREA_UNKNOWN; +} + +// change the play area mode, note that this should return false if the mode is not available +bool XRInterface::set_play_area_mode(XRInterface::PlayAreaMode p_mode) { + return p_mode == XR_PLAY_AREA_UNKNOWN; +} + +// if available, returns an array of vectors denoting the play area the player can move around in +PackedVector3Array XRInterface::get_play_area() const { + // Return an empty array by default. + // Note implementation is responsible for applying our reference frame and world scale to the raw data. + // `play_area_changed` should be emitted if play area data is available and either the reference frame or world scale changes. + return PackedVector3Array(); +}; + /** these will only be implemented on AR interfaces, so we want dummies for VR **/ bool XRInterface::get_anchor_detection_is_enabled() const { return false; @@ -114,9 +152,24 @@ int XRInterface::get_camera_feed_id() { } /** these are optional, so we want dummies **/ +PackedStringArray XRInterface::get_suggested_tracker_names() const { + PackedStringArray arr; + + return arr; +} + +PackedStringArray XRInterface::get_suggested_pose_names(const StringName &p_tracker_name) const { + PackedStringArray arr; + + return arr; +} + XRInterface::TrackingStatus XRInterface::get_tracking_status() const { return XR_UNKNOWN_TRACKING; } void XRInterface::notification(int p_what) { } + +void XRInterface::trigger_haptic_pulse(const String &p_action_name, const StringName &p_tracker_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec) { +} diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h index 534fa18d8a..b489481f75 100644 --- a/servers/xr/xr_interface.h +++ b/servers/xr/xr_interface.h @@ -58,14 +58,10 @@ public: XR_NONE = 0, /* no capabilities */ XR_MONO = 1, /* can be used with mono output */ XR_STEREO = 2, /* can be used with stereo output */ - XR_AR = 4, /* offers a camera feed for AR */ - XR_EXTERNAL = 8 /* renders to external device */ - }; - - enum Eyes { - EYE_MONO, /* my son says we should call this EYE_CYCLOPS */ - EYE_LEFT, - EYE_RIGHT + XR_QUAD = 4, /* can be used with quad output (not currently supported) */ + XR_VR = 8, /* offers VR support */ + XR_AR = 16, /* offers AR support */ + XR_EXTERNAL = 32 /* renders to external device */ }; enum TrackingStatus { /* tracking status currently based on AR but we can start doing more with this for VR as well */ @@ -76,7 +72,14 @@ public: XR_NOT_TRACKING }; -private: + enum PlayAreaMode { /* defines the mode used by the XR interface for tracking */ + XR_PLAY_AREA_UNKNOWN, /* Area mode not set or not available */ + XR_PLAY_AREA_3DOF, /* Only support orientation tracking, no positional tracking, area will center around player */ + XR_PLAY_AREA_SITTING, /* Player is in seated position, limited positional tracking, fixed guardian around player */ + XR_PLAY_AREA_ROOMSCALE, /* Player is free to move around, full positional tracking */ + XR_PLAY_AREA_STAGE, /* Same as roomscale but origin point is fixed to the center of the physical space, XRServer.center_on_hmd disabled */ + }; + protected: _THREAD_SAFE_CLASS_ @@ -94,10 +97,18 @@ public: virtual bool initialize() = 0; /* initialize this interface, if this has an HMD it becomes the primary interface */ virtual void uninitialize() = 0; /* deinitialize this interface */ + /** input and output **/ + + virtual PackedStringArray get_suggested_tracker_names() const; /* return a list of likely/suggested tracker names */ + virtual PackedStringArray get_suggested_pose_names(const StringName &p_tracker_name) const; /* return a list of likely/suggested action names for this tracker */ virtual TrackingStatus get_tracking_status() const; /* get the status of our current tracking */ + virtual void trigger_haptic_pulse(const String &p_action_name, const StringName &p_tracker_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec = 0); /* trigger a haptic pulse */ /** specific to VR **/ - // nothing yet + virtual bool supports_play_area_mode(XRInterface::PlayAreaMode p_mode); /* query if this interface supports this play area mode */ + virtual XRInterface::PlayAreaMode get_play_area_mode() const; /* get the current play area mode */ + virtual bool set_play_area_mode(XRInterface::PlayAreaMode p_mode); /* change the play area mode, note that this should return false if the mode is not available */ + virtual PackedVector3Array get_play_area() const; /* if available, returns an array of vectors denoting the play area the player can move around in */ /** specific to AR **/ virtual bool get_anchor_detection_is_enabled() const; @@ -124,7 +135,7 @@ public: }; VARIANT_ENUM_CAST(XRInterface::Capabilities); -VARIANT_ENUM_CAST(XRInterface::Eyes); VARIANT_ENUM_CAST(XRInterface::TrackingStatus); +VARIANT_ENUM_CAST(XRInterface::PlayAreaMode); #endif // !XR_INTERFACE_H diff --git a/servers/xr/xr_interface_extension.cpp b/servers/xr/xr_interface_extension.cpp index 7fdf90770d..341ba32245 100644 --- a/servers/xr/xr_interface_extension.cpp +++ b/servers/xr/xr_interface_extension.cpp @@ -43,6 +43,11 @@ void XRInterfaceExtension::_bind_methods() { GDVIRTUAL_BIND(_get_tracking_status); + GDVIRTUAL_BIND(_supports_play_area_mode, "mode"); + GDVIRTUAL_BIND(_get_play_area_mode); + GDVIRTUAL_BIND(_set_play_area_mode, "mode"); + GDVIRTUAL_BIND(_get_play_area); + GDVIRTUAL_BIND(_get_render_target_size); GDVIRTUAL_BIND(_get_view_count); GDVIRTUAL_BIND(_get_camera_transform); @@ -54,6 +59,13 @@ void XRInterfaceExtension::_bind_methods() { GDVIRTUAL_BIND(_process); GDVIRTUAL_BIND(_notification, "what"); + /** input and output **/ + + GDVIRTUAL_BIND(_get_suggested_tracker_names); + GDVIRTUAL_BIND(_get_suggested_pose_names, "tracker_name"); + GDVIRTUAL_BIND(_get_tracking_status); + GDVIRTUAL_BIND(_trigger_haptic_pulse, "action_name", "tracker_name", "frequency", "amplitude", "duration_sec", "delay_sec"); + // we don't have any properties specific to VR yet.... // but we do have properties specific to AR.... @@ -111,6 +123,22 @@ void XRInterfaceExtension::uninitialize() { GDVIRTUAL_CALL(_uninitialize); } +PackedStringArray XRInterfaceExtension::get_suggested_tracker_names() const { + PackedStringArray arr; + + GDVIRTUAL_CALL(_get_suggested_tracker_names, arr); + + return arr; +} + +PackedStringArray XRInterfaceExtension::get_suggested_pose_names(const StringName &p_tracker_name) const { + PackedStringArray arr; + + GDVIRTUAL_CALL(_get_suggested_pose_names, p_tracker_name, arr); + + return arr; +} + XRInterface::TrackingStatus XRInterfaceExtension::get_tracking_status() const { uint32_t status; @@ -121,6 +149,48 @@ XRInterface::TrackingStatus XRInterfaceExtension::get_tracking_status() const { return XR_UNKNOWN_TRACKING; } +void XRInterfaceExtension::trigger_haptic_pulse(const String &p_action_name, const StringName &p_tracker_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec) { + GDVIRTUAL_CALL(_trigger_haptic_pulse, p_action_name, p_tracker_name, p_frequency, p_amplitude, p_duration_sec, p_delay_sec); +} + +bool XRInterfaceExtension::supports_play_area_mode(XRInterface::PlayAreaMode p_mode) { + bool is_supported; + + if (GDVIRTUAL_CALL(_supports_play_area_mode, p_mode, is_supported)) { + return is_supported; + } + + return false; +} + +XRInterface::PlayAreaMode XRInterfaceExtension::get_play_area_mode() const { + uint32_t mode; + + if (GDVIRTUAL_CALL(_get_play_area_mode, mode)) { + return XRInterface::PlayAreaMode(mode); + } + + return XRInterface::XR_PLAY_AREA_UNKNOWN; +} + +bool XRInterfaceExtension::set_play_area_mode(XRInterface::PlayAreaMode p_mode) { + bool success; + + if (GDVIRTUAL_CALL(_set_play_area_mode, p_mode, success)) { + return success; + } + + return false; +} + +PackedVector3Array XRInterfaceExtension::get_play_area() const { + PackedVector3Array arr; + + GDVIRTUAL_CALL(_get_play_area, arr); + + return arr; +} + /** these will only be implemented on AR interfaces, so we want dummies for VR **/ bool XRInterfaceExtension::get_anchor_detection_is_enabled() const { bool enabled; diff --git a/servers/xr/xr_interface_extension.h b/servers/xr/xr_interface_extension.h index 3b7af4c0a2..763526de96 100644 --- a/servers/xr/xr_interface_extension.h +++ b/servers/xr/xr_interface_extension.h @@ -62,11 +62,28 @@ public: GDVIRTUAL0R(bool, _initialize); GDVIRTUAL0(_uninitialize); + /** input and output **/ + + virtual PackedStringArray get_suggested_tracker_names() const override; /* return a list of likely/suggested tracker names */ + virtual PackedStringArray get_suggested_pose_names(const StringName &p_tracker_name) const override; /* return a list of likely/suggested action names for this tracker */ virtual TrackingStatus get_tracking_status() const override; + virtual void trigger_haptic_pulse(const String &p_action_name, const StringName &p_tracker_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec = 0) override; + + GDVIRTUAL0RC(PackedStringArray, _get_suggested_tracker_names); + GDVIRTUAL1RC(PackedStringArray, _get_suggested_pose_names, const StringName &); GDVIRTUAL0RC(uint32_t, _get_tracking_status); + GDVIRTUAL6(_trigger_haptic_pulse, const String &, const StringName &, double, double, double, double); /** specific to VR **/ - // nothing yet + virtual bool supports_play_area_mode(XRInterface::PlayAreaMode p_mode) override; /* query if this interface supports this play area mode */ + virtual XRInterface::PlayAreaMode get_play_area_mode() const override; /* get the current play area mode */ + virtual bool set_play_area_mode(XRInterface::PlayAreaMode p_mode) override; /* change the play area mode, note that this should return false if the mode is not available */ + virtual PackedVector3Array get_play_area() const override; /* if available, returns an array of vectors denoting the play area the player can move around in */ + + GDVIRTUAL1RC(bool, _supports_play_area_mode, XRInterface::PlayAreaMode); + GDVIRTUAL0RC(uint32_t, _get_play_area_mode); + GDVIRTUAL1RC(bool, _set_play_area_mode, uint32_t); + GDVIRTUAL0RC(PackedVector3Array, _get_play_area); /** specific to AR **/ virtual bool get_anchor_detection_is_enabled() const override; diff --git a/servers/xr/xr_pose.cpp b/servers/xr/xr_pose.cpp new file mode 100644 index 0000000000..0d05e62b46 --- /dev/null +++ b/servers/xr/xr_pose.cpp @@ -0,0 +1,110 @@ +/*************************************************************************/ +/* xr_pose.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "xr_pose.h" + +#include "servers/xr_server.h" + +void XRPose::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_has_tracking_data", "has_tracking_data"), &XRPose::set_has_tracking_data); + ClassDB::bind_method(D_METHOD("get_has_tracking_data"), &XRPose::get_has_tracking_data); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "has_tracking_data"), "set_has_tracking_data", "get_has_tracking_data"); + + ClassDB::bind_method(D_METHOD("set_name", "name"), &XRPose::set_name); + ClassDB::bind_method(D_METHOD("get_name"), &XRPose::get_name); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "name"), "set_name", "get_name"); + + ClassDB::bind_method(D_METHOD("set_transform", "transform"), &XRPose::set_transform); + ClassDB::bind_method(D_METHOD("get_transform"), &XRPose::get_transform); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "transform"), "set_transform", "get_transform"); + ClassDB::bind_method(D_METHOD("get_adjusted_transform"), &XRPose::get_adjusted_transform); + + ClassDB::bind_method(D_METHOD("set_linear_velocity", "velocity"), &XRPose::set_linear_velocity); + ClassDB::bind_method(D_METHOD("get_linear_velocity"), &XRPose::get_linear_velocity); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); + + ClassDB::bind_method(D_METHOD("set_angular_velocity", "velocity"), &XRPose::set_angular_velocity); + ClassDB::bind_method(D_METHOD("get_angular_velocity"), &XRPose::get_angular_velocity); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); +} + +void XRPose::set_has_tracking_data(const bool p_has_tracking_data) { + has_tracking_data = p_has_tracking_data; +} +bool XRPose::get_has_tracking_data() const { + return has_tracking_data; +} + +void XRPose::set_name(const StringName &p_name) { + name = p_name; +} + +StringName XRPose::get_name() const { + return name; +} + +void XRPose::set_transform(const Transform3D p_transform) { + transform = p_transform; +} + +Transform3D XRPose::get_transform() const { + return transform; +} + +Transform3D XRPose::get_adjusted_transform() const { + Transform3D adjusted_transform = transform; + + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, transform); + + // apply world scale + adjusted_transform.origin *= xr_server->get_world_scale(); + + // apply reference frame + adjusted_transform = xr_server->get_reference_frame() * adjusted_transform; + + return adjusted_transform; +} + +void XRPose::set_linear_velocity(const Vector3 p_velocity) { + linear_velocity = p_velocity; +} + +Vector3 XRPose::get_linear_velocity() const { + return linear_velocity; +} + +void XRPose::set_angular_velocity(const Vector3 p_velocity) { + angular_velocity = p_velocity; +} + +Vector3 XRPose::get_angular_velocity() const { + return angular_velocity; +} diff --git a/servers/xr/xr_pose.h b/servers/xr/xr_pose.h new file mode 100644 index 0000000000..223e95ddfe --- /dev/null +++ b/servers/xr/xr_pose.h @@ -0,0 +1,68 @@ +/*************************************************************************/ +/* xr_pose.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef XR_POSE_H +#define XR_POSE_H + +#include "core/object/ref_counted.h" + +class XRPose : public RefCounted { + GDCLASS(XRPose, RefCounted); + +public: +private: + bool has_tracking_data = false; + StringName name; + Transform3D transform; + Vector3 linear_velocity; + Vector3 angular_velocity; + +protected: + static void _bind_methods(); + +public: + void set_has_tracking_data(const bool p_has_tracking_data); + bool get_has_tracking_data() const; + + void set_name(const StringName &p_name); + StringName get_name() const; + + void set_transform(const Transform3D p_transform); + Transform3D get_transform() const; + Transform3D get_adjusted_transform() const; + + void set_linear_velocity(const Vector3 p_velocity); + Vector3 get_linear_velocity() const; + + void set_angular_velocity(const Vector3 p_velocity); + Vector3 get_angular_velocity() const; +}; + +#endif diff --git a/servers/xr/xr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp index e9383db941..1313a91172 100644 --- a/servers/xr/xr_positional_tracker.cpp +++ b/servers/xr/xr_positional_tracker.cpp @@ -37,29 +37,37 @@ void XRPositionalTracker::_bind_methods() { BIND_ENUM_CONSTANT(TRACKER_HAND_LEFT); BIND_ENUM_CONSTANT(TRACKER_HAND_RIGHT); - // this class is read only from GDScript, so we only have access to getters.. ClassDB::bind_method(D_METHOD("get_tracker_type"), &XRPositionalTracker::get_tracker_type); - ClassDB::bind_method(D_METHOD("get_tracker_id"), &XRPositionalTracker::get_tracker_id); + ClassDB::bind_method(D_METHOD("set_tracker_type", "type"), &XRPositionalTracker::set_tracker_type); + ADD_PROPERTY(PropertyInfo(Variant::INT, "type"), "set_tracker_type", "get_tracker_type"); + ClassDB::bind_method(D_METHOD("get_tracker_name"), &XRPositionalTracker::get_tracker_name); - ClassDB::bind_method(D_METHOD("get_joy_id"), &XRPositionalTracker::get_joy_id); - ClassDB::bind_method(D_METHOD("is_tracking_orientation"), &XRPositionalTracker::is_tracking_orientation); - ClassDB::bind_method(D_METHOD("get_orientation"), &XRPositionalTracker::get_orientation); - ClassDB::bind_method(D_METHOD("is_tracking_position"), &XRPositionalTracker::is_tracking_position); - ClassDB::bind_method(D_METHOD("get_position"), &XRPositionalTracker::get_position); + ClassDB::bind_method(D_METHOD("set_tracker_name", "name"), &XRPositionalTracker::set_tracker_name); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "name"), "set_tracker_name", "get_tracker_name"); + + ClassDB::bind_method(D_METHOD("get_tracker_desc"), &XRPositionalTracker::get_tracker_desc); + ClassDB::bind_method(D_METHOD("set_tracker_desc", "description"), &XRPositionalTracker::set_tracker_desc); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "description"), "set_tracker_desc", "get_tracker_desc"); + ClassDB::bind_method(D_METHOD("get_tracker_hand"), &XRPositionalTracker::get_tracker_hand); - ClassDB::bind_method(D_METHOD("get_transform", "adjust_by_reference_frame"), &XRPositionalTracker::get_transform); - ClassDB::bind_method(D_METHOD("get_mesh"), &XRPositionalTracker::get_mesh); - - // these functions we don't want to expose to normal users but do need to be callable from GDNative - ClassDB::bind_method(D_METHOD("_set_tracker_type", "type"), &XRPositionalTracker::set_tracker_type); - ClassDB::bind_method(D_METHOD("_set_tracker_name", "name"), &XRPositionalTracker::set_tracker_name); - ClassDB::bind_method(D_METHOD("_set_joy_id", "joy_id"), &XRPositionalTracker::set_joy_id); - ClassDB::bind_method(D_METHOD("_set_orientation", "orientation"), &XRPositionalTracker::set_orientation); - ClassDB::bind_method(D_METHOD("_set_rw_position", "rw_position"), &XRPositionalTracker::set_rw_position); - ClassDB::bind_method(D_METHOD("_set_mesh", "mesh"), &XRPositionalTracker::set_mesh); + ClassDB::bind_method(D_METHOD("set_tracker_hand", "hand"), &XRPositionalTracker::set_tracker_hand); + ADD_PROPERTY(PropertyInfo(Variant::INT, "hand", PROPERTY_HINT_ENUM, "Unknown,Left,Right"), "set_tracker_hand", "get_tracker_hand"); + + ClassDB::bind_method(D_METHOD("has_pose", "name"), &XRPositionalTracker::has_pose); + ClassDB::bind_method(D_METHOD("get_pose", "name"), &XRPositionalTracker::get_pose); + ClassDB::bind_method(D_METHOD("invalidate_pose", "name"), &XRPositionalTracker::invalidate_pose); + ClassDB::bind_method(D_METHOD("set_pose", "name", "transform", "linear_velocity", "angular_velocity"), &XRPositionalTracker::set_pose); + ADD_SIGNAL(MethodInfo("pose_changed", PropertyInfo(Variant::OBJECT, "pose", PROPERTY_HINT_RESOURCE_TYPE, "XRPose"))); + + ClassDB::bind_method(D_METHOD("get_input", "name"), &XRPositionalTracker::get_input); + ClassDB::bind_method(D_METHOD("set_input", "name", "value"), &XRPositionalTracker::set_input); + ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::STRING, "name"))); + ADD_SIGNAL(MethodInfo("button_released", PropertyInfo(Variant::STRING, "name"))); + ADD_SIGNAL(MethodInfo("input_value_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::FLOAT, "value"))); + ADD_SIGNAL(MethodInfo("input_axis_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::VECTOR2, "vector"))); + ClassDB::bind_method(D_METHOD("get_rumble"), &XRPositionalTracker::get_rumble); ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRPositionalTracker::set_rumble); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble"), "set_rumble", "get_rumble"); }; @@ -67,13 +75,6 @@ void XRPositionalTracker::set_tracker_type(XRServer::TrackerType p_type) { if (type != p_type) { type = p_type; hand = XRPositionalTracker::TRACKER_HAND_UNKNOWN; - - XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL(xr_server); - - // get a tracker id for our type - // note if this is a controller this will be 3 or higher but we may change it later. - tracker_id = xr_server->get_free_tracker_id_for_type(p_type); }; }; @@ -81,7 +82,8 @@ XRServer::TrackerType XRPositionalTracker::get_tracker_type() const { return type; }; -void XRPositionalTracker::set_tracker_name(const String &p_name) { +void XRPositionalTracker::set_tracker_name(const StringName &p_name) { + // Note: this should not be changed after the tracker is registered with the XRServer! name = p_name; }; @@ -89,85 +91,13 @@ StringName XRPositionalTracker::get_tracker_name() const { return name; }; -int XRPositionalTracker::get_tracker_id() const { - return tracker_id; -}; - -void XRPositionalTracker::set_joy_id(int p_joy_id) { - joy_id = p_joy_id; -}; - -int XRPositionalTracker::get_joy_id() const { - return joy_id; -}; - -bool XRPositionalTracker::is_tracking_orientation() const { - return tracking_orientation; -}; - -void XRPositionalTracker::set_orientation(const Basis &p_orientation) { - _THREAD_SAFE_METHOD_ - - tracking_orientation = true; // obviously we have this - orientation = p_orientation; -}; - -Basis XRPositionalTracker::get_orientation() const { - _THREAD_SAFE_METHOD_ - - return orientation; -}; - -bool XRPositionalTracker::is_tracking_position() const { - return tracking_position; -}; - -void XRPositionalTracker::set_position(const Vector3 &p_position) { - _THREAD_SAFE_METHOD_ - - XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL(xr_server); - real_t world_scale = xr_server->get_world_scale(); - ERR_FAIL_COND(world_scale == 0); - - tracking_position = true; // obviously we have this - rw_position = p_position / world_scale; -}; - -Vector3 XRPositionalTracker::get_position() const { - _THREAD_SAFE_METHOD_ - - XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL_V(xr_server, rw_position); - real_t world_scale = xr_server->get_world_scale(); - - return rw_position * world_scale; -}; - -void XRPositionalTracker::set_rw_position(const Vector3 &p_rw_position) { - _THREAD_SAFE_METHOD_ - - tracking_position = true; // obviously we have this - rw_position = p_rw_position; -}; - -Vector3 XRPositionalTracker::get_rw_position() const { - _THREAD_SAFE_METHOD_ - - return rw_position; -}; - -void XRPositionalTracker::set_mesh(const Ref<Mesh> &p_mesh) { - _THREAD_SAFE_METHOD_ - - mesh = p_mesh; -}; - -Ref<Mesh> XRPositionalTracker::get_mesh() const { - _THREAD_SAFE_METHOD_ +void XRPositionalTracker::set_tracker_desc(const String &p_desc) { + description = p_desc; +} - return mesh; -}; +String XRPositionalTracker::get_tracker_desc() const { + return description; +} XRPositionalTracker::TrackerHand XRPositionalTracker::get_tracker_hand() const { return hand; @@ -182,33 +112,98 @@ void XRPositionalTracker::set_tracker_hand(const XRPositionalTracker::TrackerHan ERR_FAIL_COND((type != XRServer::TRACKER_CONTROLLER) && (p_hand != XRPositionalTracker::TRACKER_HAND_UNKNOWN)); hand = p_hand; - if (hand == XRPositionalTracker::TRACKER_HAND_LEFT) { - if (!xr_server->is_tracker_id_in_use_for_type(type, 1)) { - tracker_id = 1; - }; - } else if (hand == XRPositionalTracker::TRACKER_HAND_RIGHT) { - if (!xr_server->is_tracker_id_in_use_for_type(type, 2)) { - tracker_id = 2; - }; - }; }; }; -Transform3D XRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const { - Transform3D new_transform; +bool XRPositionalTracker::has_pose(const StringName &p_action_name) const { + return poses.has(p_action_name); +} - new_transform.basis = get_orientation(); - new_transform.origin = get_position(); +Ref<XRPose> XRPositionalTracker::get_pose(const StringName &p_action_name) const { + Ref<XRPose> pose; - if (p_adjust_by_reference_frame) { - XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL_V(xr_server, new_transform); + if (poses.has(p_action_name)) { + pose = poses[p_action_name]; + } - new_transform = xr_server->get_reference_frame() * new_transform; - }; + return pose; +} - return new_transform; -}; +void XRPositionalTracker::invalidate_pose(const StringName &p_action_name) { + // only update this if we were tracking this pose + if (poses.has(p_action_name)) { + // We just set tracking data as invalid, we leave our current transform and velocity data as is so controllers don't suddenly jump to origin. + poses[p_action_name]->set_has_tracking_data(false); + } +} + +void XRPositionalTracker::set_pose(const StringName &p_action_name, const Transform3D &p_transform, const Vector3 &p_linear_velocity, const Vector3 &p_angular_velocity) { + Ref<XRPose> new_pose; + + new_pose.instantiate(); + new_pose->set_name(p_action_name); + new_pose->set_has_tracking_data(true); + new_pose->set_transform(p_transform); + new_pose->set_linear_velocity(p_linear_velocity); + new_pose->set_angular_velocity(p_angular_velocity); + + poses[p_action_name] = new_pose; + emit_signal("pose_changed", new_pose); + + // TODO discuss whether we also want to create and emit an InputEventXRPose event +} + +Variant XRPositionalTracker::get_input(const StringName &p_action_name) const { + if (inputs.has(p_action_name)) { + return inputs[p_action_name]; + } else { + return Variant(); + } +} + +void XRPositionalTracker::set_input(const StringName &p_action_name, const Variant &p_value) { + bool changed = false; + + // XR inputs + + if (inputs.has(p_action_name)) { + changed = inputs[p_action_name] != p_value; + } else { + changed = true; + } + + if (changed) { + // store the new value + inputs[p_action_name] = p_value; + + // emit signals to let the rest of the world know + switch (p_value.get_type()) { + case Variant::BOOL: { + bool pressed = p_value; + if (pressed) { + emit_signal("button_pressed", p_action_name); + } else { + emit_signal("button_released", p_action_name); + } + + // TODO discuss whether we also want to create and emit an InputEventXRButton event + } break; + case Variant::FLOAT: { + emit_signal("input_value_changed", p_action_name, p_value); + + // TODO discuss whether we also want to create and emit an InputEventXRValue event + } break; + case Variant::VECTOR2: { + emit_signal("input_axis_changed", p_action_name, p_value); + + // TODO discuss whether we also want to create and emit an InputEventXRAxis event + } break; + default: { + // ??? + } break; + } + } +} real_t XRPositionalTracker::get_rumble() const { return rumble; @@ -225,10 +220,6 @@ void XRPositionalTracker::set_rumble(real_t p_rumble) { XRPositionalTracker::XRPositionalTracker() { type = XRServer::TRACKER_UNKNOWN; name = "Unknown"; - joy_id = -1; - tracker_id = 0; - tracking_orientation = false; - tracking_position = false; hand = TRACKER_HAND_UNKNOWN; rumble = 0.0; }; diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h index 5577582929..69eb105b5a 100644 --- a/servers/xr/xr_positional_tracker.h +++ b/servers/xr/xr_positional_tracker.h @@ -33,6 +33,7 @@ #include "core/os/thread_safe.h" #include "scene/resources/mesh.h" +#include "servers/xr/xr_pose.h" #include "servers/xr_server.h" /** @@ -57,14 +58,14 @@ public: private: XRServer::TrackerType type; // type of tracker StringName name; // (unique) name of the tracker - int tracker_id; // tracker index id that is unique per type + String description; // description of the tracker, this is interface dependent, for OpenXR this will be the interaction profile bound for to the tracker + TrackerHand hand; // if known, the hand this tracker is held in + + Map<StringName, Ref<XRPose>> poses; + Map<StringName, Variant> inputs; + int joy_id; // if we also have a related joystick entity, the id of the joystick - bool tracking_orientation; // do we track orientation? - Basis orientation; // our orientation - bool tracking_position; // do we track position? - Vector3 rw_position; // our position "in the real world, so without world_scale applied" Ref<Mesh> mesh; // when available, a mesh that can be used to render this tracker - TrackerHand hand; // if known, the hand this tracker is held in real_t rumble; // rumble strength, 0.0 is off, 1.0 is maximum, note that we only record here, xr_interface is responsible for execution protected: @@ -73,27 +74,24 @@ protected: public: void set_tracker_type(XRServer::TrackerType p_type); XRServer::TrackerType get_tracker_type() const; - void set_tracker_name(const String &p_name); + void set_tracker_name(const StringName &p_name); StringName get_tracker_name() const; - int get_tracker_id() const; - void set_joy_id(int p_joy_id); - int get_joy_id() const; - bool is_tracking_orientation() const; - void set_orientation(const Basis &p_orientation); - Basis get_orientation() const; - bool is_tracking_position() const; - void set_position(const Vector3 &p_position); // set position with world_scale applied - Vector3 get_position() const; // get position with world_scale applied - void set_rw_position(const Vector3 &p_rw_position); - Vector3 get_rw_position() const; + void set_tracker_desc(const String &p_desc); + String get_tracker_desc() const; XRPositionalTracker::TrackerHand get_tracker_hand() const; void set_tracker_hand(const XRPositionalTracker::TrackerHand p_hand); + + bool has_pose(const StringName &p_action_name) const; + Ref<XRPose> get_pose(const StringName &p_action_name) const; + void invalidate_pose(const StringName &p_action_name); + void set_pose(const StringName &p_action_name, const Transform3D &p_transform, const Vector3 &p_linear_velocity, const Vector3 &p_angular_velocity); + + Variant get_input(const StringName &p_action_name) const; + void set_input(const StringName &p_action_name, const Variant &p_value); + + // TODO replace by new implementation real_t get_rumble() const; void set_rumble(real_t p_rumble); - void set_mesh(const Ref<Mesh> &p_mesh); - Ref<Mesh> get_mesh() const; - - Transform3D get_transform(bool p_adjust_by_reference_frame) const; XRPositionalTracker(); ~XRPositionalTracker() {} diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp index 780bd10fc5..d0367ba95e 100644 --- a/servers/xr_server.cpp +++ b/servers/xr_server.cpp @@ -54,10 +54,11 @@ void XRServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_interface", "idx"), &XRServer::get_interface); ClassDB::bind_method(D_METHOD("get_interfaces"), &XRServer::get_interfaces); ClassDB::bind_method(D_METHOD("find_interface", "name"), &XRServer::find_interface); - ClassDB::bind_method(D_METHOD("get_tracker_count"), &XRServer::get_tracker_count); - ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &XRServer::get_tracker); + ClassDB::bind_method(D_METHOD("add_tracker", "tracker"), &XRServer::add_tracker); ClassDB::bind_method(D_METHOD("remove_tracker", "tracker"), &XRServer::remove_tracker); + ClassDB::bind_method(D_METHOD("get_trackers", "tracker_types"), &XRServer::get_trackers); + ClassDB::bind_method(D_METHOD("get_tracker", "tracker_name"), &XRServer::get_tracker); ClassDB::bind_method(D_METHOD("get_primary_interface"), &XRServer::get_primary_interface); ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &XRServer::set_primary_interface); @@ -68,6 +69,7 @@ void XRServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_last_commit_usec"), &XRServer::get_last_commit_usec); ClassDB::bind_method(D_METHOD("get_last_frame_usec"), &XRServer::get_last_frame_usec); + BIND_ENUM_CONSTANT(TRACKER_HEAD); BIND_ENUM_CONSTANT(TRACKER_CONTROLLER); BIND_ENUM_CONSTANT(TRACKER_BASESTATION); BIND_ENUM_CONSTANT(TRACKER_ANCHOR); @@ -82,8 +84,9 @@ void XRServer::_bind_methods() { ADD_SIGNAL(MethodInfo("interface_added", PropertyInfo(Variant::STRING_NAME, "interface_name"))); ADD_SIGNAL(MethodInfo("interface_removed", PropertyInfo(Variant::STRING_NAME, "interface_name"))); - ADD_SIGNAL(MethodInfo("tracker_added", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::INT, "type"), PropertyInfo(Variant::INT, "id"))); - ADD_SIGNAL(MethodInfo("tracker_removed", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::INT, "type"), PropertyInfo(Variant::INT, "id"))); + ADD_SIGNAL(MethodInfo("tracker_added", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::INT, "type"))); + ADD_SIGNAL(MethodInfo("tracker_updated", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::INT, "type"))); + ADD_SIGNAL(MethodInfo("tracker_removed", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::INT, "type"))); }; double XRServer::get_world_scale() const { @@ -113,35 +116,43 @@ Transform3D XRServer::get_reference_frame() const { }; void XRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) { - if (primary_interface != nullptr) { - // clear our current reference frame or we'll end up double adjusting it + if (primary_interface == nullptr) { + return; + } + + if (primary_interface->get_play_area_mode() == XRInterface::XR_PLAY_AREA_STAGE) { + // center_on_hmd is not available in this mode reference_frame = Transform3D(); + return; + } - // requesting our EYE_MONO transform should return our current HMD position - Transform3D new_reference_frame = primary_interface->get_camera_transform(); + // clear our current reference frame or we'll end up double adjusting it + reference_frame = Transform3D(); - // remove our tilt - if (p_rotation_mode == 1) { - // take the Y out of our Z - new_reference_frame.basis.set_axis(2, Vector3(new_reference_frame.basis.elements[0][2], 0.0, new_reference_frame.basis.elements[2][2]).normalized()); + // requesting our EYE_MONO transform should return our current HMD position + Transform3D new_reference_frame = primary_interface->get_camera_transform(); - // Y is straight up - new_reference_frame.basis.set_axis(1, Vector3(0.0, 1.0, 0.0)); + // remove our tilt + if (p_rotation_mode == 1) { + // take the Y out of our Z + new_reference_frame.basis.set_axis(2, Vector3(new_reference_frame.basis.elements[0][2], 0.0, new_reference_frame.basis.elements[2][2]).normalized()); - // and X is our cross reference - new_reference_frame.basis.set_axis(0, new_reference_frame.basis.get_axis(1).cross(new_reference_frame.basis.get_axis(2)).normalized()); - } else if (p_rotation_mode == 2) { - // remove our rotation, we're only interesting in centering on position - new_reference_frame.basis = Basis(); - }; + // Y is straight up + new_reference_frame.basis.set_axis(1, Vector3(0.0, 1.0, 0.0)); - // don't negate our height - if (p_keep_height) { - new_reference_frame.origin.y = 0.0; - }; + // and X is our cross reference + new_reference_frame.basis.set_axis(0, new_reference_frame.basis.get_axis(1).cross(new_reference_frame.basis.get_axis(2)).normalized()); + } else if (p_rotation_mode == 2) { + // remove our rotation, we're only interesting in centering on position + new_reference_frame.basis = Basis(); + }; - reference_frame = new_reference_frame.inverse(); + // don't negate our height + if (p_keep_height) { + new_reference_frame.origin.y = 0.0; }; + + reference_frame = new_reference_frame.inverse(); }; Transform3D XRServer::get_hmd_transform() { @@ -224,106 +235,121 @@ Array XRServer::get_interfaces() const { return ret; }; -/* - A little extra info on the tracker ids, these are unique per tracker type so we get some consistency in recognising our trackers, specifically controllers. - - The first controller that is turned of will get ID 1, the second will get ID 2, etc. - The magic happens when one of the controllers is turned off, say controller 1 turns off, controller 2 will remain controller 2, controller 3 will remain controller 3. - If controller number 1 is turned on again it again gets ID 1 unless another new controller was turned on since. - - The most likely scenario however is a controller that runs out of battery and another controller being used to replace it. - Because the controllers are often linked to physical objects, say you're holding a shield in controller 1, your left hand, and a gun in controller 2, your right hand, and controller 1 dies: - - using our tracker index would suddenly make the gun disappear and the shield jump into your right hand because controller 2 becomes controller 1. - - using this approach the shield disappears or is no longer tracked, but the gun stays firmly in your right hand because that is still controller 2, further more, if controller 1 is replaced the shield will return. -*/ - -bool XRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const { - for (int i = 0; i < trackers.size(); i++) { - if (trackers[i]->get_tracker_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) { - return true; - }; - }; - - // all good - return false; +Ref<XRInterface> XRServer::get_primary_interface() const { + return primary_interface; }; -int XRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) { - // We start checking at 1, 0 means that it's not a controller.. - // Note that for controller we reserve: - // - 1 for the left hand controller and - // - 2 for the right hand controller - // so we start at 3 :) - int tracker_id = p_tracker_type == XRServer::TRACKER_CONTROLLER ? 3 : 1; - - while (is_tracker_id_in_use_for_type(p_tracker_type, tracker_id)) { - // try the next one - tracker_id++; - }; +void XRServer::set_primary_interface(const Ref<XRInterface> &p_primary_interface) { + if (p_primary_interface.is_null()) { + print_verbose("XR: Clearing primary interface"); + primary_interface.unref(); + } else { + primary_interface = p_primary_interface; - return tracker_id; + print_verbose("XR: Primary interface set to: " + primary_interface->get_name()); + } }; void XRServer::add_tracker(Ref<XRPositionalTracker> p_tracker) { ERR_FAIL_COND(p_tracker.is_null()); - trackers.push_back(p_tracker); - emit_signal(SNAME("tracker_added"), p_tracker->get_tracker_name(), p_tracker->get_tracker_type(), p_tracker->get_tracker_id()); + StringName tracker_name = p_tracker->get_tracker_name(); + if (trackers.has(tracker_name)) { + if (trackers[tracker_name] != p_tracker) { + // We already have a tracker with this name, we're going to replace it + trackers[tracker_name] = p_tracker; + emit_signal(SNAME("tracker_updated"), tracker_name, p_tracker->get_tracker_type()); + } + } else { + trackers[tracker_name] = p_tracker; + emit_signal(SNAME("tracker_added"), tracker_name, p_tracker->get_tracker_type()); + } }; void XRServer::remove_tracker(Ref<XRPositionalTracker> p_tracker) { ERR_FAIL_COND(p_tracker.is_null()); - int idx = -1; - for (int i = 0; i < trackers.size(); i++) { - if (trackers[i] == p_tracker) { - idx = i; - break; - }; - }; - - ERR_FAIL_COND(idx == -1); + StringName tracker_name = p_tracker->get_tracker_name(); + if (trackers.has(tracker_name)) { + // we send the signal right before removing it + emit_signal(SNAME("tracker_removed"), p_tracker->get_tracker_name(), p_tracker->get_tracker_type()); - emit_signal(SNAME("tracker_removed"), p_tracker->get_tracker_name(), p_tracker->get_tracker_type(), p_tracker->get_tracker_id()); - trackers.remove(idx); + // and remove it + trackers.erase(tracker_name); + } }; -int XRServer::get_tracker_count() const { - return trackers.size(); -}; +Dictionary XRServer::get_trackers(int p_tracker_types) { + Dictionary res; -Ref<XRPositionalTracker> XRServer::get_tracker(int p_index) const { - ERR_FAIL_INDEX_V(p_index, trackers.size(), Ref<XRPositionalTracker>()); + for (int i = 0; i < trackers.size(); i++) { + Ref<XRPositionalTracker> tracker = trackers.get_value_at_index(i); + if (tracker.is_valid() && (tracker->get_tracker_type() & p_tracker_types) != 0) { + res[tracker->get_tracker_name()] = tracker; + } + } - return trackers[p_index]; + return res; +} + +Ref<XRPositionalTracker> XRServer::get_tracker(const StringName &p_name) const { + if (trackers.has(p_name)) { + return trackers[p_name]; + } else { + // tracker hasn't been registered yet, which is fine, no need to spam the error log... + return Ref<XRPositionalTracker>(); + } }; -Ref<XRPositionalTracker> XRServer::find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const { - ERR_FAIL_COND_V(p_tracker_id == 0, Ref<XRPositionalTracker>()); +PackedStringArray XRServer::get_suggested_tracker_names() const { + PackedStringArray arr; - for (int i = 0; i < trackers.size(); i++) { - if (trackers[i]->get_tracker_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) { - return trackers[i]; - }; - }; + for (int i = 0; i < interfaces.size(); i++) { + Ref<XRInterface> interface = interfaces[i]; + PackedStringArray interface_arr = interface->get_suggested_tracker_names(); + for (int a = 0; a < interface_arr.size(); a++) { + if (!arr.has(interface_arr[a])) { + arr.push_back(interface_arr[a]); + } + } + } - return Ref<XRPositionalTracker>(); -}; + if (arr.size() == 0) { + // no suggestions from our tracker? include our defaults + arr.push_back(String("head")); + arr.push_back(String("left_hand")); + arr.push_back(String("right_hand")); + } -Ref<XRInterface> XRServer::get_primary_interface() const { - return primary_interface; -}; + return arr; +} -void XRServer::set_primary_interface(const Ref<XRInterface> &p_primary_interface) { - if (p_primary_interface.is_null()) { - print_verbose("XR: Clearing primary interface"); - primary_interface.unref(); - } else { - primary_interface = p_primary_interface; +PackedStringArray XRServer::get_suggested_pose_names(const StringName &p_tracker_name) const { + PackedStringArray arr; - print_verbose("XR: Primary interface set to: " + primary_interface->get_name()); + for (int i = 0; i < interfaces.size(); i++) { + Ref<XRInterface> interface = interfaces[i]; + PackedStringArray interface_arr = interface->get_suggested_pose_names(p_tracker_name); + for (int a = 0; a < interface_arr.size(); a++) { + if (!arr.has(interface_arr[a])) { + arr.push_back(interface_arr[a]); + } + } } -}; + + if (arr.size() == 0) { + // no suggestions from our tracker? include our defaults + arr.push_back(String("default")); + + if ((p_tracker_name == "left_hand") || (p_tracker_name == "right_hand")) { + arr.push_back(String("aim")); + arr.push_back(String("grip")); + arr.push_back(String("skeleton")); + } + } + + return arr; +} uint64_t XRServer::get_last_process_usec() { return last_process_usec; @@ -373,8 +399,9 @@ XRServer::~XRServer() { interfaces.remove(0); } + // TODO pretty sure there is a clear function or something... while (trackers.size() > 0) { - trackers.remove(0); + trackers.erase(trackers.get_key_at_index(0)); } singleton = nullptr; diff --git a/servers/xr_server.h b/servers/xr_server.h index 6d07263755..48d73cac9a 100644 --- a/servers/xr_server.h +++ b/servers/xr_server.h @@ -60,9 +60,10 @@ class XRServer : public Object { public: enum TrackerType { - TRACKER_CONTROLLER = 0x01, /* tracks a controller */ - TRACKER_BASESTATION = 0x02, /* tracks location of a base station */ - TRACKER_ANCHOR = 0x04, /* tracks an anchor point, used in AR to track a real live location */ + TRACKER_HEAD = 0x01, /* tracks the position of the players head (or in case of handheld AR, location of the phone) */ + TRACKER_CONTROLLER = 0x02, /* tracks a controller */ + TRACKER_BASESTATION = 0x04, /* tracks location of a base station */ + TRACKER_ANCHOR = 0x08, /* tracks an anchor point, used in AR to track a real live location */ TRACKER_UNKNOWN = 0x80, /* unknown tracker */ TRACKER_ANY_KNOWN = 0x7f, /* all except unknown */ @@ -77,7 +78,7 @@ public: private: Vector<Ref<XRInterface>> interfaces; - Vector<Ref<XRPositionalTracker>> trackers; + Dictionary trackers; Ref<XRInterface> primary_interface; /* we'll identify one interface as primary, this will be used by our viewports */ @@ -164,13 +165,17 @@ public: Our trackers are objects that expose the orientation and position of physical devices such as controller, anchor points, etc. They are created and managed by our active AR/VR interfaces. */ - bool is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const; - int get_free_tracker_id_for_type(TrackerType p_tracker_type); void add_tracker(Ref<XRPositionalTracker> p_tracker); void remove_tracker(Ref<XRPositionalTracker> p_tracker); - int get_tracker_count() const; - Ref<XRPositionalTracker> get_tracker(int p_index) const; - Ref<XRPositionalTracker> find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const; + Dictionary get_trackers(int p_tracker_types); + Ref<XRPositionalTracker> get_tracker(const StringName &p_name) const; + + /* + We don't know which trackers and actions will existing during runtime but we can request suggested names from our interfaces to help our IDE UI. + */ + PackedStringArray get_suggested_tracker_names() const; + PackedStringArray get_suggested_pose_names(const StringName &p_tracker_name) const; + // Q: Should we add get_suggested_input_names and get_suggested_haptic_names even though we don't use them for the IDE? uint64_t get_last_process_usec(); uint64_t get_last_commit_usec(); diff --git a/tests/test_tools.h b/tests/test_tools.h index 3ea953cb07..ec18610f04 100644 --- a/tests/test_tools.h +++ b/tests/test_tools.h @@ -49,7 +49,7 @@ struct ErrorDetector { has_error = false; } - static void _detect_error(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, ErrorHandlerType p_type) { + static void _detect_error(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type) { ErrorDetector *self = (ErrorDetector *)p_self; self->has_error = true; } |