Skip to content

Commit

Permalink
Merge pull request #51896 from nekomatata/restore-ray-shape
Browse files Browse the repository at this point in the history
Refactor RayShape and rename to SeparationRayShape
  • Loading branch information
pouleyKetchoupp authored Aug 27, 2021
2 parents fec7516 + 3d5dc80 commit ca4f205
Show file tree
Hide file tree
Showing 44 changed files with 964 additions and 99 deletions.
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>
</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

0 comments on commit ca4f205

Please sign in to comment.