diff --git a/doc/classes/PhysicsDirectSpaceState3D.xml b/doc/classes/PhysicsDirectSpaceState3D.xml index b13abb04da09..2921f760dd4a 100644 --- a/doc/classes/PhysicsDirectSpaceState3D.xml +++ b/doc/classes/PhysicsDirectSpaceState3D.xml @@ -69,12 +69,21 @@ [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]face_index[/code]: The face index at the intersection point. - [b]Note:[/b] Returns a valid number only if the intersected shape is a [ConcavePolygonShape3D]. Otherwise, [code]-1[/code] is returned. + [b]Note:[/b] This value is only valid if the intersected shape is a [ConcavePolygonShape3D]. Otherwise, [code]-1[/code] is returned. [code]rid[/code]: The intersecting object's [RID]. [code]shape[/code]: The shape index of the colliding shape. If the ray did not intersect anything, then an empty dictionary is returned instead. + + + + + + Intersects a ray in a given space. Ray position and other parameters are defined through [PhysicsRayQueryParameters3D]. If an intersection occurs, this method returns true and writes the intersection information into the [PhysicsRayQueryResult3D] object passed in [code skip-lint]result[/code]. + If the ray did not intersect anything, false is returned instead. + + diff --git a/doc/classes/PhysicsRayQueryResult3D.xml b/doc/classes/PhysicsRayQueryResult3D.xml new file mode 100644 index 000000000000..87e97518ba95 --- /dev/null +++ b/doc/classes/PhysicsRayQueryResult3D.xml @@ -0,0 +1,36 @@ + + + + Stores the result of a ray intersection query. + + + This object contains the intersection information produced by [method PhysicsDirectSpaceState3D.intersect_ray_no_alloc]. + After calling [method PhysicsDirectSpaceState3D.intersect_ray_no_alloc], the fields of this object will be populated with the hit information if the ray intersects a shape. If no intersection occurred, the values remain unchanged from the previous state. + + + + + + The colliding object. + + + The colliding object's ID. + + + The face index at the intersection point. + [b]Note:[/b] This value is only valid if the intersected shape is a [ConcavePolygonShape3D]. Otherwise, [code]-1[/code] is returned. + + + 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]. + + + The intersection point. + + + The intersecting object's [RID]. + + + The shape index of the colliding shape. + + + diff --git a/servers/physics_3d/physics_server_3d.cpp b/servers/physics_3d/physics_server_3d.cpp index 67dee00fe2d9..b6627014cab9 100644 --- a/servers/physics_3d/physics_server_3d.cpp +++ b/servers/physics_3d/physics_server_3d.cpp @@ -238,6 +238,39 @@ void PhysicsRayQueryParameters3D::_bind_methods() { /////////////////////////////////////////////////////// +void PhysicsRayQueryResult3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_position", "position"), &PhysicsRayQueryResult3D::set_position); + ClassDB::bind_method(D_METHOD("get_position"), &PhysicsRayQueryResult3D::get_position); + + ClassDB::bind_method(D_METHOD("set_normal", "normal"), &PhysicsRayQueryResult3D::set_normal); + ClassDB::bind_method(D_METHOD("get_normal"), &PhysicsRayQueryResult3D::get_normal); + + ClassDB::bind_method(D_METHOD("set_rid", "rid"), &PhysicsRayQueryResult3D::set_rid); + ClassDB::bind_method(D_METHOD("get_rid"), &PhysicsRayQueryResult3D::get_rid); + + ClassDB::bind_method(D_METHOD("set_collider_id", "collider_id"), &PhysicsRayQueryResult3D::set_collider_id); + ClassDB::bind_method(D_METHOD("get_collider_id"), &PhysicsRayQueryResult3D::get_collider_id); + + ClassDB::bind_method(D_METHOD("set_collider", "collider"), &PhysicsRayQueryResult3D::set_collider); + ClassDB::bind_method(D_METHOD("get_collider"), &PhysicsRayQueryResult3D::get_collider); + + ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsRayQueryResult3D::set_shape); + ClassDB::bind_method(D_METHOD("get_shape"), &PhysicsRayQueryResult3D::get_shape); + + ClassDB::bind_method(D_METHOD("set_face_index", "face_index"), &PhysicsRayQueryResult3D::set_face_index); + ClassDB::bind_method(D_METHOD("get_face_index"), &PhysicsRayQueryResult3D::get_face_index); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position"), "set_position", "get_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "normal"), "set_normal", "get_normal"); + ADD_PROPERTY(PropertyInfo(Variant::RID, "rid"), "set_rid", "get_rid"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id"), "set_collider_id", "get_collider_id"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "set_collider", "get_collider"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "shape"), "set_shape", "get_shape"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "face_index"), "set_face_index", "get_face_index"); +} + +/////////////////////////////////////////////////////// + Ref PhysicsRayQueryParameters3D::create(Vector3 p_from, Vector3 p_to, uint32_t p_mask, const TypedArray &p_exclude) { Ref params; params.instantiate(); @@ -383,6 +416,13 @@ Dictionary PhysicsDirectSpaceState3D::_intersect_ray(RequiredParam rp_ray_query, RequiredParam rp_ray_result) { + EXTRACT_PARAM_OR_FAIL_V(p_ray_query, rp_ray_query, false); + EXTRACT_PARAM_OR_FAIL_V(p_ray_result, rp_ray_result, false); + + return intersect_ray(p_ray_query->get_parameters(), *p_ray_result->get_result_ptr()); +} + TypedArray PhysicsDirectSpaceState3D::_intersect_point(RequiredParam rp_point_query, int p_max_results) { EXTRACT_PARAM_OR_FAIL_V(p_point_query, rp_point_query, TypedArray()); @@ -488,6 +528,7 @@ PhysicsDirectSpaceState3D::PhysicsDirectSpaceState3D() { void PhysicsDirectSpaceState3D::_bind_methods() { ClassDB::bind_method(D_METHOD("intersect_point", "parameters", "max_results"), &PhysicsDirectSpaceState3D::_intersect_point, DEFVAL(32)); ClassDB::bind_method(D_METHOD("intersect_ray", "parameters"), &PhysicsDirectSpaceState3D::_intersect_ray); + ClassDB::bind_method(D_METHOD("intersect_ray_no_alloc", "parameters", "result"), &PhysicsDirectSpaceState3D::_intersect_ray_no_alloc); ClassDB::bind_method(D_METHOD("intersect_shape", "parameters", "max_results"), &PhysicsDirectSpaceState3D::_intersect_shape, DEFVAL(32)); ClassDB::bind_method(D_METHOD("cast_motion", "parameters"), &PhysicsDirectSpaceState3D::_cast_motion); ClassDB::bind_method(D_METHOD("collide_shape", "parameters", "max_results"), &PhysicsDirectSpaceState3D::_collide_shape, DEFVAL(32)); diff --git a/servers/physics_3d/physics_server_3d.h b/servers/physics_3d/physics_server_3d.h index 3738c1ee7061..ed8e21b9c08a 100644 --- a/servers/physics_3d/physics_server_3d.h +++ b/servers/physics_3d/physics_server_3d.h @@ -119,6 +119,7 @@ class PhysicsDirectBodyState3D : public Object { }; class PhysicsRayQueryParameters3D; +class PhysicsRayQueryResult3D; class PhysicsPointQueryParameters3D; class PhysicsShapeQueryParameters3D; @@ -127,6 +128,7 @@ class PhysicsDirectSpaceState3D : public Object { private: Dictionary _intersect_ray(RequiredParam rp_ray_query); + bool _intersect_ray_no_alloc(RequiredParam rp_ray_query, RequiredParam rp_ray_result); TypedArray _intersect_point(RequiredParam rp_point_query, int p_max_results = 32); TypedArray _intersect_shape(RequiredParam rp_shape_query, int p_max_results = 32); Vector _cast_motion(RequiredParam rp_shape_query); @@ -869,6 +871,39 @@ class PhysicsRayQueryParameters3D : public RefCounted { TypedArray get_exclude() const; }; +class PhysicsRayQueryResult3D : public RefCounted { + GDCLASS(PhysicsRayQueryResult3D, RefCounted); + + PhysicsDirectSpaceState3D::RayResult result; + +protected: + static void _bind_methods(); + +public: + PhysicsDirectSpaceState3D::RayResult *get_result_ptr() { return &result; } + + void set_position(const Vector3 &p_position) { result.position = p_position; } + const Vector3 &get_position() const { return result.position; } + + void set_normal(const Vector3 &p_normal) { result.normal = p_normal; } + const Vector3 &get_normal() const { return result.normal; } + + void set_rid(const RID &p_rid) { result.rid = p_rid; } + RID get_rid() const { return result.rid; } + + void set_collider_id(ObjectID p_collider_id) { result.collider_id = p_collider_id; } + ObjectID get_collider_id() const { return result.collider_id; } + + void set_collider(Object *p_collider) { result.collider = p_collider; } + Object *get_collider() const { return result.collider; } + + void set_shape(int p_shape) { result.shape = p_shape; } + int get_shape() const { return result.shape; } + + void set_face_index(int p_face_index) { result.face_index = p_face_index; } + int get_face_index() const { return result.face_index; } +}; + class PhysicsPointQueryParameters3D : public RefCounted { GDCLASS(PhysicsPointQueryParameters3D, RefCounted); diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index de4033378577..2c320f9b6e01 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -346,6 +346,7 @@ void register_server_types() { GDREGISTER_NATIVE_STRUCT(PhysicsServer3DExtensionMotionResult, "Vector3 travel;Vector3 remainder;real_t collision_depth;real_t collision_safe_fraction;real_t collision_unsafe_fraction;PhysicsServer3DExtensionMotionCollision collisions[32];int collision_count"); GDREGISTER_CLASS(PhysicsRayQueryParameters3D); + GDREGISTER_CLASS(PhysicsRayQueryResult3D); GDREGISTER_CLASS(PhysicsPointQueryParameters3D); GDREGISTER_CLASS(PhysicsShapeQueryParameters3D); GDREGISTER_CLASS(PhysicsTestMotionParameters3D);