Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor RayShape and rename to SeparationRayShape #51896

Merged
merged 5 commits into from
Aug 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions doc/classes/PhysicsServer2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,8 @@
<argument index="2" name="motion" type="Vector2" />
<argument index="3" name="margin" type="float" default="0.08" />
<argument index="4" name="result" type="PhysicsTestMotionResult2D" default="null" />
<argument index="5" name="exclude" type="Array" default="[]" />
<argument index="5" name="collide_separation_ray" type="bool" default="false" />
<argument index="6" name="exclude" type="Array" default="[]" />
<description>
Returns [code]true[/code] if a collision would result from moving in the given direction from a given point in space. Margin increases the size of the shapes involved in the collision detection. [PhysicsTestMotionResult2D] can be passed to return additional information in.
</description>
Expand Down Expand Up @@ -726,6 +727,11 @@
<description>
</description>
</method>
<method name="separation_ray_shape_create">
<return type="RID" />
<description>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not better to add a description? (same for PhysicsServer3D.xml)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense! It's needed for all the other shape create functions as well. I'm keeping a note of this, but I don't want to pollute the current PR with changing all of them.

</description>
</method>
<method name="set_active">
<return type="void" />
<argument index="0" name="active" type="bool" />
Expand Down Expand Up @@ -840,25 +846,28 @@
<constant name="SHAPE_WORLD_MARGIN" value="0" enum="ShapeType">
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.
</constant>
<constant name="SHAPE_SEGMENT" value="1" enum="ShapeType">
<constant name="SHAPE_SEPARATION_RAY" value="1" enum="ShapeType">
This is the constant for creating separation ray shapes. A separation ray is defined by a length and separates itself from what is touching its far endpoint. Useful for character controllers.
</constant>
<constant name="SHAPE_SEGMENT" value="2" enum="ShapeType">
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.
</constant>
<constant name="SHAPE_CIRCLE" value="2" enum="ShapeType">
<constant name="SHAPE_CIRCLE" value="3" enum="ShapeType">
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.
</constant>
<constant name="SHAPE_RECTANGLE" value="3" enum="ShapeType">
<constant name="SHAPE_RECTANGLE" value="4" enum="ShapeType">
This is the constant for creating rectangle shapes. A rectangle shape is defined by a width and a height. It can be used for intersections and inside/outside checks.
</constant>
<constant name="SHAPE_CAPSULE" value="4" enum="ShapeType">
<constant name="SHAPE_CAPSULE" value="5" enum="ShapeType">
This is the constant for creating capsule shapes. A capsule shape is defined by a radius and a length. It can be used for intersections and inside/outside checks.
</constant>
<constant name="SHAPE_CONVEX_POLYGON" value="5" enum="ShapeType">
<constant name="SHAPE_CONVEX_POLYGON" value="6" enum="ShapeType">
This is the constant for creating convex polygon shapes. A polygon is defined by a list of points. It can be used for intersections and inside/outside checks. Unlike the [member CollisionPolygon2D.polygon] property, polygons modified with [method shape_set_data] do not verify that the points supplied form is a convex polygon.
</constant>
<constant name="SHAPE_CONCAVE_POLYGON" value="6" enum="ShapeType">
<constant name="SHAPE_CONCAVE_POLYGON" value="7" enum="ShapeType">
This is the constant for creating concave polygon shapes. A polygon is defined by a list of points. It can be used for intersections checks, but not for inside/outside checks.
</constant>
<constant name="SHAPE_CUSTOM" value="7" enum="ShapeType">
<constant name="SHAPE_CUSTOM" value="8" enum="ShapeType">
This constant is used internally by the engine. Any attempt to create this kind of shape results in an error.
</constant>
<constant name="AREA_PARAM_GRAVITY" value="0" enum="AreaParameter">
Expand Down
29 changes: 19 additions & 10 deletions doc/classes/PhysicsServer3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,8 @@
<argument index="2" name="motion" type="Vector3" />
<argument index="3" name="margin" type="float" default="0.001" />
<argument index="4" name="result" type="PhysicsTestMotionResult3D" default="null" />
<argument index="5" name="exclude" type="Array" default="[]" />
<argument index="5" name="collide_separation_ray" type="bool" default="false" />
<argument index="6" name="exclude" type="Array" default="[]" />
<description>
Returns [code]true[/code] if a collision would result from moving in the given direction from a given point in space. Margin increases the size of the shapes involved in the collision detection. [PhysicsTestMotionResult3D] can be passed to return additional information in.
</description>
Expand Down Expand Up @@ -849,6 +850,11 @@
<description>
</description>
</method>
<method name="separation_ray_shape_create">
<return type="RID" />
<description>
</description>
</method>
<method name="set_active">
<return type="void" />
<argument index="0" name="active" type="bool" />
Expand Down Expand Up @@ -1171,31 +1177,34 @@
<constant name="SHAPE_PLANE" value="0" enum="ShapeType">
The [Shape3D] is a [WorldMarginShape3D].
</constant>
<constant name="SHAPE_SPHERE" value="1" enum="ShapeType">
<constant name="SHAPE_SEPARATION_RAY" value="1" enum="ShapeType">
The [Shape3D] is a [SeparationRayShape3D].
</constant>
<constant name="SHAPE_SPHERE" value="2" enum="ShapeType">
The [Shape3D] is a [SphereShape3D].
</constant>
<constant name="SHAPE_BOX" value="2" enum="ShapeType">
<constant name="SHAPE_BOX" value="3" enum="ShapeType">
The [Shape3D] is a [BoxShape3D].
</constant>
<constant name="SHAPE_CAPSULE" value="3" enum="ShapeType">
<constant name="SHAPE_CAPSULE" value="4" enum="ShapeType">
The [Shape3D] is a [CapsuleShape3D].
</constant>
<constant name="SHAPE_CYLINDER" value="4" enum="ShapeType">
<constant name="SHAPE_CYLINDER" value="5" enum="ShapeType">
The [Shape3D] is a [CylinderShape3D].
</constant>
<constant name="SHAPE_CONVEX_POLYGON" value="5" enum="ShapeType">
<constant name="SHAPE_CONVEX_POLYGON" value="6" enum="ShapeType">
The [Shape3D] is a [ConvexPolygonShape3D].
</constant>
<constant name="SHAPE_CONCAVE_POLYGON" value="6" enum="ShapeType">
<constant name="SHAPE_CONCAVE_POLYGON" value="7" enum="ShapeType">
The [Shape3D] is a [ConcavePolygonShape3D].
</constant>
<constant name="SHAPE_HEIGHTMAP" value="7" enum="ShapeType">
<constant name="SHAPE_HEIGHTMAP" value="8" enum="ShapeType">
The [Shape3D] is a [HeightMapShape3D].
</constant>
<constant name="SHAPE_SOFT_BODY" value="8" enum="ShapeType">
<constant name="SHAPE_SOFT_BODY" value="9" enum="ShapeType">
The [Shape3D] is a [SoftBody3D].
</constant>
<constant name="SHAPE_CUSTOM" value="9" enum="ShapeType">
<constant name="SHAPE_CUSTOM" value="10" enum="ShapeType">
This constant is used internally by the engine. Any attempt to create this kind of shape results in an error.
</constant>
<constant name="AREA_PARAM_GRAVITY" value="0" enum="AreaParameter">
Expand Down
24 changes: 24 additions & 0 deletions doc/classes/SeparationRayShape2D.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SeparationRayShape2D" inherits="Shape2D" version="4.0">
<brief_description>
Separation ray shape for 2D collisions.
</brief_description>
<description>
Separation ray shape for 2D collisions. A ray is not really a collision body; instead, it tries to separate itself from whatever is touching its far endpoint. It's often useful for characters.
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
<member name="length" type="float" setter="set_length" getter="get_length" default="20.0">
The ray's length.
</member>
<member name="slide_on_slope" type="bool" setter="set_slide_on_slope" getter="get_slide_on_slope" default="false">
If [code]false[/code] (default), the shape always separates and returns a normal along its own direction.
If [code]true[/code], the shape can return the correct normal and separate in any direction, allowing sliding motion on slopes.
</member>
</members>
<constants>
</constants>
</class>
24 changes: 24 additions & 0 deletions doc/classes/SeparationRayShape3D.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SeparationRayShape3D" inherits="Shape3D" version="4.0">
<brief_description>
Separation ray shape for 3D collisions.
</brief_description>
<description>
Separation ray shape for 3D collisions, which can be set into a [PhysicsBody3D] or [Area3D]. A ray is not really a collision body; instead, it tries to separate itself from whatever is touching its far endpoint. It's often useful for characters.
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
<member name="length" type="float" setter="set_length" getter="get_length" default="1.0">
The ray's length.
</member>
<member name="slide_on_slope" type="bool" setter="set_slide_on_slope" getter="get_slide_on_slope" default="false">
If [code]false[/code] (default), the shape always separates and returns a normal along its own direction.
If [code]true[/code], the shape can return the correct normal and separate in any direction, allowing sliding motion on slopes.
</member>
</members>
<constants>
</constants>
</class>
1 change: 1 addition & 0 deletions editor/icons/SeparationRayShape2D.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions editor/icons/SeparationRayShape3D.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions editor/import/resource_importer_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "scene/resources/box_shape_3d.h"
#include "scene/resources/packed_scene.h"
#include "scene/resources/resource_format_text.h"
#include "scene/resources/separation_ray_shape_3d.h"
#include "scene/resources/sphere_shape_3d.h"
#include "scene/resources/surface_tool.h"
#include "scene/resources/world_margin_shape_3d.h"
Expand Down Expand Up @@ -379,6 +380,11 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
BoxShape3D *boxShape = memnew(BoxShape3D);
boxShape->set_size(Vector3(2, 2, 2));
colshape->set_shape(boxShape);
} else if (empty_draw_type == "SINGLE_ARROW") {
SeparationRayShape3D *rayShape = memnew(SeparationRayShape3D);
rayShape->set_length(1);
colshape->set_shape(rayShape);
Object::cast_to<Node3D>(sb)->rotate_x(Math_PI / 2);
} else if (empty_draw_type == "IMAGE") {
WorldMarginShape3D *world_margin_shape = memnew(WorldMarginShape3D);
colshape->set_shape(world_margin_shape);
Expand Down
41 changes: 41 additions & 0 deletions editor/plugins/collision_shape_2d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "scene/resources/convex_polygon_shape_2d.h"
#include "scene/resources/rectangle_shape_2d.h"
#include "scene/resources/segment_shape_2d.h"
#include "scene/resources/separation_ray_shape_2d.h"
#include "scene/resources/world_margin_shape_2d.h"

void CollisionShape2DEditor::_node_removed(Node *p_node) {
Expand Down Expand Up @@ -80,6 +81,15 @@ Variant CollisionShape2DEditor::get_handle_value(int idx) const {

} break;

case SEPARATION_RAY_SHAPE: {
Ref<SeparationRayShape2D> ray = node->get_shape();

if (idx == 0) {
return ray->get_length();
}

} break;

case RECTANGLE_SHAPE: {
Ref<RectangleShape2D> rect = node->get_shape();

Expand Down Expand Up @@ -152,6 +162,15 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {

} break;

case SEPARATION_RAY_SHAPE: {
Ref<SeparationRayShape2D> ray = node->get_shape();

ray->set_length(Math::abs(p_point.y));

canvas_item_editor->update_viewport();

} break;

case RECTANGLE_SHAPE: {
if (idx < 8) {
Ref<RectangleShape2D> rect = node->get_shape();
Expand Down Expand Up @@ -253,6 +272,16 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {

} break;

case SEPARATION_RAY_SHAPE: {
Ref<SeparationRayShape2D> ray = node->get_shape();

undo_redo->add_do_method(ray.ptr(), "set_length", ray->get_length());
undo_redo->add_do_method(canvas_item_editor, "update_viewport");
undo_redo->add_undo_method(ray.ptr(), "set_length", p_org);
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");

} break;

case RECTANGLE_SHAPE: {
Ref<RectangleShape2D> rect = node->get_shape();

Expand Down Expand Up @@ -394,6 +423,8 @@ void CollisionShape2DEditor::_get_current_shape_type() {
shape_type = CONVEX_POLYGON_SHAPE;
} else if (Object::cast_to<WorldMarginShape2D>(*s)) {
shape_type = WORLD_MARGIN_SHAPE;
} else if (Object::cast_to<SeparationRayShape2D>(*s)) {
shape_type = SEPARATION_RAY_SHAPE;
} else if (Object::cast_to<RectangleShape2D>(*s)) {
shape_type = RECTANGLE_SHAPE;
} else if (Object::cast_to<SegmentShape2D>(*s)) {
Expand Down Expand Up @@ -471,6 +502,16 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla

} break;

case SEPARATION_RAY_SHAPE: {
Ref<SeparationRayShape2D> shape = node->get_shape();

handles.resize(1);
handles.write[0] = Point2(0, shape->get_length());

p_overlay->draw_texture(h, gt.xform(handles[0]) - size);

} break;

case RECTANGLE_SHAPE: {
Ref<RectangleShape2D> shape = node->get_shape();

Expand Down
1 change: 1 addition & 0 deletions editor/plugins/collision_shape_2d_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class CollisionShape2DEditor : public Control {
CONCAVE_POLYGON_SHAPE,
CONVEX_POLYGON_SHAPE,
WORLD_MARGIN_SHAPE,
SEPARATION_RAY_SHAPE,
RECTANGLE_SHAPE,
SEGMENT_SHAPE
};
Expand Down
53 changes: 53 additions & 0 deletions editor/plugins/node_3d_editor_gizmos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "scene/resources/cylinder_shape_3d.h"
#include "scene/resources/height_map_shape_3d.h"
#include "scene/resources/primitive_meshes.h"
#include "scene/resources/separation_ray_shape_3d.h"
#include "scene/resources/sphere_shape_3d.h"
#include "scene/resources/surface_tool.h"
#include "scene/resources/world_margin_shape_3d.h"
Expand Down Expand Up @@ -4067,6 +4068,10 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g
return p_id == 0 ? "Radius" : "Height";
}

if (Object::cast_to<SeparationRayShape3D>(*s)) {
return "Length";
}

return "";
}

Expand Down Expand Up @@ -4098,6 +4103,11 @@ Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p
return p_id == 0 ? cs2->get_radius() : cs2->get_height();
}

if (Object::cast_to<SeparationRayShape3D>(*s)) {
Ref<SeparationRayShape3D> cs2 = s;
return cs2->get_length();
}

return Variant();
}

Expand Down Expand Up @@ -4133,6 +4143,22 @@ void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i
ss->set_radius(d);
}

if (Object::cast_to<SeparationRayShape3D>(*s)) {
Ref<SeparationRayShape3D> rs = s;
Vector3 ra, rb;
Geometry3D::get_closest_points_between_segments(Vector3(), Vector3(0, 0, 4096), sg[0], sg[1], ra, rb);
float d = ra.z;
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}

if (d < 0.001) {
d = 0.001;
}

rs->set_length(d);
}

if (Object::cast_to<BoxShape3D>(*s)) {
Vector3 axis;
axis[p_id] = 1.0;
Expand Down Expand Up @@ -4287,6 +4313,20 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo

ur->commit_action();
}

if (Object::cast_to<SeparationRayShape3D>(*s)) {
Ref<SeparationRayShape3D> ss = s;
if (p_cancel) {
ss->set_length(p_restore);
return;
}

UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
ur->create_action(TTR("Change Separation Ray Shape Length"));
ur->add_do_method(ss.ptr(), "set_length", ss->get_length());
ur->add_undo_method(ss.ptr(), "set_length", p_restore);
ur->commit_action();
}
}

void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Expand Down Expand Up @@ -4557,6 +4597,19 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_collision_segments(cs2->get_debug_mesh_lines());
}

if (Object::cast_to<SeparationRayShape3D>(*s)) {
Ref<SeparationRayShape3D> rs = s;

Vector<Vector3> points;
points.push_back(Vector3());
points.push_back(Vector3(0, 0, rs->get_length()));
p_gizmo->add_lines(points, material);
p_gizmo->add_collision_segments(points);
Vector<Vector3> handles;
handles.push_back(Vector3(0, 0, rs->get_length()));
p_gizmo->add_handles(handles, handles_material);
}

if (Object::cast_to<HeightMapShape3D>(*s)) {
Ref<HeightMapShape3D> hms = s;

Expand Down
Loading