diff options
author | PouleyKetchoupp <pouleyketchoup@gmail.com> | 2021-08-17 10:15:11 -0700 |
---|---|---|
committer | PouleyKetchoupp <pouleyketchoup@gmail.com> | 2021-08-24 16:03:05 -0700 |
commit | 45c7af98625a1751f2a97aaf2a4a17d808b61092 (patch) | |
tree | c380f56cf612c6edff37bf0a38b04761789bb951 /servers | |
parent | c89a5fb8be579936ea0b56bde520133cfa7664ae (diff) |
Restore RayShape as a regular shape type
Partial revert from previously removing ray shapes completely, added
back as a shape type but without the specific character controller code.
Diffstat (limited to 'servers')
-rw-r--r-- | servers/physics_2d/collision_solver_2d_sat.cpp | 18 | ||||
-rw-r--r-- | servers/physics_2d/collision_solver_2d_sw.cpp | 54 | ||||
-rw-r--r-- | servers/physics_2d/physics_server_2d_sw.cpp | 7 | ||||
-rw-r--r-- | servers/physics_2d/physics_server_2d_sw.h | 1 | ||||
-rw-r--r-- | servers/physics_2d/physics_server_2d_wrap_mt.h | 1 | ||||
-rw-r--r-- | servers/physics_2d/shape_2d_sw.cpp | 40 | ||||
-rw-r--r-- | servers/physics_2d/shape_2d_sw.h | 35 | ||||
-rw-r--r-- | servers/physics_3d/collision_solver_3d_sat.cpp | 6 | ||||
-rw-r--r-- | servers/physics_3d/collision_solver_3d_sw.cpp | 47 | ||||
-rw-r--r-- | servers/physics_3d/physics_server_3d_sw.cpp | 6 | ||||
-rw-r--r-- | servers/physics_3d/physics_server_3d_sw.h | 1 | ||||
-rw-r--r-- | servers/physics_3d/physics_server_3d_wrap_mt.h | 1 | ||||
-rw-r--r-- | servers/physics_3d/shape_3d_sw.cpp | 85 | ||||
-rw-r--r-- | servers/physics_3d/shape_3d_sw.h | 28 | ||||
-rw-r--r-- | servers/physics_server_2d.cpp | 2 | ||||
-rw-r--r-- | servers/physics_server_2d.h | 2 | ||||
-rw-r--r-- | servers/physics_server_3d.cpp | 4 | ||||
-rw-r--r-- | servers/physics_server_3d.h | 2 |
18 files changed, 330 insertions, 10 deletions
diff --git a/servers/physics_2d/collision_solver_2d_sat.cpp b/servers/physics_2d/collision_solver_2d_sat.cpp index 30a99d3d74..3dde881c4d 100644 --- a/servers/physics_2d/collision_solver_2d_sat.cpp +++ b/servers/physics_2d/collision_solver_2d_sat.cpp @@ -1115,11 +1115,13 @@ 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_WORLD_MARGIN, 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_WORLD_MARGIN, 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] = { @@ -1382,23 +1384,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 - 1][type_B - 1]; + collision_func = collision_table_margin[type_A - 2][type_B - 2]; } else if (*motion_A != Vector2() && *motion_B == Vector2()) { - collision_func = collision_table_castA_margin[type_A - 1][type_B - 1]; + collision_func = collision_table_castA_margin[type_A - 2][type_B - 2]; } else if (*motion_A == Vector2() && *motion_B != Vector2()) { - collision_func = collision_table_castB_margin[type_A - 1][type_B - 1]; + collision_func = collision_table_castB_margin[type_A - 2][type_B - 2]; } else { - collision_func = collision_table_castA_castB_margin[type_A - 1][type_B - 1]; + collision_func = collision_table_castA_castB_margin[type_A - 2][type_B - 2]; } } else { if (*motion_A == Vector2() && *motion_B == Vector2()) { - collision_func = collision_table[type_A - 1][type_B - 1]; + collision_func = collision_table[type_A - 2][type_B - 2]; } else if (*motion_A != Vector2() && *motion_B == Vector2()) { - collision_func = collision_table_castA[type_A - 1][type_B - 1]; + collision_func = collision_table_castA[type_A - 2][type_B - 2]; } else if (*motion_A == Vector2() && *motion_B != Vector2()) { - collision_func = collision_table_castB[type_A - 1][type_B - 1]; + collision_func = collision_table_castB[type_A - 2][type_B - 2]; } else { - collision_func = collision_table_castA_castB[type_A - 1][type_B - 1]; + collision_func = collision_table_castA_castB[type_A - 2][type_B - 2]; } } diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp index 8f8a4a862c..1946dae2e3 100644 --- a/servers/physics_2d/collision_solver_2d_sw.cpp +++ b/servers/physics_2d/collision_solver_2d_sw.cpp @@ -73,6 +73,49 @@ bool CollisionSolver2DSW::solve_static_world_margin(const Shape2DSW *p_shape_A, 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; @@ -177,6 +220,17 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p return solve_static_world_margin(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false); } + } else if (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; diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp index 88c097453e..0954f3a174 100644 --- a/servers/physics_2d/physics_server_2d_sw.cpp +++ b/servers/physics_2d/physics_server_2d_sw.cpp @@ -45,6 +45,9 @@ RID PhysicsServer2DSW::_shape_create(ShapeType p_shape) { case SHAPE_WORLD_MARGIN: { shape = memnew(WorldMarginShape2DSW); } break; + case SHAPE_RAY: { + shape = memnew(RayShape2DSW); + } break; case SHAPE_SEGMENT: { shape = memnew(SegmentShape2DSW); } break; @@ -79,6 +82,10 @@ RID PhysicsServer2DSW::world_margin_shape_create() { return _shape_create(SHAPE_WORLD_MARGIN); } +RID PhysicsServer2DSW::ray_shape_create() { + return _shape_create(SHAPE_RAY); +} + RID PhysicsServer2DSW::segment_shape_create() { return _shape_create(SHAPE_SEGMENT); } diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h index 3610f43f93..1926eaac84 100644 --- a/servers/physics_2d/physics_server_2d_sw.h +++ b/servers/physics_2d/physics_server_2d_sw.h @@ -88,6 +88,7 @@ public: }; virtual RID world_margin_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; diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h index b93178919d..0ebccc2614 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.h +++ b/servers/physics_2d/physics_server_2d_wrap_mt.h @@ -80,6 +80,7 @@ public: //FUNC1RID(shape,ShapeType); todo fix FUNCRID(world_margin_shape) + FUNCRID(ray_shape) FUNCRID(segment_shape) FUNCRID(circle_shape) FUNCRID(rectangle_shape) diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index b3e4ca84c3..be2f83b705 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -143,6 +143,46 @@ Variant WorldMarginShape2DSW::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; diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/shape_2d_sw.h index 45d3379dfa..d1640b39cf 100644 --- a/servers/physics_2d/shape_2d_sw.h +++ b/servers/physics_2d/shape_2d_sw.h @@ -177,6 +177,41 @@ 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; diff --git a/servers/physics_3d/collision_solver_3d_sat.cpp b/servers/physics_3d/collision_solver_3d_sat.cpp index 6e6a2cb9e7..547f5f3e47 100644 --- a/servers/physics_3d/collision_solver_3d_sat.cpp +++ b/servers/physics_3d/collision_solver_3d_sat.cpp @@ -2273,11 +2273,13 @@ 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] = { @@ -2382,10 +2384,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 - 1][type_B - 1]; + collision_func = collision_table_margin[type_A - 2][type_B - 2]; } else { - collision_func = collision_table[type_A - 1][type_B - 1]; + collision_func = collision_table[type_A - 2][type_B - 2]; } ERR_FAIL_COND_V(!collision_func, false); diff --git a/servers/physics_3d/collision_solver_3d_sw.cpp b/servers/physics_3d/collision_solver_3d_sw.cpp index dcecac1c73..c61b9cbd4e 100644 --- a/servers/physics_3d/collision_solver_3d_sw.cpp +++ b/servers/physics_3d/collision_solver_3d_sw.cpp @@ -89,6 +89,39 @@ 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; @@ -318,6 +351,9 @@ 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; } @@ -328,6 +364,17 @@ 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. diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp index fbb374bd74..a1d776922e 100644 --- a/servers/physics_3d/physics_server_3d_sw.cpp +++ b/servers/physics_3d/physics_server_3d_sw.cpp @@ -48,6 +48,12 @@ 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); diff --git a/servers/physics_3d/physics_server_3d_sw.h b/servers/physics_3d/physics_server_3d_sw.h index 6e59a77e89..f2322a0e76 100644 --- a/servers/physics_3d/physics_server_3d_sw.h +++ b/servers/physics_3d/physics_server_3d_sw.h @@ -83,6 +83,7 @@ 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; diff --git a/servers/physics_3d/physics_server_3d_wrap_mt.h b/servers/physics_3d/physics_server_3d_wrap_mt.h index 75174628bf..d807e73731 100644 --- a/servers/physics_3d/physics_server_3d_wrap_mt.h +++ b/servers/physics_3d/physics_server_3d_wrap_mt.h @@ -79,6 +79,7 @@ public: //FUNC1RID(shape,ShapeType); todo fix FUNCRID(plane_shape) + FUNCRID(ray_shape) FUNCRID(sphere_shape) FUNCRID(box_shape) FUNCRID(capsule_shape) diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp index 664308ed7b..42a0fb32b2 100644 --- a/servers/physics_3d/shape_3d_sw.cpp +++ b/servers/physics_3d/shape_3d_sw.cpp @@ -164,6 +164,91 @@ 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 { diff --git a/servers/physics_3d/shape_3d_sw.h b/servers/physics_3d/shape_3d_sw.h index ca58900111..9f18b83f07 100644 --- a/servers/physics_3d/shape_3d_sw.h +++ b/servers/physics_3d/shape_3d_sw.h @@ -134,6 +134,34 @@ 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; diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index c96f85446c..42b3daab28 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -514,6 +514,7 @@ bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, c void PhysicsServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("world_margin_shape_create"), &PhysicsServer2D::world_margin_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); @@ -675,6 +676,7 @@ void PhysicsServer2D::_bind_methods() { BIND_ENUM_CONSTANT(SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH); BIND_ENUM_CONSTANT(SHAPE_WORLD_MARGIN); + BIND_ENUM_CONSTANT(SHAPE_RAY); BIND_ENUM_CONSTANT(SHAPE_SEGMENT); BIND_ENUM_CONSTANT(SHAPE_CIRCLE); BIND_ENUM_CONSTANT(SHAPE_RECTANGLE); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 4c559dd7bd..b6fb17b1c9 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -220,6 +220,7 @@ public: enum ShapeType { SHAPE_WORLD_MARGIN, ///< plane:"plane" + SHAPE_RAY, ///< float:"length" SHAPE_SEGMENT, ///< float:"length" SHAPE_CIRCLE, ///< float:"radius" SHAPE_RECTANGLE, ///< vec3:"extents" @@ -230,6 +231,7 @@ public: }; virtual RID world_margin_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; diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 1f46a96b27..582acaefe8 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -463,6 +463,8 @@ 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: @@ -488,6 +490,7 @@ 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); @@ -748,6 +751,7 @@ 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); diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 5201e76498..b8cbceacc7 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -222,6 +222,7 @@ 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 @@ -236,6 +237,7 @@ 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; |