summaryrefslogtreecommitdiff
path: root/servers/physics_3d
diff options
context:
space:
mode:
authorPouleyKetchoupp <pouleyketchoup@gmail.com>2021-08-17 10:15:11 -0700
committerPouleyKetchoupp <pouleyketchoup@gmail.com>2021-08-24 16:03:05 -0700
commit45c7af98625a1751f2a97aaf2a4a17d808b61092 (patch)
treec380f56cf612c6edff37bf0a38b04761789bb951 /servers/physics_3d
parentc89a5fb8be579936ea0b56bde520133cfa7664ae (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/physics_3d')
-rw-r--r--servers/physics_3d/collision_solver_3d_sat.cpp6
-rw-r--r--servers/physics_3d/collision_solver_3d_sw.cpp47
-rw-r--r--servers/physics_3d/physics_server_3d_sw.cpp6
-rw-r--r--servers/physics_3d/physics_server_3d_sw.h1
-rw-r--r--servers/physics_3d/physics_server_3d_wrap_mt.h1
-rw-r--r--servers/physics_3d/shape_3d_sw.cpp85
-rw-r--r--servers/physics_3d/shape_3d_sw.h28
7 files changed, 172 insertions, 2 deletions
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;