Remove infinite inertia and ray shapes from CharacterBody
Infinite inertia: Not needed anymore, since it's now possible to set one-directional collision layers in order for characters to ignore rigid bodies, while rigid bodies still collide with characters. Ray shapes: They were introduced as a work around to allow constant speed on slopes, which is now possible with the new property in CharacterBody instead.
This commit is contained in:
parent
ac1dab5062
commit
4da3a87f7d
46 changed files with 220 additions and 1634 deletions
|
@ -122,9 +122,6 @@
|
|||
Sets a snapping distance. When set to a value different from [code]0.0[/code], the body is kept attached to slopes when calling [method move_and_slide]. The snapping vector is determined by the given distance along the opposite direction of the [member up_direction].
|
||||
As long as the snapping vector is in contact with the ground and the body moves against `up_direction`, the body will remain attached to the surface. Snapping is not applied if the body moves along `up_direction`, so it will be able to detach from the ground when jumping.
|
||||
</member>
|
||||
<member name="infinite_inertia" type="bool" setter="set_infinite_inertia_enabled" getter="is_infinite_inertia_enabled" default="true">
|
||||
If [code]true[/code], the body will be able to push [RigidBody2D] nodes when calling [method move_and_slide], but it also won't detect any collisions with them. If [code]false[/code], it will interact with [RigidBody2D] nodes like with [StaticBody2D].
|
||||
</member>
|
||||
<member name="linear_velocity" type="Vector2" setter="set_linear_velocity" getter="get_linear_velocity" default="Vector2(0, 0)">
|
||||
Current velocity vector in pixels per second, used and modified during calls to [method move_and_slide].
|
||||
</member>
|
||||
|
|
|
@ -79,9 +79,6 @@
|
|||
<member name="floor_max_angle" type="float" setter="set_floor_max_angle" getter="get_floor_max_angle" default="0.785398">
|
||||
Maximum angle (in radians) where a slope is still considered a floor (or a ceiling), rather than a wall, when calling [method move_and_slide]. The default value equals 45 degrees.
|
||||
</member>
|
||||
<member name="infinite_inertia" type="bool" setter="set_infinite_inertia_enabled" getter="is_infinite_inertia_enabled" default="true">
|
||||
If [code]true[/code], the body will be able to push [RigidBody3D] nodes when calling [method move_and_slide], but it also won't detect any collisions with them. If [code]false[/code], it will interact with [RigidBody3D] nodes like with [StaticBody3D].
|
||||
</member>
|
||||
<member name="linear_velocity" type="Vector3" setter="set_linear_velocity" getter="get_linear_velocity" default="Vector3(0, 0, 0)">
|
||||
Current velocity vector (typically meters per second), used and modified during calls to [method move_and_slide].
|
||||
</member>
|
||||
|
|
|
@ -26,10 +26,8 @@
|
|||
<method name="move_and_collide">
|
||||
<return type="KinematicCollision2D" />
|
||||
<argument index="0" name="rel_vec" type="Vector2" />
|
||||
<argument index="1" name="infinite_inertia" type="bool" default="true" />
|
||||
<argument index="2" name="exclude_raycast_shapes" type="bool" default="true" />
|
||||
<argument index="3" name="test_only" type="bool" default="false" />
|
||||
<argument index="4" name="safe_margin" type="float" default="0.08" />
|
||||
<argument index="1" name="test_only" type="bool" default="false" />
|
||||
<argument index="2" name="safe_margin" type="float" default="0.08" />
|
||||
<description>
|
||||
Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision2D], which contains information about the collision.
|
||||
If [code]test_only[/code] is [code]true[/code], the body does not move but the would-be collision information is given.
|
||||
|
@ -47,10 +45,8 @@
|
|||
<return type="bool" />
|
||||
<argument index="0" name="from" type="Transform2D" />
|
||||
<argument index="1" name="rel_vec" type="Vector2" />
|
||||
<argument index="2" name="infinite_inertia" type="bool" default="true" />
|
||||
<argument index="3" name="exclude_raycast_shapes" type="bool" default="true" />
|
||||
<argument index="4" name="collision" type="KinematicCollision2D" default="null" />
|
||||
<argument index="5" name="safe_margin" type="float" default="0.08" />
|
||||
<argument index="2" name="collision" type="KinematicCollision2D" default="null" />
|
||||
<argument index="3" name="safe_margin" type="float" default="0.08" />
|
||||
<description>
|
||||
Checks for collisions without moving the body. Virtually sets the node's position, scale and rotation to that of the given [Transform2D], then tries to move the body along the vector [code]rel_vec[/code]. Returns [code]true[/code] if a collision would occur.
|
||||
[code]collision[/code] is an optional object of type [KinematicCollision2D], which contains additional information about the collision (should there be one).
|
||||
|
|
|
@ -33,10 +33,8 @@
|
|||
<method name="move_and_collide">
|
||||
<return type="KinematicCollision3D" />
|
||||
<argument index="0" name="rel_vec" type="Vector3" />
|
||||
<argument index="1" name="infinite_inertia" type="bool" default="true" />
|
||||
<argument index="2" name="exclude_raycast_shapes" type="bool" default="true" />
|
||||
<argument index="3" name="test_only" type="bool" default="false" />
|
||||
<argument index="4" name="safe_margin" type="float" default="0.001" />
|
||||
<argument index="1" name="test_only" type="bool" default="false" />
|
||||
<argument index="2" name="safe_margin" type="float" default="0.001" />
|
||||
<description>
|
||||
Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision3D], which contains information about the collision.
|
||||
If [code]test_only[/code] is [code]true[/code], the body does not move but the would-be collision information is given.
|
||||
|
@ -62,10 +60,8 @@
|
|||
<return type="bool" />
|
||||
<argument index="0" name="from" type="Transform3D" />
|
||||
<argument index="1" name="rel_vec" type="Vector3" />
|
||||
<argument index="2" name="infinite_inertia" type="bool" default="true" />
|
||||
<argument index="3" name="exclude_raycast_shapes" type="bool" default="true" />
|
||||
<argument index="4" name="collision" type="KinematicCollision3D" default="null" />
|
||||
<argument index="5" name="safe_margin" type="float" default="0.001" />
|
||||
<argument index="2" name="collision" type="KinematicCollision3D" default="null" />
|
||||
<argument index="3" name="safe_margin" type="float" default="0.001" />
|
||||
<description>
|
||||
Checks for collisions without moving the body. Virtually sets the node's position, scale and rotation to that of the given [Transform3D], then tries to move the body along the vector [code]rel_vec[/code]. Returns [code]true[/code] if a collision would occur.
|
||||
[code]collision[/code] is an optional object of type [KinematicCollision3D], which contains additional information about the collision (should there be one).
|
||||
|
|
|
@ -593,11 +593,9 @@
|
|||
<argument index="0" name="body" type="RID" />
|
||||
<argument index="1" name="from" type="Transform2D" />
|
||||
<argument index="2" name="motion" type="Vector2" />
|
||||
<argument index="3" name="infinite_inertia" type="bool" />
|
||||
<argument index="4" name="margin" type="float" default="0.08" />
|
||||
<argument index="5" name="result" type="PhysicsTestMotionResult2D" default="null" />
|
||||
<argument index="6" name="exclude_raycast_shapes" type="bool" default="true" />
|
||||
<argument index="7" name="exclude" type="Array" default="[]" />
|
||||
<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="[]" />
|
||||
<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>
|
||||
|
@ -723,11 +721,6 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="ray_shape_create">
|
||||
<return type="RID" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="rectangle_shape_create">
|
||||
<return type="RID" />
|
||||
<description>
|
||||
|
@ -847,27 +840,25 @@
|
|||
<constant name="SHAPE_LINE" value="0" enum="ShapeType">
|
||||
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.
|
||||
</constant>
|
||||
<constant name="SHAPE_RAY" value="1" enum="ShapeType">
|
||||
</constant>
|
||||
<constant name="SHAPE_SEGMENT" value="2" enum="ShapeType">
|
||||
<constant name="SHAPE_SEGMENT" value="1" enum="ShapeType">
|
||||
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.
|
||||
</constant>
|
||||
<constant name="SHAPE_CIRCLE" value="3" enum="ShapeType">
|
||||
<constant name="SHAPE_CIRCLE" value="2" 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="4" enum="ShapeType">
|
||||
<constant name="SHAPE_RECTANGLE" value="3" 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="5" enum="ShapeType">
|
||||
<constant name="SHAPE_CAPSULE" value="4" 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="6" enum="ShapeType">
|
||||
<constant name="SHAPE_CONVEX_POLYGON" value="5" 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="7" enum="ShapeType">
|
||||
<constant name="SHAPE_CONCAVE_POLYGON" value="6" 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="8" enum="ShapeType">
|
||||
<constant name="SHAPE_CUSTOM" value="7" 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">
|
||||
|
|
|
@ -569,11 +569,9 @@
|
|||
<argument index="0" name="body" type="RID" />
|
||||
<argument index="1" name="from" type="Transform3D" />
|
||||
<argument index="2" name="motion" type="Vector3" />
|
||||
<argument index="3" name="infinite_inertia" type="bool" />
|
||||
<argument index="4" name="margin" type="float" default="0.001" />
|
||||
<argument index="5" name="result" type="PhysicsTestMotionResult3D" default="null" />
|
||||
<argument index="6" name="exclude_raycast_shapes" type="bool" default="true" />
|
||||
<argument index="7" name="exclude" type="Array" default="[]" />
|
||||
<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="[]" />
|
||||
<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>
|
||||
|
@ -851,11 +849,6 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="ray_shape_create">
|
||||
<return type="RID" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_active">
|
||||
<return type="void" />
|
||||
<argument index="0" name="active" type="bool" />
|
||||
|
@ -1178,34 +1171,31 @@
|
|||
<constant name="SHAPE_PLANE" value="0" enum="ShapeType">
|
||||
The [Shape3D] is a [WorldMarginShape3D].
|
||||
</constant>
|
||||
<constant name="SHAPE_RAY" value="1" enum="ShapeType">
|
||||
The [Shape3D] is a [RayShape3D].
|
||||
</constant>
|
||||
<constant name="SHAPE_SPHERE" value="2" enum="ShapeType">
|
||||
<constant name="SHAPE_SPHERE" value="1" enum="ShapeType">
|
||||
The [Shape3D] is a [SphereShape3D].
|
||||
</constant>
|
||||
<constant name="SHAPE_BOX" value="3" enum="ShapeType">
|
||||
<constant name="SHAPE_BOX" value="2" enum="ShapeType">
|
||||
The [Shape3D] is a [BoxShape3D].
|
||||
</constant>
|
||||
<constant name="SHAPE_CAPSULE" value="4" enum="ShapeType">
|
||||
<constant name="SHAPE_CAPSULE" value="3" enum="ShapeType">
|
||||
The [Shape3D] is a [CapsuleShape3D].
|
||||
</constant>
|
||||
<constant name="SHAPE_CYLINDER" value="5" enum="ShapeType">
|
||||
<constant name="SHAPE_CYLINDER" value="4" enum="ShapeType">
|
||||
The [Shape3D] is a [CylinderShape3D].
|
||||
</constant>
|
||||
<constant name="SHAPE_CONVEX_POLYGON" value="6" enum="ShapeType">
|
||||
<constant name="SHAPE_CONVEX_POLYGON" value="5" enum="ShapeType">
|
||||
The [Shape3D] is a [ConvexPolygonShape3D].
|
||||
</constant>
|
||||
<constant name="SHAPE_CONCAVE_POLYGON" value="7" enum="ShapeType">
|
||||
<constant name="SHAPE_CONCAVE_POLYGON" value="6" enum="ShapeType">
|
||||
The [Shape3D] is a [ConcavePolygonShape3D].
|
||||
</constant>
|
||||
<constant name="SHAPE_HEIGHTMAP" value="8" enum="ShapeType">
|
||||
<constant name="SHAPE_HEIGHTMAP" value="7" enum="ShapeType">
|
||||
The [Shape3D] is a [HeightMapShape3D].
|
||||
</constant>
|
||||
<constant name="SHAPE_SOFT_BODY" value="9" enum="ShapeType">
|
||||
<constant name="SHAPE_SOFT_BODY" value="8" enum="ShapeType">
|
||||
The [Shape3D] is a [SoftBody3D].
|
||||
</constant>
|
||||
<constant name="SHAPE_CUSTOM" value="10" enum="ShapeType">
|
||||
<constant name="SHAPE_CUSTOM" value="9" 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">
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="RayShape2D" inherits="Shape2D" version="4.0">
|
||||
<brief_description>
|
||||
Ray shape for 2D collisions.
|
||||
</brief_description>
|
||||
<description>
|
||||
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="slips_on_slope" type="bool" setter="set_slips_on_slope" getter="get_slips_on_slope" default="false">
|
||||
If [code]true[/code], allow the shape to return the correct normal.
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="RayShape3D" inherits="Shape3D" version="4.0">
|
||||
<brief_description>
|
||||
Ray shape for 3D collisions.
|
||||
</brief_description>
|
||||
<description>
|
||||
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="slips_on_slope" type="bool" setter="set_slips_on_slope" getter="get_slips_on_slope" default="false">
|
||||
If [code]true[/code], allow the shape to return the correct normal.
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
|
@ -1 +0,0 @@
|
|||
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a1 1 0 0 0 -1 1v9.5859l-1.293-1.293a1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l3 3a1.0001 1.0001 0 0 0 .0039062.003907 1 1 0 0 0 .050781.044921 1.0001 1.0001 0 0 0 .03125.027344 1 1 0 0 0 .048828.035156 1.0001 1.0001 0 0 0 .023438.015625 1 1 0 0 0 .076172.044922 1.0001 1.0001 0 0 0 .0058593.003906 1 1 0 0 0 .013672.007813 1.0001 1.0001 0 0 0 .078125.035156 1 1 0 0 0 .074219.025391 1.0001 1.0001 0 0 0 .025391.009766 1 1 0 0 0 .039062.009765 1.0001 1.0001 0 0 0 .068359.013672 1.0001 1.0001 0 0 0 .097656.011719 1.0001 1.0001 0 0 0 .0078125 0 1 1 0 0 0 .0625.003906 1 1 0 0 0 .015625-.001953 1.0001 1.0001 0 0 0 .083984-.003906 1 1 0 0 0 .015625-.001953 1.0001 1.0001 0 0 0 .083984-.013672 1.0001 1.0001 0 0 0 .052734-.013672 1 1 0 0 0 .058594-.015625 1.0001 1.0001 0 0 0 .078125-.029297 1 1 0 0 0 .013672-.00586 1.0001 1.0001 0 0 0 .076172-.037109 1 1 0 0 0 .013672-.007812 1.0001 1.0001 0 0 0 .072266-.044922 1 1 0 0 0 .011719-.007813 1.0001 1.0001 0 0 0 .068359-.052734 1 1 0 0 0 .011719-.009766 1.0001 1.0001 0 0 0 .050781-.046875l.0097657-.011719 2.9902-2.9883a1 1 0 0 0 0-1.4141 1 1 0 0 0 -1.4141 0l-1.293 1.293v-9.5859a1 1 0 0 0 -1-1z" fill="#68b6ff" fill-rule="evenodd"/></svg>
|
Before Width: | Height: | Size: 1.3 KiB |
|
@ -1 +0,0 @@
|
|||
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd"><path d="m8 1-6 5 4 2.666v4.334l2 2v-5-2z" fill="#a2d2ff"/><path d="m8 1v7 2l-2-1.334v1.334l2 1.5v3.5l2-2v-4.334l4-2.666z" fill="#2998ff"/></g></svg>
|
Before Width: | Height: | Size: 256 B |
|
@ -45,7 +45,6 @@
|
|||
#include "scene/resources/animation.h"
|
||||
#include "scene/resources/box_shape_3d.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
#include "scene/resources/ray_shape_3d.h"
|
||||
#include "scene/resources/resource_format_text.h"
|
||||
#include "scene/resources/sphere_shape_3d.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
|
@ -381,11 +380,6 @@ 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") {
|
||||
RayShape3D *rayShape = memnew(RayShape3D);
|
||||
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);
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#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/ray_shape_2d.h"
|
||||
#include "scene/resources/rectangle_shape_2d.h"
|
||||
#include "scene/resources/segment_shape_2d.h"
|
||||
|
||||
|
@ -86,15 +85,6 @@ Variant CollisionShape2DEditor::get_handle_value(int idx) const {
|
|||
|
||||
} break;
|
||||
|
||||
case RAY_SHAPE: {
|
||||
Ref<RayShape2D> ray = node->get_shape();
|
||||
|
||||
if (idx == 0) {
|
||||
return ray->get_length();
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case RECTANGLE_SHAPE: {
|
||||
Ref<RectangleShape2D> rect = node->get_shape();
|
||||
|
||||
|
@ -167,15 +157,6 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
|
|||
|
||||
} break;
|
||||
|
||||
case RAY_SHAPE: {
|
||||
Ref<RayShape2D> 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();
|
||||
|
@ -277,16 +258,6 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
|
|||
|
||||
} break;
|
||||
|
||||
case RAY_SHAPE: {
|
||||
Ref<RayShape2D> 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();
|
||||
|
||||
|
@ -428,8 +399,6 @@ void CollisionShape2DEditor::_get_current_shape_type() {
|
|||
shape_type = CONVEX_POLYGON_SHAPE;
|
||||
} else if (Object::cast_to<LineShape2D>(*s)) {
|
||||
shape_type = LINE_SHAPE;
|
||||
} else if (Object::cast_to<RayShape2D>(*s)) {
|
||||
shape_type = RAY_SHAPE;
|
||||
} else if (Object::cast_to<RectangleShape2D>(*s)) {
|
||||
shape_type = RECTANGLE_SHAPE;
|
||||
} else if (Object::cast_to<SegmentShape2D>(*s)) {
|
||||
|
@ -507,16 +476,6 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla
|
|||
|
||||
} break;
|
||||
|
||||
case RAY_SHAPE: {
|
||||
Ref<RayShape2D> 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();
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ class CollisionShape2DEditor : public Control {
|
|||
CONCAVE_POLYGON_SHAPE,
|
||||
CONVEX_POLYGON_SHAPE,
|
||||
LINE_SHAPE,
|
||||
RAY_SHAPE,
|
||||
RECTANGLE_SHAPE,
|
||||
SEGMENT_SHAPE
|
||||
};
|
||||
|
|
|
@ -66,7 +66,6 @@
|
|||
#include "scene/resources/cylinder_shape_3d.h"
|
||||
#include "scene/resources/height_map_shape_3d.h"
|
||||
#include "scene/resources/primitive_meshes.h"
|
||||
#include "scene/resources/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"
|
||||
|
@ -4081,10 +4080,6 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g
|
|||
return p_id == 0 ? "Radius" : "Height";
|
||||
}
|
||||
|
||||
if (Object::cast_to<RayShape3D>(*s)) {
|
||||
return "Length";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -4116,11 +4111,6 @@ Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p
|
|||
return p_id == 0 ? cs2->get_radius() : cs2->get_height();
|
||||
}
|
||||
|
||||
if (Object::cast_to<RayShape3D>(*s)) {
|
||||
Ref<RayShape3D> cs2 = s;
|
||||
return cs2->get_length();
|
||||
}
|
||||
|
||||
return Variant();
|
||||
}
|
||||
|
||||
|
@ -4156,22 +4146,6 @@ void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i
|
|||
ss->set_radius(d);
|
||||
}
|
||||
|
||||
if (Object::cast_to<RayShape3D>(*s)) {
|
||||
Ref<RayShape3D> 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;
|
||||
|
@ -4330,20 +4304,6 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo
|
|||
|
||||
ur->commit_action();
|
||||
}
|
||||
|
||||
if (Object::cast_to<RayShape3D>(*s)) {
|
||||
Ref<RayShape3D> ss = s;
|
||||
if (p_cancel) {
|
||||
ss->set_length(p_restore);
|
||||
return;
|
||||
}
|
||||
|
||||
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
|
||||
ur->create_action(TTR("Change 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) {
|
||||
|
@ -4614,19 +4574,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
|
|||
p_gizmo->add_collision_segments(cs2->get_debug_mesh_lines());
|
||||
}
|
||||
|
||||
if (Object::cast_to<RayShape3D>(*s)) {
|
||||
Ref<RayShape3D> 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;
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
#include "scene/scene_string_names.h"
|
||||
|
||||
void PhysicsBody2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only", "safe_margin"), &PhysicsBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false), DEFVAL(0.08));
|
||||
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "collision", "safe_margin"), &PhysicsBody2D::test_move, DEFVAL(true), DEFVAL(true), DEFVAL(Variant()), DEFVAL(0.08));
|
||||
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "test_only", "safe_margin"), &PhysicsBody2D::_move, DEFVAL(false), DEFVAL(0.08));
|
||||
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "collision", "safe_margin"), &PhysicsBody2D::test_move, DEFVAL(Variant()), DEFVAL(0.08));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody2D::get_collision_exceptions);
|
||||
ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody2D::add_collision_exception_with);
|
||||
|
@ -59,10 +59,10 @@ PhysicsBody2D::~PhysicsBody2D() {
|
|||
}
|
||||
}
|
||||
|
||||
Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only, real_t p_margin) {
|
||||
Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_motion, bool p_test_only, real_t p_margin) {
|
||||
PhysicsServer2D::MotionResult result;
|
||||
|
||||
if (move_and_collide(p_motion, p_infinite_inertia, result, p_margin, p_exclude_raycast_shapes, p_test_only)) {
|
||||
if (move_and_collide(p_motion, result, p_margin, p_test_only)) {
|
||||
if (motion_cache.is_null()) {
|
||||
motion_cache.instantiate();
|
||||
motion_cache->owner = this;
|
||||
|
@ -75,12 +75,12 @@ Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_motion, bool p_i
|
|||
return Ref<KinematicCollision2D>();
|
||||
}
|
||||
|
||||
bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only, bool p_cancel_sliding, const Set<RID> &p_exclude) {
|
||||
bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_test_only, bool p_cancel_sliding, const Set<RID> &p_exclude) {
|
||||
if (is_only_update_transform_changes_enabled()) {
|
||||
ERR_PRINT("Move functions do not work together with 'sync to physics' option. Please read the documentation.");
|
||||
}
|
||||
Transform2D gt = get_global_transform();
|
||||
bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_margin, &r_result, p_exclude_raycast_shapes, p_exclude);
|
||||
bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_margin, &r_result, p_exclude);
|
||||
|
||||
// Restore direction of motion to be along original motion,
|
||||
// in order to avoid sliding due to recovery,
|
||||
|
@ -128,7 +128,7 @@ bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_in
|
|||
return colliding;
|
||||
}
|
||||
|
||||
bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, const Ref<KinematicCollision2D> &r_collision, real_t p_margin) {
|
||||
bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion, const Ref<KinematicCollision2D> &r_collision, real_t p_margin) {
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||
|
||||
PhysicsServer2D::MotionResult *r = nullptr;
|
||||
|
@ -137,7 +137,7 @@ bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion
|
|||
r = const_cast<PhysicsServer2D::MotionResult *>(&r_collision->result);
|
||||
}
|
||||
|
||||
return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, p_margin, r, p_exclude_raycast_shapes);
|
||||
return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_margin, r);
|
||||
}
|
||||
|
||||
TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() {
|
||||
|
@ -1080,7 +1080,7 @@ void CharacterBody2D::move_and_slide() {
|
|||
PhysicsServer2D::MotionResult floor_result;
|
||||
Set<RID> exclude;
|
||||
exclude.insert(platform_rid);
|
||||
if (move_and_collide(current_platform_velocity * delta, infinite_inertia, floor_result, true, false, false, false, exclude)) {
|
||||
if (move_and_collide(current_platform_velocity * delta, floor_result, margin, false, false, exclude)) {
|
||||
motion_results.push_back(floor_result);
|
||||
_set_collision_direction(floor_result);
|
||||
}
|
||||
|
@ -1113,123 +1113,113 @@ void CharacterBody2D::move_and_slide() {
|
|||
|
||||
Vector2 prev_position = get_global_transform().elements[2];
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
bool collided;
|
||||
if (i == 0) { // Collide.
|
||||
collided = move_and_collide(motion, infinite_inertia, result, margin, true, false, !sliding_enabled);
|
||||
} else { // Separate raycasts (if any).
|
||||
collided = separate_raycast_shapes(result);
|
||||
if (collided) {
|
||||
result.remainder = motion; // Keep.
|
||||
result.motion = Vector2();
|
||||
bool collided = move_and_collide(motion, result, margin, false, !sliding_enabled);
|
||||
|
||||
if (collided) {
|
||||
found_collision = true;
|
||||
motion_results.push_back(result);
|
||||
_set_collision_direction(result);
|
||||
|
||||
if (on_floor && stop_on_slope && (linear_velocity.normalized() + up_direction).length() < 0.01) {
|
||||
Transform2D gt = get_global_transform();
|
||||
if (result.motion.length() > margin) {
|
||||
gt.elements[2] -= result.motion.slide(up_direction);
|
||||
} else {
|
||||
gt.elements[2] -= result.motion;
|
||||
}
|
||||
set_global_transform(gt);
|
||||
linear_velocity = Vector2();
|
||||
motion = Vector2();
|
||||
break;
|
||||
}
|
||||
|
||||
if (collided) {
|
||||
found_collision = true;
|
||||
motion_results.push_back(result);
|
||||
_set_collision_direction(result);
|
||||
if (result.remainder.is_equal_approx(Vector2())) {
|
||||
motion = Vector2();
|
||||
break;
|
||||
}
|
||||
|
||||
if (on_floor && stop_on_slope && (linear_velocity.normalized() + up_direction).length() < 0.01) {
|
||||
Transform2D gt = get_global_transform();
|
||||
if (result.motion.length() > margin) {
|
||||
gt.elements[2] -= result.motion.slide(up_direction);
|
||||
} else {
|
||||
// Move on floor only checks.
|
||||
if (move_on_floor_only && on_wall && motion_slide_up.dot(result.collision_normal) <= 0) {
|
||||
// Avoid to move forward on a wall if move_on_floor_only is true.
|
||||
if (was_on_floor && !is_on_floor_only() && !vel_dir_facing_up) {
|
||||
// If the movement is large the body can be prevented from reaching the walls.
|
||||
if (result.motion.length() <= margin) {
|
||||
// Cancels the motion.
|
||||
Transform2D gt = get_global_transform();
|
||||
gt.elements[2] -= result.motion;
|
||||
set_global_transform(gt);
|
||||
}
|
||||
set_global_transform(gt);
|
||||
on_floor = true;
|
||||
platform_rid = prev_platform_rid;
|
||||
platform_layer = prev_platform_layer;
|
||||
|
||||
platform_velocity = prev_platform_velocity;
|
||||
floor_normal = prev_floor_normal;
|
||||
linear_velocity = Vector2();
|
||||
motion = Vector2();
|
||||
break;
|
||||
}
|
||||
|
||||
if (result.remainder.is_equal_approx(Vector2())) {
|
||||
motion = Vector2();
|
||||
break;
|
||||
}
|
||||
|
||||
// Move on floor only checks.
|
||||
if (move_on_floor_only && on_wall && motion_slide_up.dot(result.collision_normal) <= 0) {
|
||||
// Avoid to move forward on a wall if move_on_floor_only is true.
|
||||
if (was_on_floor && !is_on_floor_only() && !vel_dir_facing_up) {
|
||||
// If the movement is large the body can be prevented from reaching the walls.
|
||||
if (result.motion.length() <= margin) {
|
||||
// Cancels the motion.
|
||||
Transform2D gt = get_global_transform();
|
||||
gt.elements[2] -= result.motion;
|
||||
set_global_transform(gt);
|
||||
}
|
||||
on_floor = true;
|
||||
platform_rid = prev_platform_rid;
|
||||
platform_layer = prev_platform_layer;
|
||||
|
||||
platform_velocity = prev_platform_velocity;
|
||||
floor_normal = prev_floor_normal;
|
||||
linear_velocity = Vector2();
|
||||
motion = Vector2();
|
||||
break;
|
||||
}
|
||||
// Prevents the body from being able to climb a slope when it moves forward against the wall.
|
||||
else if (!is_on_floor_only()) {
|
||||
motion = up_direction * up_direction.dot(result.remainder);
|
||||
motion = motion.slide(result.collision_normal);
|
||||
} else {
|
||||
motion = result.remainder;
|
||||
}
|
||||
}
|
||||
// Constant Speed when the slope is upward.
|
||||
else if (constant_speed_on_floor && is_on_floor_only() && can_apply_constant_speed && was_on_floor && motion.dot(result.collision_normal) < 0) {
|
||||
can_apply_constant_speed = false;
|
||||
Vector2 motion_slide_norm = result.remainder.slide(result.collision_normal).normalized();
|
||||
if (!motion_slide_norm.is_equal_approx(Vector2())) {
|
||||
motion = motion_slide_norm * (motion_slide_up.length() - result.motion.slide(up_direction).length() - last_travel.slide(up_direction).length());
|
||||
}
|
||||
}
|
||||
// Regular sliding, the last part of the test handle the case when you don't want to slide on the ceiling.
|
||||
else if ((sliding_enabled || !on_floor) && (!on_ceiling || slide_on_ceiling || !vel_dir_facing_up)) {
|
||||
Vector2 slide_motion = result.remainder.slide(result.collision_normal);
|
||||
if (slide_motion.dot(linear_velocity) > 0.0) {
|
||||
motion = slide_motion;
|
||||
} else {
|
||||
motion = Vector2();
|
||||
}
|
||||
if (slide_on_ceiling && on_ceiling) {
|
||||
// Apply slide only in the direction of the input motion, otherwise just stop to avoid jittering when moving against a wall.
|
||||
if (vel_dir_facing_up) {
|
||||
linear_velocity = linear_velocity.slide(result.collision_normal);
|
||||
} else {
|
||||
// Avoid acceleration in slope when falling.
|
||||
linear_velocity = up_direction * up_direction.dot(linear_velocity);
|
||||
}
|
||||
}
|
||||
}
|
||||
// No sliding on first attempt to keep floor motion stable when possible.
|
||||
else {
|
||||
// Prevents the body from being able to climb a slope when it moves forward against the wall.
|
||||
else if (!is_on_floor_only()) {
|
||||
motion = up_direction * up_direction.dot(result.remainder);
|
||||
motion = motion.slide(result.collision_normal);
|
||||
} else {
|
||||
motion = result.remainder;
|
||||
if (on_ceiling && !slide_on_ceiling && vel_dir_facing_up) {
|
||||
linear_velocity = linear_velocity.slide(up_direction);
|
||||
motion = motion.slide(up_direction);
|
||||
}
|
||||
}
|
||||
// Constant Speed when the slope is upward.
|
||||
else if (constant_speed_on_floor && is_on_floor_only() && can_apply_constant_speed && was_on_floor && motion.dot(result.collision_normal) < 0) {
|
||||
can_apply_constant_speed = false;
|
||||
Vector2 motion_slide_norm = result.remainder.slide(result.collision_normal).normalized();
|
||||
if (!motion_slide_norm.is_equal_approx(Vector2())) {
|
||||
motion = motion_slide_norm * (motion_slide_up.length() - result.motion.slide(up_direction).length() - last_travel.slide(up_direction).length());
|
||||
}
|
||||
}
|
||||
// Regular sliding, the last part of the test handle the case when you don't want to slide on the ceiling.
|
||||
else if ((sliding_enabled || !on_floor) && (!on_ceiling || slide_on_ceiling || !vel_dir_facing_up)) {
|
||||
Vector2 slide_motion = result.remainder.slide(result.collision_normal);
|
||||
if (slide_motion.dot(linear_velocity) > 0.0) {
|
||||
motion = slide_motion;
|
||||
} else {
|
||||
motion = Vector2();
|
||||
}
|
||||
if (slide_on_ceiling && on_ceiling) {
|
||||
// Apply slide only in the direction of the input motion, otherwise just stop to avoid jittering when moving against a wall.
|
||||
if (vel_dir_facing_up) {
|
||||
linear_velocity = linear_velocity.slide(result.collision_normal);
|
||||
} else {
|
||||
// Avoid acceleration in slope when falling.
|
||||
linear_velocity = up_direction * up_direction.dot(linear_velocity);
|
||||
}
|
||||
}
|
||||
|
||||
last_travel = result.motion;
|
||||
}
|
||||
// When you move forward in a downward slope you don’t collide because you will be in the air.
|
||||
// This test ensures that constant speed is applied, only if the player is still on the ground after the snap is applied.
|
||||
else if (i == 0 && constant_speed_on_floor && first_slide && _on_floor_if_snapped(was_on_floor, vel_dir_facing_up)) {
|
||||
can_apply_constant_speed = false;
|
||||
sliding_enabled = true;
|
||||
Transform2D gt = get_global_transform();
|
||||
gt.elements[2] = prev_position;
|
||||
set_global_transform(gt);
|
||||
|
||||
Vector2 motion_slide_norm = motion.slide(prev_floor_normal).normalized();
|
||||
if (!motion_slide_norm.is_equal_approx(Vector2())) {
|
||||
motion = motion_slide_norm * (motion_slide_up.length());
|
||||
found_collision = true;
|
||||
// No sliding on first attempt to keep floor motion stable when possible.
|
||||
else {
|
||||
motion = result.remainder;
|
||||
if (on_ceiling && !slide_on_ceiling && vel_dir_facing_up) {
|
||||
linear_velocity = linear_velocity.slide(up_direction);
|
||||
motion = motion.slide(up_direction);
|
||||
}
|
||||
}
|
||||
|
||||
last_travel = result.motion;
|
||||
}
|
||||
// When you move forward in a downward slope you don’t collide because you will be in the air.
|
||||
// This test ensures that constant speed is applied, only if the player is still on the ground after the snap is applied.
|
||||
else if (constant_speed_on_floor && first_slide && _on_floor_if_snapped(was_on_floor, vel_dir_facing_up)) {
|
||||
can_apply_constant_speed = false;
|
||||
sliding_enabled = true;
|
||||
Transform2D gt = get_global_transform();
|
||||
gt.elements[2] = prev_position;
|
||||
set_global_transform(gt);
|
||||
|
||||
Vector2 motion_slide_norm = motion.slide(prev_floor_normal).normalized();
|
||||
if (!motion_slide_norm.is_equal_approx(Vector2())) {
|
||||
motion = motion_slide_norm * (motion_slide_up.length());
|
||||
found_collision = true;
|
||||
}
|
||||
}
|
||||
|
||||
can_apply_constant_speed = !can_apply_constant_speed && !sliding_enabled;
|
||||
sliding_enabled = true;
|
||||
first_slide = false;
|
||||
|
@ -1259,7 +1249,7 @@ void CharacterBody2D::_snap_on_floor(bool was_on_floor, bool vel_dir_facing_up)
|
|||
|
||||
Transform2D gt = get_global_transform();
|
||||
PhysicsServer2D::MotionResult result;
|
||||
if (move_and_collide(up_direction * -floor_snap_length, infinite_inertia, result, margin, false, true, false)) {
|
||||
if (move_and_collide(up_direction * -floor_snap_length, result, margin, true, false)) {
|
||||
bool apply = true;
|
||||
float collision_angle = Math::acos(result.collision_normal.dot(up_direction));
|
||||
if (collision_angle <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
|
||||
|
@ -1294,7 +1284,7 @@ bool CharacterBody2D::_on_floor_if_snapped(bool was_on_floor, bool vel_dir_facin
|
|||
}
|
||||
|
||||
PhysicsServer2D::MotionResult result;
|
||||
if (move_and_collide(up_direction * -floor_snap_length, infinite_inertia, result, margin, false, true, false)) {
|
||||
if (move_and_collide(up_direction * -floor_snap_length, result, margin, true, false)) {
|
||||
if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1331,42 +1321,6 @@ void CharacterBody2D::_set_platform_data(const PhysicsServer2D::MotionResult &p_
|
|||
}
|
||||
}
|
||||
|
||||
bool CharacterBody2D::separate_raycast_shapes(PhysicsServer2D::MotionResult &r_result) {
|
||||
PhysicsServer2D::SeparationResult sep_res[8]; //max 8 rays
|
||||
|
||||
Transform2D gt = get_global_transform();
|
||||
|
||||
Vector2 recover;
|
||||
int hits = PhysicsServer2D::get_singleton()->body_test_ray_separation(get_rid(), gt, infinite_inertia, recover, sep_res, 8, margin);
|
||||
int deepest = -1;
|
||||
real_t deepest_depth;
|
||||
for (int i = 0; i < hits; i++) {
|
||||
if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) {
|
||||
deepest = i;
|
||||
deepest_depth = sep_res[i].collision_depth;
|
||||
}
|
||||
}
|
||||
|
||||
gt.elements[2] += recover;
|
||||
set_global_transform(gt);
|
||||
|
||||
if (deepest != -1) {
|
||||
r_result.collider_id = sep_res[deepest].collider_id;
|
||||
r_result.collider_metadata = sep_res[deepest].collider_metadata;
|
||||
r_result.collider_shape = sep_res[deepest].collider_shape;
|
||||
r_result.collider_velocity = sep_res[deepest].collider_velocity;
|
||||
r_result.collision_point = sep_res[deepest].collision_point;
|
||||
r_result.collision_normal = sep_res[deepest].collision_normal;
|
||||
r_result.collision_local_shape = sep_res[deepest].collision_local_shape;
|
||||
r_result.motion = recover;
|
||||
r_result.remainder = Vector2();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const Vector2 &CharacterBody2D::get_linear_velocity() const {
|
||||
return linear_velocity;
|
||||
}
|
||||
|
@ -1447,16 +1401,10 @@ void CharacterBody2D::set_stop_on_slope_enabled(bool p_enabled) {
|
|||
stop_on_slope = p_enabled;
|
||||
}
|
||||
|
||||
bool CharacterBody2D::is_infinite_inertia_enabled() const {
|
||||
return infinite_inertia;
|
||||
}
|
||||
void CharacterBody2D::set_infinite_inertia_enabled(bool p_enabled) {
|
||||
infinite_inertia = p_enabled;
|
||||
}
|
||||
|
||||
bool CharacterBody2D::is_constant_speed_on_floor_enabled() const {
|
||||
return constant_speed_on_floor;
|
||||
}
|
||||
|
||||
void CharacterBody2D::set_constant_speed_on_floor_enabled(bool p_enabled) {
|
||||
constant_speed_on_floor = p_enabled;
|
||||
}
|
||||
|
@ -1464,6 +1412,7 @@ void CharacterBody2D::set_constant_speed_on_floor_enabled(bool p_enabled) {
|
|||
bool CharacterBody2D::is_move_on_floor_only_enabled() const {
|
||||
return move_on_floor_only;
|
||||
}
|
||||
|
||||
void CharacterBody2D::set_move_on_floor_only_enabled(bool p_enabled) {
|
||||
move_on_floor_only = p_enabled;
|
||||
}
|
||||
|
@ -1471,6 +1420,7 @@ void CharacterBody2D::set_move_on_floor_only_enabled(bool p_enabled) {
|
|||
bool CharacterBody2D::is_slide_on_ceiling_enabled() const {
|
||||
return slide_on_ceiling;
|
||||
}
|
||||
|
||||
void CharacterBody2D::set_slide_on_ceiling_enabled(bool p_enabled) {
|
||||
slide_on_ceiling = p_enabled;
|
||||
}
|
||||
|
@ -1541,7 +1491,6 @@ void CharacterBody2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_safe_margin"), &CharacterBody2D::get_safe_margin);
|
||||
ClassDB::bind_method(D_METHOD("is_stop_on_slope_enabled"), &CharacterBody2D::is_stop_on_slope_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_stop_on_slope_enabled", "enabled"), &CharacterBody2D::set_stop_on_slope_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_infinite_inertia_enabled"), &CharacterBody2D::is_infinite_inertia_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_constant_speed_on_floor_enabled", "enabled"), &CharacterBody2D::set_constant_speed_on_floor_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_constant_speed_on_floor_enabled"), &CharacterBody2D::is_constant_speed_on_floor_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_move_on_floor_only_enabled", "enabled"), &CharacterBody2D::set_move_on_floor_only_enabled);
|
||||
|
@ -1552,7 +1501,6 @@ void CharacterBody2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_exclude_body_layers", "exclude_layer"), &CharacterBody2D::set_exclude_body_layers);
|
||||
ClassDB::bind_method(D_METHOD("get_exclude_body_layers"), &CharacterBody2D::get_exclude_body_layers);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_infinite_inertia_enabled", "enabled"), &CharacterBody2D::set_infinite_inertia_enabled);
|
||||
ClassDB::bind_method(D_METHOD("get_max_slides"), &CharacterBody2D::get_max_slides);
|
||||
ClassDB::bind_method(D_METHOD("set_max_slides", "max_slides"), &CharacterBody2D::set_max_slides);
|
||||
ClassDB::bind_method(D_METHOD("get_floor_max_angle"), &CharacterBody2D::get_floor_max_angle);
|
||||
|
@ -1575,7 +1523,6 @@ void CharacterBody2D::_bind_methods() {
|
|||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stop_on_slope"), "set_stop_on_slope_enabled", "is_stop_on_slope_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "infinite_inertia"), "set_infinite_inertia_enabled", "is_infinite_inertia_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "constant_speed_on_floor"), "set_constant_speed_on_floor_enabled", "is_constant_speed_on_floor_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "move_on_floor_only"), "set_move_on_floor_only_enabled", "is_move_on_floor_only_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slide_on_ceiling"), "set_slide_on_ceiling_enabled", "is_slide_on_ceiling_enabled");
|
||||
|
|
|
@ -47,11 +47,11 @@ protected:
|
|||
|
||||
Ref<KinematicCollision2D> motion_cache;
|
||||
|
||||
Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false, real_t p_margin = 0.08);
|
||||
Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_test_only = false, real_t p_margin = 0.08);
|
||||
|
||||
public:
|
||||
bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false, bool p_cancel_sliding = true, const Set<RID> &p_exclude = Set<RID>());
|
||||
bool test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08);
|
||||
bool move_and_collide(const Vector2 &p_motion, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_test_only = false, bool p_cancel_sliding = true, const Set<RID> &p_exclude = Set<RID>());
|
||||
bool test_move(const Transform2D &p_from, const Vector2 &p_motion, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08);
|
||||
|
||||
TypedArray<PhysicsBody2D> get_collision_exceptions();
|
||||
void add_collision_exception_with(Node *p_node); //must be physicsbody
|
||||
|
@ -272,7 +272,6 @@ private:
|
|||
real_t margin = 0.08;
|
||||
|
||||
bool stop_on_slope = false;
|
||||
bool infinite_inertia = true;
|
||||
bool constant_speed_on_floor = false;
|
||||
bool move_on_floor_only = true;
|
||||
bool slide_on_ceiling = true;
|
||||
|
@ -294,17 +293,12 @@ private:
|
|||
Vector<PhysicsServer2D::MotionResult> motion_results;
|
||||
Vector<Ref<KinematicCollision2D>> slide_colliders;
|
||||
|
||||
bool separate_raycast_shapes(PhysicsServer2D::MotionResult &r_result);
|
||||
|
||||
void set_safe_margin(real_t p_margin);
|
||||
real_t get_safe_margin() const;
|
||||
|
||||
bool is_stop_on_slope_enabled() const;
|
||||
void set_stop_on_slope_enabled(bool p_enabled);
|
||||
|
||||
bool is_infinite_inertia_enabled() const;
|
||||
void set_infinite_inertia_enabled(bool p_enabled);
|
||||
|
||||
bool is_constant_speed_on_floor_enabled() const;
|
||||
void set_constant_speed_on_floor_enabled(bool p_enabled);
|
||||
|
||||
|
@ -317,9 +311,6 @@ private:
|
|||
int get_max_slides() const;
|
||||
void set_max_slides(int p_max_slides);
|
||||
|
||||
real_t get_move_max_angle() const;
|
||||
void set_move_max_angle(real_t p_radians);
|
||||
|
||||
real_t get_floor_max_angle() const;
|
||||
void set_floor_max_angle(real_t p_radians);
|
||||
|
||||
|
|
|
@ -33,17 +33,10 @@
|
|||
#include "core/math/quick_hull.h"
|
||||
#include "mesh_instance_3d.h"
|
||||
#include "physics_body_3d.h"
|
||||
#include "scene/resources/box_shape_3d.h"
|
||||
#include "scene/resources/capsule_shape_3d.h"
|
||||
#include "scene/resources/concave_polygon_shape_3d.h"
|
||||
#include "scene/resources/convex_polygon_shape_3d.h"
|
||||
#include "scene/resources/ray_shape_3d.h"
|
||||
#include "scene/resources/sphere_shape_3d.h"
|
||||
#include "scene/resources/world_margin_shape_3d.h"
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
//TODO: Implement CylinderShape and HeightMapShape?
|
||||
|
||||
void CollisionShape3D::make_convex_from_siblings() {
|
||||
Node *p = get_parent();
|
||||
if (!p) {
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
#endif
|
||||
|
||||
void PhysicsBody3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only", "safe_margin"), &PhysicsBody3D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false), DEFVAL(0.001));
|
||||
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "collision", "safe_margin"), &PhysicsBody3D::test_move, DEFVAL(true), DEFVAL(true), DEFVAL(Variant()), DEFVAL(0.001));
|
||||
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "test_only", "safe_margin"), &PhysicsBody3D::_move, DEFVAL(false), DEFVAL(0.001));
|
||||
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "collision", "safe_margin"), &PhysicsBody3D::test_move, DEFVAL(Variant()), DEFVAL(0.001));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicsBody3D::set_axis_lock);
|
||||
ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicsBody3D::get_axis_lock);
|
||||
|
@ -101,9 +101,9 @@ void PhysicsBody3D::remove_collision_exception_with(Node *p_node) {
|
|||
PhysicsServer3D::get_singleton()->body_remove_collision_exception(get_rid(), collision_object->get_rid());
|
||||
}
|
||||
|
||||
Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only, real_t p_margin) {
|
||||
Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_motion, bool p_test_only, real_t p_margin) {
|
||||
PhysicsServer3D::MotionResult result;
|
||||
if (move_and_collide(p_motion, p_infinite_inertia, result, p_margin, p_exclude_raycast_shapes, p_test_only)) {
|
||||
if (move_and_collide(p_motion, result, p_margin, p_test_only)) {
|
||||
if (motion_cache.is_null()) {
|
||||
motion_cache.instantiate();
|
||||
motion_cache->owner = this;
|
||||
|
@ -117,9 +117,9 @@ Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_motion, bool p_i
|
|||
return Ref<KinematicCollision3D>();
|
||||
}
|
||||
|
||||
bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only, bool p_cancel_sliding, const Set<RID> &p_exclude) {
|
||||
bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_test_only, bool p_cancel_sliding, const Set<RID> &p_exclude) {
|
||||
Transform3D gt = get_global_transform();
|
||||
bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_margin, &r_result, p_exclude_raycast_shapes, p_exclude);
|
||||
bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_margin, &r_result, p_exclude);
|
||||
|
||||
// Restore direction of motion to be along original motion,
|
||||
// in order to avoid sliding due to recovery,
|
||||
|
@ -173,7 +173,7 @@ bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_in
|
|||
return colliding;
|
||||
}
|
||||
|
||||
bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, const Ref<KinematicCollision3D> &r_collision, real_t p_margin) {
|
||||
bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_motion, const Ref<KinematicCollision3D> &r_collision, real_t p_margin) {
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||
|
||||
PhysicsServer3D::MotionResult *r = nullptr;
|
||||
|
@ -182,7 +182,7 @@ bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_motion
|
|||
r = const_cast<PhysicsServer3D::MotionResult *>(&r_collision->result);
|
||||
}
|
||||
|
||||
return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, p_margin, r, p_exclude_raycast_shapes);
|
||||
return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_margin, r);
|
||||
}
|
||||
|
||||
void PhysicsBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) {
|
||||
|
@ -1121,7 +1121,7 @@ void CharacterBody3D::move_and_slide() {
|
|||
PhysicsServer3D::MotionResult floor_result;
|
||||
Set<RID> exclude;
|
||||
exclude.insert(on_floor_body);
|
||||
if (move_and_collide(current_floor_velocity * delta, infinite_inertia, floor_result, true, false, false, false, exclude)) {
|
||||
if (move_and_collide(current_floor_velocity * delta, floor_result, margin, false, false, exclude)) {
|
||||
motion_results.push_back(floor_result);
|
||||
_set_collision_direction(floor_result);
|
||||
}
|
||||
|
@ -1138,58 +1138,45 @@ void CharacterBody3D::move_and_slide() {
|
|||
PhysicsServer3D::MotionResult result;
|
||||
bool found_collision = false;
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
bool collided;
|
||||
if (i == 0) { //collide
|
||||
collided = move_and_collide(motion, infinite_inertia, result, margin, true, false, !sliding_enabled);
|
||||
if (!collided) {
|
||||
motion = Vector3(); //clear because no collision happened and motion completed
|
||||
}
|
||||
} else { //separate raycasts (if any)
|
||||
collided = separate_raycast_shapes(result);
|
||||
if (collided) {
|
||||
result.remainder = motion; //keep
|
||||
result.motion = Vector3();
|
||||
bool collided = move_and_collide(motion, result, margin, false, !sliding_enabled);
|
||||
if (!collided) {
|
||||
motion = Vector3(); //clear because no collision happened and motion completed
|
||||
} else {
|
||||
found_collision = true;
|
||||
|
||||
motion_results.push_back(result);
|
||||
_set_collision_direction(result);
|
||||
|
||||
if (on_floor && stop_on_slope) {
|
||||
if ((body_velocity_normal + up_direction).length() < 0.01) {
|
||||
Transform3D gt = get_global_transform();
|
||||
if (result.motion.length() > margin) {
|
||||
gt.origin -= result.motion.slide(up_direction);
|
||||
} else {
|
||||
gt.origin -= result.motion;
|
||||
}
|
||||
set_global_transform(gt);
|
||||
linear_velocity = Vector3();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (collided) {
|
||||
found_collision = true;
|
||||
if (sliding_enabled || !on_floor) {
|
||||
motion = result.remainder.slide(result.collision_normal);
|
||||
linear_velocity = linear_velocity.slide(result.collision_normal);
|
||||
|
||||
motion_results.push_back(result);
|
||||
_set_collision_direction(result);
|
||||
|
||||
if (on_floor && stop_on_slope) {
|
||||
if ((body_velocity_normal + up_direction).length() < 0.01) {
|
||||
Transform3D gt = get_global_transform();
|
||||
if (result.motion.length() > margin) {
|
||||
gt.origin -= result.motion.slide(up_direction);
|
||||
} else {
|
||||
gt.origin -= result.motion;
|
||||
}
|
||||
set_global_transform(gt);
|
||||
linear_velocity = Vector3();
|
||||
return;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (locked_axis & (1 << j)) {
|
||||
linear_velocity[j] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (sliding_enabled || !on_floor) {
|
||||
motion = result.remainder.slide(result.collision_normal);
|
||||
linear_velocity = linear_velocity.slide(result.collision_normal);
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (locked_axis & (1 << j)) {
|
||||
linear_velocity[j] = 0.0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
motion = result.remainder;
|
||||
}
|
||||
} else {
|
||||
motion = result.remainder;
|
||||
}
|
||||
|
||||
sliding_enabled = true;
|
||||
}
|
||||
|
||||
sliding_enabled = true;
|
||||
|
||||
if (!found_collision || motion == Vector3()) {
|
||||
break;
|
||||
}
|
||||
|
@ -1207,7 +1194,7 @@ void CharacterBody3D::move_and_slide() {
|
|||
// Apply snap.
|
||||
Transform3D gt = get_global_transform();
|
||||
PhysicsServer3D::MotionResult result;
|
||||
if (move_and_collide(snap, infinite_inertia, result, margin, false, true, false)) {
|
||||
if (move_and_collide(snap, result, margin, true, false)) {
|
||||
bool apply = true;
|
||||
if (up_direction != Vector3()) {
|
||||
if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
|
||||
|
@ -1258,42 +1245,6 @@ void CharacterBody3D::_set_collision_direction(const PhysicsServer3D::MotionResu
|
|||
}
|
||||
}
|
||||
|
||||
bool CharacterBody3D::separate_raycast_shapes(PhysicsServer3D::MotionResult &r_result) {
|
||||
PhysicsServer3D::SeparationResult sep_res[8]; //max 8 rays
|
||||
|
||||
Transform3D gt = get_global_transform();
|
||||
|
||||
Vector3 recover;
|
||||
int hits = PhysicsServer3D::get_singleton()->body_test_ray_separation(get_rid(), gt, infinite_inertia, recover, sep_res, 8, margin);
|
||||
int deepest = -1;
|
||||
real_t deepest_depth;
|
||||
for (int i = 0; i < hits; i++) {
|
||||
if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) {
|
||||
deepest = i;
|
||||
deepest_depth = sep_res[i].collision_depth;
|
||||
}
|
||||
}
|
||||
|
||||
gt.origin += recover;
|
||||
set_global_transform(gt);
|
||||
|
||||
if (deepest != -1) {
|
||||
r_result.collider_id = sep_res[deepest].collider_id;
|
||||
r_result.collider_metadata = sep_res[deepest].collider_metadata;
|
||||
r_result.collider_shape = sep_res[deepest].collider_shape;
|
||||
r_result.collider_velocity = sep_res[deepest].collider_velocity;
|
||||
r_result.collision_point = sep_res[deepest].collision_point;
|
||||
r_result.collision_normal = sep_res[deepest].collision_normal;
|
||||
r_result.collision_local_shape = sep_res[deepest].collision_local_shape;
|
||||
r_result.motion = recover;
|
||||
r_result.remainder = Vector3();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterBody3D::set_safe_margin(real_t p_margin) {
|
||||
margin = p_margin;
|
||||
}
|
||||
|
@ -1362,13 +1313,6 @@ void CharacterBody3D::set_stop_on_slope_enabled(bool p_enabled) {
|
|||
stop_on_slope = p_enabled;
|
||||
}
|
||||
|
||||
bool CharacterBody3D::is_infinite_inertia_enabled() const {
|
||||
return infinite_inertia;
|
||||
}
|
||||
void CharacterBody3D::set_infinite_inertia_enabled(bool p_enabled) {
|
||||
infinite_inertia = p_enabled;
|
||||
}
|
||||
|
||||
int CharacterBody3D::get_max_slides() const {
|
||||
return max_slides;
|
||||
}
|
||||
|
@ -1426,8 +1370,6 @@ void CharacterBody3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_safe_margin"), &CharacterBody3D::get_safe_margin);
|
||||
ClassDB::bind_method(D_METHOD("is_stop_on_slope_enabled"), &CharacterBody3D::is_stop_on_slope_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_stop_on_slope_enabled", "enabled"), &CharacterBody3D::set_stop_on_slope_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_infinite_inertia_enabled"), &CharacterBody3D::is_infinite_inertia_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_infinite_inertia_enabled", "enabled"), &CharacterBody3D::set_infinite_inertia_enabled);
|
||||
ClassDB::bind_method(D_METHOD("get_max_slides"), &CharacterBody3D::get_max_slides);
|
||||
ClassDB::bind_method(D_METHOD("set_max_slides", "max_slides"), &CharacterBody3D::set_max_slides);
|
||||
ClassDB::bind_method(D_METHOD("get_floor_max_angle"), &CharacterBody3D::get_floor_max_angle);
|
||||
|
@ -1448,7 +1390,6 @@ void CharacterBody3D::_bind_methods() {
|
|||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stop_on_slope"), "set_stop_on_slope_enabled", "is_stop_on_slope_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "infinite_inertia"), "set_infinite_inertia_enabled", "is_infinite_inertia_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_RANGE, "1,8,1,or_greater"), "set_max_slides", "get_max_slides");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians"), "set_floor_max_angle", "get_floor_max_angle");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap"), "set_snap", "get_snap");
|
||||
|
|
|
@ -50,11 +50,11 @@ protected:
|
|||
|
||||
uint16_t locked_axis = 0;
|
||||
|
||||
Ref<KinematicCollision3D> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false, real_t p_margin = 0.001);
|
||||
Ref<KinematicCollision3D> _move(const Vector3 &p_motion, bool p_test_only = false, real_t p_margin = 0.001);
|
||||
|
||||
public:
|
||||
bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false, bool p_cancel_sliding = true, const Set<RID> &p_exclude = Set<RID>());
|
||||
bool test_move(const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, const Ref<KinematicCollision3D> &r_collision = Ref<KinematicCollision3D>(), real_t p_margin = 0.001);
|
||||
bool move_and_collide(const Vector3 &p_motion, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_test_only = false, bool p_cancel_sliding = true, const Set<RID> &p_exclude = Set<RID>());
|
||||
bool test_move(const Transform3D &p_from, const Vector3 &p_motion, const Ref<KinematicCollision3D> &r_collision = Ref<KinematicCollision3D>(), real_t p_margin = 0.001);
|
||||
|
||||
void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock);
|
||||
bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const;
|
||||
|
@ -279,7 +279,6 @@ private:
|
|||
real_t margin = 0.001;
|
||||
|
||||
bool stop_on_slope = false;
|
||||
bool infinite_inertia = true;
|
||||
int max_slides = 4;
|
||||
real_t floor_max_angle = Math::deg2rad((real_t)45.0);
|
||||
Vector3 snap;
|
||||
|
@ -300,17 +299,12 @@ private:
|
|||
|
||||
void _set_collision_direction(const PhysicsServer3D::MotionResult &p_result);
|
||||
|
||||
bool separate_raycast_shapes(PhysicsServer3D::MotionResult &r_result);
|
||||
|
||||
void set_safe_margin(real_t p_margin);
|
||||
real_t get_safe_margin() const;
|
||||
|
||||
bool is_stop_on_slope_enabled() const;
|
||||
void set_stop_on_slope_enabled(bool p_enabled);
|
||||
|
||||
bool is_infinite_inertia_enabled() const;
|
||||
void set_infinite_inertia_enabled(bool p_enabled);
|
||||
|
||||
int get_max_slides() const;
|
||||
void set_max_slides(int p_max_slides);
|
||||
|
||||
|
|
|
@ -158,8 +158,6 @@
|
|||
#include "scene/resources/physics_material.h"
|
||||
#include "scene/resources/polygon_path_finder.h"
|
||||
#include "scene/resources/primitive_meshes.h"
|
||||
#include "scene/resources/ray_shape_2d.h"
|
||||
#include "scene/resources/ray_shape_3d.h"
|
||||
#include "scene/resources/rectangle_shape_2d.h"
|
||||
#include "scene/resources/resource_format_text.h"
|
||||
#include "scene/resources/segment_shape_2d.h"
|
||||
|
@ -747,7 +745,6 @@ void register_scene_types() {
|
|||
OS::get_singleton()->yield(); //may take time to init
|
||||
|
||||
GDREGISTER_VIRTUAL_CLASS(Shape3D);
|
||||
GDREGISTER_CLASS(RayShape3D);
|
||||
GDREGISTER_CLASS(SphereShape3D);
|
||||
GDREGISTER_CLASS(BoxShape3D);
|
||||
GDREGISTER_CLASS(CapsuleShape3D);
|
||||
|
@ -828,7 +825,6 @@ void register_scene_types() {
|
|||
GDREGISTER_VIRTUAL_CLASS(Shape2D);
|
||||
GDREGISTER_CLASS(LineShape2D);
|
||||
GDREGISTER_CLASS(SegmentShape2D);
|
||||
GDREGISTER_CLASS(RayShape2D);
|
||||
GDREGISTER_CLASS(CircleShape2D);
|
||||
GDREGISTER_CLASS(RectangleShape2D);
|
||||
GDREGISTER_CLASS(CapsuleShape2D);
|
||||
|
@ -948,7 +944,6 @@ void register_scene_types() {
|
|||
ClassDB::add_compatibility_class("ProceduralSky", "Sky");
|
||||
ClassDB::add_compatibility_class("ProximityGroup", "ProximityGroup3D");
|
||||
ClassDB::add_compatibility_class("RayCast", "RayCast3D");
|
||||
ClassDB::add_compatibility_class("RayShape", "RayShape3D");
|
||||
ClassDB::add_compatibility_class("RemoteTransform", "RemoteTransform3D");
|
||||
ClassDB::add_compatibility_class("RigidBody", "RigidBody3D");
|
||||
ClassDB::add_compatibility_class("Shape", "Shape3D");
|
||||
|
|
|
@ -1,119 +0,0 @@
|
|||
/*************************************************************************/
|
||||
/* ray_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 "ray_shape_2d.h"
|
||||
|
||||
#include "servers/physics_server_2d.h"
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
void RayShape2D::_update_shape() {
|
||||
Dictionary d;
|
||||
d["length"] = length;
|
||||
d["slips_on_slope"] = slips_on_slope;
|
||||
PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), d);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) {
|
||||
const Vector2 target_position = Vector2(0, get_length());
|
||||
|
||||
const float max_arrow_size = 6;
|
||||
const float line_width = 1.4;
|
||||
bool no_line = target_position.length() < line_width;
|
||||
float arrow_size = CLAMP(target_position.length() * 2 / 3, line_width, max_arrow_size);
|
||||
|
||||
if (no_line) {
|
||||
arrow_size = target_position.length();
|
||||
} else {
|
||||
RS::get_singleton()->canvas_item_add_line(p_to_rid, Vector2(), target_position - target_position.normalized() * arrow_size, p_color, line_width);
|
||||
}
|
||||
|
||||
Transform2D xf;
|
||||
xf.rotate(target_position.angle());
|
||||
xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0));
|
||||
|
||||
Vector<Vector2> pts;
|
||||
pts.push_back(xf.xform(Vector2(arrow_size, 0)));
|
||||
pts.push_back(xf.xform(Vector2(0, 0.5 * arrow_size)));
|
||||
pts.push_back(xf.xform(Vector2(0, -0.5 * arrow_size)));
|
||||
|
||||
Vector<Color> cols;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
cols.push_back(p_color);
|
||||
}
|
||||
|
||||
RS::get_singleton()->canvas_item_add_primitive(p_to_rid, pts, cols, Vector<Point2>(), RID());
|
||||
}
|
||||
|
||||
Rect2 RayShape2D::get_rect() const {
|
||||
Rect2 rect;
|
||||
rect.position = Vector2();
|
||||
rect.expand_to(Vector2(0, length));
|
||||
rect = rect.grow(Math_SQRT12 * 4);
|
||||
return rect;
|
||||
}
|
||||
|
||||
real_t RayShape2D::get_enclosing_radius() const {
|
||||
return length;
|
||||
}
|
||||
|
||||
void RayShape2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape2D::set_length);
|
||||
ClassDB::bind_method(D_METHOD("get_length"), &RayShape2D::get_length);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape2D::set_slips_on_slope);
|
||||
ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape2D::get_slips_on_slope);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length"), "set_length", "get_length");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slips_on_slope"), "set_slips_on_slope", "get_slips_on_slope");
|
||||
}
|
||||
|
||||
void RayShape2D::set_length(real_t p_length) {
|
||||
length = p_length;
|
||||
_update_shape();
|
||||
}
|
||||
|
||||
real_t RayShape2D::get_length() const {
|
||||
return length;
|
||||
}
|
||||
|
||||
void RayShape2D::set_slips_on_slope(bool p_active) {
|
||||
slips_on_slope = p_active;
|
||||
_update_shape();
|
||||
}
|
||||
|
||||
bool RayShape2D::get_slips_on_slope() const {
|
||||
return slips_on_slope;
|
||||
}
|
||||
|
||||
RayShape2D::RayShape2D() :
|
||||
Shape2D(PhysicsServer2D::get_singleton()->ray_shape_create()) {
|
||||
_update_shape();
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*************************************************************************/
|
||||
/* ray_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 RAY_SHAPE_2D_H
|
||||
#define RAY_SHAPE_2D_H
|
||||
|
||||
#include "scene/resources/shape_2d.h"
|
||||
|
||||
class RayShape2D : public Shape2D {
|
||||
GDCLASS(RayShape2D, Shape2D);
|
||||
|
||||
real_t length = 20.0;
|
||||
bool slips_on_slope = false;
|
||||
|
||||
void _update_shape();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_length(real_t p_length);
|
||||
real_t get_length() const;
|
||||
|
||||
void set_slips_on_slope(bool p_active);
|
||||
bool get_slips_on_slope() 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;
|
||||
|
||||
RayShape2D();
|
||||
};
|
||||
|
||||
#endif // RAY_SHAPE_2D_H
|
|
@ -1,91 +0,0 @@
|
|||
/*************************************************************************/
|
||||
/* ray_shape_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 "ray_shape_3d.h"
|
||||
|
||||
#include "servers/physics_server_3d.h"
|
||||
|
||||
Vector<Vector3> RayShape3D::get_debug_mesh_lines() const {
|
||||
Vector<Vector3> points;
|
||||
points.push_back(Vector3());
|
||||
points.push_back(Vector3(0, 0, get_length()));
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
real_t RayShape3D::get_enclosing_radius() const {
|
||||
return length;
|
||||
}
|
||||
|
||||
void RayShape3D::_update_shape() {
|
||||
Dictionary d;
|
||||
d["length"] = length;
|
||||
d["slips_on_slope"] = slips_on_slope;
|
||||
PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), d);
|
||||
Shape3D::_update_shape();
|
||||
}
|
||||
|
||||
void RayShape3D::set_length(float p_length) {
|
||||
length = p_length;
|
||||
_update_shape();
|
||||
notify_change_to_owners();
|
||||
}
|
||||
|
||||
float RayShape3D::get_length() const {
|
||||
return length;
|
||||
}
|
||||
|
||||
void RayShape3D::set_slips_on_slope(bool p_active) {
|
||||
slips_on_slope = p_active;
|
||||
_update_shape();
|
||||
notify_change_to_owners();
|
||||
}
|
||||
|
||||
bool RayShape3D::get_slips_on_slope() const {
|
||||
return slips_on_slope;
|
||||
}
|
||||
|
||||
void RayShape3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape3D::set_length);
|
||||
ClassDB::bind_method(D_METHOD("get_length"), &RayShape3D::get_length);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape3D::set_slips_on_slope);
|
||||
ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape3D::get_slips_on_slope);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_RANGE, "0,4096,0.001"), "set_length", "get_length");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slips_on_slope"), "set_slips_on_slope", "get_slips_on_slope");
|
||||
}
|
||||
|
||||
RayShape3D::RayShape3D() :
|
||||
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_RAY)) {
|
||||
/* Code copied from setters to prevent the use of uninitialized variables */
|
||||
_update_shape();
|
||||
notify_change_to_owners();
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/*************************************************************************/
|
||||
/* ray_shape_3d.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 RAY_SHAPE_H
|
||||
#define RAY_SHAPE_H
|
||||
#include "scene/resources/shape_3d.h"
|
||||
|
||||
class RayShape3D : public Shape3D {
|
||||
GDCLASS(RayShape3D, Shape3D);
|
||||
float length = 1.0;
|
||||
bool slips_on_slope = false;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
virtual void _update_shape() override;
|
||||
|
||||
public:
|
||||
void set_length(float p_length);
|
||||
float get_length() const;
|
||||
|
||||
void set_slips_on_slope(bool p_active);
|
||||
bool get_slips_on_slope() const;
|
||||
|
||||
virtual Vector<Vector3> get_debug_mesh_lines() const override;
|
||||
virtual real_t get_enclosing_radius() const override;
|
||||
|
||||
RayShape3D();
|
||||
};
|
||||
#endif // RAY_SHAPE_H
|
|
@ -1098,13 +1098,11 @@ bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D
|
|||
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_RAY,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_RAY,false);
|
||||
ERR_FAIL_COND_V(p_shape_B->is_concave(), false);
|
||||
|
||||
static const CollisionFunc collision_table[5][5] = {
|
||||
|
@ -1367,23 +1365,23 @@ bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D
|
|||
|
||||
if (p_margin_A || p_margin_B) {
|
||||
if (*motion_A == Vector2() && *motion_B == Vector2()) {
|
||||
collision_func = collision_table_margin[type_A - 2][type_B - 2];
|
||||
collision_func = collision_table_margin[type_A - 1][type_B - 1];
|
||||
} else if (*motion_A != Vector2() && *motion_B == Vector2()) {
|
||||
collision_func = collision_table_castA_margin[type_A - 2][type_B - 2];
|
||||
collision_func = collision_table_castA_margin[type_A - 1][type_B - 1];
|
||||
} else if (*motion_A == Vector2() && *motion_B != Vector2()) {
|
||||
collision_func = collision_table_castB_margin[type_A - 2][type_B - 2];
|
||||
collision_func = collision_table_castB_margin[type_A - 1][type_B - 1];
|
||||
} else {
|
||||
collision_func = collision_table_castA_castB_margin[type_A - 2][type_B - 2];
|
||||
collision_func = collision_table_castA_castB_margin[type_A - 1][type_B - 1];
|
||||
}
|
||||
} else {
|
||||
if (*motion_A == Vector2() && *motion_B == Vector2()) {
|
||||
collision_func = collision_table[type_A - 2][type_B - 2];
|
||||
collision_func = collision_table[type_A - 1][type_B - 1];
|
||||
} else if (*motion_A != Vector2() && *motion_B == Vector2()) {
|
||||
collision_func = collision_table_castA[type_A - 2][type_B - 2];
|
||||
collision_func = collision_table_castA[type_A - 1][type_B - 1];
|
||||
} else if (*motion_A == Vector2() && *motion_B != Vector2()) {
|
||||
collision_func = collision_table_castB[type_A - 2][type_B - 2];
|
||||
collision_func = collision_table_castB[type_A - 1][type_B - 1];
|
||||
} else {
|
||||
collision_func = collision_table_castA_castB[type_A - 2][type_B - 2];
|
||||
collision_func = collision_table_castA_castB[type_A - 1][type_B - 1];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,49 +73,6 @@ bool CollisionSolver2DSW::solve_static_line(const Shape2DSW *p_shape_A, const Tr
|
|||
return found;
|
||||
}
|
||||
|
||||
bool CollisionSolver2DSW::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) {
|
||||
const RayShape2DSW *ray = static_cast<const RayShape2DSW *>(p_shape_A);
|
||||
if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_RAY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector2 from = p_transform_A.get_origin();
|
||||
Vector2 to = from + p_transform_A[1] * ray->get_length();
|
||||
if (p_motion_A != Vector2()) {
|
||||
//not the best but should be enough
|
||||
Vector2 normal = (to - from).normalized();
|
||||
to += normal * MAX(0.0, normal.dot(p_motion_A));
|
||||
}
|
||||
Vector2 support_A = to;
|
||||
|
||||
Transform2D invb = p_transform_B.affine_inverse();
|
||||
from = invb.xform(from);
|
||||
to = invb.xform(to);
|
||||
|
||||
Vector2 p, n;
|
||||
if (!p_shape_B->intersect_segment(from, to, p, n)) {
|
||||
if (sep_axis) {
|
||||
*sep_axis = p_transform_A[1].normalized();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector2 support_B = p_transform_B.xform(p);
|
||||
if (ray->get_slips_on_slope()) {
|
||||
Vector2 global_n = invb.basis_xform_inv(n).normalized();
|
||||
support_B = support_A + (support_B - support_A).length() * global_n;
|
||||
}
|
||||
|
||||
if (p_result_callback) {
|
||||
if (p_swap_result) {
|
||||
p_result_callback(support_B, support_A, p_userdata);
|
||||
} else {
|
||||
p_result_callback(support_A, support_B, p_userdata);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct _ConcaveCollisionInfo2D {
|
||||
const Transform2D *transform_A;
|
||||
const Shape2DSW *shape_A;
|
||||
|
@ -210,7 +167,7 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p
|
|||
}
|
||||
|
||||
if (type_A == PhysicsServer2D::SHAPE_LINE) {
|
||||
if (type_B == PhysicsServer2D::SHAPE_LINE || type_B == PhysicsServer2D::SHAPE_RAY) {
|
||||
if (type_B == PhysicsServer2D::SHAPE_LINE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -220,17 +177,6 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p
|
|||
return solve_static_line(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false);
|
||||
}
|
||||
|
||||
} else if (type_A == PhysicsServer2D::SHAPE_RAY) {
|
||||
if (type_B == PhysicsServer2D::SHAPE_RAY) {
|
||||
return false; //no ray-ray
|
||||
}
|
||||
|
||||
if (swap) {
|
||||
return solve_raycast(p_shape_B, p_motion_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true, sep_axis);
|
||||
} else {
|
||||
return solve_raycast(p_shape_A, p_motion_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, sep_axis);
|
||||
}
|
||||
|
||||
} else if (concave_B) {
|
||||
if (concave_A) {
|
||||
return false;
|
||||
|
|
|
@ -45,9 +45,6 @@ RID PhysicsServer2DSW::_shape_create(ShapeType p_shape) {
|
|||
case SHAPE_LINE: {
|
||||
shape = memnew(LineShape2DSW);
|
||||
} break;
|
||||
case SHAPE_RAY: {
|
||||
shape = memnew(RayShape2DSW);
|
||||
} break;
|
||||
case SHAPE_SEGMENT: {
|
||||
shape = memnew(SegmentShape2DSW);
|
||||
} break;
|
||||
|
@ -82,10 +79,6 @@ RID PhysicsServer2DSW::line_shape_create() {
|
|||
return _shape_create(SHAPE_LINE);
|
||||
}
|
||||
|
||||
RID PhysicsServer2DSW::ray_shape_create() {
|
||||
return _shape_create(SHAPE_RAY);
|
||||
}
|
||||
|
||||
RID PhysicsServer2DSW::segment_shape_create() {
|
||||
return _shape_create(SHAPE_SEGMENT);
|
||||
}
|
||||
|
@ -946,7 +939,7 @@ void PhysicsServer2DSW::body_set_pickable(RID p_body, bool p_pickable) {
|
|||
body->set_pickable(p_pickable);
|
||||
}
|
||||
|
||||
bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, MotionResult *r_result, bool p_exclude_raycast_shapes, const Set<RID> &p_exclude) {
|
||||
bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin, MotionResult *r_result, const Set<RID> &p_exclude) {
|
||||
Body2DSW *body = body_owner.getornull(p_body);
|
||||
ERR_FAIL_COND_V(!body, false);
|
||||
ERR_FAIL_COND_V(!body->get_space(), false);
|
||||
|
@ -954,16 +947,7 @@ bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from,
|
|||
|
||||
_update_shapes();
|
||||
|
||||
return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes, p_exclude);
|
||||
}
|
||||
|
||||
int PhysicsServer2DSW::body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) {
|
||||
Body2DSW *body = body_owner.getornull(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);
|
||||
|
||||
return body->get_space()->test_body_ray_separation(body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin);
|
||||
return body->get_space()->test_body_motion(body, p_from, p_motion, p_margin, r_result, p_exclude);
|
||||
}
|
||||
|
||||
PhysicsDirectBodyState2D *PhysicsServer2DSW::body_get_direct_state(RID p_body) {
|
||||
|
|
|
@ -88,7 +88,6 @@ public:
|
|||
};
|
||||
|
||||
virtual RID line_shape_create() override;
|
||||
virtual RID ray_shape_create() override;
|
||||
virtual RID segment_shape_create() override;
|
||||
virtual RID circle_shape_create() override;
|
||||
virtual RID rectangle_shape_create() override;
|
||||
|
@ -247,8 +246,7 @@ public:
|
|||
|
||||
virtual void body_set_pickable(RID p_body, bool p_pickable) override;
|
||||
|
||||
virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true, const Set<RID> &p_exclude = Set<RID>()) override;
|
||||
virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.08) override;
|
||||
virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin = 0.08, MotionResult *r_result = nullptr, const Set<RID> &p_exclude = Set<RID>()) override;
|
||||
|
||||
// this function only works on physics process, errors and returns null otherwise
|
||||
virtual PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) override;
|
||||
|
|
|
@ -80,7 +80,6 @@ public:
|
|||
|
||||
//FUNC1RID(shape,ShapeType); todo fix
|
||||
FUNCRID(line_shape)
|
||||
FUNCRID(ray_shape)
|
||||
FUNCRID(segment_shape)
|
||||
FUNCRID(circle_shape)
|
||||
FUNCRID(rectangle_shape)
|
||||
|
@ -253,14 +252,9 @@ public:
|
|||
|
||||
FUNC2(body_set_pickable, RID, bool);
|
||||
|
||||
bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true, const Set<RID> &p_exclude = Set<RID>()) override {
|
||||
bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin = 0.08, MotionResult *r_result = nullptr, const Set<RID> &p_exclude = Set<RID>()) override {
|
||||
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
|
||||
return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes, p_exclude);
|
||||
}
|
||||
|
||||
int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.08) override {
|
||||
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
|
||||
return physics_2d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin);
|
||||
return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_margin, r_result, p_exclude);
|
||||
}
|
||||
|
||||
// this function only works on physics process, errors and returns null otherwise
|
||||
|
|
|
@ -143,46 +143,6 @@ Variant LineShape2DSW::get_data() const {
|
|||
/*********************************************************/
|
||||
/*********************************************************/
|
||||
|
||||
void RayShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
|
||||
r_amount = 1;
|
||||
|
||||
if (p_normal.y > 0) {
|
||||
*r_supports = Vector2(0, length);
|
||||
} else {
|
||||
*r_supports = Vector2();
|
||||
}
|
||||
}
|
||||
|
||||
bool RayShape2DSW::contains_point(const Vector2 &p_point) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RayShape2DSW::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 RayShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
|
||||
return 0; //rays are mass-less
|
||||
}
|
||||
|
||||
void RayShape2DSW::set_data(const Variant &p_data) {
|
||||
Dictionary d = p_data;
|
||||
length = d["length"];
|
||||
slips_on_slope = d["slips_on_slope"];
|
||||
configure(Rect2(0, 0, 0.001, length));
|
||||
}
|
||||
|
||||
Variant RayShape2DSW::get_data() const {
|
||||
Dictionary d;
|
||||
d["length"] = length;
|
||||
d["slips_on_slope"] = slips_on_slope;
|
||||
return d;
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
/*********************************************************/
|
||||
/*********************************************************/
|
||||
|
||||
void SegmentShape2DSW::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;
|
||||
|
|
|
@ -189,41 +189,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class RayShape2DSW : public Shape2DSW {
|
||||
real_t length;
|
||||
bool slips_on_slope;
|
||||
|
||||
public:
|
||||
_FORCE_INLINE_ real_t get_length() const { return length; }
|
||||
_FORCE_INLINE_ bool get_slips_on_slope() const { return slips_on_slope; }
|
||||
|
||||
virtual PhysicsServer2D::ShapeType get_type() const { return PhysicsServer2D::SHAPE_RAY; }
|
||||
|
||||
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;
|
||||
|
||||
virtual bool contains_point(const Vector2 &p_point) const;
|
||||
virtual bool intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const;
|
||||
virtual real_t get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const;
|
||||
|
||||
virtual void set_data(const Variant &p_data);
|
||||
virtual Variant get_data() const;
|
||||
|
||||
_FORCE_INLINE_ void project_range(const Vector2 &p_normal, const Transform2D &p_transform, real_t &r_min, real_t &r_max) const {
|
||||
//real large
|
||||
r_max = p_normal.dot(p_transform.get_origin());
|
||||
r_min = p_normal.dot(p_transform.xform(Vector2(0, length)));
|
||||
if (r_max < r_min) {
|
||||
SWAP(r_max, r_min);
|
||||
}
|
||||
}
|
||||
|
||||
DEFAULT_PROJECT_RANGE_CAST
|
||||
|
||||
_FORCE_INLINE_ RayShape2DSW() {}
|
||||
_FORCE_INLINE_ RayShape2DSW(real_t p_length) { length = p_length; }
|
||||
};
|
||||
|
||||
class SegmentShape2DSW : public Shape2DSW {
|
||||
Vector2 a;
|
||||
Vector2 b;
|
||||
|
|
|
@ -528,188 +528,7 @@ int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) {
|
|||
return amount;
|
||||
}
|
||||
|
||||
int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, PhysicsServer2D::SeparationResult *r_results, int p_result_max, real_t p_margin) {
|
||||
Rect2 body_aabb;
|
||||
|
||||
bool shapes_found = false;
|
||||
|
||||
for (int i = 0; i < p_body->get_shape_count(); i++) {
|
||||
if (p_body->is_shape_disabled(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p_body->get_shape(i)->get_type() != PhysicsServer2D::SHAPE_RAY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!shapes_found) {
|
||||
body_aabb = p_body->get_shape_aabb(i);
|
||||
shapes_found = true;
|
||||
} else {
|
||||
body_aabb = body_aabb.merge(p_body->get_shape_aabb(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (!shapes_found) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Undo the currently transform the physics server is aware of and apply the provided one
|
||||
body_aabb = p_transform.xform(p_body->get_inv_transform().xform(body_aabb));
|
||||
body_aabb = body_aabb.grow(p_margin);
|
||||
|
||||
Transform2D body_transform = p_transform;
|
||||
|
||||
for (int i = 0; i < p_result_max; i++) {
|
||||
//reset results
|
||||
r_results[i].collision_depth = 0;
|
||||
}
|
||||
|
||||
int rays_found = 0;
|
||||
|
||||
{
|
||||
// raycast AND separate
|
||||
|
||||
const int max_results = 32;
|
||||
int recover_attempts = 4;
|
||||
Vector2 sr[max_results * 2];
|
||||
PhysicsServer2DSW::CollCbkData cbk;
|
||||
cbk.max = max_results;
|
||||
PhysicsServer2DSW::CollCbkData *cbkptr = &cbk;
|
||||
CollisionSolver2DSW::CallbackResult cbkres = PhysicsServer2DSW::_shape_col_cbk;
|
||||
|
||||
do {
|
||||
Vector2 recover_motion;
|
||||
|
||||
bool collided = false;
|
||||
|
||||
int amount = _cull_aabb_for_body(p_body, body_aabb);
|
||||
|
||||
for (int j = 0; j < p_body->get_shape_count(); j++) {
|
||||
if (p_body->is_shape_disabled(j)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Shape2DSW *body_shape = p_body->get_shape(j);
|
||||
|
||||
if (body_shape->get_type() != PhysicsServer2D::SHAPE_RAY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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];
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
cbk.amount = 0;
|
||||
cbk.passed = 0;
|
||||
cbk.ptr = sr;
|
||||
cbk.invalid_by_dir = 0;
|
||||
|
||||
if (CollisionObject2DSW::TYPE_BODY == col_obj->get_type()) {
|
||||
const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
|
||||
if (p_infinite_inertia && PhysicsServer2D::BODY_MODE_STATIC != b->get_mode() && PhysicsServer2D::BODY_MODE_KINEMATIC != b->get_mode()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Transform2D col_obj_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
|
||||
|
||||
/*
|
||||
* There is no point in supporting one way collisions with ray shapes, as they will always collide in the desired
|
||||
* direction. Use a short ray shape if you want to achieve a similar effect.
|
||||
*
|
||||
if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
|
||||
cbk.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
|
||||
cbk.valid_depth = p_margin; //only valid depth is the collision margin
|
||||
cbk.invalid_by_dir = 0;
|
||||
|
||||
} else {
|
||||
*/
|
||||
|
||||
cbk.valid_dir = Vector2();
|
||||
cbk.valid_depth = 0;
|
||||
cbk.invalid_by_dir = 0;
|
||||
|
||||
/*
|
||||
}
|
||||
*/
|
||||
|
||||
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_margin)) {
|
||||
if (cbk.amount > 0) {
|
||||
collided = true;
|
||||
}
|
||||
|
||||
int ray_index = -1; //reuse shape
|
||||
for (int k = 0; k < rays_found; k++) {
|
||||
if (r_results[ray_index].collision_local_shape == j) {
|
||||
ray_index = k;
|
||||
}
|
||||
}
|
||||
|
||||
if (ray_index == -1 && rays_found < p_result_max) {
|
||||
ray_index = rays_found;
|
||||
rays_found++;
|
||||
}
|
||||
|
||||
if (ray_index != -1) {
|
||||
PhysicsServer2D::SeparationResult &result = r_results[ray_index];
|
||||
|
||||
for (int k = 0; k < cbk.amount; k++) {
|
||||
Vector2 a = sr[k * 2 + 0];
|
||||
Vector2 b = sr[k * 2 + 1];
|
||||
|
||||
recover_motion += (b - a) / cbk.amount;
|
||||
|
||||
real_t depth = a.distance_to(b);
|
||||
if (depth > result.collision_depth) {
|
||||
result.collision_depth = depth;
|
||||
result.collision_point = b;
|
||||
result.collision_normal = (b - a).normalized();
|
||||
result.collision_local_shape = j;
|
||||
result.collider_shape = shape_idx;
|
||||
result.collider = col_obj->get_self();
|
||||
result.collider_id = col_obj->get_instance_id();
|
||||
result.collider_metadata = col_obj->get_shape_metadata(shape_idx);
|
||||
if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
|
||||
Body2DSW *body = (Body2DSW *)col_obj;
|
||||
|
||||
Vector2 rel_vec = b - body->get_transform().get_origin();
|
||||
result.collider_velocity = Vector2(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!collided || recover_motion == Vector2()) {
|
||||
break;
|
||||
}
|
||||
|
||||
body_transform.elements[2] += recover_motion;
|
||||
body_aabb.position += recover_motion;
|
||||
|
||||
recover_attempts--;
|
||||
} while (recover_attempts);
|
||||
}
|
||||
|
||||
//optimize results (remove non colliding)
|
||||
for (int i = 0; i < rays_found; i++) {
|
||||
if (r_results[i].collision_depth == 0) {
|
||||
rays_found--;
|
||||
SWAP(r_results[i], r_results[rays_found]);
|
||||
}
|
||||
}
|
||||
|
||||
r_recover_motion = body_transform.elements[2] - p_transform.elements[2];
|
||||
return rays_found;
|
||||
}
|
||||
|
||||
bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer2D::MotionResult *r_result, bool p_exclude_raycast_shapes, const Set<RID> &p_exclude) {
|
||||
bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin, PhysicsServer2D::MotionResult *r_result, const Set<RID> &p_exclude) {
|
||||
//give me back regular physics engine logic
|
||||
//this is madness
|
||||
//and most people using this function will think
|
||||
|
@ -730,10 +549,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
continue;
|
||||
}
|
||||
|
||||
if (p_exclude_raycast_shapes && p_body->get_shape(i)->get_type() == PhysicsServer2D::SHAPE_RAY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!shapes_found) {
|
||||
body_aabb = p_body->get_shape_aabb(i);
|
||||
shapes_found = true;
|
||||
|
@ -794,24 +609,15 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
}
|
||||
|
||||
Shape2DSW *body_shape = p_body->get_shape(j);
|
||||
if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer2D::SHAPE_RAY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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];
|
||||
if (p_exclude.has(col_obj->get_self())) {
|
||||
continue;
|
||||
}
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
if (CollisionObject2DSW::TYPE_BODY == col_obj->get_type()) {
|
||||
const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
|
||||
if (p_infinite_inertia && PhysicsServer2D::BODY_MODE_STATIC != b->get_mode() && PhysicsServer2D::BODY_MODE_KINEMATIC != b->get_mode()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
Transform2D col_obj_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
|
||||
|
||||
|
@ -920,10 +726,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
}
|
||||
|
||||
Shape2DSW *body_shape = p_body->get_shape(body_shape_idx);
|
||||
if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer2D::SHAPE_RAY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(body_shape_idx);
|
||||
|
||||
bool stuck = false;
|
||||
|
@ -939,13 +741,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
int col_shape_idx = intersection_query_subindex_results[i];
|
||||
Shape2DSW *against_shape = col_obj->get_shape(col_shape_idx);
|
||||
|
||||
if (CollisionObject2DSW::TYPE_BODY == col_obj->get_type()) {
|
||||
const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
|
||||
if (p_infinite_inertia && PhysicsServer2D::BODY_MODE_STATIC != b->get_mode() && PhysicsServer2D::BODY_MODE_KINEMATIC != b->get_mode()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
bool excluded = false;
|
||||
|
||||
for (int k = 0; k < excluded_shape_pair_count; k++) {
|
||||
|
@ -1082,10 +877,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
Transform2D body_shape_xform = ugt * p_body->get_shape_transform(j);
|
||||
Shape2DSW *body_shape = p_body->get_shape(j);
|
||||
|
||||
if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer2D::SHAPE_RAY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
body_aabb.position += p_motion * unsafe;
|
||||
|
||||
int amount = _cull_aabb_for_body(p_body, body_aabb);
|
||||
|
@ -1095,14 +886,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
if (p_exclude.has(col_obj->get_self())) {
|
||||
continue;
|
||||
}
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
if (CollisionObject2DSW::TYPE_BODY == col_obj->get_type()) {
|
||||
const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
|
||||
if (p_infinite_inertia && PhysicsServer2D::BODY_MODE_STATIC != b->get_mode() && PhysicsServer2D::BODY_MODE_KINEMATIC != b->get_mode()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
|
||||
|
||||
|
|
|
@ -183,8 +183,7 @@ public:
|
|||
|
||||
int get_collision_pairs() const { return collision_pairs; }
|
||||
|
||||
bool test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer2D::MotionResult *r_result, bool p_exclude_raycast_shapes = true, const Set<RID> &p_exclude = Set<RID>());
|
||||
int test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, PhysicsServer2D::SeparationResult *r_results, int p_result_max, real_t p_margin);
|
||||
bool test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin, PhysicsServer2D::MotionResult *r_result, const Set<RID> &p_exclude = Set<RID>());
|
||||
|
||||
void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); }
|
||||
_FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.is_empty(); }
|
||||
|
|
|
@ -2273,13 +2273,11 @@ bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform3D &p_
|
|||
PhysicsServer3D::ShapeType type_A = p_shape_A->get_type();
|
||||
|
||||
ERR_FAIL_COND_V(type_A == PhysicsServer3D::SHAPE_PLANE, false);
|
||||
ERR_FAIL_COND_V(type_A == PhysicsServer3D::SHAPE_RAY, false);
|
||||
ERR_FAIL_COND_V(p_shape_A->is_concave(), false);
|
||||
|
||||
PhysicsServer3D::ShapeType type_B = p_shape_B->get_type();
|
||||
|
||||
ERR_FAIL_COND_V(type_B == PhysicsServer3D::SHAPE_PLANE, false);
|
||||
ERR_FAIL_COND_V(type_B == PhysicsServer3D::SHAPE_RAY, false);
|
||||
ERR_FAIL_COND_V(p_shape_B->is_concave(), false);
|
||||
|
||||
static const CollisionFunc collision_table[6][6] = {
|
||||
|
@ -2384,10 +2382,10 @@ bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform3D &p_
|
|||
|
||||
CollisionFunc collision_func;
|
||||
if (margin_A != 0.0 || margin_B != 0.0) {
|
||||
collision_func = collision_table_margin[type_A - 2][type_B - 2];
|
||||
collision_func = collision_table_margin[type_A - 1][type_B - 1];
|
||||
|
||||
} else {
|
||||
collision_func = collision_table[type_A - 2][type_B - 2];
|
||||
collision_func = collision_table[type_A - 1][type_B - 1];
|
||||
}
|
||||
ERR_FAIL_COND_V(!collision_func, false);
|
||||
|
||||
|
|
|
@ -89,39 +89,6 @@ bool CollisionSolver3DSW::solve_static_plane(const Shape3DSW *p_shape_A, const T
|
|||
return found;
|
||||
}
|
||||
|
||||
bool CollisionSolver3DSW::solve_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) {
|
||||
const RayShape3DSW *ray = static_cast<const RayShape3DSW *>(p_shape_A);
|
||||
|
||||
Vector3 from = p_transform_A.origin;
|
||||
Vector3 to = from + p_transform_A.basis.get_axis(2) * ray->get_length();
|
||||
Vector3 support_A = to;
|
||||
|
||||
Transform3D ai = p_transform_B.affine_inverse();
|
||||
|
||||
from = ai.xform(from);
|
||||
to = ai.xform(to);
|
||||
|
||||
Vector3 p, n;
|
||||
if (!p_shape_B->intersect_segment(from, to, p, n)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3 support_B = p_transform_B.xform(p);
|
||||
if (ray->get_slips_on_slope()) {
|
||||
Vector3 global_n = ai.basis.xform_inv(n).normalized();
|
||||
support_B = support_A + (support_B - support_A).length() * global_n;
|
||||
}
|
||||
|
||||
if (p_result_callback) {
|
||||
if (p_swap_result) {
|
||||
p_result_callback(support_B, 0, support_A, 0, p_userdata);
|
||||
} else {
|
||||
p_result_callback(support_A, 0, support_B, 0, p_userdata);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct _SoftBodyContactCollisionInfo {
|
||||
int node_index = 0;
|
||||
CollisionSolver3DSW::CallbackResult result_callback = nullptr;
|
||||
|
@ -347,9 +314,6 @@ bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transfo
|
|||
if (type_B == PhysicsServer3D::SHAPE_PLANE) {
|
||||
return false;
|
||||
}
|
||||
if (type_B == PhysicsServer3D::SHAPE_RAY) {
|
||||
return false;
|
||||
}
|
||||
if (type_B == PhysicsServer3D::SHAPE_SOFT_BODY) {
|
||||
return false;
|
||||
}
|
||||
|
@ -360,17 +324,6 @@ bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transfo
|
|||
return solve_static_plane(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false);
|
||||
}
|
||||
|
||||
} else if (type_A == PhysicsServer3D::SHAPE_RAY) {
|
||||
if (type_B == PhysicsServer3D::SHAPE_RAY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (swap) {
|
||||
return solve_ray(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true);
|
||||
} else {
|
||||
return solve_ray(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false);
|
||||
}
|
||||
|
||||
} else if (type_B == PhysicsServer3D::SHAPE_SOFT_BODY) {
|
||||
if (type_A == PhysicsServer3D::SHAPE_SOFT_BODY) {
|
||||
// Soft Body / Soft Body not supported.
|
||||
|
|
|
@ -48,12 +48,6 @@ RID PhysicsServer3DSW::plane_shape_create() {
|
|||
shape->set_self(rid);
|
||||
return rid;
|
||||
}
|
||||
RID PhysicsServer3DSW::ray_shape_create() {
|
||||
Shape3DSW *shape = memnew(RayShape3DSW);
|
||||
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);
|
||||
|
@ -854,7 +848,7 @@ void PhysicsServer3DSW::body_set_ray_pickable(RID p_body, bool p_enable) {
|
|||
body->set_ray_pickable(p_enable);
|
||||
}
|
||||
|
||||
bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, MotionResult *r_result, bool p_exclude_raycast_shapes, const Set<RID> &p_exclude) {
|
||||
bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin, MotionResult *r_result, const Set<RID> &p_exclude) {
|
||||
Body3DSW *body = body_owner.getornull(p_body);
|
||||
ERR_FAIL_COND_V(!body, false);
|
||||
ERR_FAIL_COND_V(!body->get_space(), false);
|
||||
|
@ -862,18 +856,7 @@ bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform3D &p_from,
|
|||
|
||||
_update_shapes();
|
||||
|
||||
return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes, p_exclude);
|
||||
}
|
||||
|
||||
int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) {
|
||||
Body3DSW *body = body_owner.getornull(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_ray_separation(body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin);
|
||||
return body->get_space()->test_body_motion(body, p_from, p_motion, p_margin, r_result, p_exclude);
|
||||
}
|
||||
|
||||
PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) {
|
||||
|
|
|
@ -83,7 +83,6 @@ public:
|
|||
static void _shape_col_cbk(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B, void *p_userdata);
|
||||
|
||||
virtual RID plane_shape_create() override;
|
||||
virtual RID ray_shape_create() override;
|
||||
virtual RID sphere_shape_create() override;
|
||||
virtual RID box_shape_create() override;
|
||||
virtual RID capsule_shape_create() override;
|
||||
|
@ -242,8 +241,7 @@ public:
|
|||
|
||||
virtual void body_set_ray_pickable(RID p_body, bool p_enable) override;
|
||||
|
||||
virtual bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true, const Set<RID> &p_exclude = Set<RID>()) override;
|
||||
virtual int body_test_ray_separation(RID p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override;
|
||||
virtual bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin = 0.001, MotionResult *r_result = nullptr, const Set<RID> &p_exclude = Set<RID>()) override;
|
||||
|
||||
// this function only works on physics process, errors and returns null otherwise
|
||||
virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override;
|
||||
|
|
|
@ -79,7 +79,6 @@ public:
|
|||
|
||||
//FUNC1RID(shape,ShapeType); todo fix
|
||||
FUNCRID(plane_shape)
|
||||
FUNCRID(ray_shape)
|
||||
FUNCRID(sphere_shape)
|
||||
FUNCRID(box_shape)
|
||||
FUNCRID(capsule_shape)
|
||||
|
@ -250,14 +249,9 @@ public:
|
|||
|
||||
FUNC2(body_set_ray_pickable, RID, bool);
|
||||
|
||||
bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true, const Set<RID> &p_exclude = Set<RID>()) override {
|
||||
bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin = 0.001, MotionResult *r_result = nullptr, const Set<RID> &p_exclude = Set<RID>()) override {
|
||||
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
|
||||
return physics_3d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes, p_exclude);
|
||||
}
|
||||
|
||||
int body_test_ray_separation(RID p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override {
|
||||
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
|
||||
return physics_3d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin);
|
||||
return physics_3d_server->body_test_motion(p_body, p_from, p_motion, p_margin, r_result, p_exclude);
|
||||
}
|
||||
|
||||
// this function only works on physics process, errors and returns null otherwise
|
||||
|
|
|
@ -164,91 +164,6 @@ Variant PlaneShape3DSW::get_data() const {
|
|||
PlaneShape3DSW::PlaneShape3DSW() {
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
real_t RayShape3DSW::get_length() const {
|
||||
return length;
|
||||
}
|
||||
|
||||
bool RayShape3DSW::get_slips_on_slope() const {
|
||||
return slips_on_slope;
|
||||
}
|
||||
|
||||
void RayShape3DSW::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 RayShape3DSW::get_support(const Vector3 &p_normal) const {
|
||||
if (p_normal.z > 0) {
|
||||
return Vector3(0, 0, length);
|
||||
} else {
|
||||
return Vector3(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RayShape3DSW::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;
|
||||
r_supports[0] = Vector3(0, 0, 0);
|
||||
r_supports[1] = Vector3(0, 0, length);
|
||||
} else if (p_normal.z > 0) {
|
||||
r_amount = 1;
|
||||
r_type = FEATURE_POINT;
|
||||
*r_supports = Vector3(0, 0, length);
|
||||
} else {
|
||||
r_amount = 1;
|
||||
r_type = FEATURE_POINT;
|
||||
*r_supports = Vector3(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool RayShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
|
||||
return false; //simply not possible
|
||||
}
|
||||
|
||||
bool RayShape3DSW::intersect_point(const Vector3 &p_point) const {
|
||||
return false; //simply not possible
|
||||
}
|
||||
|
||||
Vector3 RayShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
|
||||
Vector3 s[2] = {
|
||||
Vector3(0, 0, 0),
|
||||
Vector3(0, 0, length)
|
||||
};
|
||||
|
||||
return Geometry3D::get_closest_point_to_segment(p_point, s);
|
||||
}
|
||||
|
||||
Vector3 RayShape3DSW::get_moment_of_inertia(real_t p_mass) const {
|
||||
return Vector3();
|
||||
}
|
||||
|
||||
void RayShape3DSW::_setup(real_t p_length, bool p_slips_on_slope) {
|
||||
length = p_length;
|
||||
slips_on_slope = p_slips_on_slope;
|
||||
configure(AABB(Vector3(0, 0, 0), Vector3(0.1, 0.1, length)));
|
||||
}
|
||||
|
||||
void RayShape3DSW::set_data(const Variant &p_data) {
|
||||
Dictionary d = p_data;
|
||||
_setup(d["length"], d["slips_on_slope"]);
|
||||
}
|
||||
|
||||
Variant RayShape3DSW::get_data() const {
|
||||
Dictionary d;
|
||||
d["length"] = length;
|
||||
d["slips_on_slope"] = slips_on_slope;
|
||||
return d;
|
||||
}
|
||||
|
||||
RayShape3DSW::RayShape3DSW() {
|
||||
length = 1;
|
||||
slips_on_slope = false;
|
||||
}
|
||||
|
||||
/********** SPHERE *************/
|
||||
|
||||
real_t SphereShape3DSW::get_radius() const {
|
||||
|
|
|
@ -145,34 +145,6 @@ public:
|
|||
PlaneShape3DSW();
|
||||
};
|
||||
|
||||
class RayShape3DSW : public Shape3DSW {
|
||||
real_t length;
|
||||
bool slips_on_slope;
|
||||
|
||||
void _setup(real_t p_length, bool p_slips_on_slope);
|
||||
|
||||
public:
|
||||
real_t get_length() const;
|
||||
bool get_slips_on_slope() const;
|
||||
|
||||
virtual real_t get_area() const { return 0.0; }
|
||||
virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_RAY; }
|
||||
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const;
|
||||
virtual Vector3 get_support(const Vector3 &p_normal) const;
|
||||
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const;
|
||||
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
|
||||
virtual bool intersect_point(const Vector3 &p_point) const;
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
|
||||
|
||||
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
|
||||
|
||||
virtual void set_data(const Variant &p_data);
|
||||
virtual Variant get_data() const;
|
||||
|
||||
RayShape3DSW();
|
||||
};
|
||||
|
||||
class SphereShape3DSW : public Shape3DSW {
|
||||
real_t radius;
|
||||
|
||||
|
|
|
@ -569,158 +569,7 @@ int Space3DSW::_cull_aabb_for_body(Body3DSW *p_body, const AABB &p_aabb) {
|
|||
return amount;
|
||||
}
|
||||
|
||||
int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin) {
|
||||
AABB body_aabb;
|
||||
|
||||
bool shapes_found = false;
|
||||
|
||||
for (int i = 0; i < p_body->get_shape_count(); i++) {
|
||||
if (p_body->is_shape_disabled(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!shapes_found) {
|
||||
body_aabb = p_body->get_shape_aabb(i);
|
||||
shapes_found = true;
|
||||
} else {
|
||||
body_aabb = body_aabb.merge(p_body->get_shape_aabb(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (!shapes_found) {
|
||||
return 0;
|
||||
}
|
||||
// Undo the currently transform the physics server is aware of and apply the provided one
|
||||
body_aabb = p_transform.xform(p_body->get_inv_transform().xform(body_aabb));
|
||||
body_aabb = body_aabb.grow(p_margin);
|
||||
|
||||
Transform3D body_transform = p_transform;
|
||||
|
||||
for (int i = 0; i < p_result_max; i++) {
|
||||
//reset results
|
||||
r_results[i].collision_depth = 0;
|
||||
}
|
||||
|
||||
int rays_found = 0;
|
||||
|
||||
{
|
||||
// raycast AND separate
|
||||
|
||||
const int max_results = 32;
|
||||
int recover_attempts = 4;
|
||||
Vector3 sr[max_results * 2];
|
||||
PhysicsServer3DSW::CollCbkData cbk;
|
||||
cbk.max = max_results;
|
||||
PhysicsServer3DSW::CollCbkData *cbkptr = &cbk;
|
||||
CollisionSolver3DSW::CallbackResult cbkres = PhysicsServer3DSW::_shape_col_cbk;
|
||||
|
||||
do {
|
||||
Vector3 recover_motion;
|
||||
|
||||
bool collided = false;
|
||||
|
||||
int amount = _cull_aabb_for_body(p_body, body_aabb);
|
||||
|
||||
for (int j = 0; j < p_body->get_shape_count(); j++) {
|
||||
if (p_body->is_shape_disabled(j)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Shape3DSW *body_shape = p_body->get_shape(j);
|
||||
|
||||
if (body_shape->get_type() != PhysicsServer3D::SHAPE_RAY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Transform3D body_shape_xform = body_transform * p_body->get_shape_transform(j);
|
||||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
const CollisionObject3DSW *col_obj = intersection_query_results[i];
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
cbk.amount = 0;
|
||||
cbk.ptr = sr;
|
||||
|
||||
if (CollisionObject3DSW::TYPE_BODY == col_obj->get_type()) {
|
||||
const Body3DSW *b = static_cast<const Body3DSW *>(col_obj);
|
||||
if (p_infinite_inertia && PhysicsServer3D::BODY_MODE_STATIC != b->get_mode() && PhysicsServer3D::BODY_MODE_KINEMATIC != b->get_mode()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Shape3DSW *against_shape = col_obj->get_shape(shape_idx);
|
||||
if (CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_margin)) {
|
||||
if (cbk.amount > 0) {
|
||||
collided = true;
|
||||
}
|
||||
|
||||
int ray_index = -1; //reuse shape
|
||||
for (int k = 0; k < rays_found; k++) {
|
||||
if (r_results[k].collision_local_shape == j) {
|
||||
ray_index = k;
|
||||
}
|
||||
}
|
||||
|
||||
if (ray_index == -1 && rays_found < p_result_max) {
|
||||
ray_index = rays_found;
|
||||
rays_found++;
|
||||
}
|
||||
|
||||
if (ray_index != -1) {
|
||||
PhysicsServer3D::SeparationResult &result = r_results[ray_index];
|
||||
|
||||
for (int k = 0; k < cbk.amount; k++) {
|
||||
Vector3 a = sr[k * 2 + 0];
|
||||
Vector3 b = sr[k * 2 + 1];
|
||||
|
||||
recover_motion += (b - a) / cbk.amount;
|
||||
|
||||
real_t depth = a.distance_to(b);
|
||||
if (depth > result.collision_depth) {
|
||||
result.collision_depth = depth;
|
||||
result.collision_point = b;
|
||||
result.collision_normal = (b - a).normalized();
|
||||
result.collision_local_shape = j;
|
||||
result.collider = col_obj->get_self();
|
||||
result.collider_id = col_obj->get_instance_id();
|
||||
result.collider_shape = shape_idx;
|
||||
//result.collider_metadata = col_obj->get_shape_metadata(shape_idx);
|
||||
if (col_obj->get_type() == CollisionObject3DSW::TYPE_BODY) {
|
||||
Body3DSW *body = (Body3DSW *)col_obj;
|
||||
Vector3 rel_vec = b - (body->get_transform().origin + body->get_center_of_mass());
|
||||
result.collider_velocity = body->get_linear_velocity() + (body->get_angular_velocity()).cross(rel_vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!collided || recover_motion == Vector3()) {
|
||||
break;
|
||||
}
|
||||
|
||||
body_transform.origin += recover_motion;
|
||||
body_aabb.position += recover_motion;
|
||||
|
||||
recover_attempts--;
|
||||
} while (recover_attempts);
|
||||
}
|
||||
|
||||
//optimize results (remove non colliding)
|
||||
for (int i = 0; i < rays_found; i++) {
|
||||
if (r_results[i].collision_depth == 0) {
|
||||
rays_found--;
|
||||
SWAP(r_results[i], r_results[rays_found]);
|
||||
}
|
||||
}
|
||||
|
||||
r_recover_motion = body_transform.origin - p_transform.origin;
|
||||
return rays_found;
|
||||
}
|
||||
|
||||
bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes, const Set<RID> &p_exclude) {
|
||||
bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin, PhysicsServer3D::MotionResult *r_result, const Set<RID> &p_exclude) {
|
||||
//give me back regular physics engine logic
|
||||
//this is madness
|
||||
//and most people using this function will think
|
||||
|
@ -795,23 +644,14 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
|
||||
Transform3D body_shape_xform = body_transform * p_body->get_shape_transform(j);
|
||||
Shape3DSW *body_shape = p_body->get_shape(j);
|
||||
if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer3D::SHAPE_RAY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
const CollisionObject3DSW *col_obj = intersection_query_results[i];
|
||||
if (p_exclude.has(col_obj->get_self())) {
|
||||
continue;
|
||||
}
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
if (CollisionObject3DSW::TYPE_BODY == col_obj->get_type()) {
|
||||
const Body3DSW *b = static_cast<const Body3DSW *>(col_obj);
|
||||
if (p_infinite_inertia && PhysicsServer3D::BODY_MODE_STATIC != b->get_mode() && PhysicsServer3D::BODY_MODE_KINEMATIC != b->get_mode()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
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_margin)) {
|
||||
collided = cbk.amount > 0;
|
||||
|
@ -877,10 +717,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
Transform3D body_shape_xform = body_transform * p_body->get_shape_transform(j);
|
||||
Shape3DSW *body_shape = p_body->get_shape(j);
|
||||
|
||||
if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer3D::SHAPE_RAY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Transform3D body_shape_xform_inv = body_shape_xform.affine_inverse();
|
||||
MotionShape3DSW mshape;
|
||||
mshape.shape = body_shape;
|
||||
|
@ -896,14 +732,8 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
if (p_exclude.has(col_obj->get_self())) {
|
||||
continue;
|
||||
}
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
if (CollisionObject3DSW::TYPE_BODY == col_obj->get_type()) {
|
||||
const Body3DSW *b = static_cast<const Body3DSW *>(col_obj);
|
||||
if (p_infinite_inertia && PhysicsServer3D::BODY_MODE_STATIC != b->get_mode() && PhysicsServer3D::BODY_MODE_KINEMATIC != b->get_mode()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
//test initial overlap, does it collide if going all the way?
|
||||
Vector3 point_A, point_B;
|
||||
|
@ -1011,10 +841,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
Transform3D body_shape_xform = ugt * p_body->get_shape_transform(j);
|
||||
Shape3DSW *body_shape = p_body->get_shape(j);
|
||||
|
||||
if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer3D::SHAPE_RAY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
body_aabb.position += p_motion * unsafe;
|
||||
|
||||
int amount = _cull_aabb_for_body(p_body, body_aabb);
|
||||
|
@ -1026,13 +852,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
}
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
if (CollisionObject3DSW::TYPE_BODY == col_obj->get_type()) {
|
||||
const Body3DSW *b = static_cast<const Body3DSW *>(col_obj);
|
||||
if (p_infinite_inertia && PhysicsServer3D::BODY_MODE_STATIC != b->get_mode() && PhysicsServer3D::BODY_MODE_KINEMATIC != b->get_mode()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
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_margin);
|
||||
|
|
|
@ -203,8 +203,7 @@ 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]; }
|
||||
|
||||
int test_body_ray_separation(Body3DSW *p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin);
|
||||
bool test_body_motion(Body3DSW *p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes, const Set<RID> &p_exclude = Set<RID>());
|
||||
bool test_body_motion(Body3DSW *p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin, PhysicsServer3D::MotionResult *r_result, const Set<RID> &p_exclude = Set<RID>());
|
||||
|
||||
Space3DSW();
|
||||
~Space3DSW();
|
||||
|
|
|
@ -500,7 +500,7 @@ void PhysicsTestMotionResult2D::_bind_methods() {
|
|||
|
||||
///////////////////////////////////////
|
||||
|
||||
bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, const Ref<PhysicsTestMotionResult2D> &p_result, bool p_exclude_raycast_shapes, const Vector<RID> &p_exclude) {
|
||||
bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin, const Ref<PhysicsTestMotionResult2D> &p_result, const Vector<RID> &p_exclude) {
|
||||
MotionResult *r = nullptr;
|
||||
if (p_result.is_valid()) {
|
||||
r = p_result->get_result_ptr();
|
||||
|
@ -509,12 +509,11 @@ bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, c
|
|||
for (int i = 0; i < p_exclude.size(); i++) {
|
||||
exclude.insert(p_exclude[i]);
|
||||
}
|
||||
return body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r, p_exclude_raycast_shapes, exclude);
|
||||
return body_test_motion(p_body, p_from, p_motion, p_margin, r, exclude);
|
||||
}
|
||||
|
||||
void PhysicsServer2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("line_shape_create"), &PhysicsServer2D::line_shape_create);
|
||||
ClassDB::bind_method(D_METHOD("ray_shape_create"), &PhysicsServer2D::ray_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);
|
||||
|
@ -636,7 +635,7 @@ void PhysicsServer2D::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("body_set_force_integration_callback", "body", "callable", "userdata"), &PhysicsServer2D::body_set_force_integration_callback, DEFVAL(Variant()));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("body_test_motion", "body", "from", "motion", "infinite_inertia", "margin", "result", "exclude_raycast_shapes", "exclude"), &PhysicsServer2D::_body_test_motion, DEFVAL(0.08), DEFVAL(Variant()), DEFVAL(true), DEFVAL(Array()));
|
||||
ClassDB::bind_method(D_METHOD("body_test_motion", "body", "from", "motion", "margin", "result", "exclude"), &PhysicsServer2D::_body_test_motion, DEFVAL(0.08), DEFVAL(Variant()), DEFVAL(Array()));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("body_get_direct_state", "body"), &PhysicsServer2D::body_get_direct_state);
|
||||
|
||||
|
@ -676,7 +675,6 @@ void PhysicsServer2D::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH);
|
||||
|
||||
BIND_ENUM_CONSTANT(SHAPE_LINE);
|
||||
BIND_ENUM_CONSTANT(SHAPE_RAY);
|
||||
BIND_ENUM_CONSTANT(SHAPE_SEGMENT);
|
||||
BIND_ENUM_CONSTANT(SHAPE_CIRCLE);
|
||||
BIND_ENUM_CONSTANT(SHAPE_RECTANGLE);
|
||||
|
|
|
@ -210,7 +210,7 @@ class PhysicsServer2D : public Object {
|
|||
|
||||
static PhysicsServer2D *singleton;
|
||||
|
||||
virtual bool _body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>(), bool p_exclude_raycast_shapes = true, const Vector<RID> &p_exclude = Vector<RID>());
|
||||
virtual bool _body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>(), const Vector<RID> &p_exclude = Vector<RID>());
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
@ -220,7 +220,6 @@ public:
|
|||
|
||||
enum ShapeType {
|
||||
SHAPE_LINE, ///< plane:"plane"
|
||||
SHAPE_RAY, ///< float:"length"
|
||||
SHAPE_SEGMENT, ///< float:"length"
|
||||
SHAPE_CIRCLE, ///< float:"radius"
|
||||
SHAPE_RECTANGLE, ///< vec3:"extents"
|
||||
|
@ -231,7 +230,6 @@ public:
|
|||
};
|
||||
|
||||
virtual RID line_shape_create() = 0;
|
||||
virtual RID ray_shape_create() = 0;
|
||||
virtual RID segment_shape_create() = 0;
|
||||
virtual RID circle_shape_create() = 0;
|
||||
virtual RID rectangle_shape_create() = 0;
|
||||
|
@ -483,7 +481,7 @@ public:
|
|||
Variant collider_metadata;
|
||||
};
|
||||
|
||||
virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true, const Set<RID> &p_exclude = Set<RID>()) = 0;
|
||||
virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin = 0.08, MotionResult *r_result = nullptr, const Set<RID> &p_exclude = Set<RID>()) = 0;
|
||||
|
||||
struct SeparationResult {
|
||||
real_t collision_depth;
|
||||
|
@ -497,8 +495,6 @@ public:
|
|||
Variant collider_metadata;
|
||||
};
|
||||
|
||||
virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.08) = 0;
|
||||
|
||||
/* JOINT API */
|
||||
|
||||
virtual RID joint_create() = 0;
|
||||
|
|
|
@ -447,7 +447,7 @@ void PhysicsTestMotionResult3D::_bind_methods() {
|
|||
|
||||
///////////////////////////////////////
|
||||
|
||||
bool PhysicsServer3D::_body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, const Ref<PhysicsTestMotionResult3D> &p_result, bool p_exclude_raycast_shapes, const Vector<RID> &p_exclude) {
|
||||
bool PhysicsServer3D::_body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin, const Ref<PhysicsTestMotionResult3D> &p_result, const Vector<RID> &p_exclude) {
|
||||
MotionResult *r = nullptr;
|
||||
if (p_result.is_valid()) {
|
||||
r = p_result->get_result_ptr();
|
||||
|
@ -456,15 +456,13 @@ bool PhysicsServer3D::_body_test_motion(RID p_body, const Transform3D &p_from, c
|
|||
for (int i = 0; i < p_exclude.size(); i++) {
|
||||
exclude.insert(p_exclude[i]);
|
||||
}
|
||||
return body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r, p_exclude_raycast_shapes, exclude);
|
||||
return body_test_motion(p_body, p_from, p_motion, p_margin, r, exclude);
|
||||
}
|
||||
|
||||
RID PhysicsServer3D::shape_create(ShapeType p_shape) {
|
||||
switch (p_shape) {
|
||||
case SHAPE_PLANE:
|
||||
return plane_shape_create();
|
||||
case SHAPE_RAY:
|
||||
return ray_shape_create();
|
||||
case SHAPE_SPHERE:
|
||||
return sphere_shape_create();
|
||||
case SHAPE_BOX:
|
||||
|
@ -490,7 +488,6 @@ void PhysicsServer3D::_bind_methods() {
|
|||
#ifndef _3D_DISABLED
|
||||
|
||||
ClassDB::bind_method(D_METHOD("plane_shape_create"), &PhysicsServer3D::plane_shape_create);
|
||||
ClassDB::bind_method(D_METHOD("ray_shape_create"), &PhysicsServer3D::ray_shape_create);
|
||||
ClassDB::bind_method(D_METHOD("sphere_shape_create"), &PhysicsServer3D::sphere_shape_create);
|
||||
ClassDB::bind_method(D_METHOD("box_shape_create"), &PhysicsServer3D::box_shape_create);
|
||||
ClassDB::bind_method(D_METHOD("capsule_shape_create"), &PhysicsServer3D::capsule_shape_create);
|
||||
|
@ -612,7 +609,7 @@ void PhysicsServer3D::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("body_set_ray_pickable", "body", "enable"), &PhysicsServer3D::body_set_ray_pickable);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("body_test_motion", "body", "from", "motion", "infinite_inertia", "margin", "result", "exclude_raycast_shapes", "exclude"), &PhysicsServer3D::_body_test_motion, DEFVAL(0.001), DEFVAL(Variant()), DEFVAL(true), DEFVAL(Array()));
|
||||
ClassDB::bind_method(D_METHOD("body_test_motion", "body", "from", "motion", "margin", "result", "exclude"), &PhysicsServer3D::_body_test_motion, DEFVAL(0.001), DEFVAL(Variant()), DEFVAL(Array()));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("body_get_direct_state", "body"), &PhysicsServer3D::body_get_direct_state);
|
||||
|
||||
|
@ -751,7 +748,6 @@ void PhysicsServer3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &PhysicsServer3D::get_process_info);
|
||||
|
||||
BIND_ENUM_CONSTANT(SHAPE_PLANE);
|
||||
BIND_ENUM_CONSTANT(SHAPE_RAY);
|
||||
BIND_ENUM_CONSTANT(SHAPE_SPHERE);
|
||||
BIND_ENUM_CONSTANT(SHAPE_BOX);
|
||||
BIND_ENUM_CONSTANT(SHAPE_CAPSULE);
|
||||
|
|
|
@ -212,7 +212,7 @@ class PhysicsServer3D : public Object {
|
|||
|
||||
static PhysicsServer3D *singleton;
|
||||
|
||||
virtual bool _body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, const Ref<PhysicsTestMotionResult3D> &p_result = Ref<PhysicsTestMotionResult3D>(), bool p_exclude_raycast_shapes = true, const Vector<RID> &p_exclude = Vector<RID>());
|
||||
virtual bool _body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin = 0.001, const Ref<PhysicsTestMotionResult3D> &p_result = Ref<PhysicsTestMotionResult3D>(), const Vector<RID> &p_exclude = Vector<RID>());
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
@ -222,7 +222,6 @@ public:
|
|||
|
||||
enum ShapeType {
|
||||
SHAPE_PLANE, ///< plane:"plane"
|
||||
SHAPE_RAY, ///< float:"length"
|
||||
SHAPE_SPHERE, ///< float:"radius"
|
||||
SHAPE_BOX, ///< vec3:"extents"
|
||||
SHAPE_CAPSULE, ///< dict( float:"radius", float:"height"):capsule
|
||||
|
@ -237,7 +236,6 @@ public:
|
|||
RID shape_create(ShapeType p_shape);
|
||||
|
||||
virtual RID plane_shape_create() = 0;
|
||||
virtual RID ray_shape_create() = 0;
|
||||
virtual RID sphere_shape_create() = 0;
|
||||
virtual RID box_shape_create() = 0;
|
||||
virtual RID capsule_shape_create() = 0;
|
||||
|
@ -491,21 +489,7 @@ public:
|
|||
Variant collider_metadata;
|
||||
};
|
||||
|
||||
virtual bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true, const Set<RID> &p_exclude = Set<RID>()) = 0;
|
||||
|
||||
struct SeparationResult {
|
||||
real_t collision_depth;
|
||||
Vector3 collision_point;
|
||||
Vector3 collision_normal;
|
||||
Vector3 collider_velocity;
|
||||
int collision_local_shape;
|
||||
ObjectID collider_id;
|
||||
RID collider;
|
||||
int collider_shape;
|
||||
Variant collider_metadata;
|
||||
};
|
||||
|
||||
virtual int body_test_ray_separation(RID p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) = 0;
|
||||
virtual bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin = 0.001, MotionResult *r_result = nullptr, const Set<RID> &p_exclude = Set<RID>()) = 0;
|
||||
|
||||
/* SOFT BODY */
|
||||
|
||||
|
|
Loading…
Reference in a new issue