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.
This commit is contained in:
parent
c89a5fb8be
commit
45c7af9862
33 changed files with 842 additions and 26 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue