Use parameter classes instead of arguments for all physics queries

Same as what is already done for shape queries, applied to point and ray
queries. Easier to document and more flexible to add more parameters.

Also expose intersect_point method to script in 3D.
Remove intersect_point_on_canvas in 2D, replaced with a parameter.
This commit is contained in:
PouleyKetchoupp 2021-11-01 18:00:58 -07:00
parent 25bea73544
commit acbd24ea84
27 changed files with 980 additions and 540 deletions

View File

@ -13,7 +13,7 @@
<methods> <methods>
<method name="cast_motion"> <method name="cast_motion">
<return type="Array" /> <return type="Array" />
<argument index="0" name="shape" type="PhysicsShapeQueryParameters2D" /> <argument index="0" name="parameters" type="PhysicsShapeQueryParameters2D" />
<description> <description>
Checks how far a [Shape2D] can move without colliding. All the parameters for the query, including the shape and the motion, are supplied through a [PhysicsShapeQueryParameters2D] object. Checks how far a [Shape2D] can move without colliding. All the parameters for the query, including the shape and the motion, are supplied through a [PhysicsShapeQueryParameters2D] object.
Returns an array with the safe and unsafe proportions (between 0 and 1) of the motion. The safe proportion is the maximum fraction of the motion that can be made without a collision. The unsafe proportion is the minimum fraction of the distance that must be moved for a collision. If no collision is detected a result of [code][1.0, 1.0][/code] will be returned. Returns an array with the safe and unsafe proportions (between 0 and 1) of the motion. The safe proportion is the maximum fraction of the motion that can be made without a collision. The unsafe proportion is the minimum fraction of the distance that must be moved for a collision. If no collision is detected a result of [code][1.0, 1.0][/code] will be returned.
@ -22,7 +22,7 @@
</method> </method>
<method name="collide_shape"> <method name="collide_shape">
<return type="Array" /> <return type="Array" />
<argument index="0" name="shape" type="PhysicsShapeQueryParameters2D" /> <argument index="0" name="parameters" type="PhysicsShapeQueryParameters2D" />
<argument index="1" name="max_results" type="int" default="32" /> <argument index="1" name="max_results" type="int" default="32" />
<description> <description>
Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters2D] object, against the space. The resulting array contains a list of points where the shape intersects another. Like with [method intersect_shape], the number of returned results can be limited to save processing time. Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters2D] object, against the space. The resulting array contains a list of points where the shape intersects another. Like with [method intersect_shape], the number of returned results can be limited to save processing time.
@ -31,7 +31,7 @@
</method> </method>
<method name="get_rest_info"> <method name="get_rest_info">
<return type="Dictionary" /> <return type="Dictionary" />
<argument index="0" name="shape" type="PhysicsShapeQueryParameters2D" /> <argument index="0" name="parameters" type="PhysicsShapeQueryParameters2D" />
<description> <description>
Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters2D] object, against the space. If it collides with more than one shape, the nearest one is selected. If the shape did not intersect anything, then an empty dictionary is returned instead. Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters2D] object, against the space. If it collides with more than one shape, the nearest one is selected. If the shape did not intersect anything, then an empty dictionary is returned instead.
[b]Note:[/b] This method does not take into account the [code]motion[/code] property of the object. The returned object is a dictionary containing the following fields: [b]Note:[/b] This method does not take into account the [code]motion[/code] property of the object. The returned object is a dictionary containing the following fields:
@ -45,51 +45,23 @@
</method> </method>
<method name="intersect_point"> <method name="intersect_point">
<return type="Array" /> <return type="Array" />
<argument index="0" name="point" type="Vector2" /> <argument index="0" name="parameters" type="PhysicsPointQueryParameters2D" />
<argument index="1" name="max_results" type="int" default="32" /> <argument index="1" name="max_results" type="int" default="32" />
<argument index="2" name="exclude" type="Array" default="[]" />
<argument index="3" name="collision_mask" type="int" default="4294967295" />
<argument index="4" name="collide_with_bodies" type="bool" default="true" />
<argument index="5" name="collide_with_areas" type="bool" default="false" />
<description> <description>
Checks whether a point is inside any solid shape. The shapes the point is inside of are returned in an array containing dictionaries with the following fields: Checks whether a point is inside any solid shape. Position and other parameters are defined through [PhysicsPointQueryParameters2D]. The shapes the point is inside of are returned in an array containing dictionaries with the following fields:
[code]collider[/code]: The colliding object. [code]collider[/code]: The colliding object.
[code]collider_id[/code]: The colliding object's ID. [code]collider_id[/code]: The colliding object's ID.
[code]rid[/code]: The intersecting object's [RID]. [code]rid[/code]: The intersecting object's [RID].
[code]shape[/code]: The shape index of the colliding shape. [code]shape[/code]: The shape index of the colliding shape.
Additionally, the method can take an [code]exclude[/code] array of objects or [RID]s that are to be excluded from collisions, a [code]collision_mask[/code] bitmask representing the physics layers to detect (all layers by default), or booleans to determine if the ray should collide with [PhysicsBody2D]s or [Area2D]s, respectively. The number of intersections can be limited with the [code]max_results[/code] parameter, to reduce the processing time.
[b]Note:[/b] [ConcavePolygonShape2D]s and [CollisionPolygon2D]s in [code]Segments[/code] build mode are not solid shapes. Therefore, they will not be detected.
</description>
</method>
<method name="intersect_point_on_canvas">
<return type="Array" />
<argument index="0" name="point" type="Vector2" />
<argument index="1" name="canvas_instance_id" type="int" />
<argument index="2" name="max_results" type="int" default="32" />
<argument index="3" name="exclude" type="Array" default="[]" />
<argument index="4" name="collision_mask" type="int" default="4294967295" />
<argument index="5" name="collide_with_bodies" type="bool" default="true" />
<argument index="6" name="collide_with_areas" type="bool" default="false" />
<description>
Checks whether a point is inside any solid shape, in a specific canvas layer given by [code]canvas_instance_id[/code]. The shapes the point is inside of are returned in an array containing dictionaries with the following fields:
[code]collider[/code]: The colliding object.
[code]collider_id[/code]: The colliding object's ID.
[code]rid[/code]: The intersecting object's [RID].
[code]shape[/code]: The shape index of the colliding shape.
Additionally, the method can take an [code]exclude[/code] array of objects or [RID]s that are to be excluded from collisions, a [code]collision_mask[/code] bitmask representing the physics layers to detect (all layers by default), or booleans to determine if the ray should collide with [PhysicsBody2D]s or [Area2D]s, respectively.
[b]Note:[/b] [ConcavePolygonShape2D]s and [CollisionPolygon2D]s in [code]Segments[/code] build mode are not solid shapes. Therefore, they will not be detected. [b]Note:[/b] [ConcavePolygonShape2D]s and [CollisionPolygon2D]s in [code]Segments[/code] build mode are not solid shapes. Therefore, they will not be detected.
</description> </description>
</method> </method>
<method name="intersect_ray"> <method name="intersect_ray">
<return type="Dictionary" /> <return type="Dictionary" />
<argument index="0" name="from" type="Vector2" /> <argument index="0" name="parameters" type="PhysicsRayQueryParameters2D" />
<argument index="1" name="to" type="Vector2" />
<argument index="2" name="exclude" type="Array" default="[]" />
<argument index="3" name="collision_mask" type="int" default="4294967295" />
<argument index="4" name="collide_with_bodies" type="bool" default="true" />
<argument index="5" name="collide_with_areas" type="bool" default="false" />
<description> <description>
Intersects a ray in a given space. The returned object is a dictionary with the following fields: 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[/code]: The colliding object.
[code]collider_id[/code]: The colliding object's ID. [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.
@ -97,16 +69,14 @@
[code]rid[/code]: The intersecting object's [RID]. [code]rid[/code]: The intersecting object's [RID].
[code]shape[/code]: The shape index of the colliding shape. [code]shape[/code]: The shape index of the colliding shape.
If the ray did not intersect anything, then an empty dictionary is returned instead. If the ray did not intersect anything, then an empty dictionary is returned instead.
Additionally, the method can take an [code]exclude[/code] array of objects or [RID]s that are to be excluded from collisions, a [code]collision_mask[/code] bitmask representing the physics layers to detect (all layers by default), or booleans to determine if the ray should collide with [PhysicsBody2D]s or [Area2D]s, respectively.
</description> </description>
</method> </method>
<method name="intersect_shape"> <method name="intersect_shape">
<return type="Array" /> <return type="Array" />
<argument index="0" name="shape" type="PhysicsShapeQueryParameters2D" /> <argument index="0" name="parameters" type="PhysicsShapeQueryParameters2D" />
<argument index="1" name="max_results" type="int" default="32" /> <argument index="1" name="max_results" type="int" default="32" />
<description> <description>
Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters2D] object, against the space. Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters2D] object, against the space. The intersected shapes are returned in an array containing dictionaries with the following fields:
[b]Note:[/b] This method does not take into account the [code]motion[/code] property of the object. The intersected shapes are returned in an array containing dictionaries with the following fields:
[code]collider[/code]: The colliding object. [code]collider[/code]: The colliding object.
[code]collider_id[/code]: The colliding object's ID. [code]collider_id[/code]: The colliding object's ID.
[code]rid[/code]: The intersecting object's [RID]. [code]rid[/code]: The intersecting object's [RID].

View File

@ -13,8 +13,7 @@
<methods> <methods>
<method name="cast_motion"> <method name="cast_motion">
<return type="Array" /> <return type="Array" />
<argument index="0" name="shape" type="PhysicsShapeQueryParameters3D" /> <argument index="0" name="parameters" type="PhysicsShapeQueryParameters3D" />
<argument index="1" name="motion" type="Vector3" />
<description> <description>
Checks how far a [Shape3D] can move without colliding. All the parameters for the query, including the shape, are supplied through a [PhysicsShapeQueryParameters3D] object. Checks how far a [Shape3D] can move without colliding. All the parameters for the query, including the shape, are supplied through a [PhysicsShapeQueryParameters3D] object.
Returns an array with the safe and unsafe proportions (between 0 and 1) of the motion. The safe proportion is the maximum fraction of the motion that can be made without a collision. The unsafe proportion is the minimum fraction of the distance that must be moved for a collision. If no collision is detected a result of [code][1.0, 1.0][/code] will be returned. Returns an array with the safe and unsafe proportions (between 0 and 1) of the motion. The safe proportion is the maximum fraction of the motion that can be made without a collision. The unsafe proportion is the minimum fraction of the distance that must be moved for a collision. If no collision is detected a result of [code][1.0, 1.0][/code] will be returned.
@ -23,16 +22,17 @@
</method> </method>
<method name="collide_shape"> <method name="collide_shape">
<return type="Array" /> <return type="Array" />
<argument index="0" name="shape" type="PhysicsShapeQueryParameters3D" /> <argument index="0" name="parameters" type="PhysicsShapeQueryParameters3D" />
<argument index="1" name="max_results" type="int" default="32" /> <argument index="1" name="max_results" type="int" default="32" />
<description> <description>
Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters3D] object, against the space. The resulting array contains a list of points where the shape intersects another. Like with [method intersect_shape], the number of returned results can be limited to save processing time. Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters3D] object, against the space. The resulting array contains a list of points where the shape intersects another. Like with [method intersect_shape], the number of returned results can be limited to save processing time.
Returned points are a list of pairs of contact points. For each pair the first one is in the shape passed in [PhysicsShapeQueryParameters3D] object, second one is in the collided shape from the physics space. Returned points are a list of pairs of contact points. For each pair the first one is in the shape passed in [PhysicsShapeQueryParameters3D] object, second one is in the collided shape from the physics space.
[b]Note:[/b] This method does not take into account the [code]motion[/code] property of the object.
</description> </description>
</method> </method>
<method name="get_rest_info"> <method name="get_rest_info">
<return type="Dictionary" /> <return type="Dictionary" />
<argument index="0" name="shape" type="PhysicsShapeQueryParameters3D" /> <argument index="0" name="parameters" type="PhysicsShapeQueryParameters3D" />
<description> <description>
Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters3D] object, against the space. If it collides with more than one shape, the nearest one is selected. The returned object is a dictionary containing the following fields: Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters3D] object, against the space. If it collides with more than one shape, the nearest one is selected. The returned object is a dictionary containing the following fields:
[code]collider_id[/code]: The colliding object's ID. [code]collider_id[/code]: The colliding object's ID.
@ -42,18 +42,27 @@
[code]rid[/code]: The intersecting object's [RID]. [code]rid[/code]: The intersecting object's [RID].
[code]shape[/code]: The shape index of the colliding shape. [code]shape[/code]: The shape index of the colliding shape.
If the shape did not intersect anything, then an empty dictionary is returned instead. If the shape did not intersect anything, then an empty dictionary is returned instead.
[b]Note:[/b] This method does not take into account the [code]motion[/code] property of the object.
</description>
</method>
<method name="intersect_point">
<return type="Array" />
<argument index="0" name="parameters" type="PhysicsPointQueryParameters3D" />
<argument index="1" name="max_results" type="int" default="32" />
<description>
Checks whether a point is inside any solid shape. Position and other parameters are defined through [PhysicsPointQueryParameters3D]. The shapes the point is inside of are returned in an array containing dictionaries with the following fields:
[code]collider[/code]: The colliding object.
[code]collider_id[/code]: The colliding object's ID.
[code]rid[/code]: The intersecting object's [RID].
[code]shape[/code]: The shape index of the colliding shape.
The number of intersections can be limited with the [code]max_results[/code] parameter, to reduce the processing time.
</description> </description>
</method> </method>
<method name="intersect_ray"> <method name="intersect_ray">
<return type="Dictionary" /> <return type="Dictionary" />
<argument index="0" name="from" type="Vector3" /> <argument index="0" name="parameters" type="PhysicsRayQueryParameters3D" />
<argument index="1" name="to" type="Vector3" />
<argument index="2" name="exclude" type="Array" default="[]" />
<argument index="3" name="collision_mask" type="int" default="4294967295" />
<argument index="4" name="collide_with_bodies" type="bool" default="true" />
<argument index="5" name="collide_with_areas" type="bool" default="false" />
<description> <description>
Intersects a ray in a given space. The returned object is a dictionary with the following fields: 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[/code]: The colliding object.
[code]collider_id[/code]: The colliding object's ID. [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.
@ -61,12 +70,11 @@
[code]rid[/code]: The intersecting object's [RID]. [code]rid[/code]: The intersecting object's [RID].
[code]shape[/code]: The shape index of the colliding shape. [code]shape[/code]: The shape index of the colliding shape.
If the ray did not intersect anything, then an empty dictionary is returned instead. If the ray did not intersect anything, then an empty dictionary is returned instead.
Additionally, the method can take an [code]exclude[/code] array of objects or [RID]s that are to be excluded from collisions, a [code]collision_mask[/code] bitmask representing the physics layers to detect (all layers by default), or booleans to determine if the ray should collide with [PhysicsBody3D]s or [Area3D]s, respectively.
</description> </description>
</method> </method>
<method name="intersect_shape"> <method name="intersect_shape">
<return type="Array" /> <return type="Array" />
<argument index="0" name="shape" type="PhysicsShapeQueryParameters3D" /> <argument index="0" name="parameters" type="PhysicsShapeQueryParameters3D" />
<argument index="1" name="max_results" type="int" default="32" /> <argument index="1" name="max_results" type="int" default="32" />
<description> <description>
Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters3D] object, against the space. The intersected shapes are returned in an array containing dictionaries with the following fields: Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters3D] object, against the space. The intersected shapes are returned in an array containing dictionaries with the following fields:
@ -75,6 +83,7 @@
[code]rid[/code]: The intersecting object's [RID]. [code]rid[/code]: The intersecting object's [RID].
[code]shape[/code]: The shape index of the colliding shape. [code]shape[/code]: The shape index of the colliding shape.
The number of intersections can be limited with the [code]max_results[/code] parameter, to reduce the processing time. The number of intersections can be limited with the [code]max_results[/code] parameter, to reduce the processing time.
[b]Note:[/b] This method does not take into account the [code]motion[/code] property of the object.
</description> </description>
</method> </method>
</methods> </methods>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsPointQueryParameters2D" inherits="RefCounted" version="4.0">
<brief_description>
Parameters to be sent to a 2D point physics query.
</brief_description>
<description>
This class contains the position and other parameters to be used for [method PhysicsDirectSpaceState2D.intersect_point].
</description>
<tutorials>
</tutorials>
<members>
<member name="canvas_instance_id" type="int" setter="set_canvas_instance_id" getter="get_canvas_instance_id" default="0">
If different from [code]0[/code], restricts the query to a specific canvas layer specified by its instance id. See [method Object.get_instance_id].
</member>
<member name="collide_with_areas" type="bool" setter="set_collide_with_areas" getter="is_collide_with_areas_enabled" default="false">
If [code]true[/code], the query will take [Area2D]s into account.
</member>
<member name="collide_with_bodies" type="bool" setter="set_collide_with_bodies" getter="is_collide_with_bodies_enabled" default="true">
If [code]true[/code], the query will take [PhysicsBody2D]s into account.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="4294967295">
The physics layers the query will detect (as a bitmask). By default, all collision layers are detected. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="exclude" type="Array" setter="set_exclude" getter="get_exclude" default="[]">
The list of objects or object [RID]s that will be excluded from collisions.
</member>
<member name="position" type="Vector2" setter="set_position" getter="get_position" default="Vector2(0, 0)">
The position being queried for, in global coordinates.
</member>
</members>
</class>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsPointQueryParameters3D" inherits="RefCounted" version="4.0">
<brief_description>
Parameters to be sent to a 3D point physics query.
</brief_description>
<description>
This class contains the position and other parameters to be used for [method PhysicsDirectSpaceState3D.intersect_point].
</description>
<tutorials>
</tutorials>
<members>
<member name="collide_with_areas" type="bool" setter="set_collide_with_areas" getter="is_collide_with_areas_enabled" default="false">
If [code]true[/code], the query will take [Area3D]s into account.
</member>
<member name="collide_with_bodies" type="bool" setter="set_collide_with_bodies" getter="is_collide_with_bodies_enabled" default="true">
If [code]true[/code], the query will take [PhysicsBody3D]s into account.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="4294967295">
The physics layers the query will detect (as a bitmask). By default, all collision layers are detected. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="exclude" type="Array" setter="set_exclude" getter="get_exclude" default="[]">
The list of objects or object [RID]s that will be excluded from collisions.
</member>
<member name="position" type="Vector3" setter="set_position" getter="get_position" default="Vector3(0, 0, 0)">
The position being queried for, in global coordinates.
</member>
</members>
</class>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsRayQueryParameters2D" inherits="RefCounted" version="4.0">
<brief_description>
Parameters to be sent to a 2D ray physics query.
</brief_description>
<description>
This class contains the ray position and other parameters to be used for [method PhysicsDirectSpaceState2D.intersect_ray].
</description>
<tutorials>
</tutorials>
<members>
<member name="collide_with_areas" type="bool" setter="set_collide_with_areas" getter="is_collide_with_areas_enabled" default="false">
If [code]true[/code], the query will take [Area2D]s into account.
</member>
<member name="collide_with_bodies" type="bool" setter="set_collide_with_bodies" getter="is_collide_with_bodies_enabled" default="true">
If [code]true[/code], the query will take [PhysicsBody2D]s into account.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="4294967295">
The physics layers the query will detect (as a bitmask). By default, all collision layers are detected. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="exclude" type="Array" setter="set_exclude" getter="get_exclude" default="[]">
The list of objects or object [RID]s that will be excluded from collisions.
</member>
<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="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>
</members>
</class>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsRayQueryParameters3D" inherits="RefCounted" version="4.0">
<brief_description>
Parameters to be sent to a 3D ray physics query.
</brief_description>
<description>
This class contains the ray position and other parameters to be used for [method PhysicsDirectSpaceState3D.intersect_ray].
</description>
<tutorials>
</tutorials>
<members>
<member name="collide_with_areas" type="bool" setter="set_collide_with_areas" getter="is_collide_with_areas_enabled" default="false">
If [code]true[/code], the query will take [Area3D]s into account.
</member>
<member name="collide_with_bodies" type="bool" setter="set_collide_with_bodies" getter="is_collide_with_bodies_enabled" default="true">
If [code]true[/code], the query will take [PhysicsBody3D]s into account.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="4294967295">
The physics layers the query will detect (as a bitmask). By default, all collision layers are detected. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="exclude" type="Array" setter="set_exclude" getter="get_exclude" default="[]">
The list of objects or object [RID]s that will be excluded from collisions.
</member>
<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="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>
</members>
</class>

View File

@ -4,7 +4,7 @@
Parameters to be sent to a 2D shape physics query. Parameters to be sent to a 2D shape physics query.
</brief_description> </brief_description>
<description> <description>
This class contains the shape and other parameters for 2D intersection/collision queries. This class contains the shape and other parameters for [PhysicsDirectSpaceState2D] intersection/collision queries.
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>

View File

@ -4,7 +4,7 @@
Parameters to be sent to a 3D shape physics query. Parameters to be sent to a 3D shape physics query.
</brief_description> </brief_description>
<description> <description>
This class contains the shape and other parameters for 3D intersection/collision queries. This class contains the shape and other parameters for [PhysicsDirectSpaceState3D] intersection/collision queries.
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
@ -24,6 +24,9 @@
<member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.0"> <member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.0">
The collision margin for the shape. The collision margin for the shape.
</member> </member>
<member name="motion" type="Vector3" setter="set_motion" getter="get_motion" default="Vector3(0, 0, 0)">
The motion of the shape being queried for.
</member>
<member name="shape" type="Resource" setter="set_shape" getter="get_shape"> <member name="shape" type="Resource" setter="set_shape" getter="get_shape">
The [Shape3D] that will be used for collision/intersection queries. This stores the actual reference which avoids the shape to be released while being used for queries, so always prefer using this over [member shape_rid]. The [Shape3D] that will be used for collision/intersection queries. This stores the actual reference which avoids the shape to be released while being used for queries, so always prefer using this over [member shape_rid].
</member> </member>

View File

@ -3936,9 +3936,13 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const
Vector3 point = world_pos + world_ray * MAX_DISTANCE; Vector3 point = world_pos + world_ray * MAX_DISTANCE;
PhysicsDirectSpaceState3D *ss = get_tree()->get_root()->get_world_3d()->get_direct_space_state(); PhysicsDirectSpaceState3D *ss = get_tree()->get_root()->get_world_3d()->get_direct_space_state();
PhysicsDirectSpaceState3D::RayResult result;
if (ss->intersect_ray(world_pos, world_pos + world_ray * MAX_DISTANCE, result)) { PhysicsDirectSpaceState3D::RayParameters ray_params;
ray_params.from = world_pos;
ray_params.to = world_pos + world_ray * MAX_DISTANCE;
PhysicsDirectSpaceState3D::RayResult result;
if (ss->intersect_ray(ray_params, result)) {
point = result.position; point = result.position;
} }
@ -6566,7 +6570,12 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
Vector3 to = from - Vector3(0.0, max_snap_height, 0.0); Vector3 to = from - Vector3(0.0, max_snap_height, 0.0);
Set<RID> excluded = _get_physics_bodies_rid(sp); Set<RID> excluded = _get_physics_bodies_rid(sp);
if (ss->intersect_ray(from, to, result, excluded)) { PhysicsDirectSpaceState3D::RayParameters ray_params;
ray_params.from = from;
ray_params.to = to;
ray_params.exclude = excluded;
if (ss->intersect_ray(ray_params, result)) {
snapped_to_floor = true; snapped_to_floor = true;
} }
} }
@ -6583,7 +6592,12 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
Vector3 to = from - Vector3(0.0, max_snap_height, 0.0); Vector3 to = from - Vector3(0.0, max_snap_height, 0.0);
Set<RID> excluded = _get_physics_bodies_rid(sp); Set<RID> excluded = _get_physics_bodies_rid(sp);
if (ss->intersect_ray(from, to, result, excluded)) { PhysicsDirectSpaceState3D::RayParameters ray_params;
ray_params.from = from;
ray_params.to = to;
ray_params.exclude = excluded;
if (ss->intersect_ray(ray_params, result)) {
Vector3 position_offset = d["position_offset"]; Vector3 position_offset = d["position_offset"];
Transform3D new_transform = sp->get_global_transform(); Transform3D new_transform = sp->get_global_transform();

View File

@ -112,7 +112,13 @@ StringName AudioStreamPlayer2D::_get_actual_bus() {
PhysicsDirectSpaceState2D *space_state = PhysicsServer2D::get_singleton()->space_get_direct_state(world_2d->get_space()); PhysicsDirectSpaceState2D *space_state = PhysicsServer2D::get_singleton()->space_get_direct_state(world_2d->get_space());
PhysicsDirectSpaceState2D::ShapeResult sr[MAX_INTERSECT_AREAS]; PhysicsDirectSpaceState2D::ShapeResult sr[MAX_INTERSECT_AREAS];
int areas = space_state->intersect_point(global_pos, sr, MAX_INTERSECT_AREAS, Set<RID>(), area_mask, false, true); PhysicsDirectSpaceState2D::PointParameters point_params;
point_params.position = global_pos;
point_params.collision_mask = area_mask;
point_params.collide_with_bodies = false;
point_params.collide_with_areas = true;
int areas = space_state->intersect_point(point_params, sr, MAX_INTERSECT_AREAS);
for (int i = 0; i < areas; i++) { for (int i = 0; i < areas; i++) {
Area2D *area2d = Object::cast_to<Area2D>(sr[i].collider); Area2D *area2d = Object::cast_to<Area2D>(sr[i].collider);

View File

@ -192,7 +192,16 @@ void RayCast2D::_update_raycast_state() {
PhysicsDirectSpaceState2D::RayResult rr; PhysicsDirectSpaceState2D::RayResult rr;
bool prev_collision_state = collided; bool prev_collision_state = collided;
if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask, collide_with_bodies, collide_with_areas)) {
PhysicsDirectSpaceState2D::RayParameters ray_params;
ray_params.from = gt.get_origin();
ray_params.to = gt.xform(to);
ray_params.exclude = exclude;
ray_params.collision_mask = collision_mask;
ray_params.collide_with_bodies = collide_with_bodies;
ray_params.collide_with_areas = collide_with_areas;
if (dss->intersect_ray(ray_params, rr)) {
collided = true; collided = true;
against = rr.collider_id; against = rr.collider_id;
collision_point = rr.position; collision_point = rr.position;

View File

@ -327,7 +327,13 @@ Area3D *AudioStreamPlayer3D::_get_overriding_area() {
PhysicsDirectSpaceState3D::ShapeResult sr[MAX_INTERSECT_AREAS]; PhysicsDirectSpaceState3D::ShapeResult sr[MAX_INTERSECT_AREAS];
int areas = space_state->intersect_point(global_pos, sr, MAX_INTERSECT_AREAS, Set<RID>(), area_mask, false, true); PhysicsDirectSpaceState3D::PointParameters point_params;
point_params.position = global_pos;
point_params.collision_mask = area_mask;
point_params.collide_with_bodies = false;
point_params.collide_with_areas = true;
int areas = space_state->intersect_point(point_params, sr, MAX_INTERSECT_AREAS);
for (int i = 0; i < areas; i++) { for (int i = 0; i < areas; i++) {
if (!sr[i].collider) { if (!sr[i].collider) {

View File

@ -212,9 +212,16 @@ void RayCast3D::_update_raycast_state() {
to = Vector3(0, 0.01, 0); to = Vector3(0, 0.01, 0);
} }
PhysicsDirectSpaceState3D::RayResult rr; PhysicsDirectSpaceState3D::RayParameters ray_params;
ray_params.from = gt.get_origin();
ray_params.to = gt.xform(to);
ray_params.exclude = exclude;
ray_params.collision_mask = collision_mask;
ray_params.collide_with_bodies = collide_with_bodies;
ray_params.collide_with_areas = collide_with_areas;
if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask, collide_with_bodies, collide_with_areas)) { PhysicsDirectSpaceState3D::RayResult rr;
if (dss->intersect_ray(ray_params, rr)) {
collided = true; collided = true;
against = rr.collider_id; against = rr.collider_id;
collision_point = rr.position; collision_point = rr.position;

View File

@ -149,10 +149,24 @@ void SpringArm3D::process_spring() {
//use camera rotation, but spring arm position //use camera rotation, but spring arm position
Transform3D base_transform = camera->get_global_transform(); Transform3D base_transform = camera->get_global_transform();
base_transform.origin = get_global_transform().origin; base_transform.origin = get_global_transform().origin;
get_world_3d()->get_direct_space_state()->cast_motion(camera->get_pyramid_shape_rid(), base_transform, motion, 0, motion_delta, motion_delta_unsafe, excluded_objects, mask);
PhysicsDirectSpaceState3D::ShapeParameters shape_params;
shape_params.shape_rid = camera->get_pyramid_shape_rid();
shape_params.transform = base_transform;
shape_params.motion = motion;
shape_params.exclude = excluded_objects;
shape_params.collision_mask = mask;
get_world_3d()->get_direct_space_state()->cast_motion(shape_params, motion_delta, motion_delta_unsafe);
} else { } else {
PhysicsDirectSpaceState3D::RayParameters ray_params;
ray_params.from = get_global_transform().origin;
ray_params.to = get_global_transform().origin + motion;
ray_params.exclude = excluded_objects;
ray_params.collision_mask = mask;
PhysicsDirectSpaceState3D::RayResult r; PhysicsDirectSpaceState3D::RayResult r;
bool intersected = get_world_3d()->get_direct_space_state()->intersect_ray(get_global_transform().origin, get_global_transform().origin + motion, r, excluded_objects, mask); bool intersected = get_world_3d()->get_direct_space_state()->intersect_ray(ray_params, r);
if (intersected) { if (intersected) {
real_t dist = get_global_transform().origin.distance_to(r.position); real_t dist = get_global_transform().origin.distance_to(r.position);
dist -= margin; dist -= margin;
@ -160,7 +174,14 @@ void SpringArm3D::process_spring() {
} }
} }
} else { } else {
get_world_3d()->get_direct_space_state()->cast_motion(shape->get_rid(), get_global_transform(), motion, 0, motion_delta, motion_delta_unsafe, excluded_objects, mask); PhysicsDirectSpaceState3D::ShapeParameters shape_params;
shape_params.shape_rid = shape->get_rid();
shape_params.transform = get_global_transform();
shape_params.motion = motion;
shape_params.exclude = excluded_objects;
shape_params.collision_mask = mask;
get_world_3d()->get_direct_space_state()->cast_motion(shape_params, motion_delta, motion_delta_unsafe);
} }
current_spring_length = spring_length * motion_delta; current_spring_length = spring_length * motion_delta;

View File

@ -407,7 +407,13 @@ real_t VehicleBody3D::_ray_cast(int p_idx, PhysicsDirectBodyState3D *s) {
PhysicsDirectSpaceState3D *ss = s->get_space_state(); PhysicsDirectSpaceState3D *ss = s->get_space_state();
bool col = ss->intersect_ray(source, target, rr, exclude, get_collision_mask()); PhysicsDirectSpaceState3D::RayParameters ray_params;
ray_params.from = source;
ray_params.to = target;
ray_params.exclude = exclude;
ray_params.collision_mask = get_collision_mask();
bool col = ss->intersect_ray(ray_params, rr);
wheel.m_raycastInfo.m_groundObject = nullptr; wheel.m_raycastInfo.m_groundObject = nullptr;

View File

@ -638,7 +638,13 @@ void Viewport::_process_picking() {
Vector2 point = canvas_transform.affine_inverse().xform(pos); Vector2 point = canvas_transform.affine_inverse().xform(pos);
int rc = ss2d->intersect_point_on_canvas(point, canvas_layer_id, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true); PhysicsDirectSpaceState2D::PointParameters point_params;
point_params.position = point;
point_params.canvas_instance_id = canvas_layer_id;
point_params.collide_with_areas = true;
point_params.pick_point = true;
int rc = ss2d->intersect_point(point_params, res, 64);
for (int i = 0; i < rc; i++) { for (int i = 0; i < rc; i++) {
if (res[i].collider_id.is_valid() && res[i].collider) { if (res[i].collider_id.is_valid() && res[i].collider) {
CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider); CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider);
@ -719,7 +725,13 @@ void Viewport::_process_picking() {
PhysicsDirectSpaceState3D *space = PhysicsServer3D::get_singleton()->space_get_direct_state(find_world_3d()->get_space()); PhysicsDirectSpaceState3D *space = PhysicsServer3D::get_singleton()->space_get_direct_state(find_world_3d()->get_space());
if (space) { if (space) {
bool col = space->intersect_ray(from, from + dir * far, result, Set<RID>(), 0xFFFFFFFF, true, true, true); PhysicsDirectSpaceState3D::RayParameters ray_params;
ray_params.from = from;
ray_params.to = from + dir * far;
ray_params.collide_with_areas = true;
ray_params.pick_ray = true;
bool col = space->intersect_ray(ray_params, result);
ObjectID new_collider; ObjectID new_collider;
if (col) { if (col) {
CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider); CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider);

View File

@ -194,9 +194,13 @@ void SkeletonModification2DJiggle::_execute_jiggle_joint(int p_joint_idx, Node2D
PhysicsDirectSpaceState2D *space_state = PhysicsServer2D::get_singleton()->space_get_direct_state(world_2d->get_space()); PhysicsDirectSpaceState2D *space_state = PhysicsServer2D::get_singleton()->space_get_direct_state(world_2d->get_space());
PhysicsDirectSpaceState2D::RayResult ray_result; PhysicsDirectSpaceState2D::RayResult ray_result;
PhysicsDirectSpaceState2D::RayParameters ray_params;
ray_params.from = operation_bone_trans.get_origin();
ray_params.to = jiggle_data_chain[p_joint_idx].dynamic_position;
ray_params.collision_mask = collision_mask;
// Add exception support? // Add exception support?
bool ray_hit = space_state->intersect_ray(operation_bone_trans.get_origin(), jiggle_data_chain[p_joint_idx].dynamic_position, bool ray_hit = space_state->intersect_ray(ray_params, ray_result);
ray_result, Set<RID>(), collision_mask);
if (ray_hit) { if (ray_hit) {
jiggle_data_chain.write[p_joint_idx].dynamic_position = jiggle_data_chain[p_joint_idx].last_noncollision_position; jiggle_data_chain.write[p_joint_idx].dynamic_position = jiggle_data_chain[p_joint_idx].last_noncollision_position;

View File

@ -206,8 +206,12 @@ void SkeletonModification3DJiggle::_execute_jiggle_joint(int p_joint_idx, Node3D
Transform3D new_bone_trans_world = stack->skeleton->global_pose_to_world_transform(new_bone_trans); Transform3D new_bone_trans_world = stack->skeleton->global_pose_to_world_transform(new_bone_trans);
Transform3D dynamic_position_world = stack->skeleton->global_pose_to_world_transform(Transform3D(Basis(), jiggle_data_chain[p_joint_idx].dynamic_position)); Transform3D dynamic_position_world = stack->skeleton->global_pose_to_world_transform(Transform3D(Basis(), jiggle_data_chain[p_joint_idx].dynamic_position));
bool ray_hit = space_state->intersect_ray(new_bone_trans_world.origin, dynamic_position_world.get_origin(), PhysicsDirectSpaceState3D::RayParameters ray_params;
ray_result, Set<RID>(), collision_mask); ray_params.from = new_bone_trans_world.origin;
ray_params.to = dynamic_position_world.get_origin();
ray_params.collision_mask = collision_mask;
bool ray_hit = space_state->intersect_ray(ray_params, ray_result);
if (ray_hit) { if (ray_hit) {
jiggle_data_chain[p_joint_idx].dynamic_position = jiggle_data_chain[p_joint_idx].last_noncollision_position; jiggle_data_chain[p_joint_idx].dynamic_position = jiggle_data_chain[p_joint_idx].last_noncollision_position;

View File

@ -54,13 +54,13 @@ _FORCE_INLINE_ static bool _can_collide_with(GodotCollisionObject2D *p_object, u
return true; return true;
} }
int GodotPhysicsDirectSpaceState2D::_intersect_point_impl(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point, bool p_filter_by_canvas, ObjectID p_canvas_instance_id) { int GodotPhysicsDirectSpaceState2D::intersect_point(const PointParameters &p_parameters, ShapeResult *r_results, int p_result_max) {
if (p_result_max <= 0) { if (p_result_max <= 0) {
return 0; return 0;
} }
Rect2 aabb; Rect2 aabb;
aabb.position = p_point - Vector2(0.00001, 0.00001); aabb.position = p_parameters.position - Vector2(0.00001, 0.00001);
aabb.size = Vector2(0.00002, 0.00002); aabb.size = Vector2(0.00002, 0.00002);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@ -68,21 +68,21 @@ int GodotPhysicsDirectSpaceState2D::_intersect_point_impl(const Vector2 &p_point
int cc = 0; int cc = 0;
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { if (!_can_collide_with(space->intersection_query_results[i], p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas)) {
continue; continue;
} }
if (p_exclude.has(space->intersection_query_results[i]->get_self())) { if (p_parameters.exclude.has(space->intersection_query_results[i]->get_self())) {
continue; continue;
} }
const GodotCollisionObject2D *col_obj = space->intersection_query_results[i]; const GodotCollisionObject2D *col_obj = space->intersection_query_results[i];
if (p_pick_point && !col_obj->is_pickable()) { if (p_parameters.pick_point && !col_obj->is_pickable()) {
continue; continue;
} }
if (p_filter_by_canvas && col_obj->get_canvas_instance_id() != p_canvas_instance_id) { if (p_parameters.canvas_instance_id.is_valid() && col_obj->get_canvas_instance_id() != p_parameters.canvas_instance_id) {
continue; continue;
} }
@ -90,7 +90,7 @@ int GodotPhysicsDirectSpaceState2D::_intersect_point_impl(const Vector2 &p_point
GodotShape2D *shape = col_obj->get_shape(shape_idx); GodotShape2D *shape = col_obj->get_shape(shape_idx);
Vector2 local_point = (col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).affine_inverse().xform(p_point); Vector2 local_point = (col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).affine_inverse().xform(p_parameters.position);
if (!shape->contains_point(local_point)) { if (!shape->contains_point(local_point)) {
continue; continue;
@ -113,21 +113,13 @@ int GodotPhysicsDirectSpaceState2D::_intersect_point_impl(const Vector2 &p_point
return cc; return cc;
} }
int GodotPhysicsDirectSpaceState2D::intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point) { bool GodotPhysicsDirectSpaceState2D::intersect_ray(const RayParameters &p_parameters, RayResult &r_result) {
return _intersect_point_impl(p_point, r_results, p_result_max, p_exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas, p_pick_point);
}
int GodotPhysicsDirectSpaceState2D::intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point) {
return _intersect_point_impl(p_point, r_results, p_result_max, p_exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas, p_pick_point, true, p_canvas_instance_id);
}
bool GodotPhysicsDirectSpaceState2D::intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
ERR_FAIL_COND_V(space->locked, false); ERR_FAIL_COND_V(space->locked, false);
Vector2 begin, end; Vector2 begin, end;
Vector2 normal; Vector2 normal;
begin = p_from; begin = p_parameters.from;
end = p_to; end = p_parameters.to;
normal = (end - begin).normalized(); normal = (end - begin).normalized();
int amount = space->broadphase->cull_segment(begin, end, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int amount = space->broadphase->cull_segment(begin, end, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@ -141,11 +133,11 @@ bool GodotPhysicsDirectSpaceState2D::intersect_ray(const Vector2 &p_from, const
real_t min_d = 1e10; real_t min_d = 1e10;
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { if (!_can_collide_with(space->intersection_query_results[i], p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas)) {
continue; continue;
} }
if (p_exclude.has(space->intersection_query_results[i]->get_self())) { if (p_parameters.exclude.has(space->intersection_query_results[i]->get_self())) {
continue; continue;
} }
@ -157,12 +149,6 @@ bool GodotPhysicsDirectSpaceState2D::intersect_ray(const Vector2 &p_from, const
Vector2 local_from = inv_xform.xform(begin); Vector2 local_from = inv_xform.xform(begin);
Vector2 local_to = inv_xform.xform(end); Vector2 local_to = inv_xform.xform(end);
/*local_from = col_obj->get_inv_transform().xform(begin);
local_from = col_obj->get_shape_inv_transform(shape_idx).xform(local_from);
local_to = col_obj->get_inv_transform().xform(end);
local_to = col_obj->get_shape_inv_transform(shape_idx).xform(local_to);*/
const GodotShape2D *shape = col_obj->get_shape(shape_idx); const GodotShape2D *shape = col_obj->get_shape(shape_idx);
Vector2 shape_point, shape_normal; Vector2 shape_point, shape_normal;
@ -200,16 +186,17 @@ bool GodotPhysicsDirectSpaceState2D::intersect_ray(const Vector2 &p_from, const
return true; return true;
} }
int GodotPhysicsDirectSpaceState2D::intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { int GodotPhysicsDirectSpaceState2D::intersect_shape(const ShapeParameters &p_parameters, ShapeResult *r_results, int p_result_max) {
if (p_result_max <= 0) { if (p_result_max <= 0) {
return 0; return 0;
} }
GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_shape); GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid);
ERR_FAIL_COND_V(!shape, 0); ERR_FAIL_COND_V(!shape, 0);
Rect2 aabb = p_xform.xform(shape->get_aabb()); Rect2 aabb = p_parameters.transform.xform(shape->get_aabb());
aabb = aabb.grow(p_margin); aabb = aabb.merge(Rect2(aabb.position + p_parameters.motion, aabb.size)); //motion
aabb = aabb.grow(p_parameters.margin);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@ -220,18 +207,18 @@ int GodotPhysicsDirectSpaceState2D::intersect_shape(const RID &p_shape, const Tr
break; break;
} }
if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { if (!_can_collide_with(space->intersection_query_results[i], p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas)) {
continue; continue;
} }
if (p_exclude.has(space->intersection_query_results[i]->get_self())) { if (p_parameters.exclude.has(space->intersection_query_results[i]->get_self())) {
continue; continue;
} }
const GodotCollisionObject2D *col_obj = space->intersection_query_results[i]; const GodotCollisionObject2D *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i]; int shape_idx = space->intersection_query_subindex_results[i];
if (!GodotCollisionSolver2D::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), nullptr, nullptr, nullptr, p_margin)) { if (!GodotCollisionSolver2D::solve(shape, p_parameters.transform, p_parameters.motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), nullptr, nullptr, nullptr, p_parameters.margin)) {
continue; continue;
} }
@ -248,13 +235,13 @@ int GodotPhysicsDirectSpaceState2D::intersect_shape(const RID &p_shape, const Tr
return cc; return cc;
} }
bool GodotPhysicsDirectSpaceState2D::cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { bool GodotPhysicsDirectSpaceState2D::cast_motion(const ShapeParameters &p_parameters, real_t &p_closest_safe, real_t &p_closest_unsafe) {
GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_shape); GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid);
ERR_FAIL_COND_V(!shape, false); ERR_FAIL_COND_V(!shape, false);
Rect2 aabb = p_xform.xform(shape->get_aabb()); Rect2 aabb = p_parameters.transform.xform(shape->get_aabb());
aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion aabb = aabb.merge(Rect2(aabb.position + p_parameters.motion, aabb.size)); //motion
aabb = aabb.grow(p_margin); aabb = aabb.grow(p_parameters.margin);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@ -262,11 +249,11 @@ bool GodotPhysicsDirectSpaceState2D::cast_motion(const RID &p_shape, const Trans
real_t best_unsafe = 1; real_t best_unsafe = 1;
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { if (!_can_collide_with(space->intersection_query_results[i], p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas)) {
continue; continue;
} }
if (p_exclude.has(space->intersection_query_results[i]->get_self())) { if (p_parameters.exclude.has(space->intersection_query_results[i]->get_self())) {
continue; //ignore excluded continue; //ignore excluded
} }
@ -275,16 +262,16 @@ bool GodotPhysicsDirectSpaceState2D::cast_motion(const RID &p_shape, const Trans
Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
//test initial overlap, does it collide if going all the way? //test initial overlap, does it collide if going all the way?
if (!GodotCollisionSolver2D::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) { if (!GodotCollisionSolver2D::solve(shape, p_parameters.transform, p_parameters.motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_parameters.margin)) {
continue; continue;
} }
//test initial overlap, ignore objects it's inside of. //test initial overlap, ignore objects it's inside of.
if (GodotCollisionSolver2D::solve(shape, p_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) { if (GodotCollisionSolver2D::solve(shape, p_parameters.transform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_parameters.margin)) {
continue; continue;
} }
Vector2 mnormal = p_motion.normalized(); Vector2 mnormal = p_parameters.motion.normalized();
//just do kinematic solving //just do kinematic solving
real_t low = 0.0; real_t low = 0.0;
@ -294,7 +281,7 @@ bool GodotPhysicsDirectSpaceState2D::cast_motion(const RID &p_shape, const Trans
real_t fraction = low + (hi - low) * fraction_coeff; real_t fraction = low + (hi - low) * fraction_coeff;
Vector2 sep = mnormal; //important optimization for this to work fast enough Vector2 sep = mnormal; //important optimization for this to work fast enough
bool collided = GodotCollisionSolver2D::solve(shape, p_xform, p_motion * fraction, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, &sep, p_margin); bool collided = GodotCollisionSolver2D::solve(shape, p_parameters.transform, p_parameters.motion * fraction, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, &sep, p_parameters.margin);
if (collided) { if (collided) {
hi = fraction; hi = fraction;
@ -331,17 +318,17 @@ bool GodotPhysicsDirectSpaceState2D::cast_motion(const RID &p_shape, const Trans
return true; return true;
} }
bool GodotPhysicsDirectSpaceState2D::collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { bool GodotPhysicsDirectSpaceState2D::collide_shape(const ShapeParameters &p_parameters, Vector2 *r_results, int p_result_max, int &r_result_count) {
if (p_result_max <= 0) { if (p_result_max <= 0) {
return false; return false;
} }
GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_shape); GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid);
ERR_FAIL_COND_V(!shape, 0); ERR_FAIL_COND_V(!shape, 0);
Rect2 aabb = p_shape_xform.xform(shape->get_aabb()); Rect2 aabb = p_parameters.transform.xform(shape->get_aabb());
aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion aabb = aabb.merge(Rect2(aabb.position + p_parameters.motion, aabb.size)); //motion
aabb = aabb.grow(p_margin); aabb = aabb.grow(p_parameters.margin);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@ -358,13 +345,13 @@ bool GodotPhysicsDirectSpaceState2D::collide_shape(RID p_shape, const Transform2
GodotPhysicsServer2D::CollCbkData *cbkptr = &cbk; GodotPhysicsServer2D::CollCbkData *cbkptr = &cbk;
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { if (!_can_collide_with(space->intersection_query_results[i], p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas)) {
continue; continue;
} }
const GodotCollisionObject2D *col_obj = space->intersection_query_results[i]; const GodotCollisionObject2D *col_obj = space->intersection_query_results[i];
if (p_exclude.has(col_obj->get_self())) { if (p_parameters.exclude.has(col_obj->get_self())) {
continue; continue;
} }
@ -373,7 +360,7 @@ bool GodotPhysicsDirectSpaceState2D::collide_shape(RID p_shape, const Transform2
cbk.valid_dir = Vector2(); cbk.valid_dir = Vector2();
cbk.valid_depth = 0; cbk.valid_depth = 0;
if (GodotCollisionSolver2D::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, nullptr, p_margin)) { if (GodotCollisionSolver2D::solve(shape, p_parameters.transform, p_parameters.motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, nullptr, p_parameters.margin)) {
collided = cbk.amount > 0; collided = cbk.amount > 0;
} }
} }
@ -432,15 +419,15 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B,
rd->best_local_shape = rd->local_shape; rd->best_local_shape = rd->local_shape;
} }
bool GodotPhysicsDirectSpaceState2D::rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { bool GodotPhysicsDirectSpaceState2D::rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) {
GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_shape); GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid);
ERR_FAIL_COND_V(!shape, 0); ERR_FAIL_COND_V(!shape, 0);
real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR; real_t min_contact_depth = p_parameters.margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
Rect2 aabb = p_shape_xform.xform(shape->get_aabb()); Rect2 aabb = p_parameters.transform.xform(shape->get_aabb());
aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion aabb = aabb.merge(Rect2(aabb.position + p_parameters.motion, aabb.size)); //motion
aabb = aabb.grow(p_margin); aabb = aabb.grow(p_parameters.margin);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@ -451,13 +438,13 @@ bool GodotPhysicsDirectSpaceState2D::rest_info(RID p_shape, const Transform2D &p
rcd.min_allowed_depth = min_contact_depth; rcd.min_allowed_depth = min_contact_depth;
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { if (!_can_collide_with(space->intersection_query_results[i], p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas)) {
continue; continue;
} }
const GodotCollisionObject2D *col_obj = space->intersection_query_results[i]; const GodotCollisionObject2D *col_obj = space->intersection_query_results[i];
if (p_exclude.has(col_obj->get_self())) { if (p_parameters.exclude.has(col_obj->get_self())) {
continue; continue;
} }
@ -467,7 +454,7 @@ bool GodotPhysicsDirectSpaceState2D::rest_info(RID p_shape, const Transform2D &p
rcd.object = col_obj; rcd.object = col_obj;
rcd.shape = shape_idx; rcd.shape = shape_idx;
rcd.local_shape = 0; rcd.local_shape = 0;
bool sc = GodotCollisionSolver2D::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, nullptr, p_margin); bool sc = GodotCollisionSolver2D::solve(shape, p_parameters.transform, p_parameters.motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, nullptr, p_parameters.margin);
if (!sc) { if (!sc) {
continue; continue;
} }

View File

@ -45,18 +45,15 @@
class GodotPhysicsDirectSpaceState2D : public PhysicsDirectSpaceState2D { class GodotPhysicsDirectSpaceState2D : public PhysicsDirectSpaceState2D {
GDCLASS(GodotPhysicsDirectSpaceState2D, PhysicsDirectSpaceState2D); GDCLASS(GodotPhysicsDirectSpaceState2D, PhysicsDirectSpaceState2D);
int _intersect_point_impl(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point, bool p_filter_by_canvas = false, ObjectID p_canvas_instance_id = ObjectID());
public: public:
GodotSpace2D *space = nullptr; GodotSpace2D *space = nullptr;
virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) override; virtual int intersect_point(const PointParameters &p_parameters, ShapeResult *r_results, int p_result_max) override;
virtual int intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) override; virtual bool intersect_ray(const RayParameters &p_parameters, RayResult &r_result) override;
virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual int intersect_shape(const ShapeParameters &p_parameters, ShapeResult *r_results, int p_result_max) override;
virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual bool cast_motion(const ShapeParameters &p_parameters, real_t &p_closest_safe, real_t &p_closest_unsafe) override;
virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual bool collide_shape(const ShapeParameters &p_parameters, Vector2 *r_results, int p_result_max, int &r_result_count) override;
virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual bool rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) override;
virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override;
GodotPhysicsDirectSpaceState2D() {} GodotPhysicsDirectSpaceState2D() {}
}; };

View File

@ -57,9 +57,9 @@ _FORCE_INLINE_ static bool _can_collide_with(GodotCollisionObject3D *p_object, u
return true; return true;
} }
int GodotPhysicsDirectSpaceState3D::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { int GodotPhysicsDirectSpaceState3D::intersect_point(const PointParameters &p_parameters, ShapeResult *r_results, int p_result_max) {
ERR_FAIL_COND_V(space->locked, false); ERR_FAIL_COND_V(space->locked, false);
int amount = space->broadphase->cull_point(p_point, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int amount = space->broadphase->cull_point(p_parameters.position, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
int cc = 0; int cc = 0;
//Transform3D ai = p_xform.affine_inverse(); //Transform3D ai = p_xform.affine_inverse();
@ -69,13 +69,13 @@ int GodotPhysicsDirectSpaceState3D::intersect_point(const Vector3 &p_point, Shap
break; break;
} }
if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { if (!_can_collide_with(space->intersection_query_results[i], p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas)) {
continue; continue;
} }
//area can't be picked by ray (default) //area can't be picked by ray (default)
if (p_exclude.has(space->intersection_query_results[i]->get_self())) { if (p_parameters.exclude.has(space->intersection_query_results[i]->get_self())) {
continue; continue;
} }
@ -85,7 +85,7 @@ int GodotPhysicsDirectSpaceState3D::intersect_point(const Vector3 &p_point, Shap
Transform3D inv_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); Transform3D inv_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
inv_xform.affine_invert(); inv_xform.affine_invert();
if (!col_obj->get_shape(shape_idx)->intersect_point(inv_xform.xform(p_point))) { if (!col_obj->get_shape(shape_idx)->intersect_point(inv_xform.xform(p_parameters.position))) {
continue; continue;
} }
@ -104,13 +104,13 @@ int GodotPhysicsDirectSpaceState3D::intersect_point(const Vector3 &p_point, Shap
return cc; return cc;
} }
bool GodotPhysicsDirectSpaceState3D::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_ray) { bool GodotPhysicsDirectSpaceState3D::intersect_ray(const RayParameters &p_parameters, RayResult &r_result) {
ERR_FAIL_COND_V(space->locked, false); ERR_FAIL_COND_V(space->locked, false);
Vector3 begin, end; Vector3 begin, end;
Vector3 normal; Vector3 normal;
begin = p_from; begin = p_parameters.from;
end = p_to; end = p_parameters.to;
normal = (end - begin).normalized(); normal = (end - begin).normalized();
int amount = space->broadphase->cull_segment(begin, end, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int amount = space->broadphase->cull_segment(begin, end, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@ -124,15 +124,15 @@ bool GodotPhysicsDirectSpaceState3D::intersect_ray(const Vector3 &p_from, const
real_t min_d = 1e10; real_t min_d = 1e10;
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { if (!_can_collide_with(space->intersection_query_results[i], p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas)) {
continue; continue;
} }
if (p_pick_ray && !(space->intersection_query_results[i]->is_ray_pickable())) { if (p_parameters.pick_ray && !(space->intersection_query_results[i]->is_ray_pickable())) {
continue; continue;
} }
if (p_exclude.has(space->intersection_query_results[i]->get_self())) { if (p_parameters.exclude.has(space->intersection_query_results[i]->get_self())) {
continue; continue;
} }
@ -183,15 +183,15 @@ bool GodotPhysicsDirectSpaceState3D::intersect_ray(const Vector3 &p_from, const
return true; return true;
} }
int GodotPhysicsDirectSpaceState3D::intersect_shape(const RID &p_shape, const Transform3D &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { int GodotPhysicsDirectSpaceState3D::intersect_shape(const ShapeParameters &p_parameters, ShapeResult *r_results, int p_result_max) {
if (p_result_max <= 0) { if (p_result_max <= 0) {
return 0; return 0;
} }
GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_shape); GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid);
ERR_FAIL_COND_V(!shape, 0); ERR_FAIL_COND_V(!shape, 0);
AABB aabb = p_xform.xform(shape->get_aabb()); AABB aabb = p_parameters.transform.xform(shape->get_aabb());
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@ -204,20 +204,20 @@ int GodotPhysicsDirectSpaceState3D::intersect_shape(const RID &p_shape, const Tr
break; break;
} }
if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { if (!_can_collide_with(space->intersection_query_results[i], p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas)) {
continue; continue;
} }
//area can't be picked by ray (default) //area can't be picked by ray (default)
if (p_exclude.has(space->intersection_query_results[i]->get_self())) { if (p_parameters.exclude.has(space->intersection_query_results[i]->get_self())) {
continue; continue;
} }
const GodotCollisionObject3D *col_obj = space->intersection_query_results[i]; const GodotCollisionObject3D *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i]; int shape_idx = space->intersection_query_subindex_results[i];
if (!GodotCollisionSolver3D::solve_static(shape, p_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), nullptr, nullptr, nullptr, p_margin, 0)) { if (!GodotCollisionSolver3D::solve_static(shape, p_parameters.transform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), nullptr, nullptr, nullptr, p_parameters.margin, 0)) {
continue; continue;
} }
@ -238,36 +238,36 @@ int GodotPhysicsDirectSpaceState3D::intersect_shape(const RID &p_shape, const Tr
return cc; return cc;
} }
bool GodotPhysicsDirectSpaceState3D::cast_motion(const RID &p_shape, const Transform3D &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { bool GodotPhysicsDirectSpaceState3D::cast_motion(const ShapeParameters &p_parameters, real_t &p_closest_safe, real_t &p_closest_unsafe, ShapeRestInfo *r_info) {
GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_shape); GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid);
ERR_FAIL_COND_V(!shape, false); ERR_FAIL_COND_V(!shape, false);
AABB aabb = p_xform.xform(shape->get_aabb()); AABB aabb = p_parameters.transform.xform(shape->get_aabb());
aabb = aabb.merge(AABB(aabb.position + p_motion, aabb.size)); //motion aabb = aabb.merge(AABB(aabb.position + p_parameters.motion, aabb.size)); //motion
aabb = aabb.grow(p_margin); aabb = aabb.grow(p_parameters.margin);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
real_t best_safe = 1; real_t best_safe = 1;
real_t best_unsafe = 1; real_t best_unsafe = 1;
Transform3D xform_inv = p_xform.affine_inverse(); Transform3D xform_inv = p_parameters.transform.affine_inverse();
GodotMotionShape3D mshape; GodotMotionShape3D mshape;
mshape.shape = shape; mshape.shape = shape;
mshape.motion = xform_inv.basis.xform(p_motion); mshape.motion = xform_inv.basis.xform(p_parameters.motion);
bool best_first = true; bool best_first = true;
Vector3 motion_normal = p_motion.normalized(); Vector3 motion_normal = p_parameters.motion.normalized();
Vector3 closest_A, closest_B; Vector3 closest_A, closest_B;
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { if (!_can_collide_with(space->intersection_query_results[i], p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas)) {
continue; continue;
} }
if (p_exclude.has(space->intersection_query_results[i]->get_self())) { if (p_parameters.exclude.has(space->intersection_query_results[i]->get_self())) {
continue; //ignore excluded continue; //ignore excluded
} }
@ -279,14 +279,14 @@ bool GodotPhysicsDirectSpaceState3D::cast_motion(const RID &p_shape, const Trans
Transform3D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); Transform3D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
//test initial overlap, does it collide if going all the way? //test initial overlap, does it collide if going all the way?
if (GodotCollisionSolver3D::solve_distance(&mshape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) { if (GodotCollisionSolver3D::solve_distance(&mshape, p_parameters.transform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) {
continue; continue;
} }
//test initial overlap, ignore objects it's inside of. //test initial overlap, ignore objects it's inside of.
sep_axis = motion_normal; sep_axis = motion_normal;
if (!GodotCollisionSolver3D::solve_distance(shape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) { if (!GodotCollisionSolver3D::solve_distance(shape, p_parameters.transform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) {
continue; continue;
} }
@ -297,11 +297,11 @@ bool GodotPhysicsDirectSpaceState3D::cast_motion(const RID &p_shape, const Trans
for (int j = 0; j < 8; j++) { //steps should be customizable.. for (int j = 0; j < 8; j++) { //steps should be customizable..
real_t fraction = low + (hi - low) * fraction_coeff; real_t fraction = low + (hi - low) * fraction_coeff;
mshape.motion = xform_inv.basis.xform(p_motion * fraction); mshape.motion = xform_inv.basis.xform(p_parameters.motion * fraction);
Vector3 lA, lB; Vector3 lA, lB;
Vector3 sep = motion_normal; //important optimization for this to work fast enough Vector3 sep = motion_normal; //important optimization for this to work fast enough
bool collided = !GodotCollisionSolver3D::solve_distance(&mshape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, aabb, &sep); bool collided = !GodotCollisionSolver3D::solve_distance(&mshape, p_parameters.transform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, aabb, &sep);
if (collided) { if (collided) {
hi = fraction; hi = fraction;
@ -357,16 +357,16 @@ bool GodotPhysicsDirectSpaceState3D::cast_motion(const RID &p_shape, const Trans
return true; return true;
} }
bool GodotPhysicsDirectSpaceState3D::collide_shape(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { bool GodotPhysicsDirectSpaceState3D::collide_shape(const ShapeParameters &p_parameters, Vector3 *r_results, int p_result_max, int &r_result_count) {
if (p_result_max <= 0) { if (p_result_max <= 0) {
return false; return false;
} }
GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_shape); GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid);
ERR_FAIL_COND_V(!shape, 0); ERR_FAIL_COND_V(!shape, 0);
AABB aabb = p_shape_xform.xform(shape->get_aabb()); AABB aabb = p_parameters.transform.xform(shape->get_aabb());
aabb = aabb.grow(p_margin); aabb = aabb.grow(p_parameters.margin);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@ -382,19 +382,19 @@ bool GodotPhysicsDirectSpaceState3D::collide_shape(RID p_shape, const Transform3
GodotPhysicsServer3D::CollCbkData *cbkptr = &cbk; GodotPhysicsServer3D::CollCbkData *cbkptr = &cbk;
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { if (!_can_collide_with(space->intersection_query_results[i], p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas)) {
continue; continue;
} }
const GodotCollisionObject3D *col_obj = space->intersection_query_results[i]; const GodotCollisionObject3D *col_obj = space->intersection_query_results[i];
if (p_exclude.has(col_obj->get_self())) { if (p_parameters.exclude.has(col_obj->get_self())) {
continue; continue;
} }
int shape_idx = space->intersection_query_subindex_results[i]; int shape_idx = space->intersection_query_subindex_results[i];
if (GodotCollisionSolver3D::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_margin)) { if (GodotCollisionSolver3D::solve_static(shape, p_parameters.transform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_parameters.margin)) {
collided = true; collided = true;
} }
} }
@ -487,14 +487,14 @@ static void _rest_cbk_result(const Vector3 &p_point_A, int p_index_A, const Vect
rd->best_result.local_shape = rd->local_shape; rd->best_result.local_shape = rd->local_shape;
} }
bool GodotPhysicsDirectSpaceState3D::rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { bool GodotPhysicsDirectSpaceState3D::rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) {
GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_shape); GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid);
ERR_FAIL_COND_V(!shape, 0); ERR_FAIL_COND_V(!shape, 0);
real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR; real_t min_contact_depth = p_parameters.margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
AABB aabb = p_shape_xform.xform(shape->get_aabb()); AABB aabb = p_parameters.transform.xform(shape->get_aabb());
aabb = aabb.grow(p_margin); aabb = aabb.grow(p_parameters.margin);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@ -502,13 +502,13 @@ bool GodotPhysicsDirectSpaceState3D::rest_info(RID p_shape, const Transform3D &p
rcd.min_allowed_depth = min_contact_depth; rcd.min_allowed_depth = min_contact_depth;
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { if (!_can_collide_with(space->intersection_query_results[i], p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas)) {
continue; continue;
} }
const GodotCollisionObject3D *col_obj = space->intersection_query_results[i]; const GodotCollisionObject3D *col_obj = space->intersection_query_results[i];
if (p_exclude.has(col_obj->get_self())) { if (p_parameters.exclude.has(col_obj->get_self())) {
continue; continue;
} }
@ -516,7 +516,7 @@ bool GodotPhysicsDirectSpaceState3D::rest_info(RID p_shape, const Transform3D &p
rcd.object = col_obj; rcd.object = col_obj;
rcd.shape = shape_idx; rcd.shape = shape_idx;
bool sc = GodotCollisionSolver3D::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin); bool sc = GodotCollisionSolver3D::solve_static(shape, p_parameters.transform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_parameters.margin);
if (!sc) { if (!sc) {
continue; continue;
} }

View File

@ -49,12 +49,12 @@ class GodotPhysicsDirectSpaceState3D : public PhysicsDirectSpaceState3D {
public: public:
GodotSpace3D *space; GodotSpace3D *space;
virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual int intersect_point(const PointParameters &p_parameters, ShapeResult *r_results, int p_result_max) override;
virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false) override; virtual bool intersect_ray(const RayParameters &p_parameters, RayResult &r_result) override;
virtual int intersect_shape(const RID &p_shape, const Transform3D &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual int intersect_shape(const ShapeParameters &p_parameters, ShapeResult *r_results, int p_result_max) override;
virtual bool cast_motion(const RID &p_shape, const Transform3D &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) override; virtual bool cast_motion(const ShapeParameters &p_parameters, real_t &p_closest_safe, real_t &p_closest_unsafe, ShapeRestInfo *r_info = nullptr) override;
virtual bool collide_shape(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual bool collide_shape(const ShapeParameters &p_parameters, Vector3 *r_results, int p_result_max, int &r_result_count) override;
virtual bool rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual bool rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) override;
virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const override; virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const override;
GodotPhysicsDirectSpaceState3D(); GodotPhysicsDirectSpaceState3D();

View File

@ -134,95 +134,132 @@ PhysicsDirectBodyState2D::PhysicsDirectBodyState2D() {}
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
void PhysicsShapeQueryParameters2D::set_shape(const RES &p_shape_ref) { void PhysicsRayQueryParameters2D::set_exclude(const Vector<RID> &p_exclude) {
ERR_FAIL_COND(p_shape_ref.is_null()); parameters.exclude.clear();
shape_ref = p_shape_ref;
shape = p_shape_ref->get_rid();
}
RES PhysicsShapeQueryParameters2D::get_shape() const {
return shape_ref;
}
void PhysicsShapeQueryParameters2D::set_shape_rid(const RID &p_shape) {
if (shape != p_shape) {
shape_ref = RES();
shape = p_shape;
}
}
RID PhysicsShapeQueryParameters2D::get_shape_rid() const {
return shape;
}
void PhysicsShapeQueryParameters2D::set_transform(const Transform2D &p_transform) {
transform = p_transform;
}
Transform2D PhysicsShapeQueryParameters2D::get_transform() const {
return transform;
}
void PhysicsShapeQueryParameters2D::set_motion(const Vector2 &p_motion) {
motion = p_motion;
}
Vector2 PhysicsShapeQueryParameters2D::get_motion() const {
return motion;
}
void PhysicsShapeQueryParameters2D::set_margin(real_t p_margin) {
margin = p_margin;
}
real_t PhysicsShapeQueryParameters2D::get_margin() const {
return margin;
}
void PhysicsShapeQueryParameters2D::set_collision_mask(uint32_t p_collision_mask) {
collision_mask = p_collision_mask;
}
uint32_t PhysicsShapeQueryParameters2D::get_collision_mask() const {
return collision_mask;
}
void PhysicsShapeQueryParameters2D::set_exclude(const Vector<RID> &p_exclude) {
exclude.clear();
for (int i = 0; i < p_exclude.size(); i++) { for (int i = 0; i < p_exclude.size(); i++) {
exclude.insert(p_exclude[i]); parameters.exclude.insert(p_exclude[i]);
} }
} }
Vector<RID> PhysicsShapeQueryParameters2D::get_exclude() const { Vector<RID> PhysicsRayQueryParameters2D::get_exclude() const {
Vector<RID> ret; Vector<RID> ret;
ret.resize(exclude.size()); ret.resize(parameters.exclude.size());
int idx = 0; int idx = 0;
for (Set<RID>::Element *E = exclude.front(); E; E = E->next()) { for (Set<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) {
ret.write[idx++] = E->get(); ret.write[idx++] = E->get();
} }
return ret; return ret;
} }
void PhysicsShapeQueryParameters2D::set_collide_with_bodies(bool p_enable) { void PhysicsRayQueryParameters2D::_bind_methods() {
collide_with_bodies = p_enable; ClassDB::bind_method(D_METHOD("set_from", "from"), &PhysicsRayQueryParameters2D::set_from);
ClassDB::bind_method(D_METHOD("get_from"), &PhysicsRayQueryParameters2D::get_from);
ClassDB::bind_method(D_METHOD("set_to", "to"), &PhysicsRayQueryParameters2D::set_to);
ClassDB::bind_method(D_METHOD("get_to"), &PhysicsRayQueryParameters2D::get_to);
ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &PhysicsRayQueryParameters2D::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &PhysicsRayQueryParameters2D::get_collision_mask);
ClassDB::bind_method(D_METHOD("set_exclude", "exclude"), &PhysicsRayQueryParameters2D::set_exclude);
ClassDB::bind_method(D_METHOD("get_exclude"), &PhysicsRayQueryParameters2D::get_exclude);
ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &PhysicsRayQueryParameters2D::set_collide_with_bodies);
ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &PhysicsRayQueryParameters2D::is_collide_with_bodies_enabled);
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);
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");
} }
bool PhysicsShapeQueryParameters2D::is_collide_with_bodies_enabled() const { ///////////////////////////////////////////////////////
return collide_with_bodies;
void PhysicsPointQueryParameters2D::set_exclude(const Vector<RID> &p_exclude) {
parameters.exclude.clear();
for (int i = 0; i < p_exclude.size(); i++) {
parameters.exclude.insert(p_exclude[i]);
}
} }
void PhysicsShapeQueryParameters2D::set_collide_with_areas(bool p_enable) { Vector<RID> PhysicsPointQueryParameters2D::get_exclude() const {
collide_with_areas = p_enable; Vector<RID> ret;
ret.resize(parameters.exclude.size());
int idx = 0;
for (Set<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) {
ret.write[idx++] = E->get();
}
return ret;
} }
bool PhysicsShapeQueryParameters2D::is_collide_with_areas_enabled() const { void PhysicsPointQueryParameters2D::_bind_methods() {
return collide_with_areas; ClassDB::bind_method(D_METHOD("set_position", "position"), &PhysicsPointQueryParameters2D::set_position);
ClassDB::bind_method(D_METHOD("get_position"), &PhysicsPointQueryParameters2D::get_position);
ClassDB::bind_method(D_METHOD("set_canvas_instance_id", "canvas_instance_id"), &PhysicsPointQueryParameters2D::set_canvas_instance_id);
ClassDB::bind_method(D_METHOD("get_canvas_instance_id"), &PhysicsPointQueryParameters2D::get_canvas_instance_id);
ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &PhysicsPointQueryParameters2D::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &PhysicsPointQueryParameters2D::get_collision_mask);
ClassDB::bind_method(D_METHOD("set_exclude", "exclude"), &PhysicsPointQueryParameters2D::set_exclude);
ClassDB::bind_method(D_METHOD("get_exclude"), &PhysicsPointQueryParameters2D::get_exclude);
ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &PhysicsPointQueryParameters2D::set_collide_with_bodies);
ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &PhysicsPointQueryParameters2D::is_collide_with_bodies_enabled);
ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &PhysicsPointQueryParameters2D::set_collide_with_areas);
ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &PhysicsPointQueryParameters2D::is_collide_with_areas_enabled);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position");
ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_instance_id", PROPERTY_HINT_OBJECT_ID), "set_canvas_instance_id", "get_canvas_instance_id");
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");
}
///////////////////////////////////////////////////////
void PhysicsShapeQueryParameters2D::set_shape(const RES &p_shape_ref) {
ERR_FAIL_COND(p_shape_ref.is_null());
shape_ref = p_shape_ref;
parameters.shape_rid = p_shape_ref->get_rid();
}
void PhysicsShapeQueryParameters2D::set_shape_rid(const RID &p_shape) {
if (parameters.shape_rid != p_shape) {
shape_ref = RES();
parameters.shape_rid = p_shape;
}
}
void PhysicsShapeQueryParameters2D::set_exclude(const Vector<RID> &p_exclude) {
parameters.exclude.clear();
for (int i = 0; i < p_exclude.size(); i++) {
parameters.exclude.insert(p_exclude[i]);
}
}
Vector<RID> PhysicsShapeQueryParameters2D::get_exclude() const {
Vector<RID> ret;
ret.resize(parameters.exclude.size());
int idx = 0;
for (Set<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) {
ret.write[idx++] = E->get();
}
return ret;
} }
void PhysicsShapeQueryParameters2D::_bind_methods() { void PhysicsShapeQueryParameters2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters2D::set_shape); ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters2D::set_shape);
ClassDB::bind_method(D_METHOD("get_shape"), &PhysicsShapeQueryParameters2D::get_shape); ClassDB::bind_method(D_METHOD("get_shape"), &PhysicsShapeQueryParameters2D::get_shape);
ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &PhysicsShapeQueryParameters2D::set_shape_rid); ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &PhysicsShapeQueryParameters2D::set_shape_rid);
ClassDB::bind_method(D_METHOD("get_shape_rid"), &PhysicsShapeQueryParameters2D::get_shape_rid); ClassDB::bind_method(D_METHOD("get_shape_rid"), &PhysicsShapeQueryParameters2D::get_shape_rid);
@ -248,7 +285,7 @@ void PhysicsShapeQueryParameters2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &PhysicsShapeQueryParameters2D::is_collide_with_areas_enabled); ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &PhysicsShapeQueryParameters2D::is_collide_with_areas_enabled);
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask"); 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_NONE, itos(Variant::RID) + ":"), "set_exclude", "get_exclude"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_exclude", "get_exclude");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion"), "set_motion", "get_motion"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion"), "set_motion", "get_motion");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape");
@ -258,80 +295,34 @@ void PhysicsShapeQueryParameters2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas"), "set_collide_with_areas", "is_collide_with_areas_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas"), "set_collide_with_areas", "is_collide_with_areas_enabled");
} }
Dictionary PhysicsDirectSpaceState2D::_intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) { ///////////////////////////////////////////////////////
RayResult inters;
Set<RID> exclude;
for (int i = 0; i < p_exclude.size(); i++) {
exclude.insert(p_exclude[i]);
}
bool res = intersect_ray(p_from, p_to, inters, exclude, p_layers, p_collide_with_bodies, p_collide_with_areas); Dictionary PhysicsDirectSpaceState2D::_intersect_ray(const Ref<PhysicsRayQueryParameters2D> &p_ray_query) {
ERR_FAIL_COND_V(!p_ray_query.is_valid(), Dictionary());
RayResult result;
bool res = intersect_ray(p_ray_query->get_parameters(), result);
if (!res) { if (!res) {
return Dictionary(); return Dictionary();
} }
Dictionary d; Dictionary d;
d["position"] = inters.position; d["position"] = result.position;
d["normal"] = inters.normal; d["normal"] = result.normal;
d["collider_id"] = inters.collider_id; d["collider_id"] = result.collider_id;
d["collider"] = inters.collider; d["collider"] = result.collider;
d["shape"] = inters.shape; d["shape"] = result.shape;
d["rid"] = inters.rid; d["rid"] = result.rid;
return d; return d;
} }
Array PhysicsDirectSpaceState2D::_intersect_shape(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query, int p_max_results) { Array PhysicsDirectSpaceState2D::_intersect_point(const Ref<PhysicsPointQueryParameters2D> &p_point_query, int p_max_results) {
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
Vector<ShapeResult> sr;
sr.resize(p_max_results);
int rc = intersect_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, sr.ptrw(), sr.size(), p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
Array ret;
ret.resize(rc);
for (int i = 0; i < rc; i++) {
Dictionary d;
d["rid"] = sr[i].rid;
d["collider_id"] = sr[i].collider_id;
d["collider"] = sr[i].collider;
d["shape"] = sr[i].shape;
ret[i] = d;
}
return ret;
}
Array PhysicsDirectSpaceState2D::_cast_motion(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query) {
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
real_t closest_safe, closest_unsafe;
bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
if (!res) {
return Array();
}
Array ret;
ret.resize(2);
ret[0] = closest_safe;
ret[1] = closest_unsafe;
return ret;
}
Array PhysicsDirectSpaceState2D::_intersect_point_impl(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_filter_by_canvas, ObjectID p_canvas_instance_id) {
Set<RID> exclude;
for (int i = 0; i < p_exclude.size(); i++) {
exclude.insert(p_exclude[i]);
}
Vector<ShapeResult> ret; Vector<ShapeResult> ret;
ret.resize(p_max_results); ret.resize(p_max_results);
int rc; int rc = intersect_point(p_point_query->get_parameters(), ret.ptrw(), ret.size());
if (p_filter_by_canvas) {
rc = intersect_point(p_point, ret.ptrw(), ret.size(), exclude, p_layers, p_collide_with_bodies, p_collide_with_areas);
} else {
rc = intersect_point_on_canvas(p_point, p_canvas_instance_id, ret.ptrw(), ret.size(), exclude, p_layers, p_collide_with_bodies, p_collide_with_areas);
}
if (rc == 0) { if (rc == 0) {
return Array(); return Array();
@ -350,12 +341,39 @@ Array PhysicsDirectSpaceState2D::_intersect_point_impl(const Vector2 &p_point, i
return r; return r;
} }
Array PhysicsDirectSpaceState2D::_intersect_point(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) { Array PhysicsDirectSpaceState2D::_intersect_shape(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query, int p_max_results) {
return _intersect_point_impl(p_point, p_max_results, p_exclude, p_layers, p_collide_with_bodies, p_collide_with_areas); ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
Vector<ShapeResult> sr;
sr.resize(p_max_results);
int rc = intersect_shape(p_shape_query->get_parameters(), sr.ptrw(), sr.size());
Array ret;
ret.resize(rc);
for (int i = 0; i < rc; i++) {
Dictionary d;
d["rid"] = sr[i].rid;
d["collider_id"] = sr[i].collider_id;
d["collider"] = sr[i].collider;
d["shape"] = sr[i].shape;
ret[i] = d;
} }
Array PhysicsDirectSpaceState2D::_intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_intance_id, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) { return ret;
return _intersect_point_impl(p_point, p_max_results, p_exclude, p_layers, p_collide_with_bodies, p_collide_with_areas, true, p_canvas_intance_id); }
Array PhysicsDirectSpaceState2D::_cast_motion(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query) {
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
real_t closest_safe, closest_unsafe;
bool res = cast_motion(p_shape_query->get_parameters(), closest_safe, closest_unsafe);
if (!res) {
return Array();
}
Array ret;
ret.resize(2);
ret[0] = closest_safe;
ret[1] = closest_unsafe;
return ret;
} }
Array PhysicsDirectSpaceState2D::_collide_shape(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query, int p_max_results) { Array PhysicsDirectSpaceState2D::_collide_shape(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query, int p_max_results) {
@ -364,7 +382,7 @@ Array PhysicsDirectSpaceState2D::_collide_shape(const Ref<PhysicsShapeQueryParam
Vector<Vector2> ret; Vector<Vector2> ret;
ret.resize(p_max_results * 2); ret.resize(p_max_results * 2);
int rc = 0; int rc = 0;
bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, ret.ptrw(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); bool res = collide_shape(p_shape_query->get_parameters(), ret.ptrw(), p_max_results, rc);
if (!res) { if (!res) {
return Array(); return Array();
} }
@ -381,7 +399,7 @@ Dictionary PhysicsDirectSpaceState2D::_get_rest_info(const Ref<PhysicsShapeQuery
ShapeRestInfo sri; ShapeRestInfo sri;
bool res = rest_info(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, &sri, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); bool res = rest_info(p_shape_query->get_parameters(), &sri);
Dictionary r; Dictionary r;
if (!res) { if (!res) {
return r; return r;
@ -401,13 +419,12 @@ PhysicsDirectSpaceState2D::PhysicsDirectSpaceState2D() {
} }
void PhysicsDirectSpaceState2D::_bind_methods() { void PhysicsDirectSpaceState2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("intersect_point", "point", "max_results", "exclude", "collision_mask", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState2D::_intersect_point, DEFVAL(32), DEFVAL(Array()), DEFVAL(UINT32_MAX), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("intersect_point", "parameters", "max_results"), &PhysicsDirectSpaceState2D::_intersect_point, DEFVAL(32));
ClassDB::bind_method(D_METHOD("intersect_point_on_canvas", "point", "canvas_instance_id", "max_results", "exclude", "collision_mask", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState2D::_intersect_point_on_canvas, DEFVAL(32), DEFVAL(Array()), DEFVAL(UINT32_MAX), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("intersect_ray", "parameters"), &PhysicsDirectSpaceState2D::_intersect_ray);
ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_mask", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState2D::_intersect_ray, DEFVAL(Array()), DEFVAL(UINT32_MAX), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("intersect_shape", "parameters", "max_results"), &PhysicsDirectSpaceState2D::_intersect_shape, DEFVAL(32));
ClassDB::bind_method(D_METHOD("intersect_shape", "shape", "max_results"), &PhysicsDirectSpaceState2D::_intersect_shape, DEFVAL(32)); ClassDB::bind_method(D_METHOD("cast_motion", "parameters"), &PhysicsDirectSpaceState2D::_cast_motion);
ClassDB::bind_method(D_METHOD("cast_motion", "shape"), &PhysicsDirectSpaceState2D::_cast_motion); ClassDB::bind_method(D_METHOD("collide_shape", "parameters", "max_results"), &PhysicsDirectSpaceState2D::_collide_shape, DEFVAL(32));
ClassDB::bind_method(D_METHOD("collide_shape", "shape", "max_results"), &PhysicsDirectSpaceState2D::_collide_shape, DEFVAL(32)); ClassDB::bind_method(D_METHOD("get_rest_info", "parameters"), &PhysicsDirectSpaceState2D::_get_rest_info);
ClassDB::bind_method(D_METHOD("get_rest_info", "shape"), &PhysicsDirectSpaceState2D::_get_rest_info);
} }
/////////////////////////////// ///////////////////////////////
@ -473,7 +490,7 @@ void PhysicsTestMotionParameters2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion"), "set_motion", "get_motion"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion"), "set_motion", "get_motion");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_separation_ray"), "set_collide_separation_ray_enabled", "is_collide_separation_ray_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_separation_ray"), "set_collide_separation_ray_enabled", "is_collide_separation_ray_enabled");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_bodies"), "set_exclude_bodies", "get_exclude_bodies"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_bodies", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_exclude_bodies", "get_exclude_bodies");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_objects"), "set_exclude_objects", "get_exclude_objects"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_objects"), "set_exclude_objects", "get_exclude_objects");
} }

View File

@ -94,60 +94,15 @@ public:
PhysicsDirectBodyState2D(); PhysicsDirectBodyState2D();
}; };
//used for script class PhysicsRayQueryParameters2D;
class PhysicsShapeQueryParameters2D : public RefCounted { class PhysicsPointQueryParameters2D;
GDCLASS(PhysicsShapeQueryParameters2D, RefCounted); class PhysicsShapeQueryParameters2D;
friend class PhysicsDirectSpaceState2D;
RES shape_ref;
RID shape;
Transform2D transform;
Vector2 motion;
real_t margin = 0.0;
Set<RID> exclude;
uint32_t collision_mask = UINT32_MAX;
bool collide_with_bodies = true;
bool collide_with_areas = false;
protected:
static void _bind_methods();
public:
void set_shape(const RES &p_shape_ref);
RES get_shape() const;
void set_shape_rid(const RID &p_shape);
RID get_shape_rid() const;
void set_transform(const Transform2D &p_transform);
Transform2D get_transform() const;
void set_motion(const Vector2 &p_motion);
Vector2 get_motion() const;
void set_margin(real_t p_margin);
real_t get_margin() const;
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
void set_collide_with_bodies(bool p_enable);
bool is_collide_with_bodies_enabled() const;
void set_collide_with_areas(bool p_enable);
bool is_collide_with_areas_enabled() const;
void set_exclude(const Vector<RID> &p_exclude);
Vector<RID> get_exclude() const;
};
class PhysicsDirectSpaceState2D : public Object { class PhysicsDirectSpaceState2D : public Object {
GDCLASS(PhysicsDirectSpaceState2D, Object); GDCLASS(PhysicsDirectSpaceState2D, Object);
Dictionary _intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); Dictionary _intersect_ray(const Ref<PhysicsRayQueryParameters2D> &p_ray_query);
Array _intersect_point(const Vector2 &p_point, int p_max_results = 32, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); Array _intersect_point(const Ref<PhysicsPointQueryParameters2D> &p_point_query, int p_max_results = 32);
Array _intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_intance_id, int p_max_results = 32, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
Array _intersect_point_impl(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclud, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_filter_by_canvas = false, ObjectID p_canvas_instance_id = ObjectID());
Array _intersect_shape(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query, int p_max_results = 32); Array _intersect_shape(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query, int p_max_results = 32);
Array _cast_motion(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query); Array _cast_motion(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query);
Array _collide_shape(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query, int p_max_results = 32); Array _collide_shape(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query, int p_max_results = 32);
@ -157,6 +112,16 @@ protected:
static void _bind_methods(); static void _bind_methods();
public: public:
struct RayParameters {
Vector2 from;
Vector2 to;
Set<RID> exclude;
uint32_t collision_mask = UINT32_MAX;
bool collide_with_bodies = true;
bool collide_with_areas = false;
};
struct RayResult { struct RayResult {
Vector2 position; Vector2 position;
Vector2 normal; Vector2 normal;
@ -166,7 +131,7 @@ public:
int shape = 0; int shape = 0;
}; };
virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; virtual bool intersect_ray(const RayParameters &p_parameters, RayResult &r_result) = 0;
struct ShapeResult { struct ShapeResult {
RID rid; RID rid;
@ -175,14 +140,31 @@ public:
int shape = 0; int shape = 0;
}; };
virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) = 0; struct PointParameters {
virtual int intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) = 0; Vector2 position;
ObjectID canvas_instance_id;
Set<RID> exclude;
uint32_t collision_mask = UINT32_MAX;
virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; bool collide_with_bodies = true;
bool collide_with_areas = false;
virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; bool pick_point = false;
};
virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; virtual int intersect_point(const PointParameters &p_parameters, ShapeResult *r_results, int p_result_max) = 0;
struct ShapeParameters {
RID shape_rid;
Transform2D transform;
Vector2 motion;
real_t margin = 0.0;
Set<RID> exclude;
uint32_t collision_mask = UINT32_MAX;
bool collide_with_bodies = true;
bool collide_with_areas = false;
};
struct ShapeRestInfo { struct ShapeRestInfo {
Vector2 point; Vector2 point;
@ -190,10 +172,13 @@ public:
RID rid; RID rid;
ObjectID collider_id; ObjectID collider_id;
int shape = 0; int shape = 0;
Vector2 linear_velocity; //velocity at contact point Vector2 linear_velocity; // Velocity at contact point.
}; };
virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; virtual int intersect_shape(const ShapeParameters &p_parameters, ShapeResult *r_results, int p_result_max) = 0;
virtual bool cast_motion(const ShapeParameters &p_parameters, real_t &p_closest_safe, real_t &p_closest_unsafe) = 0;
virtual bool collide_shape(const ShapeParameters &p_parameters, Vector2 *r_results, int p_result_max, int &r_result_count) = 0;
virtual bool rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) = 0;
PhysicsDirectSpaceState2D(); PhysicsDirectSpaceState2D();
}; };
@ -592,6 +577,107 @@ public:
~PhysicsServer2D(); ~PhysicsServer2D();
}; };
class PhysicsRayQueryParameters2D : public RefCounted {
GDCLASS(PhysicsRayQueryParameters2D, RefCounted);
PhysicsDirectSpaceState2D::RayParameters parameters;
protected:
static void _bind_methods();
public:
const PhysicsDirectSpaceState2D::RayParameters &get_parameters() const { return parameters; }
void set_from(const Vector2 &p_from) { parameters.from = p_from; }
const Vector2 &get_from() const { return parameters.from; }
void set_to(const Vector2 &p_to) { parameters.to = p_to; }
const Vector2 &get_to() const { return parameters.to; }
void set_collision_mask(uint32_t p_mask) { parameters.collision_mask = p_mask; }
uint32_t get_collision_mask() const { return parameters.collision_mask; }
void set_collide_with_bodies(bool p_enable) { parameters.collide_with_bodies = p_enable; }
bool is_collide_with_bodies_enabled() const { return parameters.collide_with_bodies; }
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_exclude(const Vector<RID> &p_exclude);
Vector<RID> get_exclude() const;
};
class PhysicsPointQueryParameters2D : public RefCounted {
GDCLASS(PhysicsPointQueryParameters2D, RefCounted);
PhysicsDirectSpaceState2D::PointParameters parameters;
protected:
static void _bind_methods();
public:
const PhysicsDirectSpaceState2D::PointParameters &get_parameters() const { return parameters; }
void set_position(const Vector2 &p_position) { parameters.position = p_position; }
const Vector2 &get_position() const { return parameters.position; }
void set_canvas_instance_id(ObjectID p_canvas_instance_id) { parameters.canvas_instance_id = p_canvas_instance_id; }
ObjectID get_canvas_instance_id() const { return parameters.canvas_instance_id; }
void set_collision_mask(uint32_t p_mask) { parameters.collision_mask = p_mask; }
uint32_t get_collision_mask() const { return parameters.collision_mask; }
void set_collide_with_bodies(bool p_enable) { parameters.collide_with_bodies = p_enable; }
bool is_collide_with_bodies_enabled() const { return parameters.collide_with_bodies; }
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_exclude(const Vector<RID> &p_exclude);
Vector<RID> get_exclude() const;
};
class PhysicsShapeQueryParameters2D : public RefCounted {
GDCLASS(PhysicsShapeQueryParameters2D, RefCounted);
PhysicsDirectSpaceState2D::ShapeParameters parameters;
RES shape_ref;
protected:
static void _bind_methods();
public:
const PhysicsDirectSpaceState2D::ShapeParameters &get_parameters() const { return parameters; }
void set_shape(const RES &p_shape_ref);
RES get_shape() const { return shape_ref; }
void set_shape_rid(const RID &p_shape);
RID get_shape_rid() const { return parameters.shape_rid; }
void set_transform(const Transform2D &p_transform) { parameters.transform = p_transform; }
const Transform2D &get_transform() const { return parameters.transform; }
void set_motion(const Vector2 &p_motion) { parameters.motion = p_motion; }
const Vector2 &get_motion() const { return parameters.motion; }
void set_margin(real_t p_margin) { parameters.margin = p_margin; }
real_t get_margin() const { return parameters.margin; }
void set_collision_mask(uint32_t p_mask) { parameters.collision_mask = p_mask; }
uint32_t get_collision_mask() const { return parameters.collision_mask; }
void set_collide_with_bodies(bool p_enable) { parameters.collide_with_bodies = p_enable; }
bool is_collide_with_bodies_enabled() const { return parameters.collide_with_bodies; }
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_exclude(const Vector<RID> &p_exclude);
Vector<RID> get_exclude() const;
};
class PhysicsTestMotionParameters2D : public RefCounted { class PhysicsTestMotionParameters2D : public RefCounted {
GDCLASS(PhysicsTestMotionParameters2D, RefCounted); GDCLASS(PhysicsTestMotionParameters2D, RefCounted);

View File

@ -137,93 +137,137 @@ PhysicsDirectBodyState3D::PhysicsDirectBodyState3D() {}
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
void PhysicsShapeQueryParameters3D::set_shape(const RES &p_shape_ref) { void PhysicsRayQueryParameters3D::set_exclude(const Vector<RID> &p_exclude) {
ERR_FAIL_COND(p_shape_ref.is_null()); parameters.exclude.clear();
shape_ref = p_shape_ref;
shape = p_shape_ref->get_rid();
}
RES PhysicsShapeQueryParameters3D::get_shape() const {
return shape_ref;
}
void PhysicsShapeQueryParameters3D::set_shape_rid(const RID &p_shape) {
if (shape != p_shape) {
shape_ref = RES();
shape = p_shape;
}
}
RID PhysicsShapeQueryParameters3D::get_shape_rid() const {
return shape;
}
void PhysicsShapeQueryParameters3D::set_transform(const Transform3D &p_transform) {
transform = p_transform;
}
Transform3D PhysicsShapeQueryParameters3D::get_transform() const {
return transform;
}
void PhysicsShapeQueryParameters3D::set_margin(real_t p_margin) {
margin = p_margin;
}
real_t PhysicsShapeQueryParameters3D::get_margin() const {
return margin;
}
void PhysicsShapeQueryParameters3D::set_collision_mask(uint32_t p_collision_mask) {
collision_mask = p_collision_mask;
}
uint32_t PhysicsShapeQueryParameters3D::get_collision_mask() const {
return collision_mask;
}
void PhysicsShapeQueryParameters3D::set_exclude(const Vector<RID> &p_exclude) {
exclude.clear();
for (int i = 0; i < p_exclude.size(); i++) { for (int i = 0; i < p_exclude.size(); i++) {
exclude.insert(p_exclude[i]); parameters.exclude.insert(p_exclude[i]);
} }
} }
Vector<RID> PhysicsShapeQueryParameters3D::get_exclude() const { Vector<RID> PhysicsRayQueryParameters3D::get_exclude() const {
Vector<RID> ret; Vector<RID> ret;
ret.resize(exclude.size()); ret.resize(parameters.exclude.size());
int idx = 0; int idx = 0;
for (Set<RID>::Element *E = exclude.front(); E; E = E->next()) { for (Set<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) {
ret.write[idx++] = E->get(); ret.write[idx++] = E->get();
} }
return ret; return ret;
} }
void PhysicsShapeQueryParameters3D::set_collide_with_bodies(bool p_enable) { void PhysicsRayQueryParameters3D::_bind_methods() {
collide_with_bodies = p_enable; ClassDB::bind_method(D_METHOD("set_from", "from"), &PhysicsRayQueryParameters3D::set_from);
ClassDB::bind_method(D_METHOD("get_from"), &PhysicsRayQueryParameters3D::get_from);
ClassDB::bind_method(D_METHOD("set_to", "to"), &PhysicsRayQueryParameters3D::set_to);
ClassDB::bind_method(D_METHOD("get_to"), &PhysicsRayQueryParameters3D::get_to);
ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &PhysicsRayQueryParameters3D::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &PhysicsRayQueryParameters3D::get_collision_mask);
ClassDB::bind_method(D_METHOD("set_exclude", "exclude"), &PhysicsRayQueryParameters3D::set_exclude);
ClassDB::bind_method(D_METHOD("get_exclude"), &PhysicsRayQueryParameters3D::get_exclude);
ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &PhysicsRayQueryParameters3D::set_collide_with_bodies);
ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &PhysicsRayQueryParameters3D::is_collide_with_bodies_enabled);
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);
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");
} }
bool PhysicsShapeQueryParameters3D::is_collide_with_bodies_enabled() const { ///////////////////////////////////////////////////////
return collide_with_bodies;
void PhysicsPointQueryParameters3D::set_exclude(const Vector<RID> &p_exclude) {
parameters.exclude.clear();
for (int i = 0; i < p_exclude.size(); i++) {
parameters.exclude.insert(p_exclude[i]);
}
} }
void PhysicsShapeQueryParameters3D::set_collide_with_areas(bool p_enable) { Vector<RID> PhysicsPointQueryParameters3D::get_exclude() const {
collide_with_areas = p_enable; Vector<RID> ret;
ret.resize(parameters.exclude.size());
int idx = 0;
for (Set<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) {
ret.write[idx++] = E->get();
}
return ret;
} }
bool PhysicsShapeQueryParameters3D::is_collide_with_areas_enabled() const { void PhysicsPointQueryParameters3D::_bind_methods() {
return collide_with_areas; ClassDB::bind_method(D_METHOD("set_position", "position"), &PhysicsPointQueryParameters3D::set_position);
ClassDB::bind_method(D_METHOD("get_position"), &PhysicsPointQueryParameters3D::get_position);
ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &PhysicsPointQueryParameters3D::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &PhysicsPointQueryParameters3D::get_collision_mask);
ClassDB::bind_method(D_METHOD("set_exclude", "exclude"), &PhysicsPointQueryParameters3D::set_exclude);
ClassDB::bind_method(D_METHOD("get_exclude"), &PhysicsPointQueryParameters3D::get_exclude);
ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &PhysicsPointQueryParameters3D::set_collide_with_bodies);
ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &PhysicsPointQueryParameters3D::is_collide_with_bodies_enabled);
ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &PhysicsPointQueryParameters3D::set_collide_with_areas);
ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &PhysicsPointQueryParameters3D::is_collide_with_areas_enabled);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position"), "set_position", "get_position");
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");
}
///////////////////////////////////////////////////////
void PhysicsShapeQueryParameters3D::set_shape(const RES &p_shape_ref) {
ERR_FAIL_COND(p_shape_ref.is_null());
shape_ref = p_shape_ref;
parameters.shape_rid = p_shape_ref->get_rid();
}
void PhysicsShapeQueryParameters3D::set_shape_rid(const RID &p_shape) {
if (parameters.shape_rid != p_shape) {
shape_ref = RES();
parameters.shape_rid = p_shape;
}
}
void PhysicsShapeQueryParameters3D::set_exclude(const Vector<RID> &p_exclude) {
parameters.exclude.clear();
for (int i = 0; i < p_exclude.size(); i++) {
parameters.exclude.insert(p_exclude[i]);
}
}
Vector<RID> PhysicsShapeQueryParameters3D::get_exclude() const {
Vector<RID> ret;
ret.resize(parameters.exclude.size());
int idx = 0;
for (Set<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) {
ret.write[idx++] = E->get();
}
return ret;
} }
void PhysicsShapeQueryParameters3D::_bind_methods() { void PhysicsShapeQueryParameters3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters3D::set_shape); ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters3D::set_shape);
ClassDB::bind_method(D_METHOD("get_shape"), &PhysicsShapeQueryParameters3D::get_shape); ClassDB::bind_method(D_METHOD("get_shape"), &PhysicsShapeQueryParameters3D::get_shape);
ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &PhysicsShapeQueryParameters3D::set_shape_rid); ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &PhysicsShapeQueryParameters3D::set_shape_rid);
ClassDB::bind_method(D_METHOD("get_shape_rid"), &PhysicsShapeQueryParameters3D::get_shape_rid); ClassDB::bind_method(D_METHOD("get_shape_rid"), &PhysicsShapeQueryParameters3D::get_shape_rid);
ClassDB::bind_method(D_METHOD("set_transform", "transform"), &PhysicsShapeQueryParameters3D::set_transform); ClassDB::bind_method(D_METHOD("set_transform", "transform"), &PhysicsShapeQueryParameters3D::set_transform);
ClassDB::bind_method(D_METHOD("get_transform"), &PhysicsShapeQueryParameters3D::get_transform); ClassDB::bind_method(D_METHOD("get_transform"), &PhysicsShapeQueryParameters3D::get_transform);
ClassDB::bind_method(D_METHOD("set_motion", "motion"), &PhysicsShapeQueryParameters3D::set_motion);
ClassDB::bind_method(D_METHOD("get_motion"), &PhysicsShapeQueryParameters3D::get_motion);
ClassDB::bind_method(D_METHOD("set_margin", "margin"), &PhysicsShapeQueryParameters3D::set_margin); ClassDB::bind_method(D_METHOD("set_margin", "margin"), &PhysicsShapeQueryParameters3D::set_margin);
ClassDB::bind_method(D_METHOD("get_margin"), &PhysicsShapeQueryParameters3D::get_margin); ClassDB::bind_method(D_METHOD("get_margin"), &PhysicsShapeQueryParameters3D::get_margin);
@ -240,8 +284,9 @@ void PhysicsShapeQueryParameters3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &PhysicsShapeQueryParameters3D::is_collide_with_areas_enabled); ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &PhysicsShapeQueryParameters3D::is_collide_with_areas_enabled);
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); 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_NONE, itos(Variant::RID) + ":"), "set_exclude", "get_exclude"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_exclude", "get_exclude");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion"), "set_motion", "get_motion");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape3D"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape3D"), "set_shape", "get_shape");
ADD_PROPERTY(PropertyInfo(Variant::RID, "shape_rid"), "set_shape_rid", "get_shape_rid"); ADD_PROPERTY(PropertyInfo(Variant::RID, "shape_rid"), "set_shape_rid", "get_shape_rid");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform"), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform"), "set_transform", "get_transform");
@ -251,36 +296,56 @@ void PhysicsShapeQueryParameters3D::_bind_methods() {
///////////////////////////////////// /////////////////////////////////////
Dictionary PhysicsDirectSpaceState3D::_intersect_ray(const Vector3 &p_from, const Vector3 &p_to, const Vector<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { Dictionary PhysicsDirectSpaceState3D::_intersect_ray(const Ref<PhysicsRayQueryParameters3D> &p_ray_query) {
RayResult inters; ERR_FAIL_COND_V(!p_ray_query.is_valid(), Dictionary());
Set<RID> exclude;
for (int i = 0; i < p_exclude.size(); i++) {
exclude.insert(p_exclude[i]);
}
bool res = intersect_ray(p_from, p_to, inters, exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas); RayResult result;
bool res = intersect_ray(p_ray_query->get_parameters(), result);
if (!res) { if (!res) {
return Dictionary(); return Dictionary();
} }
Dictionary d; Dictionary d;
d["position"] = inters.position; d["position"] = result.position;
d["normal"] = inters.normal; d["normal"] = result.normal;
d["collider_id"] = inters.collider_id; d["collider_id"] = result.collider_id;
d["collider"] = inters.collider; d["collider"] = result.collider;
d["shape"] = inters.shape; d["shape"] = result.shape;
d["rid"] = inters.rid; d["rid"] = result.rid;
return d; return d;
} }
Array PhysicsDirectSpaceState3D::_intersect_point(const Ref<PhysicsPointQueryParameters3D> &p_point_query, int p_max_results) {
Vector<ShapeResult> ret;
ret.resize(p_max_results);
int rc = intersect_point(p_point_query->get_parameters(), ret.ptrw(), ret.size());
if (rc == 0) {
return Array();
}
Array r;
r.resize(rc);
for (int i = 0; i < rc; i++) {
Dictionary d;
d["rid"] = ret[i].rid;
d["collider_id"] = ret[i].collider_id;
d["collider"] = ret[i].collider;
d["shape"] = ret[i].shape;
r[i] = d;
}
return r;
}
Array PhysicsDirectSpaceState3D::_intersect_shape(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, int p_max_results) { Array PhysicsDirectSpaceState3D::_intersect_shape(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, int p_max_results) {
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array()); ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
Vector<ShapeResult> sr; Vector<ShapeResult> sr;
sr.resize(p_max_results); sr.resize(p_max_results);
int rc = intersect_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, sr.ptrw(), sr.size(), p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); int rc = intersect_shape(p_shape_query->get_parameters(), sr.ptrw(), sr.size());
Array ret; Array ret;
ret.resize(rc); ret.resize(rc);
for (int i = 0; i < rc; i++) { for (int i = 0; i < rc; i++) {
@ -295,11 +360,11 @@ Array PhysicsDirectSpaceState3D::_intersect_shape(const Ref<PhysicsShapeQueryPar
return ret; return ret;
} }
Array PhysicsDirectSpaceState3D::_cast_motion(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, const Vector3 &p_motion) { Array PhysicsDirectSpaceState3D::_cast_motion(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query) {
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array()); ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
real_t closest_safe = 1.0f, closest_unsafe = 1.0f; real_t closest_safe = 1.0f, closest_unsafe = 1.0f;
bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); bool res = cast_motion(p_shape_query->get_parameters(), closest_safe, closest_unsafe);
if (!res) { if (!res) {
return Array(); return Array();
} }
@ -316,7 +381,7 @@ Array PhysicsDirectSpaceState3D::_collide_shape(const Ref<PhysicsShapeQueryParam
Vector<Vector3> ret; Vector<Vector3> ret;
ret.resize(p_max_results * 2); ret.resize(p_max_results * 2);
int rc = 0; int rc = 0;
bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, ret.ptrw(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); bool res = collide_shape(p_shape_query->get_parameters(), ret.ptrw(), p_max_results, rc);
if (!res) { if (!res) {
return Array(); return Array();
} }
@ -333,7 +398,7 @@ Dictionary PhysicsDirectSpaceState3D::_get_rest_info(const Ref<PhysicsShapeQuery
ShapeRestInfo sri; ShapeRestInfo sri;
bool res = rest_info(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, &sri, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); bool res = rest_info(p_shape_query->get_parameters(), &sri);
Dictionary r; Dictionary r;
if (!res) { if (!res) {
return r; return r;
@ -353,11 +418,12 @@ PhysicsDirectSpaceState3D::PhysicsDirectSpaceState3D() {
} }
void PhysicsDirectSpaceState3D::_bind_methods() { void PhysicsDirectSpaceState3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_mask", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState3D::_intersect_ray, DEFVAL(Array()), DEFVAL(UINT32_MAX), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("intersect_point", "parameters", "max_results"), &PhysicsDirectSpaceState3D::_intersect_point, DEFVAL(32));
ClassDB::bind_method(D_METHOD("intersect_shape", "shape", "max_results"), &PhysicsDirectSpaceState3D::_intersect_shape, DEFVAL(32)); ClassDB::bind_method(D_METHOD("intersect_ray", "parameters"), &PhysicsDirectSpaceState3D::_intersect_ray);
ClassDB::bind_method(D_METHOD("cast_motion", "shape", "motion"), &PhysicsDirectSpaceState3D::_cast_motion); ClassDB::bind_method(D_METHOD("intersect_shape", "parameters", "max_results"), &PhysicsDirectSpaceState3D::_intersect_shape, DEFVAL(32));
ClassDB::bind_method(D_METHOD("collide_shape", "shape", "max_results"), &PhysicsDirectSpaceState3D::_collide_shape, DEFVAL(32)); ClassDB::bind_method(D_METHOD("cast_motion", "parameters"), &PhysicsDirectSpaceState3D::_cast_motion);
ClassDB::bind_method(D_METHOD("get_rest_info", "shape"), &PhysicsDirectSpaceState3D::_get_rest_info); ClassDB::bind_method(D_METHOD("collide_shape", "parameters", "max_results"), &PhysicsDirectSpaceState3D::_collide_shape, DEFVAL(32));
ClassDB::bind_method(D_METHOD("get_rest_info", "parameters"), &PhysicsDirectSpaceState3D::_get_rest_info);
} }
/////////////////////////////// ///////////////////////////////
@ -427,7 +493,7 @@ void PhysicsTestMotionParameters3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_collisions"), "set_max_collisions", "get_max_collisions"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_collisions"), "set_max_collisions", "get_max_collisions");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_separation_ray"), "set_collide_separation_ray_enabled", "is_collide_separation_ray_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_separation_ray"), "set_collide_separation_ray_enabled", "is_collide_separation_ray_enabled");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_bodies"), "set_exclude_bodies", "get_exclude_bodies"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_bodies", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_exclude_bodies", "get_exclude_bodies");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_objects"), "set_exclude_objects", "get_exclude_objects"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_objects"), "set_exclude_objects", "get_exclude_objects");
} }

View File

@ -96,55 +96,18 @@ public:
PhysicsDirectBodyState3D(); PhysicsDirectBodyState3D();
}; };
class PhysicsShapeQueryParameters3D : public RefCounted { class PhysicsRayQueryParameters3D;
GDCLASS(PhysicsShapeQueryParameters3D, RefCounted); class PhysicsPointQueryParameters3D;
friend class PhysicsDirectSpaceState3D; class PhysicsShapeQueryParameters3D;
RES shape_ref;
RID shape;
Transform3D transform;
real_t margin = 0.0;
Set<RID> exclude;
uint32_t collision_mask = UINT32_MAX;
bool collide_with_bodies = true;
bool collide_with_areas = false;
protected:
static void _bind_methods();
public:
void set_shape(const RES &p_shape_ref);
RES get_shape() const;
void set_shape_rid(const RID &p_shape);
RID get_shape_rid() const;
void set_transform(const Transform3D &p_transform);
Transform3D get_transform() const;
void set_margin(real_t p_margin);
real_t get_margin() const;
void set_collision_mask(uint32_t p_collision_mask);
uint32_t get_collision_mask() const;
void set_exclude(const Vector<RID> &p_exclude);
Vector<RID> get_exclude() const;
void set_collide_with_bodies(bool p_enable);
bool is_collide_with_bodies_enabled() const;
void set_collide_with_areas(bool p_enable);
bool is_collide_with_areas_enabled() const;
};
class PhysicsDirectSpaceState3D : public Object { class PhysicsDirectSpaceState3D : public Object {
GDCLASS(PhysicsDirectSpaceState3D, Object); GDCLASS(PhysicsDirectSpaceState3D, Object);
private: private:
Dictionary _intersect_ray(const Vector3 &p_from, const Vector3 &p_to, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); Dictionary _intersect_ray(const Ref<PhysicsRayQueryParameters3D> &p_ray_query);
Array _intersect_point(const Ref<PhysicsPointQueryParameters3D> &p_point_query, int p_max_results = 32);
Array _intersect_shape(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, int p_max_results = 32); Array _intersect_shape(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, int p_max_results = 32);
Array _cast_motion(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, const Vector3 &p_motion); Array _cast_motion(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query);
Array _collide_shape(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, int p_max_results = 32); Array _collide_shape(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, int p_max_results = 32);
Dictionary _get_rest_info(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query); Dictionary _get_rest_info(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query);
@ -152,14 +115,17 @@ protected:
static void _bind_methods(); static void _bind_methods();
public: public:
struct ShapeResult { struct RayParameters {
RID rid; Vector3 from;
ObjectID collider_id; Vector3 to;
Object *collider = nullptr; Set<RID> exclude;
int shape = 0; uint32_t collision_mask = UINT32_MAX;
};
virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; bool collide_with_bodies = true;
bool collide_with_areas = false;
bool pick_ray = false;
};
struct RayResult { struct RayResult {
Vector3 position; Vector3 position;
@ -170,9 +136,37 @@ public:
int shape = 0; int shape = 0;
}; };
virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false) = 0; virtual bool intersect_ray(const RayParameters &p_parameters, RayResult &r_result) = 0;
virtual int intersect_shape(const RID &p_shape, const Transform3D &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; struct ShapeResult {
RID rid;
ObjectID collider_id;
Object *collider = nullptr;
int shape = 0;
};
struct PointParameters {
Vector3 position;
Set<RID> exclude;
uint32_t collision_mask = UINT32_MAX;
bool collide_with_bodies = true;
bool collide_with_areas = false;
};
virtual int intersect_point(const PointParameters &p_parameters, ShapeResult *r_results, int p_result_max) = 0;
struct ShapeParameters {
RID shape_rid;
Transform3D transform;
Vector3 motion;
real_t margin = 0.0;
Set<RID> exclude;
uint32_t collision_mask = UINT32_MAX;
bool collide_with_bodies = true;
bool collide_with_areas = false;
};
struct ShapeRestInfo { struct ShapeRestInfo {
Vector3 point; Vector3 point;
@ -180,14 +174,13 @@ public:
RID rid; RID rid;
ObjectID collider_id; ObjectID collider_id;
int shape = 0; int shape = 0;
Vector3 linear_velocity; //velocity at contact point Vector3 linear_velocity; // Velocity at contact point.
}; };
virtual bool cast_motion(const RID &p_shape, const Transform3D &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) = 0; virtual int intersect_shape(const ShapeParameters &p_parameters, ShapeResult *r_results, int p_result_max) = 0;
virtual bool cast_motion(const ShapeParameters &p_parameters, real_t &p_closest_safe, real_t &p_closest_unsafe, ShapeRestInfo *r_info = nullptr) = 0;
virtual bool collide_shape(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; virtual bool collide_shape(const ShapeParameters &p_parameters, Vector3 *r_results, int p_result_max, int &r_result_count) = 0;
virtual bool rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) = 0;
virtual bool rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const = 0; virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const = 0;
@ -785,6 +778,104 @@ public:
~PhysicsServer3D(); ~PhysicsServer3D();
}; };
class PhysicsRayQueryParameters3D : public RefCounted {
GDCLASS(PhysicsRayQueryParameters3D, RefCounted);
PhysicsDirectSpaceState3D::RayParameters parameters;
protected:
static void _bind_methods();
public:
const PhysicsDirectSpaceState3D::RayParameters &get_parameters() const { return parameters; }
void set_from(const Vector3 &p_from) { parameters.from = p_from; }
const Vector3 &get_from() const { return parameters.from; }
void set_to(const Vector3 &p_to) { parameters.to = p_to; }
const Vector3 &get_to() const { return parameters.to; }
void set_collision_mask(uint32_t p_mask) { parameters.collision_mask = p_mask; }
uint32_t get_collision_mask() const { return parameters.collision_mask; }
void set_collide_with_bodies(bool p_enable) { parameters.collide_with_bodies = p_enable; }
bool is_collide_with_bodies_enabled() const { return parameters.collide_with_bodies; }
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_exclude(const Vector<RID> &p_exclude);
Vector<RID> get_exclude() const;
};
class PhysicsPointQueryParameters3D : public RefCounted {
GDCLASS(PhysicsPointQueryParameters3D, RefCounted);
PhysicsDirectSpaceState3D::PointParameters parameters;
protected:
static void _bind_methods();
public:
const PhysicsDirectSpaceState3D::PointParameters &get_parameters() const { return parameters; }
void set_position(const Vector3 &p_position) { parameters.position = p_position; }
const Vector3 &get_position() const { return parameters.position; }
void set_collision_mask(uint32_t p_mask) { parameters.collision_mask = p_mask; }
uint32_t get_collision_mask() const { return parameters.collision_mask; }
void set_collide_with_bodies(bool p_enable) { parameters.collide_with_bodies = p_enable; }
bool is_collide_with_bodies_enabled() const { return parameters.collide_with_bodies; }
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_exclude(const Vector<RID> &p_exclude);
Vector<RID> get_exclude() const;
};
class PhysicsShapeQueryParameters3D : public RefCounted {
GDCLASS(PhysicsShapeQueryParameters3D, RefCounted);
PhysicsDirectSpaceState3D::ShapeParameters parameters;
RES shape_ref;
protected:
static void _bind_methods();
public:
const PhysicsDirectSpaceState3D::ShapeParameters &get_parameters() const { return parameters; }
void set_shape(const RES &p_shape_ref);
RES get_shape() const { return shape_ref; }
void set_shape_rid(const RID &p_shape);
RID get_shape_rid() const { return parameters.shape_rid; }
void set_transform(const Transform3D &p_transform) { parameters.transform = p_transform; }
const Transform3D &get_transform() const { return parameters.transform; }
void set_motion(const Vector3 &p_motion) { parameters.motion = p_motion; }
const Vector3 &get_motion() const { return parameters.motion; }
void set_margin(real_t p_margin) { parameters.margin = p_margin; }
real_t get_margin() const { return parameters.margin; }
void set_collision_mask(uint32_t p_mask) { parameters.collision_mask = p_mask; }
uint32_t get_collision_mask() const { return parameters.collision_mask; }
void set_collide_with_bodies(bool p_enable) { parameters.collide_with_bodies = p_enable; }
bool is_collide_with_bodies_enabled() const { return parameters.collide_with_bodies; }
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_exclude(const Vector<RID> &p_exclude);
Vector<RID> get_exclude() const;
};
class PhysicsTestMotionParameters3D : public RefCounted { class PhysicsTestMotionParameters3D : public RefCounted {
GDCLASS(PhysicsTestMotionParameters3D, RefCounted); GDCLASS(PhysicsTestMotionParameters3D, RefCounted);

View File

@ -209,13 +209,17 @@ void register_server_types() {
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState2D); GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState2D);
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState2D); GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState2D);
GDREGISTER_CLASS(PhysicsRayQueryParameters2D);
GDREGISTER_CLASS(PhysicsPointQueryParameters2D);
GDREGISTER_CLASS(PhysicsShapeQueryParameters2D);
GDREGISTER_CLASS(PhysicsTestMotionParameters2D); GDREGISTER_CLASS(PhysicsTestMotionParameters2D);
GDREGISTER_CLASS(PhysicsTestMotionResult2D); GDREGISTER_CLASS(PhysicsTestMotionResult2D);
GDREGISTER_CLASS(PhysicsShapeQueryParameters2D);
GDREGISTER_CLASS(PhysicsShapeQueryParameters3D);
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState3D); GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState3D);
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState3D); GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState3D);
GDREGISTER_CLASS(PhysicsRayQueryParameters3D);
GDREGISTER_CLASS(PhysicsPointQueryParameters3D);
GDREGISTER_CLASS(PhysicsShapeQueryParameters3D);
GDREGISTER_CLASS(PhysicsTestMotionParameters3D); GDREGISTER_CLASS(PhysicsTestMotionParameters3D);
GDREGISTER_CLASS(PhysicsTestMotionResult3D); GDREGISTER_CLASS(PhysicsTestMotionResult3D);