From 8e3f71d75060c70745f541d5cab509f7bea690df Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Fri, 13 Aug 2021 19:23:31 +0200 Subject: Rename LineShape2D to WorldMarginShape2D The new name makes it more obvious that it acts as an infinite plane, and is consistent with its 3D counterpart (WorldMarginShape3D). --- doc/classes/LineShape2D.xml | 23 ---- doc/classes/PhysicsServer2D.xml | 16 +-- doc/classes/WorldMarginShape2D.xml | 23 ++++ editor/icons/LineShape2D.svg | 1 - editor/icons/WorldMarginShape2D.svg | 1 + .../plugins/collision_shape_2d_editor_plugin.cpp | 22 ++-- editor/plugins/collision_shape_2d_editor_plugin.h | 2 +- scene/register_scene_types.cpp | 5 +- scene/resources/line_shape_2d.cpp | 117 --------------------- scene/resources/line_shape_2d.h | 64 ----------- scene/resources/world_margin_shape_2d.cpp | 117 +++++++++++++++++++++ scene/resources/world_margin_shape_2d.h | 64 +++++++++++ servers/physics_2d/collision_solver_2d_sat.cpp | 4 +- servers/physics_2d/collision_solver_2d_sw.cpp | 18 ++-- servers/physics_2d/collision_solver_2d_sw.h | 2 +- servers/physics_2d/physics_server_2d_sw.cpp | 8 +- servers/physics_2d/physics_server_2d_sw.h | 2 +- servers/physics_2d/physics_server_2d_wrap_mt.h | 2 +- servers/physics_2d/shape_2d_sw.cpp | 12 +-- servers/physics_2d/shape_2d_sw.h | 6 +- servers/physics_server_2d.cpp | 4 +- servers/physics_server_2d.h | 4 +- tests/test_physics_2d.cpp | 2 +- 23 files changed, 260 insertions(+), 259 deletions(-) delete mode 100644 doc/classes/LineShape2D.xml create mode 100644 doc/classes/WorldMarginShape2D.xml delete mode 100644 editor/icons/LineShape2D.svg create mode 100644 editor/icons/WorldMarginShape2D.svg delete mode 100644 scene/resources/line_shape_2d.cpp delete mode 100644 scene/resources/line_shape_2d.h create mode 100644 scene/resources/world_margin_shape_2d.cpp create mode 100644 scene/resources/world_margin_shape_2d.h diff --git a/doc/classes/LineShape2D.xml b/doc/classes/LineShape2D.xml deleted file mode 100644 index 434e6fba8e..0000000000 --- a/doc/classes/LineShape2D.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - Line shape for 2D collisions. - - - Line shape for 2D collisions. It works like a 2D plane and will not allow any physics body to go to the negative side. Not recommended for rigid bodies, and usually not recommended for static bodies either because it forces checks against it on every frame. - - - - - - - - The line's distance from the origin. - - - The line's normal. Defaults to [code]Vector2.UP[/code]. - - - - - diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml index 387d79d210..1df2fd0158 100644 --- a/doc/classes/PhysicsServer2D.xml +++ b/doc/classes/PhysicsServer2D.xml @@ -716,11 +716,6 @@ Sets a joint parameter. See [enum JointParam] for a list of available parameters. - - - - - @@ -812,6 +807,11 @@ Sets the value for a space parameter. See [enum SpaceParameter] for a list of available parameters. + + + + + @@ -837,11 +837,11 @@ - - This is the constant for creating line shapes. A line shape is an infinite line with an origin point, and a normal. Thus, it can be used for front/behind checks. + + This is the constant for creating world margin shapes. A world margin shape is an [i]infinite[/i] line with an origin point, and a normal. Thus, it can be used for front/behind checks. - This is the constant for creating segment shapes. A segment shape is a line from a point A to a point B. It can be checked for intersections. + This is the constant for creating segment shapes. A segment shape is a [i]finite[/i] line from a point A to a point B. It can be checked for intersections. This is the constant for creating circle shapes. A circle shape only has a radius. It can be used for intersections and inside/outside checks. diff --git a/doc/classes/WorldMarginShape2D.xml b/doc/classes/WorldMarginShape2D.xml new file mode 100644 index 0000000000..1839ab16ad --- /dev/null +++ b/doc/classes/WorldMarginShape2D.xml @@ -0,0 +1,23 @@ + + + + Line shape for 2D collisions. + + + Line shape for 2D collisions. It works like a 2D plane and will not allow any physics body to go to the negative side. Not recommended for rigid bodies, and usually not recommended for static bodies either because it forces checks against it on every frame. + + + + + + + + The line's distance from the origin. + + + The line's normal. Defaults to [code]Vector2.UP[/code]. + + + + + diff --git a/editor/icons/LineShape2D.svg b/editor/icons/LineShape2D.svg deleted file mode 100644 index f1dbe97c6f..0000000000 --- a/editor/icons/LineShape2D.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/editor/icons/WorldMarginShape2D.svg b/editor/icons/WorldMarginShape2D.svg new file mode 100644 index 0000000000..f1dbe97c6f --- /dev/null +++ b/editor/icons/WorldMarginShape2D.svg @@ -0,0 +1 @@ + diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index 4266e0f676..486f947e43 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -36,9 +36,9 @@ #include "scene/resources/circle_shape_2d.h" #include "scene/resources/concave_polygon_shape_2d.h" #include "scene/resources/convex_polygon_shape_2d.h" -#include "scene/resources/line_shape_2d.h" #include "scene/resources/rectangle_shape_2d.h" #include "scene/resources/segment_shape_2d.h" +#include "scene/resources/world_margin_shape_2d.h" void CollisionShape2DEditor::_node_removed(Node *p_node) { if (p_node == node) { @@ -74,8 +74,8 @@ Variant CollisionShape2DEditor::get_handle_value(int idx) const { case CONVEX_POLYGON_SHAPE: { } break; - case LINE_SHAPE: { - Ref line = node->get_shape(); + case WORLD_MARGIN_SHAPE: { + Ref line = node->get_shape(); if (idx == 0) { return line->get_distance(); @@ -142,9 +142,9 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { case CONVEX_POLYGON_SHAPE: { } break; - case LINE_SHAPE: { + case WORLD_MARGIN_SHAPE: { if (idx < 2) { - Ref line = node->get_shape(); + Ref line = node->get_shape(); if (idx == 0) { line->set_distance(p_point.length()); @@ -241,8 +241,8 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { // Cannot be edited directly, use CollisionPolygon2D instead. } break; - case LINE_SHAPE: { - Ref line = node->get_shape(); + case WORLD_MARGIN_SHAPE: { + Ref line = node->get_shape(); if (idx == 0) { undo_redo->add_do_method(line.ptr(), "set_distance", line->get_distance()); @@ -397,8 +397,8 @@ void CollisionShape2DEditor::_get_current_shape_type() { shape_type = CONCAVE_POLYGON_SHAPE; } else if (Object::cast_to(*s)) { shape_type = CONVEX_POLYGON_SHAPE; - } else if (Object::cast_to(*s)) { - shape_type = LINE_SHAPE; + } else if (Object::cast_to(*s)) { + shape_type = WORLD_MARGIN_SHAPE; } else if (Object::cast_to(*s)) { shape_type = RECTANGLE_SHAPE; } else if (Object::cast_to(*s)) { @@ -464,8 +464,8 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla case CONVEX_POLYGON_SHAPE: { } break; - case LINE_SHAPE: { - Ref shape = node->get_shape(); + case WORLD_MARGIN_SHAPE: { + Ref shape = node->get_shape(); handles.resize(2); handles.write[0] = shape->get_normal() * shape->get_distance(); diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h index 130ec708cf..056e1b5b7d 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.h +++ b/editor/plugins/collision_shape_2d_editor_plugin.h @@ -46,7 +46,7 @@ class CollisionShape2DEditor : public Control { CIRCLE_SHAPE, CONCAVE_POLYGON_SHAPE, CONVEX_POLYGON_SHAPE, - LINE_SHAPE, + WORLD_MARGIN_SHAPE, RECTANGLE_SHAPE, SEGMENT_SHAPE }; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 0c83c57de6..47c7e57e3f 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -148,7 +148,6 @@ #include "scene/resources/gradient.h" #include "scene/resources/height_map_shape_3d.h" #include "scene/resources/immediate_mesh.h" -#include "scene/resources/line_shape_2d.h" #include "scene/resources/material.h" #include "scene/resources/mesh.h" #include "scene/resources/mesh_data_tool.h" @@ -187,6 +186,7 @@ #include "scene/resources/visual_shader_sdf_nodes.h" #include "scene/resources/world_2d.h" #include "scene/resources/world_3d.h" +#include "scene/resources/world_margin_shape_2d.h" #include "scene/resources/world_margin_shape_3d.h" #include "scene/scene_string_names.h" @@ -823,7 +823,7 @@ void register_scene_types() { OS::get_singleton()->yield(); //may take time to init GDREGISTER_VIRTUAL_CLASS(Shape2D); - GDREGISTER_CLASS(LineShape2D); + GDREGISTER_CLASS(WorldMarginShape2D); GDREGISTER_CLASS(SegmentShape2D); GDREGISTER_CLASS(CircleShape2D); GDREGISTER_CLASS(RectangleShape2D); @@ -910,6 +910,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("KinematicBody2D", "CharacterBody2D"); ClassDB::add_compatibility_class("KinematicCollision", "KinematicCollision3D"); ClassDB::add_compatibility_class("Light", "Light3D"); + ClassDB::add_compatibility_class("LineShape2D", "WorldMarginShape2D"); ClassDB::add_compatibility_class("Listener", "Listener3D"); ClassDB::add_compatibility_class("MeshInstance", "MeshInstance3D"); ClassDB::add_compatibility_class("MultiMeshInstance", "MultiMeshInstance3D"); diff --git a/scene/resources/line_shape_2d.cpp b/scene/resources/line_shape_2d.cpp deleted file mode 100644 index d206f12287..0000000000 --- a/scene/resources/line_shape_2d.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************/ -/* line_shape_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 "line_shape_2d.h" - -#include "core/math/geometry_2d.h" -#include "servers/physics_server_2d.h" -#include "servers/rendering_server.h" - -bool LineShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - Vector2 point = get_distance() * get_normal(); - Vector2 l[2][2] = { { point - get_normal().orthogonal() * 100, point + get_normal().orthogonal() * 100 }, { point, point + get_normal() * 30 } }; - - for (int i = 0; i < 2; i++) { - Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, l[i]); - if (p_point.distance_to(closest) < p_tolerance) { - return true; - } - } - - return false; -} - -void LineShape2D::_update_shape() { - Array arr; - arr.push_back(normal); - arr.push_back(distance); - PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), arr); - emit_changed(); -} - -void LineShape2D::set_normal(const Vector2 &p_normal) { - normal = p_normal; - _update_shape(); -} - -void LineShape2D::set_distance(real_t p_distance) { - distance = p_distance; - _update_shape(); -} - -Vector2 LineShape2D::get_normal() const { - return normal; -} - -real_t LineShape2D::get_distance() const { - return distance; -} - -void LineShape2D::draw(const RID &p_to_rid, const Color &p_color) { - Vector2 point = get_distance() * get_normal(); - - Vector2 l1[2] = { point - get_normal().orthogonal() * 100, point + get_normal().orthogonal() * 100 }; - RS::get_singleton()->canvas_item_add_line(p_to_rid, l1[0], l1[1], p_color, 3); - Vector2 l2[2] = { point, point + get_normal() * 30 }; - RS::get_singleton()->canvas_item_add_line(p_to_rid, l2[0], l2[1], p_color, 3); -} - -Rect2 LineShape2D::get_rect() const { - Vector2 point = get_distance() * get_normal(); - - Vector2 l1[2] = { point - get_normal().orthogonal() * 100, point + get_normal().orthogonal() * 100 }; - Vector2 l2[2] = { point, point + get_normal() * 30 }; - Rect2 rect; - rect.position = l1[0]; - rect.expand_to(l1[1]); - rect.expand_to(l2[0]); - rect.expand_to(l2[1]); - return rect; -} - -real_t LineShape2D::get_enclosing_radius() const { - return distance; -} - -void LineShape2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_normal", "normal"), &LineShape2D::set_normal); - ClassDB::bind_method(D_METHOD("get_normal"), &LineShape2D::get_normal); - - ClassDB::bind_method(D_METHOD("set_distance", "distance"), &LineShape2D::set_distance); - ClassDB::bind_method(D_METHOD("get_distance"), &LineShape2D::get_distance); - - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "normal"), "set_normal", "get_normal"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance"), "set_distance", "get_distance"); -} - -LineShape2D::LineShape2D() : - Shape2D(PhysicsServer2D::get_singleton()->line_shape_create()) { - _update_shape(); -} diff --git a/scene/resources/line_shape_2d.h b/scene/resources/line_shape_2d.h deleted file mode 100644 index 210a1aa9e6..0000000000 --- a/scene/resources/line_shape_2d.h +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************/ -/* line_shape_2d.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 LINE_SHAPE_2D_H -#define LINE_SHAPE_2D_H - -#include "scene/resources/shape_2d.h" - -class LineShape2D : public Shape2D { - GDCLASS(LineShape2D, Shape2D); - - // LineShape2D is often used for one-way platforms, where the normal pointing up makes sense. - Vector2 normal = Vector2(0, -1); - real_t distance = 0.0; - - void _update_shape(); - -protected: - static void _bind_methods(); - -public: - virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override; - - void set_normal(const Vector2 &p_normal); - void set_distance(real_t p_distance); - - Vector2 get_normal() const; - real_t get_distance() const; - - virtual void draw(const RID &p_to_rid, const Color &p_color) override; - virtual Rect2 get_rect() const override; - virtual real_t get_enclosing_radius() const override; - - LineShape2D(); -}; - -#endif // LINE_SHAPE_2D_H diff --git a/scene/resources/world_margin_shape_2d.cpp b/scene/resources/world_margin_shape_2d.cpp new file mode 100644 index 0000000000..3b43681528 --- /dev/null +++ b/scene/resources/world_margin_shape_2d.cpp @@ -0,0 +1,117 @@ +/*************************************************************************/ +/* world_margin_shape_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 "world_margin_shape_2d.h" + +#include "core/math/geometry_2d.h" +#include "servers/physics_server_2d.h" +#include "servers/rendering_server.h" + +bool WorldMarginShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { + Vector2 point = get_distance() * get_normal(); + Vector2 l[2][2] = { { point - get_normal().orthogonal() * 100, point + get_normal().orthogonal() * 100 }, { point, point + get_normal() * 30 } }; + + for (int i = 0; i < 2; i++) { + Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, l[i]); + if (p_point.distance_to(closest) < p_tolerance) { + return true; + } + } + + return false; +} + +void WorldMarginShape2D::_update_shape() { + Array arr; + arr.push_back(normal); + arr.push_back(distance); + PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), arr); + emit_changed(); +} + +void WorldMarginShape2D::set_normal(const Vector2 &p_normal) { + normal = p_normal; + _update_shape(); +} + +void WorldMarginShape2D::set_distance(real_t p_distance) { + distance = p_distance; + _update_shape(); +} + +Vector2 WorldMarginShape2D::get_normal() const { + return normal; +} + +real_t WorldMarginShape2D::get_distance() const { + return distance; +} + +void WorldMarginShape2D::draw(const RID &p_to_rid, const Color &p_color) { + Vector2 point = get_distance() * get_normal(); + + Vector2 l1[2] = { point - get_normal().orthogonal() * 100, point + get_normal().orthogonal() * 100 }; + RS::get_singleton()->canvas_item_add_line(p_to_rid, l1[0], l1[1], p_color, 3); + Vector2 l2[2] = { point, point + get_normal() * 30 }; + RS::get_singleton()->canvas_item_add_line(p_to_rid, l2[0], l2[1], p_color, 3); +} + +Rect2 WorldMarginShape2D::get_rect() const { + Vector2 point = get_distance() * get_normal(); + + Vector2 l1[2] = { point - get_normal().orthogonal() * 100, point + get_normal().orthogonal() * 100 }; + Vector2 l2[2] = { point, point + get_normal() * 30 }; + Rect2 rect; + rect.position = l1[0]; + rect.expand_to(l1[1]); + rect.expand_to(l2[0]); + rect.expand_to(l2[1]); + return rect; +} + +real_t WorldMarginShape2D::get_enclosing_radius() const { + return distance; +} + +void WorldMarginShape2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_normal", "normal"), &WorldMarginShape2D::set_normal); + ClassDB::bind_method(D_METHOD("get_normal"), &WorldMarginShape2D::get_normal); + + ClassDB::bind_method(D_METHOD("set_distance", "distance"), &WorldMarginShape2D::set_distance); + ClassDB::bind_method(D_METHOD("get_distance"), &WorldMarginShape2D::get_distance); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "normal"), "set_normal", "get_normal"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance"), "set_distance", "get_distance"); +} + +WorldMarginShape2D::WorldMarginShape2D() : + Shape2D(PhysicsServer2D::get_singleton()->world_margin_shape_create()) { + _update_shape(); +} diff --git a/scene/resources/world_margin_shape_2d.h b/scene/resources/world_margin_shape_2d.h new file mode 100644 index 0000000000..3c1d593ffe --- /dev/null +++ b/scene/resources/world_margin_shape_2d.h @@ -0,0 +1,64 @@ +/*************************************************************************/ +/* world_margin_shape_2d.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 WORLD_MARGIN_SHAPE_2D_H +#define WORLD_MARGIN_SHAPE_2D_H + +#include "scene/resources/shape_2d.h" + +class WorldMarginShape2D : public Shape2D { + GDCLASS(WorldMarginShape2D, Shape2D); + + // WorldMarginShape2D is often used for one-way platforms, where the normal pointing up makes sense. + Vector2 normal = Vector2(0, -1); + real_t distance = 0.0; + + void _update_shape(); + +protected: + static void _bind_methods(); + +public: + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override; + + void set_normal(const Vector2 &p_normal); + void set_distance(real_t p_distance); + + Vector2 get_normal() const; + real_t get_distance() const; + + virtual void draw(const RID &p_to_rid, const Color &p_color) override; + virtual Rect2 get_rect() const override; + virtual real_t get_enclosing_radius() const override; + + WorldMarginShape2D(); +}; + +#endif // WORLD_MARGIN_SHAPE_2D_H diff --git a/servers/physics_2d/collision_solver_2d_sat.cpp b/servers/physics_2d/collision_solver_2d_sat.cpp index 45b9e6414d..30a99d3d74 100644 --- a/servers/physics_2d/collision_solver_2d_sat.cpp +++ b/servers/physics_2d/collision_solver_2d_sat.cpp @@ -1114,12 +1114,12 @@ 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) { PhysicsServer2D::ShapeType type_A = p_shape_A->get_type(); - ERR_FAIL_COND_V(type_A == PhysicsServer2D::SHAPE_LINE, false); + ERR_FAIL_COND_V(type_A == PhysicsServer2D::SHAPE_WORLD_MARGIN, false); ERR_FAIL_COND_V(p_shape_A->is_concave(), false); PhysicsServer2D::ShapeType type_B = p_shape_B->get_type(); - ERR_FAIL_COND_V(type_B == PhysicsServer2D::SHAPE_LINE, false); + ERR_FAIL_COND_V(type_B == PhysicsServer2D::SHAPE_WORLD_MARGIN, false); ERR_FAIL_COND_V(p_shape_B->is_concave(), false); static const CollisionFunc collision_table[5][5] = { diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp index ed398a24e5..8f8a4a862c 100644 --- a/servers/physics_2d/collision_solver_2d_sw.cpp +++ b/servers/physics_2d/collision_solver_2d_sw.cpp @@ -34,14 +34,14 @@ #define collision_solver sat_2d_calculate_penetration //#define collision_solver gjk_epa_calculate_penetration -bool CollisionSolver2DSW::solve_static_line(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 LineShape2DSW *line = static_cast(p_shape_A); - if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_LINE) { +bool CollisionSolver2DSW::solve_static_world_margin(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 WorldMarginShape2DSW *world_margin = static_cast(p_shape_A); + if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_WORLD_MARGIN) { return false; } - Vector2 n = p_transform_A.basis_xform(line->get_normal()).normalized(); - Vector2 p = p_transform_A.xform(line->get_normal() * line->get_d()); + Vector2 n = p_transform_A.basis_xform(world_margin->get_normal()).normalized(); + Vector2 p = p_transform_A.xform(world_margin->get_normal() * world_margin->get_d()); real_t d = n.dot(p); Vector2 supports[2]; @@ -166,15 +166,15 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p swap = true; } - if (type_A == PhysicsServer2D::SHAPE_LINE) { - if (type_B == PhysicsServer2D::SHAPE_LINE) { + if (type_A == PhysicsServer2D::SHAPE_WORLD_MARGIN) { + if (type_B == PhysicsServer2D::SHAPE_WORLD_MARGIN) { return false; } if (swap) { - return solve_static_line(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true); + return solve_static_world_margin(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true); } else { - return solve_static_line(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false); + return solve_static_world_margin(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false); } } else if (concave_B) { diff --git a/servers/physics_2d/collision_solver_2d_sw.h b/servers/physics_2d/collision_solver_2d_sw.h index 4f12ca9e88..17c0c2fe70 100644 --- a/servers/physics_2d/collision_solver_2d_sw.h +++ b/servers/physics_2d/collision_solver_2d_sw.h @@ -38,7 +38,7 @@ public: typedef void (*CallbackResult)(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_userdata); private: - static bool solve_static_line(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 solve_static_world_margin(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 void 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 *sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); static bool solve_raycast(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 *sep_axis = nullptr); diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp index 4dcc4a9cfd..88c097453e 100644 --- a/servers/physics_2d/physics_server_2d_sw.cpp +++ b/servers/physics_2d/physics_server_2d_sw.cpp @@ -42,8 +42,8 @@ RID PhysicsServer2DSW::_shape_create(ShapeType p_shape) { Shape2DSW *shape = nullptr; switch (p_shape) { - case SHAPE_LINE: { - shape = memnew(LineShape2DSW); + case SHAPE_WORLD_MARGIN: { + shape = memnew(WorldMarginShape2DSW); } break; case SHAPE_SEGMENT: { shape = memnew(SegmentShape2DSW); @@ -75,8 +75,8 @@ RID PhysicsServer2DSW::_shape_create(ShapeType p_shape) { return id; } -RID PhysicsServer2DSW::line_shape_create() { - return _shape_create(SHAPE_LINE); +RID PhysicsServer2DSW::world_margin_shape_create() { + return _shape_create(SHAPE_WORLD_MARGIN); } RID PhysicsServer2DSW::segment_shape_create() { diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h index e1ad6a56ee..3610f43f93 100644 --- a/servers/physics_2d/physics_server_2d_sw.h +++ b/servers/physics_2d/physics_server_2d_sw.h @@ -87,7 +87,7 @@ public: Vector2 *ptr; }; - virtual RID line_shape_create() override; + virtual RID world_margin_shape_create() override; virtual RID segment_shape_create() override; virtual RID circle_shape_create() override; virtual RID rectangle_shape_create() override; diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h index 7bc1096f93..b93178919d 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.h +++ b/servers/physics_2d/physics_server_2d_wrap_mt.h @@ -79,7 +79,7 @@ public: #include "servers/server_wrap_mt_common.h" //FUNC1RID(shape,ShapeType); todo fix - FUNCRID(line_shape) + FUNCRID(world_margin_shape) FUNCRID(segment_shape) FUNCRID(circle_shape) FUNCRID(rectangle_shape) diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index b16efbfe64..b3e4ca84c3 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -88,15 +88,15 @@ Shape2DSW::~Shape2DSW() { /*********************************************************/ /*********************************************************/ -void LineShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { +void WorldMarginShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { r_amount = 0; } -bool LineShape2DSW::contains_point(const Vector2 &p_point) const { +bool WorldMarginShape2DSW::contains_point(const Vector2 &p_point) const { return normal.dot(p_point) < d; } -bool LineShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { +bool WorldMarginShape2DSW::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); @@ -118,11 +118,11 @@ bool LineShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_e return true; } -real_t LineShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { +real_t WorldMarginShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { return 0; } -void LineShape2DSW::set_data(const Variant &p_data) { +void WorldMarginShape2DSW::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); @@ -131,7 +131,7 @@ void LineShape2DSW::set_data(const Variant &p_data) { configure(Rect2(Vector2(-1e4, -1e4), Vector2(1e4 * 2, 1e4 * 2))); } -Variant LineShape2DSW::get_data() const { +Variant WorldMarginShape2DSW::get_data() const { Array arr; arr.resize(2); arr[0] = normal; diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/shape_2d_sw.h index 3e4271b156..2de0f3cb9f 100644 --- a/servers/physics_2d/shape_2d_sw.h +++ b/servers/physics_2d/shape_2d_sw.h @@ -36,7 +36,7 @@ /* -SHAPE_LINE, ///< plane:"plane" +SHAPE_WORLD_MARGIN, ///< plane:"plane" SHAPE_SEGMENT, ///< real_t:"length" SHAPE_CIRCLE, ///< real_t:"radius" SHAPE_RECTANGLE, ///< vec3:"extents" @@ -152,7 +152,7 @@ public: r_max = MAX(maxa, maxb); \ } -class LineShape2DSW : public Shape2DSW { +class WorldMarginShape2DSW : public Shape2DSW { Vector2 normal; real_t d; @@ -160,7 +160,7 @@ public: _FORCE_INLINE_ Vector2 get_normal() const { return normal; } _FORCE_INLINE_ real_t get_d() const { return d; } - virtual PhysicsServer2D::ShapeType get_type() const { return PhysicsServer2D::SHAPE_LINE; } + virtual PhysicsServer2D::ShapeType get_type() const { return PhysicsServer2D::SHAPE_WORLD_MARGIN; } virtual void project_rangev(const Vector2 &p_normal, const Transform2D &p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal, p_transform, r_min, r_max); } virtual void get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const; diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index c2dedde0be..092c3ae7a9 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -513,7 +513,7 @@ bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, c } void PhysicsServer2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("line_shape_create"), &PhysicsServer2D::line_shape_create); + ClassDB::bind_method(D_METHOD("world_margin_shape_create"), &PhysicsServer2D::world_margin_shape_create); ClassDB::bind_method(D_METHOD("segment_shape_create"), &PhysicsServer2D::segment_shape_create); ClassDB::bind_method(D_METHOD("circle_shape_create"), &PhysicsServer2D::circle_shape_create); ClassDB::bind_method(D_METHOD("rectangle_shape_create"), &PhysicsServer2D::rectangle_shape_create); @@ -674,7 +674,7 @@ void PhysicsServer2D::_bind_methods() { BIND_ENUM_CONSTANT(SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS); BIND_ENUM_CONSTANT(SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH); - BIND_ENUM_CONSTANT(SHAPE_LINE); + BIND_ENUM_CONSTANT(SHAPE_WORLD_MARGIN); BIND_ENUM_CONSTANT(SHAPE_SEGMENT); BIND_ENUM_CONSTANT(SHAPE_CIRCLE); BIND_ENUM_CONSTANT(SHAPE_RECTANGLE); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index dbbc128793..27bc654594 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -219,7 +219,7 @@ public: static PhysicsServer2D *get_singleton(); enum ShapeType { - SHAPE_LINE, ///< plane:"plane" + SHAPE_WORLD_MARGIN, ///< plane:"plane" SHAPE_SEGMENT, ///< float:"length" SHAPE_CIRCLE, ///< float:"radius" SHAPE_RECTANGLE, ///< vec3:"extents" @@ -229,7 +229,7 @@ public: SHAPE_CUSTOM, ///< Server-Implementation based custom shape, calling shape_create() with this value will result in an error }; - virtual RID line_shape_create() = 0; + virtual RID world_margin_shape_create() = 0; virtual RID segment_shape_create() = 0; virtual RID circle_shape_create() = 0; virtual RID rectangle_shape_create() = 0; diff --git a/tests/test_physics_2d.cpp b/tests/test_physics_2d.cpp index 40dc74e89c..61b8951afa 100644 --- a/tests/test_physics_2d.cpp +++ b/tests/test_physics_2d.cpp @@ -255,7 +255,7 @@ protected: arr.push_back(p_normal); arr.push_back(p_d); - RID plane = ps->line_shape_create(); + RID plane = ps->world_margin_shape_create(); ps->shape_set_data(plane, arr); RID plane_body = ps->body_create(); -- cgit v1.2.3