mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 04:06:14 +00:00
Add raycast options to hit when starting inside / hit back faces
Makes the results consistent for all shape types with options to set the desired behavior.
This commit is contained in:
parent
3668312e78
commit
c3ae7ddedd
@ -64,7 +64,7 @@
|
||||
Intersects a ray in a given space. Ray position and other parameters are defined through [PhysicsRayQueryParameters2D]. The returned object is a dictionary with the following fields:
|
||||
[code]collider[/code]: The colliding object.
|
||||
[code]collider_id[/code]: The colliding object's ID.
|
||||
[code]normal[/code]: The object's surface normal at the intersection point.
|
||||
[code]normal[/code]: The object's surface normal at the intersection point, or [code]Vector2(0, 0)[/code] if the ray starts inside the shape and [member PhysicsRayQueryParameters2D.hit_from_inside] is [code]true[/code].
|
||||
[code]position[/code]: The intersection point.
|
||||
[code]rid[/code]: The intersecting object's [RID].
|
||||
[code]shape[/code]: The shape index of the colliding shape.
|
||||
|
@ -65,7 +65,7 @@
|
||||
Intersects a ray in a given space. Ray position and other parameters are defined through [PhysicsRayQueryParameters3D]. The returned object is a dictionary with the following fields:
|
||||
[code]collider[/code]: The colliding object.
|
||||
[code]collider_id[/code]: The colliding object's ID.
|
||||
[code]normal[/code]: The object's surface normal at the intersection point.
|
||||
[code]normal[/code]: The object's surface normal at the intersection point, or [code]Vector3(0, 0, 0)[/code] if the ray starts inside the shape and [member PhysicsRayQueryParameters3D.hit_from_inside] is [code]true[/code].
|
||||
[code]position[/code]: The intersection point.
|
||||
[code]rid[/code]: The intersecting object's [RID].
|
||||
[code]shape[/code]: The shape index of the colliding shape.
|
||||
|
@ -24,6 +24,9 @@
|
||||
<member name="from" type="Vector2" setter="set_from" getter="get_from" default="Vector2(0, 0)">
|
||||
The starting point of the ray being queried for, in global coordinates.
|
||||
</member>
|
||||
<member name="hit_from_inside" type="bool" setter="set_hit_from_inside" getter="is_hit_from_inside_enabled" default="false">
|
||||
If [code]true[/code], the query will detect a hit when starting inside shapes. In this case the collision normal will be [code]Vector2(0, 0)[/code]. Does not affect concave polygon shapes.
|
||||
</member>
|
||||
<member name="to" type="Vector2" setter="set_to" getter="get_to" default="Vector2(0, 0)">
|
||||
The ending point of the ray being queried for, in global coordinates.
|
||||
</member>
|
||||
|
@ -24,6 +24,12 @@
|
||||
<member name="from" type="Vector3" setter="set_from" getter="get_from" default="Vector3(0, 0, 0)">
|
||||
The starting point of the ray being queried for, in global coordinates.
|
||||
</member>
|
||||
<member name="hit_back_faces" type="bool" setter="set_hit_back_faces" getter="is_hit_back_faces_enabled" default="true">
|
||||
If [code]true[/code], the query will hit back faces with concave polygon shapes with back face enabled or heightmap shapes.
|
||||
</member>
|
||||
<member name="hit_from_inside" type="bool" setter="set_hit_from_inside" getter="is_hit_from_inside_enabled" default="false">
|
||||
If [code]true[/code], the query will detect a hit when starting inside shapes. In this case the collision normal will be [code]Vector3(0, 0, 0)[/code]. Does not affect concave polygon shapes or heightmap shapes.
|
||||
</member>
|
||||
<member name="to" type="Vector3" setter="set_to" getter="get_to" default="Vector3(0, 0, 0)">
|
||||
The ending point of the ray being queried for, in global coordinates.
|
||||
</member>
|
||||
|
@ -63,7 +63,7 @@
|
||||
<method name="get_collision_normal" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<description>
|
||||
Returns the normal of the intersecting object's shape at the collision point.
|
||||
Returns the normal of the intersecting object's shape at the collision point, or [code]Vector2(0, 0)[/code] if the ray starts inside the shape and [member hit_from_inside] is [code]true[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_point" qualifiers="const">
|
||||
@ -118,6 +118,9 @@
|
||||
<member name="exclude_parent" type="bool" setter="set_exclude_parent_body" getter="get_exclude_parent_body" default="true">
|
||||
If [code]true[/code], the parent node will be excluded from collision detection.
|
||||
</member>
|
||||
<member name="hit_from_inside" type="bool" setter="set_hit_from_inside" getter="is_hit_from_inside_enabled" default="false">
|
||||
If [code]true[/code], the ray will detect a hit when starting inside shapes. In this case the collision normal will be [code]Vector2(0, 0)[/code]. Does not affect concave polygon shapes.
|
||||
</member>
|
||||
<member name="target_position" type="Vector2" setter="set_target_position" getter="get_target_position" default="Vector2(0, 50)">
|
||||
The ray's destination point, relative to the RayCast's [code]position[/code].
|
||||
</member>
|
||||
|
@ -65,7 +65,7 @@
|
||||
<method name="get_collision_normal" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<description>
|
||||
Returns the normal of the intersecting object's shape at the collision point.
|
||||
Returns the normal of the intersecting object's shape at the collision point, or [code]Vector3(0, 0, 0)[/code] if the ray starts inside the shape and [member hit_from_inside] is [code]true[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_point" qualifiers="const">
|
||||
@ -127,6 +127,9 @@
|
||||
<member name="exclude_parent" type="bool" setter="set_exclude_parent_body" getter="get_exclude_parent_body" default="true">
|
||||
If [code]true[/code], collisions will be ignored for this RayCast3D's immediate parent.
|
||||
</member>
|
||||
<member name="hit_from_inside" type="bool" setter="set_hit_from_inside" getter="is_hit_from_inside_enabled" default="false">
|
||||
If [code]true[/code], the ray will detect a hit when starting inside shapes. In this case the collision normal will be [code]Vector3(0, 0, 0)[/code]. Does not affect shapes with no volume like concave polygon or heightmap.
|
||||
</member>
|
||||
<member name="target_position" type="Vector3" setter="set_target_position" getter="get_target_position" default="Vector3(0, -1, 0)">
|
||||
The ray's destination point, relative to the RayCast's [code]position[/code].
|
||||
</member>
|
||||
|
@ -200,6 +200,7 @@ void RayCast2D::_update_raycast_state() {
|
||||
ray_params.collision_mask = collision_mask;
|
||||
ray_params.collide_with_bodies = collide_with_bodies;
|
||||
ray_params.collide_with_areas = collide_with_areas;
|
||||
ray_params.hit_from_inside = hit_from_inside;
|
||||
|
||||
if (dss->intersect_ray(ray_params, rr)) {
|
||||
collided = true;
|
||||
@ -290,22 +291,30 @@ void RayCast2D::clear_exceptions() {
|
||||
exclude.clear();
|
||||
}
|
||||
|
||||
void RayCast2D::set_collide_with_areas(bool p_clip) {
|
||||
collide_with_areas = p_clip;
|
||||
void RayCast2D::set_collide_with_areas(bool p_enabled) {
|
||||
collide_with_areas = p_enabled;
|
||||
}
|
||||
|
||||
bool RayCast2D::is_collide_with_areas_enabled() const {
|
||||
return collide_with_areas;
|
||||
}
|
||||
|
||||
void RayCast2D::set_collide_with_bodies(bool p_clip) {
|
||||
collide_with_bodies = p_clip;
|
||||
void RayCast2D::set_collide_with_bodies(bool p_enabled) {
|
||||
collide_with_bodies = p_enabled;
|
||||
}
|
||||
|
||||
bool RayCast2D::is_collide_with_bodies_enabled() const {
|
||||
return collide_with_bodies;
|
||||
}
|
||||
|
||||
void RayCast2D::set_hit_from_inside(bool p_enabled) {
|
||||
hit_from_inside = p_enabled;
|
||||
}
|
||||
|
||||
bool RayCast2D::is_hit_from_inside_enabled() const {
|
||||
return hit_from_inside;
|
||||
}
|
||||
|
||||
void RayCast2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast2D::set_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_enabled"), &RayCast2D::is_enabled);
|
||||
@ -344,10 +353,14 @@ void RayCast2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &RayCast2D::set_collide_with_bodies);
|
||||
ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &RayCast2D::is_collide_with_bodies_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_hit_from_inside", "enable"), &RayCast2D::set_hit_from_inside);
|
||||
ClassDB::bind_method(D_METHOD("is_hit_from_inside_enabled"), &RayCast2D::is_hit_from_inside_enabled);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position"), "set_target_position", "get_target_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hit_from_inside"), "set_hit_from_inside", "is_hit_from_inside_enabled");
|
||||
|
||||
ADD_GROUP("Collide With", "collide_with");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_areas", "is_collide_with_areas_enabled");
|
||||
|
@ -51,6 +51,8 @@ class RayCast2D : public Node2D {
|
||||
bool collide_with_areas = false;
|
||||
bool collide_with_bodies = true;
|
||||
|
||||
bool hit_from_inside = false;
|
||||
|
||||
void _draw_debug_shape();
|
||||
|
||||
protected:
|
||||
@ -65,6 +67,9 @@ public:
|
||||
void set_collide_with_bodies(bool p_clip);
|
||||
bool is_collide_with_bodies_enabled() const;
|
||||
|
||||
void set_hit_from_inside(bool p_enable);
|
||||
bool is_hit_from_inside_enabled() const;
|
||||
|
||||
void set_enabled(bool p_enabled);
|
||||
bool is_enabled() const;
|
||||
|
||||
|
@ -219,6 +219,7 @@ void RayCast3D::_update_raycast_state() {
|
||||
ray_params.collision_mask = collision_mask;
|
||||
ray_params.collide_with_bodies = collide_with_bodies;
|
||||
ray_params.collide_with_areas = collide_with_areas;
|
||||
ray_params.hit_from_inside = hit_from_inside;
|
||||
|
||||
PhysicsDirectSpaceState3D::RayResult rr;
|
||||
if (dss->intersect_ray(ray_params, rr)) {
|
||||
@ -268,22 +269,30 @@ void RayCast3D::clear_exceptions() {
|
||||
exclude.clear();
|
||||
}
|
||||
|
||||
void RayCast3D::set_collide_with_areas(bool p_clip) {
|
||||
collide_with_areas = p_clip;
|
||||
void RayCast3D::set_collide_with_areas(bool p_enabled) {
|
||||
collide_with_areas = p_enabled;
|
||||
}
|
||||
|
||||
bool RayCast3D::is_collide_with_areas_enabled() const {
|
||||
return collide_with_areas;
|
||||
}
|
||||
|
||||
void RayCast3D::set_collide_with_bodies(bool p_clip) {
|
||||
collide_with_bodies = p_clip;
|
||||
void RayCast3D::set_collide_with_bodies(bool p_enabled) {
|
||||
collide_with_bodies = p_enabled;
|
||||
}
|
||||
|
||||
bool RayCast3D::is_collide_with_bodies_enabled() const {
|
||||
return collide_with_bodies;
|
||||
}
|
||||
|
||||
void RayCast3D::set_hit_from_inside(bool p_enabled) {
|
||||
hit_from_inside = p_enabled;
|
||||
}
|
||||
|
||||
bool RayCast3D::is_hit_from_inside_enabled() const {
|
||||
return hit_from_inside;
|
||||
}
|
||||
|
||||
void RayCast3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast3D::set_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_enabled"), &RayCast3D::is_enabled);
|
||||
@ -322,6 +331,9 @@ void RayCast3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &RayCast3D::set_collide_with_bodies);
|
||||
ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &RayCast3D::is_collide_with_bodies_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_hit_from_inside", "enable"), &RayCast3D::set_hit_from_inside);
|
||||
ClassDB::bind_method(D_METHOD("is_hit_from_inside_enabled"), &RayCast3D::is_hit_from_inside_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_debug_shape_custom_color", "debug_shape_custom_color"), &RayCast3D::set_debug_shape_custom_color);
|
||||
ClassDB::bind_method(D_METHOD("get_debug_shape_custom_color"), &RayCast3D::get_debug_shape_custom_color);
|
||||
|
||||
@ -332,6 +344,7 @@ void RayCast3D::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position"), "set_target_position", "get_target_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hit_from_inside"), "set_hit_from_inside", "is_hit_from_inside_enabled");
|
||||
|
||||
ADD_GROUP("Collide With", "collide_with");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_areas", "is_collide_with_areas_enabled");
|
||||
|
@ -65,18 +65,23 @@ class RayCast3D : public Node3D {
|
||||
bool collide_with_areas = false;
|
||||
bool collide_with_bodies = true;
|
||||
|
||||
bool hit_from_inside = false;
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
void _update_raycast_state();
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_collide_with_areas(bool p_clip);
|
||||
void set_collide_with_areas(bool p_enabled);
|
||||
bool is_collide_with_areas_enabled() const;
|
||||
|
||||
void set_collide_with_bodies(bool p_clip);
|
||||
void set_collide_with_bodies(bool p_enabled);
|
||||
bool is_collide_with_bodies_enabled() const;
|
||||
|
||||
void set_hit_from_inside(bool p_enabled);
|
||||
bool is_hit_from_inside_enabled() const;
|
||||
|
||||
void set_enabled(bool p_enabled);
|
||||
bool is_enabled() const;
|
||||
|
||||
|
@ -153,6 +153,22 @@ bool GodotPhysicsDirectSpaceState2D::intersect_ray(const RayParameters &p_parame
|
||||
|
||||
Vector2 shape_point, shape_normal;
|
||||
|
||||
if (shape->contains_point(local_from)) {
|
||||
if (p_parameters.hit_from_inside) {
|
||||
// Hit shape at starting point.
|
||||
min_d = 0;
|
||||
res_point = local_from;
|
||||
res_normal = Vector2();
|
||||
res_shape = shape_idx;
|
||||
res_obj = col_obj;
|
||||
collided = true;
|
||||
break;
|
||||
} else {
|
||||
// Ignore shape when starting inside.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (shape->intersect_segment(local_from, local_to, shape_point, shape_normal)) {
|
||||
Transform2D xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
|
||||
shape_point = xform.xform(shape_point);
|
||||
|
@ -191,7 +191,7 @@ bool GodotBodyPair3D::_test_ccd(real_t p_step, GodotBody3D *p_A, int p_shape_A,
|
||||
Vector3 local_to = from_inv.xform(to);
|
||||
|
||||
Vector3 rpos, rnorm;
|
||||
if (!p_B->get_shape(p_shape_B)->intersect_segment(local_from, local_to, rpos, rnorm)) {
|
||||
if (!p_B->get_shape(p_shape_B)->intersect_segment(local_from, local_to, rpos, rnorm, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ bool GodotCollisionSolver3D::solve_separation_ray(const GodotShape3D *p_shape_A,
|
||||
to = ai.xform(to);
|
||||
|
||||
Vector3 p, n;
|
||||
if (!p_shape_B->intersect_segment(from, to, p, n)) {
|
||||
if (!p_shape_B->intersect_segment(from, to, p, n, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ Vector3 GodotWorldBoundaryShape3D::get_support(const Vector3 &p_normal) const {
|
||||
return p_normal * 1e15;
|
||||
}
|
||||
|
||||
bool GodotWorldBoundaryShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
|
||||
bool GodotWorldBoundaryShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const {
|
||||
bool inters = plane.intersects_segment(p_begin, p_end, &r_result);
|
||||
if (inters) {
|
||||
r_normal = plane.normal;
|
||||
@ -200,7 +200,7 @@ void GodotSeparationRayShape3D::get_supports(const Vector3 &p_normal, int p_max,
|
||||
}
|
||||
}
|
||||
|
||||
bool GodotSeparationRayShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
|
||||
bool GodotSeparationRayShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const {
|
||||
return false; //simply not possible
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ void GodotSphereShape3D::get_supports(const Vector3 &p_normal, int p_max, Vector
|
||||
r_type = FEATURE_POINT;
|
||||
}
|
||||
|
||||
bool GodotSphereShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
|
||||
bool GodotSphereShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const {
|
||||
return Geometry3D::segment_intersects_sphere(p_begin, p_end, Vector3(), radius, &r_result, &r_normal);
|
||||
}
|
||||
|
||||
@ -410,7 +410,7 @@ void GodotBoxShape3D::get_supports(const Vector3 &p_normal, int p_max, Vector3 *
|
||||
r_supports[0] = point;
|
||||
}
|
||||
|
||||
bool GodotBoxShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
|
||||
bool GodotBoxShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const {
|
||||
AABB aabb(-half_extents, half_extents * 2.0);
|
||||
|
||||
return aabb.intersects_segment(p_begin, p_end, &r_result, &r_normal);
|
||||
@ -546,7 +546,7 @@ void GodotCapsuleShape3D::get_supports(const Vector3 &p_normal, int p_max, Vecto
|
||||
}
|
||||
}
|
||||
|
||||
bool GodotCapsuleShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
|
||||
bool GodotCapsuleShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const {
|
||||
Vector3 norm = (p_end - p_begin).normalized();
|
||||
real_t min_d = 1e20;
|
||||
|
||||
@ -761,7 +761,7 @@ void GodotCylinderShape3D::get_supports(const Vector3 &p_normal, int p_max, Vect
|
||||
}
|
||||
}
|
||||
|
||||
bool GodotCylinderShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
|
||||
bool GodotCylinderShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const {
|
||||
return Geometry3D::segment_intersects_cylinder(p_begin, p_end, height, radius, &r_result, &r_normal, 1);
|
||||
}
|
||||
|
||||
@ -954,7 +954,7 @@ void GodotConvexPolygonShape3D::get_supports(const Vector3 &p_normal, int p_max,
|
||||
r_type = FEATURE_POINT;
|
||||
}
|
||||
|
||||
bool GodotConvexPolygonShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
|
||||
bool GodotConvexPolygonShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const {
|
||||
const Geometry3D::MeshData::Face *faces = mesh.faces.ptr();
|
||||
int fc = mesh.faces.size();
|
||||
|
||||
@ -1188,12 +1188,12 @@ void GodotFaceShape3D::get_supports(const Vector3 &p_normal, int p_max, Vector3
|
||||
r_supports[0] = vertex[vert_support_idx];
|
||||
}
|
||||
|
||||
bool GodotFaceShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
|
||||
bool GodotFaceShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const {
|
||||
bool c = Geometry3D::segment_intersects_triangle(p_begin, p_end, vertex[0], vertex[1], vertex[2], &r_result);
|
||||
if (c) {
|
||||
r_normal = Plane(vertex[0], vertex[1], vertex[2]).normal;
|
||||
if (r_normal.dot(p_end - p_begin) > 0) {
|
||||
if (backface_collision) {
|
||||
if (backface_collision && p_hit_back_faces) {
|
||||
r_normal = -r_normal;
|
||||
} else {
|
||||
c = false;
|
||||
@ -1304,7 +1304,7 @@ void GodotConcavePolygonShape3D::_cull_segment(int p_idx, _SegmentCullParams *p_
|
||||
|
||||
Vector3 res;
|
||||
Vector3 normal;
|
||||
if (face->intersect_segment(p_params->from, p_params->to, res, normal)) {
|
||||
if (face->intersect_segment(p_params->from, p_params->to, res, normal, true)) {
|
||||
real_t d = p_params->dir.dot(res) - p_params->dir.dot(p_params->from);
|
||||
if ((d > 0) && (d < p_params->min_d)) {
|
||||
p_params->min_d = d;
|
||||
@ -1323,7 +1323,7 @@ void GodotConcavePolygonShape3D::_cull_segment(int p_idx, _SegmentCullParams *p_
|
||||
}
|
||||
}
|
||||
|
||||
bool GodotConcavePolygonShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
|
||||
bool GodotConcavePolygonShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const {
|
||||
if (faces.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
@ -1334,7 +1334,7 @@ bool GodotConcavePolygonShape3D::intersect_segment(const Vector3 &p_begin, const
|
||||
const BVH *br = bvh.ptr();
|
||||
|
||||
GodotFaceShape3D face;
|
||||
face.backface_collision = backface_collision;
|
||||
face.backface_collision = backface_collision && p_hit_back_faces;
|
||||
|
||||
_SegmentCullParams params;
|
||||
params.from = p_begin;
|
||||
@ -1675,7 +1675,7 @@ struct _HeightmapGridCullState {
|
||||
_FORCE_INLINE_ bool _heightmap_face_cull_segment(_HeightmapSegmentCullParams &p_params) {
|
||||
Vector3 res;
|
||||
Vector3 normal;
|
||||
if (p_params.face->intersect_segment(p_params.from, p_params.to, res, normal)) {
|
||||
if (p_params.face->intersect_segment(p_params.from, p_params.to, res, normal, true)) {
|
||||
p_params.result = res;
|
||||
p_params.normal = normal;
|
||||
return true;
|
||||
@ -1881,7 +1881,7 @@ bool GodotHeightMapShape3D::_intersect_grid_segment(ProcessFunction &p_process,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GodotHeightMapShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const {
|
||||
bool GodotHeightMapShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, bool p_hit_back_faces) const {
|
||||
if (heights.is_empty()) {
|
||||
return false;
|
||||
}
|
||||
@ -1899,7 +1899,7 @@ bool GodotHeightMapShape3D::intersect_segment(const Vector3 &p_begin, const Vect
|
||||
// Simple case for rays that don't traverse the grid horizontally.
|
||||
// Just perform a test on the given cell.
|
||||
GodotFaceShape3D face;
|
||||
face.backface_collision = false;
|
||||
face.backface_collision = p_hit_back_faces;
|
||||
|
||||
_HeightmapSegmentCullParams params;
|
||||
params.from = p_begin;
|
||||
|
@ -80,7 +80,7 @@ public:
|
||||
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 = 0;
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const = 0;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const = 0;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, bool p_hit_back_faces) const = 0;
|
||||
virtual bool intersect_point(const Vector3 &p_point) const = 0;
|
||||
virtual Vector3 get_moment_of_inertia(real_t p_mass) const = 0;
|
||||
|
||||
@ -126,7 +126,7 @@ public:
|
||||
virtual Vector3 get_support(const Vector3 &p_normal) const override;
|
||||
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override { r_amount = 0; }
|
||||
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const override;
|
||||
virtual bool intersect_point(const Vector3 &p_point) const override;
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
|
||||
virtual Vector3 get_moment_of_inertia(real_t p_mass) const override;
|
||||
@ -153,7 +153,7 @@ public:
|
||||
virtual Vector3 get_support(const Vector3 &p_normal) const override;
|
||||
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
|
||||
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const override;
|
||||
virtual bool intersect_point(const Vector3 &p_point) const override;
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
|
||||
|
||||
@ -180,7 +180,7 @@ public:
|
||||
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
|
||||
virtual Vector3 get_support(const Vector3 &p_normal) const override;
|
||||
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const override;
|
||||
virtual bool intersect_point(const Vector3 &p_point) const override;
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
|
||||
|
||||
@ -205,7 +205,7 @@ public:
|
||||
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
|
||||
virtual Vector3 get_support(const Vector3 &p_normal) const override;
|
||||
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const override;
|
||||
virtual bool intersect_point(const Vector3 &p_point) const override;
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
|
||||
|
||||
@ -234,7 +234,7 @@ public:
|
||||
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
|
||||
virtual Vector3 get_support(const Vector3 &p_normal) const override;
|
||||
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const override;
|
||||
virtual bool intersect_point(const Vector3 &p_point) const override;
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
|
||||
|
||||
@ -263,7 +263,7 @@ public:
|
||||
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
|
||||
virtual Vector3 get_support(const Vector3 &p_normal) const override;
|
||||
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const override;
|
||||
virtual bool intersect_point(const Vector3 &p_point) const override;
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
|
||||
|
||||
@ -288,7 +288,7 @@ public:
|
||||
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
|
||||
virtual Vector3 get_support(const Vector3 &p_normal) const override;
|
||||
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const override;
|
||||
virtual bool intersect_point(const Vector3 &p_point) const override;
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
|
||||
|
||||
@ -366,7 +366,7 @@ public:
|
||||
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
|
||||
virtual Vector3 get_support(const Vector3 &p_normal) const override;
|
||||
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const override;
|
||||
virtual bool intersect_point(const Vector3 &p_point) const override;
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
|
||||
|
||||
@ -429,7 +429,7 @@ public:
|
||||
|
||||
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
|
||||
virtual Vector3 get_support(const Vector3 &p_normal) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, bool p_hit_back_faces) const override;
|
||||
virtual bool intersect_point(const Vector3 &p_point) const override;
|
||||
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
|
||||
@ -456,7 +456,7 @@ struct GodotFaceShape3D : public GodotShape3D {
|
||||
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
|
||||
virtual Vector3 get_support(const Vector3 &p_normal) const override;
|
||||
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const override;
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const override;
|
||||
virtual bool intersect_point(const Vector3 &p_point) const override;
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
|
||||
|
||||
@ -495,7 +495,7 @@ struct GodotMotionShape3D : public GodotShape3D {
|
||||
}
|
||||
|
||||
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override { r_amount = 0; }
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const override { return false; }
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const override { return false; }
|
||||
virtual bool intersect_point(const Vector3 &p_point) const override { return false; }
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override { return p_point; }
|
||||
|
||||
|
@ -1300,7 +1300,7 @@ struct _SoftBodyIntersectSegmentInfo {
|
||||
}
|
||||
};
|
||||
|
||||
bool GodotSoftBodyShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
|
||||
bool GodotSoftBodyShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const {
|
||||
_SoftBodyIntersectSegmentInfo query_info;
|
||||
query_info.soft_body = soft_body;
|
||||
query_info.from = p_begin;
|
||||
|
@ -257,18 +257,18 @@ class GodotSoftBodyShape3D : public GodotShape3D {
|
||||
public:
|
||||
GodotSoftBody3D *get_soft_body() const { return soft_body; }
|
||||
|
||||
virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_SOFT_BODY; }
|
||||
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { r_min = r_max = 0.0; }
|
||||
virtual Vector3 get_support(const Vector3 &p_normal) const { return Vector3(); }
|
||||
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { r_amount = 0; }
|
||||
virtual PhysicsServer3D::ShapeType get_type() const override { return PhysicsServer3D::SHAPE_SOFT_BODY; }
|
||||
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override { r_min = r_max = 0.0; }
|
||||
virtual Vector3 get_support(const Vector3 &p_normal) const override { return Vector3(); }
|
||||
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override { r_amount = 0; }
|
||||
|
||||
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 { return Vector3(); }
|
||||
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, bool p_hit_back_faces) const override;
|
||||
virtual bool intersect_point(const Vector3 &p_point) const override;
|
||||
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
|
||||
virtual Vector3 get_moment_of_inertia(real_t p_mass) const override { return Vector3(); }
|
||||
|
||||
virtual void set_data(const Variant &p_data) {}
|
||||
virtual Variant get_data() const { return Variant(); }
|
||||
virtual void set_data(const Variant &p_data) override {}
|
||||
virtual Variant get_data() const override { return Variant(); }
|
||||
|
||||
void update_bounds();
|
||||
|
||||
|
@ -148,7 +148,23 @@ bool GodotPhysicsDirectSpaceState3D::intersect_ray(const RayParameters &p_parame
|
||||
|
||||
Vector3 shape_point, shape_normal;
|
||||
|
||||
if (shape->intersect_segment(local_from, local_to, shape_point, shape_normal)) {
|
||||
if (shape->intersect_point(local_from)) {
|
||||
if (p_parameters.hit_from_inside) {
|
||||
// Hit shape at starting point.
|
||||
min_d = 0;
|
||||
res_point = local_from;
|
||||
res_normal = Vector3();
|
||||
res_shape = shape_idx;
|
||||
res_obj = col_obj;
|
||||
collided = true;
|
||||
break;
|
||||
} else {
|
||||
// Ignore shape when starting inside.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (shape->intersect_segment(local_from, local_to, shape_point, shape_normal, p_parameters.hit_back_faces)) {
|
||||
Transform3D xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
|
||||
shape_point = xform.xform(shape_point);
|
||||
|
||||
|
@ -172,12 +172,16 @@ void PhysicsRayQueryParameters2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &PhysicsRayQueryParameters2D::set_collide_with_areas);
|
||||
ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &PhysicsRayQueryParameters2D::is_collide_with_areas_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_hit_from_inside", "enable"), &PhysicsRayQueryParameters2D::set_hit_from_inside);
|
||||
ClassDB::bind_method(D_METHOD("is_hit_from_inside_enabled"), &PhysicsRayQueryParameters2D::is_hit_from_inside_enabled);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "from"), "set_from", "get_from");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "to"), "set_to", "get_to");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_exclude", "get_exclude");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "is_collide_with_bodies_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas"), "set_collide_with_areas", "is_collide_with_areas_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hit_from_inside"), "set_hit_from_inside", "is_hit_from_inside_enabled");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
@ -121,6 +121,8 @@ public:
|
||||
|
||||
bool collide_with_bodies = true;
|
||||
bool collide_with_areas = false;
|
||||
|
||||
bool hit_from_inside = false;
|
||||
};
|
||||
|
||||
struct RayResult {
|
||||
@ -604,6 +606,9 @@ public:
|
||||
void set_collide_with_areas(bool p_enable) { parameters.collide_with_areas = p_enable; }
|
||||
bool is_collide_with_areas_enabled() const { return parameters.collide_with_areas; }
|
||||
|
||||
void set_hit_from_inside(bool p_enable) { parameters.hit_from_inside = p_enable; }
|
||||
bool is_hit_from_inside_enabled() const { return parameters.hit_from_inside; }
|
||||
|
||||
void set_exclude(const Vector<RID> &p_exclude);
|
||||
Vector<RID> get_exclude() const;
|
||||
};
|
||||
|
@ -175,12 +175,20 @@ void PhysicsRayQueryParameters3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &PhysicsRayQueryParameters3D::set_collide_with_areas);
|
||||
ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &PhysicsRayQueryParameters3D::is_collide_with_areas_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_hit_from_inside", "enable"), &PhysicsRayQueryParameters3D::set_hit_from_inside);
|
||||
ClassDB::bind_method(D_METHOD("is_hit_from_inside_enabled"), &PhysicsRayQueryParameters3D::is_hit_from_inside_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_hit_back_faces", "enable"), &PhysicsRayQueryParameters3D::set_hit_back_faces);
|
||||
ClassDB::bind_method(D_METHOD("is_hit_back_faces_enabled"), &PhysicsRayQueryParameters3D::is_hit_back_faces_enabled);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "from"), "set_from", "get_from");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "to"), "set_to", "get_to");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_exclude", "get_exclude");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "is_collide_with_bodies_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas"), "set_collide_with_areas", "is_collide_with_areas_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hit_from_inside"), "set_hit_from_inside", "is_hit_from_inside_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hit_back_faces"), "set_hit_back_faces", "is_hit_back_faces_enabled");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
@ -125,6 +125,9 @@ public:
|
||||
bool collide_with_bodies = true;
|
||||
bool collide_with_areas = false;
|
||||
|
||||
bool hit_from_inside = false;
|
||||
bool hit_back_faces = true;
|
||||
|
||||
bool pick_ray = false;
|
||||
};
|
||||
|
||||
@ -805,6 +808,12 @@ public:
|
||||
void set_collide_with_areas(bool p_enable) { parameters.collide_with_areas = p_enable; }
|
||||
bool is_collide_with_areas_enabled() const { return parameters.collide_with_areas; }
|
||||
|
||||
void set_hit_from_inside(bool p_enable) { parameters.hit_from_inside = p_enable; }
|
||||
bool is_hit_from_inside_enabled() const { return parameters.hit_from_inside; }
|
||||
|
||||
void set_hit_back_faces(bool p_enable) { parameters.hit_back_faces = p_enable; }
|
||||
bool is_hit_back_faces_enabled() const { return parameters.hit_back_faces; }
|
||||
|
||||
void set_exclude(const Vector<RID> &p_exclude);
|
||||
Vector<RID> get_exclude() const;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user