Script interface improvements for test body motion
-Physics servers test body motion use a class to hold parameters instead of multiple arguments to make it more readable and flexible since there are many options -Improved documentation for test body motion and kinematic collision -Removed read-only properties for body motion results (not handled in scripts, so they should be get_ methods only instead)
This commit is contained in:
parent
073db83569
commit
3ae5687d48
|
@ -14,43 +14,74 @@
|
|||
<return type="float" />
|
||||
<argument index="0" name="up_direction" type="Vector2" default="Vector2(0, -1)" />
|
||||
<description>
|
||||
The collision angle according to [code]up_direction[/code], which is [code]Vector2.UP[/code] by default. This value is always positive.
|
||||
Returns the collision angle according to [code]up_direction[/code], which is [code]Vector2.UP[/code] by default. This value is always positive.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider" qualifiers="const">
|
||||
<return type="Object" />
|
||||
<description>
|
||||
Returns the colliding body's attached [Object].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_id" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the unique instance ID of the colliding body's attached [Object]. See [method Object.get_instance_id].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_rid" qualifiers="const">
|
||||
<return type="RID" />
|
||||
<description>
|
||||
Returns the colliding body's [RID] used by the [PhysicsServer2D].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_shape" qualifiers="const">
|
||||
<return type="Object" />
|
||||
<description>
|
||||
Returns the colliding body's shape.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_shape_index" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the colliding body's shape index. See [CollisionObject2D].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_velocity" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<description>
|
||||
Returns the colliding body's velocity.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_local_shape" qualifiers="const">
|
||||
<return type="Object" />
|
||||
<description>
|
||||
Returns the moving object's colliding shape.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_normal" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<description>
|
||||
Returns the colliding body's shape's normal at the point of collision.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_position" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<description>
|
||||
Returns the point of collision in global coordinates.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_remainder" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<description>
|
||||
Returns the moving object's remaining movement vector.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_travel" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<description>
|
||||
Returns the moving object's travel before collision.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="collider" type="Object" setter="" getter="get_collider">
|
||||
The colliding body.
|
||||
</member>
|
||||
<member name="collider_id" type="int" setter="" getter="get_collider_id" default="0">
|
||||
The colliding body's unique instance ID. See [method Object.get_instance_id].
|
||||
</member>
|
||||
<member name="collider_rid" type="RID" setter="" getter="get_collider_rid">
|
||||
The colliding body's [RID] used by the [PhysicsServer2D].
|
||||
</member>
|
||||
<member name="collider_shape" type="Object" setter="" getter="get_collider_shape">
|
||||
The colliding body's shape.
|
||||
</member>
|
||||
<member name="collider_shape_index" type="int" setter="" getter="get_collider_shape_index" default="0">
|
||||
The colliding shape's index. See [CollisionObject2D].
|
||||
</member>
|
||||
<member name="collider_velocity" type="Vector2" setter="" getter="get_collider_velocity" default="Vector2(0, 0)">
|
||||
The colliding object's velocity.
|
||||
</member>
|
||||
<member name="local_shape" type="Object" setter="" getter="get_local_shape">
|
||||
The moving object's colliding shape.
|
||||
</member>
|
||||
<member name="normal" type="Vector2" setter="" getter="get_normal" default="Vector2(0, 0)">
|
||||
The colliding body's shape's normal at the point of collision.
|
||||
</member>
|
||||
<member name="position" type="Vector2" setter="" getter="get_position" default="Vector2(0, 0)">
|
||||
The point of collision, in global coordinates.
|
||||
</member>
|
||||
<member name="remainder" type="Vector2" setter="" getter="get_remainder" default="Vector2(0, 0)">
|
||||
The moving object's remaining movement vector.
|
||||
</member>
|
||||
<member name="travel" type="Vector2" setter="" getter="get_travel" default="Vector2(0, 0)">
|
||||
The distance the moving object traveled before collision.
|
||||
</member>
|
||||
</members>
|
||||
</class>
|
||||
|
|
|
@ -15,108 +15,89 @@
|
|||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<argument index="1" name="up_direction" type="Vector3" default="Vector3(0, 1, 0)" />
|
||||
<description>
|
||||
The collision angle according to [code]up_direction[/code], which is [code]Vector3.UP[/code] by default. This value is always positive.
|
||||
Returns the collision angle according to [code]up_direction[/code], which is [code]Vector3.UP[/code] by default. This value is always positive.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider" qualifiers="const">
|
||||
<return type="Object" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the collider by index (the latest by default).
|
||||
Returns the colliding body's attached [Object] given a collision index (the deepest collision by default).
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_id" qualifiers="const">
|
||||
<return type="int" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the collider ID by index (the latest by default).
|
||||
Returns the unique instance ID of the colliding body's attached [Object] given a collision index (the deepest collision by default). See [method Object.get_instance_id].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_rid" qualifiers="const">
|
||||
<return type="RID" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the collider RID by index (the latest by default).
|
||||
Returns the colliding body's [RID] used by the [PhysicsServer3D] given a collision index (the deepest collision by default).
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_shape" qualifiers="const">
|
||||
<return type="Object" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the collider shape by index (the latest by default).
|
||||
Returns the colliding body's shape given a collision index (the deepest collision by default).
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_shape_index" qualifiers="const">
|
||||
<return type="int" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the collider shape index by index (the latest by default).
|
||||
Returns the colliding body's shape index given a collision index (the deepest collision by default). See [CollisionObject3D].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_velocity" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the collider velocity by index (the latest by default).
|
||||
Returns the colliding body's velocity given a collision index (the deepest collision by default).
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the number of detected collisions.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_local_shape" qualifiers="const">
|
||||
<return type="Object" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the collider velocity by index (the latest by default).
|
||||
Returns the moving object's colliding shape given a collision index (the deepest collision by default).
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_normal" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the collider normal by index (the latest by default).
|
||||
Returns the colliding body's shape's normal at the point of collision given a collision index (the deepest collision by default).
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_position" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the collider collision point by index (the latest by default).
|
||||
Returns the point of collision in global coordinates given a collision index (the deepest collision by default).
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_remainder" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<description>
|
||||
Returns the moving object's remaining movement vector.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_travel" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<description>
|
||||
Returns the moving object's travel before collision.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="collider" type="Object" setter="" getter="get_best_collider">
|
||||
The colliding body.
|
||||
</member>
|
||||
<member name="collider_id" type="int" setter="" getter="get_best_collider_id" default="0">
|
||||
The colliding body's unique instance ID. See [method Object.get_instance_id].
|
||||
</member>
|
||||
<member name="collider_rid" type="RID" setter="" getter="get_best_collider_rid">
|
||||
The colliding body's [RID] used by the [PhysicsServer3D].
|
||||
</member>
|
||||
<member name="collider_shape" type="Object" setter="" getter="get_best_collider_shape">
|
||||
The colliding body's shape.
|
||||
</member>
|
||||
<member name="collider_shape_index" type="int" setter="" getter="get_best_collider_shape_index" default="0">
|
||||
The colliding shape's index. See [CollisionObject3D].
|
||||
</member>
|
||||
<member name="collider_velocity" type="Vector3" setter="" getter="get_best_collider_velocity" default="Vector3(0, 0, 0)">
|
||||
The colliding object's velocity.
|
||||
</member>
|
||||
<member name="collision_count" type="int" setter="" getter="get_collision_count" default="0">
|
||||
</member>
|
||||
<member name="local_shape" type="Object" setter="" getter="get_best_local_shape">
|
||||
The moving object's colliding shape.
|
||||
</member>
|
||||
<member name="normal" type="Vector3" setter="" getter="get_best_normal" default="Vector3(0, 0, 0)">
|
||||
The colliding body's shape's normal at the point of collision.
|
||||
</member>
|
||||
<member name="position" type="Vector3" setter="" getter="get_best_position" default="Vector3(0, 0, 0)">
|
||||
The point of collision, in global coordinates.
|
||||
</member>
|
||||
<member name="remainder" type="Vector3" setter="" getter="get_remainder" default="Vector3(0, 0, 0)">
|
||||
The moving object's remaining movement vector.
|
||||
</member>
|
||||
<member name="travel" type="Vector3" setter="" getter="get_travel" default="Vector3(0, 0, 0)">
|
||||
The distance the moving object traveled before collision.
|
||||
</member>
|
||||
</members>
|
||||
</class>
|
||||
|
|
|
@ -584,14 +584,10 @@
|
|||
<method name="body_test_motion">
|
||||
<return type="bool" />
|
||||
<argument index="0" name="body" type="RID" />
|
||||
<argument index="1" name="from" type="Transform2D" />
|
||||
<argument index="2" name="motion" type="Vector2" />
|
||||
<argument index="3" name="margin" type="float" default="0.08" />
|
||||
<argument index="4" name="result" type="PhysicsTestMotionResult2D" default="null" />
|
||||
<argument index="5" name="collide_separation_ray" type="bool" default="false" />
|
||||
<argument index="6" name="exclude" type="Array" default="[]" />
|
||||
<argument index="1" name="parameters" type="PhysicsTestMotionParameters2D" />
|
||||
<argument index="2" name="result" type="PhysicsTestMotionResult2D" default="null" />
|
||||
<description>
|
||||
Returns [code]true[/code] if a collision would result from moving in the given direction from a given point in space. Margin increases the size of the shapes involved in the collision detection. [PhysicsTestMotionResult2D] can be passed to return additional information in.
|
||||
Returns [code]true[/code] if a collision would result from moving along a motion vector from a given point in space. [PhysicsTestMotionParameters2D] is passed to set motion parameters. [PhysicsTestMotionResult2D] can be passed to return additional information.
|
||||
</description>
|
||||
</method>
|
||||
<method name="capsule_shape_create">
|
||||
|
|
|
@ -577,15 +577,10 @@
|
|||
<method name="body_test_motion">
|
||||
<return type="bool" />
|
||||
<argument index="0" name="body" type="RID" />
|
||||
<argument index="1" name="from" type="Transform3D" />
|
||||
<argument index="2" name="motion" type="Vector3" />
|
||||
<argument index="3" name="margin" type="float" default="0.001" />
|
||||
<argument index="4" name="result" type="PhysicsTestMotionResult3D" default="null" />
|
||||
<argument index="5" name="collide_separation_ray" type="bool" default="false" />
|
||||
<argument index="6" name="exclude" type="Array" default="[]" />
|
||||
<argument index="7" name="max_collisions" type="int" default="1" />
|
||||
<argument index="1" name="parameters" type="PhysicsTestMotionParameters3D" />
|
||||
<argument index="2" name="result" type="PhysicsTestMotionResult3D" default="null" />
|
||||
<description>
|
||||
Returns [code]true[/code] if a collision would result from moving in the given direction from a given point in space. Margin increases the size of the shapes involved in the collision detection. [PhysicsTestMotionResult3D] can be passed to return additional information in.
|
||||
Returns [code]true[/code] if a collision would result from moving along a motion vector from a given point in space. [PhysicsTestMotionParameters3D] is passed to set motion parameters. [PhysicsTestMotionResult3D] can be passed to return additional information.
|
||||
</description>
|
||||
</method>
|
||||
<method name="box_shape_create">
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="PhysicsTestMotionParameters2D" inherits="RefCounted" version="4.0">
|
||||
<brief_description>
|
||||
Parameters to be sent to a 2D body motion test.
|
||||
</brief_description>
|
||||
<description>
|
||||
This class contains parameters used in [method PhysicsServer2D.body_test_motion].
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<members>
|
||||
<member name="collide_separation_ray" type="bool" setter="set_collide_separation_ray_enabled" getter="is_collide_separation_ray_enabled" default="false">
|
||||
If set to [code]true[/code], shapes of type [constant PhysicsServer2D.SHAPE_SEPARATION_RAY] are used to detect collisions and can stop the motion. Can be useful when snapping to the ground.
|
||||
If set to [code]false[/code], shapes of type [constant PhysicsServer2D.SHAPE_SEPARATION_RAY] are only used for separation when overlapping with other bodies. That's the main use for separation ray shapes.
|
||||
</member>
|
||||
<member name="exclude_bodies" type="Array" setter="set_exclude_bodies" getter="get_exclude_bodies" default="[]">
|
||||
Optional array of body [RID] to exclude from collision.
|
||||
</member>
|
||||
<member name="from" type="Transform2D" setter="set_from" getter="get_from" default="Transform2D(1, 0, 0, 1, 0, 0)">
|
||||
Transform in global space where the motion should start. Usually set to [member Node2D.global_transform] for the current body's transform.
|
||||
</member>
|
||||
<member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.08">
|
||||
Increases the size of the shapes involved in the collision detection.
|
||||
</member>
|
||||
<member name="motion" type="Vector2" setter="set_motion" getter="get_motion" default="Vector2(0, 0)">
|
||||
Motion vector to define the length and direction of the motion to test.
|
||||
</member>
|
||||
</members>
|
||||
</class>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="PhysicsTestMotionParameters3D" inherits="RefCounted" version="4.0">
|
||||
<brief_description>
|
||||
Parameters to be sent to a 3D body motion test.
|
||||
</brief_description>
|
||||
<description>
|
||||
This class contains parameters used in [method PhysicsServer3D.body_test_motion].
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<members>
|
||||
<member name="collide_separation_ray" type="bool" setter="set_collide_separation_ray_enabled" getter="is_collide_separation_ray_enabled" default="false">
|
||||
If set to [code]true[/code], shapes of type [constant PhysicsServer3D.SHAPE_SEPARATION_RAY] are used to detect collisions and can stop the motion. Can be useful when snapping to the ground.
|
||||
If set to [code]false[/code], shapes of type [constant PhysicsServer3D.SHAPE_SEPARATION_RAY] are only used for separation when overlapping with other bodies. That's the main use for separation ray shapes.
|
||||
</member>
|
||||
<member name="exclude_bodies" type="Array" setter="set_exclude_bodies" getter="get_exclude_bodies" default="[]">
|
||||
Optional array of body [RID] to exclude from collision.
|
||||
</member>
|
||||
<member name="from" type="Transform3D" setter="set_from" getter="get_from" default="Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)">
|
||||
Transform in global space where the motion should start. Usually set to [member Node3D.global_transform] for the current body's transform.
|
||||
</member>
|
||||
<member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.001">
|
||||
Increases the size of the shapes involved in the collision detection.
|
||||
</member>
|
||||
<member name="max_collisions" type="int" setter="set_max_collisions" getter="get_max_collisions" default="1">
|
||||
Maximum number of returned collisions, between [code]1[/code] and [code]32[/code]. Always returns the deepest detected collisions.
|
||||
</member>
|
||||
<member name="motion" type="Vector3" setter="set_motion" getter="get_motion" default="Vector3(0, 0, 0)">
|
||||
Motion vector to define the length and direction of the motion to test.
|
||||
</member>
|
||||
</members>
|
||||
</class>
|
|
@ -1,35 +1,91 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="PhysicsTestMotionResult2D" inherits="RefCounted" version="4.0">
|
||||
<brief_description>
|
||||
Result from a 2D body motion test.
|
||||
</brief_description>
|
||||
<description>
|
||||
This class contains the motion and collision result from [method PhysicsServer2D.body_test_motion].
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<members>
|
||||
<member name="collider" type="Object" setter="" getter="get_collider">
|
||||
</member>
|
||||
<member name="collider_id" type="int" setter="" getter="get_collider_id" default="0">
|
||||
</member>
|
||||
<member name="collider_rid" type="RID" setter="" getter="get_collider_rid">
|
||||
</member>
|
||||
<member name="collider_shape" type="int" setter="" getter="get_collider_shape" default="0">
|
||||
</member>
|
||||
<member name="collider_velocity" type="Vector2" setter="" getter="get_collider_velocity" default="Vector2(0, 0)">
|
||||
</member>
|
||||
<member name="collision_depth" type="float" setter="" getter="get_collision_depth" default="0.0">
|
||||
</member>
|
||||
<member name="collision_normal" type="Vector2" setter="" getter="get_collision_normal" default="Vector2(0, 0)">
|
||||
</member>
|
||||
<member name="collision_point" type="Vector2" setter="" getter="get_collision_point" default="Vector2(0, 0)">
|
||||
</member>
|
||||
<member name="collision_safe_fraction" type="float" setter="" getter="get_collision_safe_fraction" default="0.0">
|
||||
</member>
|
||||
<member name="collision_unsafe_fraction" type="float" setter="" getter="get_collision_unsafe_fraction" default="0.0">
|
||||
</member>
|
||||
<member name="remainder" type="Vector2" setter="" getter="get_remainder" default="Vector2(0, 0)">
|
||||
</member>
|
||||
<member name="travel" type="Vector2" setter="" getter="get_travel" default="Vector2(0, 0)">
|
||||
</member>
|
||||
</members>
|
||||
<methods>
|
||||
<method name="get_collider" qualifiers="const">
|
||||
<return type="Object" />
|
||||
<description>
|
||||
Returns the colliding body's attached [Object], if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_id" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the unique instance ID of the colliding body's attached [Object], if a collision occured. See [method Object.get_instance_id].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_rid" qualifiers="const">
|
||||
<return type="RID" />
|
||||
<description>
|
||||
Returns the colliding body's [RID] used by the [PhysicsServer2D], if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_shape" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the colliding body's shape index, if a collision occured. See [CollisionObject2D].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_velocity" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<description>
|
||||
Returns the colliding body's velocity, if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_depth" qualifiers="const">
|
||||
<return type="float" />
|
||||
<description>
|
||||
Returns the length of overlap along the collision normal, if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_local_shape" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the moving object's colliding shape, if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_normal" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<description>
|
||||
Returns the colliding body's shape's normal at the point of collision, if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_point" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<description>
|
||||
Returns the point of collision in global coordinates, if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_safe_fraction" qualifiers="const">
|
||||
<return type="float" />
|
||||
<description>
|
||||
Returns the maximum fraction of the motion that can occur without a collision, between [code]0[/code] and [code]1[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_unsafe_fraction" qualifiers="const">
|
||||
<return type="float" />
|
||||
<description>
|
||||
Returns the minimum fraction of the motion needed to collide, if a collision occured, between [code]0[/code] and [code]1[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_remainder" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<description>
|
||||
Returns the moving object's remaining movement vector.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_travel" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<description>
|
||||
Returns the moving object's travel before collision.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
</class>
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="PhysicsTestMotionResult3D" inherits="RefCounted" version="4.0">
|
||||
<brief_description>
|
||||
Result from a 3D body motion test.
|
||||
</brief_description>
|
||||
<description>
|
||||
This class contains the motion and collision result from [method PhysicsServer3D.body_test_motion].
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
|
@ -11,77 +13,94 @@
|
|||
<return type="Object" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the colliding body's attached [Object] given a collision index (the deepest collision by default), if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_id" qualifiers="const">
|
||||
<return type="int" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the unique instance ID of the colliding body's attached [Object] given a collision index (the deepest collision by default), if a collision occured. See [method Object.get_instance_id].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_rid" qualifiers="const">
|
||||
<return type="RID" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the colliding body's [RID] used by the [PhysicsServer3D] given a collision index (the deepest collision by default), if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_shape" qualifiers="const">
|
||||
<return type="int" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the colliding body's shape index given a collision index (the deepest collision by default), if a collision occured. See [CollisionObject3D].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_velocity" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the colliding body's velocity given a collision index (the deepest collision by default), if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the number of detected collisions.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_depth" qualifiers="const">
|
||||
<return type="float" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the length of overlap along the collision normal given a collision index (the deepest collision by default), if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_local_shape" qualifiers="const">
|
||||
<return type="int" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the moving object's colliding shape given a collision index (the deepest collision by default), if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_normal" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the colliding body's shape's normal at the point of collision given a collision index (the deepest collision by default), if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_point" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<argument index="0" name="collision_index" type="int" default="0" />
|
||||
<description>
|
||||
Returns the point of collision in global coordinates given a collision index (the deepest collision by default), if a collision occured.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_safe_fraction" qualifiers="const">
|
||||
<return type="float" />
|
||||
<description>
|
||||
Returns the maximum fraction of the motion that can occur without a collision, between [code]0[/code] and [code]1[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_unsafe_fraction" qualifiers="const">
|
||||
<return type="float" />
|
||||
<description>
|
||||
Returns the minimum fraction of the motion needed to collide, if a collision occured, between [code]0[/code] and [code]1[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_remainder" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<description>
|
||||
Returns the moving object's remaining movement vector.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_travel" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<description>
|
||||
Returns the moving object's travel before collision.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="collider" type="Object" setter="" getter="get_best_collider">
|
||||
</member>
|
||||
<member name="collider_id" type="int" setter="" getter="get_best_collider_id" default="0">
|
||||
</member>
|
||||
<member name="collider_rid" type="RID" setter="" getter="get_best_collider_rid">
|
||||
</member>
|
||||
<member name="collider_shape" type="int" setter="" getter="get_best_collider_shape" default="0">
|
||||
</member>
|
||||
<member name="collider_velocity" type="Vector3" setter="" getter="get_best_collider_velocity" default="Vector3(0, 0, 0)">
|
||||
</member>
|
||||
<member name="collision_count" type="int" setter="" getter="get_collision_count" default="0">
|
||||
</member>
|
||||
<member name="collision_depth" type="float" setter="" getter="get_best_collision_depth" default="0.0">
|
||||
</member>
|
||||
<member name="collision_normal" type="Vector3" setter="" getter="get_best_collision_normal" default="Vector3(0, 0, 0)">
|
||||
</member>
|
||||
<member name="collision_point" type="Vector3" setter="" getter="get_best_collision_point" default="Vector3(0, 0, 0)">
|
||||
</member>
|
||||
<member name="remainder" type="Vector3" setter="" getter="get_remainder" default="Vector3(0, 0, 0)">
|
||||
</member>
|
||||
<member name="safe_fraction" type="float" setter="" getter="get_safe_fraction" default="0.0">
|
||||
</member>
|
||||
<member name="travel" type="Vector3" setter="" getter="get_travel" default="Vector3(0, 0, 0)">
|
||||
</member>
|
||||
<member name="unsafe_fraction" type="float" setter="" getter="get_unsafe_fraction" default="0.0">
|
||||
</member>
|
||||
</members>
|
||||
</class>
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
<return type="Vector2i" />
|
||||
<argument index="0" name="body" type="RID" />
|
||||
<description>
|
||||
Returns the coodinates of the tile for given physics body RID. Such RID can be retrieved from [member KinematicCollision2D.collider_rid], when colliding with a tile.
|
||||
Returns the coodinates of the tile for given physics body RID. Such RID can be retrieved from [method KinematicCollision2D.get_collider_rid], when colliding with a tile.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_layer_name" qualifiers="const">
|
||||
|
|
|
@ -54,13 +54,14 @@ PhysicsBody2D::~PhysicsBody2D() {
|
|||
}
|
||||
}
|
||||
|
||||
Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_motion, bool p_test_only, real_t p_margin) {
|
||||
PhysicsServer2D::MotionResult result;
|
||||
|
||||
Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_linear_velocity, bool p_test_only, real_t p_margin) {
|
||||
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
|
||||
double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
|
||||
|
||||
if (move_and_collide(p_motion * delta, result, p_margin, p_test_only)) {
|
||||
PhysicsServer2D::MotionParameters parameters(get_global_transform(), p_linear_velocity * delta, p_margin);
|
||||
|
||||
PhysicsServer2D::MotionResult result;
|
||||
if (move_and_collide(parameters, result, p_test_only)) {
|
||||
// Create a new instance when the cached reference is invalid or still in use in script.
|
||||
if (motion_cache.is_null() || motion_cache->reference_get_count() > 1) {
|
||||
motion_cache.instantiate();
|
||||
|
@ -74,18 +75,18 @@ Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_motion, bool p_t
|
|||
return Ref<KinematicCollision2D>();
|
||||
}
|
||||
|
||||
bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_test_only, bool p_cancel_sliding, bool p_collide_separation_ray, const Set<RID> &p_exclude) {
|
||||
bool PhysicsBody2D::move_and_collide(const PhysicsServer2D::MotionParameters &p_parameters, PhysicsServer2D::MotionResult &r_result, bool p_test_only, bool p_cancel_sliding) {
|
||||
if (is_only_update_transform_changes_enabled()) {
|
||||
ERR_PRINT("Move functions do not work together with 'sync to physics' option. Please read the documentation.");
|
||||
}
|
||||
Transform2D gt = get_global_transform();
|
||||
bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_margin, &r_result, p_collide_separation_ray, p_exclude);
|
||||
|
||||
bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), p_parameters, &r_result);
|
||||
|
||||
// Restore direction of motion to be along original motion,
|
||||
// in order to avoid sliding due to recovery,
|
||||
// but only if collision depth is low enough to avoid tunneling.
|
||||
if (p_cancel_sliding) {
|
||||
real_t motion_length = p_motion.length();
|
||||
real_t motion_length = p_parameters.motion.length();
|
||||
real_t precision = 0.001;
|
||||
|
||||
if (colliding) {
|
||||
|
@ -93,7 +94,7 @@ bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, PhysicsServer2D::M
|
|||
// so even in normal resting cases the depth can be a bit more than the margin.
|
||||
precision += motion_length * (r_result.collision_unsafe_fraction - r_result.collision_safe_fraction);
|
||||
|
||||
if (r_result.collision_depth > (real_t)p_margin + precision) {
|
||||
if (r_result.collision_depth > p_parameters.margin + precision) {
|
||||
p_cancel_sliding = false;
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +103,7 @@ bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, PhysicsServer2D::M
|
|||
// When motion is null, recovery is the resulting motion.
|
||||
Vector2 motion_normal;
|
||||
if (motion_length > CMP_EPSILON) {
|
||||
motion_normal = p_motion / motion_length;
|
||||
motion_normal = p_parameters.motion / motion_length;
|
||||
}
|
||||
|
||||
// Check depth of recovery.
|
||||
|
@ -111,15 +112,16 @@ bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, PhysicsServer2D::M
|
|||
real_t recovery_length = recovery.length();
|
||||
// Fixes cases where canceling slide causes the motion to go too deep into the ground,
|
||||
// because we're only taking rest information into account and not general recovery.
|
||||
if (recovery_length < (real_t)p_margin + precision) {
|
||||
if (recovery_length < p_parameters.margin + precision) {
|
||||
// Apply adjustment to motion.
|
||||
r_result.travel = motion_normal * projected_length;
|
||||
r_result.remainder = p_motion - r_result.travel;
|
||||
r_result.remainder = p_parameters.motion - r_result.travel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!p_test_only) {
|
||||
Transform2D gt = p_parameters.from;
|
||||
gt.elements[2] += r_result.travel;
|
||||
set_global_transform(gt);
|
||||
}
|
||||
|
@ -127,7 +129,7 @@ bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, PhysicsServer2D::M
|
|||
return colliding;
|
||||
}
|
||||
|
||||
bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion, const Ref<KinematicCollision2D> &r_collision, real_t p_margin) {
|
||||
bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_linear_velocity, const Ref<KinematicCollision2D> &r_collision, real_t p_margin) {
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||
|
||||
PhysicsServer2D::MotionResult *r = nullptr;
|
||||
|
@ -139,7 +141,9 @@ bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion
|
|||
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
|
||||
double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
|
||||
|
||||
return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion * delta, p_margin, r);
|
||||
PhysicsServer2D::MotionParameters parameters(p_from, p_linear_velocity * delta, p_margin);
|
||||
|
||||
return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), parameters, r);
|
||||
}
|
||||
|
||||
TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() {
|
||||
|
@ -1083,10 +1087,11 @@ bool CharacterBody2D::move_and_slide() {
|
|||
on_wall = false;
|
||||
|
||||
if (!current_platform_velocity.is_equal_approx(Vector2())) {
|
||||
PhysicsServer2D::MotionParameters parameters(get_global_transform(), current_platform_velocity * delta, margin);
|
||||
parameters.exclude_bodies.insert(platform_rid);
|
||||
|
||||
PhysicsServer2D::MotionResult floor_result;
|
||||
Set<RID> exclude;
|
||||
exclude.insert(platform_rid);
|
||||
if (move_and_collide(current_platform_velocity * delta, floor_result, margin, false, false, false, exclude)) {
|
||||
if (move_and_collide(parameters, floor_result, false, false)) {
|
||||
motion_results.push_back(floor_result);
|
||||
_set_collision_direction(floor_result);
|
||||
}
|
||||
|
@ -1138,11 +1143,13 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
|
|||
Vector2 last_travel;
|
||||
|
||||
for (int iteration = 0; iteration < max_slides; ++iteration) {
|
||||
PhysicsServer2D::MotionParameters parameters(get_global_transform(), motion, margin);
|
||||
|
||||
Vector2 prev_position = parameters.from.elements[2];
|
||||
|
||||
PhysicsServer2D::MotionResult result;
|
||||
bool collided = move_and_collide(parameters, result, false, !sliding_enabled);
|
||||
|
||||
Vector2 prev_position = get_global_transform().elements[2];
|
||||
|
||||
bool collided = move_and_collide(motion, result, margin, false, !sliding_enabled);
|
||||
last_motion = result.travel;
|
||||
|
||||
if (collided) {
|
||||
|
@ -1283,9 +1290,11 @@ void CharacterBody2D::_move_and_slide_free(double p_delta) {
|
|||
|
||||
bool first_slide = true;
|
||||
for (int iteration = 0; iteration < max_slides; ++iteration) {
|
||||
PhysicsServer2D::MotionResult result;
|
||||
PhysicsServer2D::MotionParameters parameters(get_global_transform(), motion, margin);
|
||||
|
||||
PhysicsServer2D::MotionResult result;
|
||||
bool collided = move_and_collide(parameters, result, false, false);
|
||||
|
||||
bool collided = move_and_collide(motion, result, margin, false, false);
|
||||
last_motion = result.travel;
|
||||
|
||||
if (collided) {
|
||||
|
@ -1327,10 +1336,11 @@ void CharacterBody2D::_snap_on_floor(bool was_on_floor, bool vel_dir_facing_up)
|
|||
// Snap by at least collision margin to keep floor state consistent.
|
||||
real_t length = MAX(floor_snap_length, margin);
|
||||
|
||||
Transform2D gt = get_global_transform();
|
||||
PhysicsServer2D::MotionParameters parameters(get_global_transform(), -up_direction * length, margin);
|
||||
parameters.collide_separation_ray = true;
|
||||
|
||||
PhysicsServer2D::MotionResult result;
|
||||
if (move_and_collide(-up_direction * length, result, margin, true, false, true)) {
|
||||
bool apply = true;
|
||||
if (move_and_collide(parameters, result, true, false)) {
|
||||
if (result.get_angle(up_direction) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
|
||||
on_floor = true;
|
||||
floor_normal = result.collision_normal;
|
||||
|
@ -1345,13 +1355,9 @@ void CharacterBody2D::_snap_on_floor(bool was_on_floor, bool vel_dir_facing_up)
|
|||
result.travel = Vector2();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
apply = false;
|
||||
}
|
||||
|
||||
if (apply) {
|
||||
gt.elements[2] += result.travel;
|
||||
set_global_transform(gt);
|
||||
parameters.from.elements[2] += result.travel;
|
||||
set_global_transform(parameters.from);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1364,8 +1370,11 @@ bool CharacterBody2D::_on_floor_if_snapped(bool was_on_floor, bool vel_dir_facin
|
|||
// Snap by at least collision margin to keep floor state consistent.
|
||||
real_t length = MAX(floor_snap_length, margin);
|
||||
|
||||
PhysicsServer2D::MotionParameters parameters(get_global_transform(), -up_direction * length, margin);
|
||||
parameters.collide_separation_ray = true;
|
||||
|
||||
PhysicsServer2D::MotionResult result;
|
||||
if (move_and_collide(-up_direction * length, result, margin, true, false, true)) {
|
||||
if (move_and_collide(parameters, result, true, false)) {
|
||||
if (result.get_angle(up_direction) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1806,16 +1815,4 @@ void KinematicCollision2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicCollision2D::get_collider_shape);
|
||||
ClassDB::bind_method(D_METHOD("get_collider_shape_index"), &KinematicCollision2D::get_collider_shape_index);
|
||||
ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicCollision2D::get_collider_velocity);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "", "get_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "normal"), "", "get_normal");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "travel"), "", "get_travel");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "remainder"), "", "get_remainder");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "local_shape"), "", "get_local_shape");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_collider");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id"), "", "get_collider_id");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::RID, "collider_rid"), "", "get_collider_rid");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider_shape"), "", "get_collider_shape");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape_index"), "", "get_collider_shape_index");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "collider_velocity"), "", "get_collider_velocity");
|
||||
}
|
||||
|
|
|
@ -47,11 +47,11 @@ protected:
|
|||
|
||||
Ref<KinematicCollision2D> motion_cache;
|
||||
|
||||
Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_test_only = false, real_t p_margin = 0.08);
|
||||
Ref<KinematicCollision2D> _move(const Vector2 &p_linear_velocity, bool p_test_only = false, real_t p_margin = 0.08);
|
||||
|
||||
public:
|
||||
bool move_and_collide(const Vector2 &p_motion, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_test_only = false, bool p_cancel_sliding = true, bool p_collide_separation_ray = false, const Set<RID> &p_exclude = Set<RID>());
|
||||
bool test_move(const Transform2D &p_from, const Vector2 &p_motion, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08);
|
||||
bool move_and_collide(const PhysicsServer2D::MotionParameters &p_parameters, PhysicsServer2D::MotionResult &r_result, bool p_test_only = false, bool p_cancel_sliding = true);
|
||||
bool test_move(const Transform2D &p_from, const Vector2 &p_linear_velocity, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08);
|
||||
|
||||
TypedArray<PhysicsBody2D> get_collision_exceptions();
|
||||
void add_collision_exception_with(Node *p_node); //must be physicsbody
|
||||
|
|
|
@ -91,12 +91,15 @@ void PhysicsBody3D::remove_collision_exception_with(Node *p_node) {
|
|||
PhysicsServer3D::get_singleton()->body_remove_collision_exception(get_rid(), collision_object->get_rid());
|
||||
}
|
||||
|
||||
Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_motion, bool p_test_only, real_t p_margin, int p_max_collisions) {
|
||||
PhysicsServer3D::MotionResult result;
|
||||
Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_linear_velocity, bool p_test_only, real_t p_margin, int p_max_collisions) {
|
||||
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
|
||||
double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
|
||||
|
||||
if (move_and_collide(p_motion * delta, result, p_margin, p_test_only, p_max_collisions)) {
|
||||
PhysicsServer3D::MotionParameters parameters(get_global_transform(), p_linear_velocity * delta, p_margin);
|
||||
parameters.max_collisions = p_max_collisions;
|
||||
|
||||
PhysicsServer3D::MotionResult result;
|
||||
if (move_and_collide(parameters, result, p_test_only)) {
|
||||
// Create a new instance when the cached reference is invalid or still in use in script.
|
||||
if (motion_cache.is_null() || motion_cache->reference_get_count() > 1) {
|
||||
motion_cache.instantiate();
|
||||
|
@ -111,23 +114,22 @@ Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_motion, bool p_t
|
|||
return Ref<KinematicCollision3D>();
|
||||
}
|
||||
|
||||
bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_test_only, int p_max_collisions, bool p_cancel_sliding, bool p_collide_separation_ray, const Set<RID> &p_exclude) {
|
||||
Transform3D gt = get_global_transform();
|
||||
bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_margin, &r_result, p_max_collisions, p_collide_separation_ray, p_exclude);
|
||||
bool PhysicsBody3D::move_and_collide(const PhysicsServer3D::MotionParameters &p_parameters, PhysicsServer3D::MotionResult &r_result, bool p_test_only, bool p_cancel_sliding) {
|
||||
bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), p_parameters, &r_result);
|
||||
|
||||
// Restore direction of motion to be along original motion,
|
||||
// in order to avoid sliding due to recovery,
|
||||
// but only if collision depth is low enough to avoid tunneling.
|
||||
if (p_cancel_sliding) {
|
||||
real_t motion_length = p_motion.length();
|
||||
real_t motion_length = p_parameters.motion.length();
|
||||
real_t precision = 0.001;
|
||||
|
||||
if (colliding) {
|
||||
// Can't just use margin as a threshold because collision depth is calculated on unsafe motion,
|
||||
// so even in normal resting cases the depth can be a bit more than the margin.
|
||||
precision += motion_length * (r_result.unsafe_fraction - r_result.safe_fraction);
|
||||
precision += motion_length * (r_result.collision_unsafe_fraction - r_result.collision_safe_fraction);
|
||||
|
||||
if (r_result.collisions[0].depth > (real_t)p_margin + precision) {
|
||||
if (r_result.collisions[0].depth > p_parameters.margin + precision) {
|
||||
p_cancel_sliding = false;
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +138,7 @@ bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, PhysicsServer3D::M
|
|||
// When motion is null, recovery is the resulting motion.
|
||||
Vector3 motion_normal;
|
||||
if (motion_length > CMP_EPSILON) {
|
||||
motion_normal = p_motion / motion_length;
|
||||
motion_normal = p_parameters.motion / motion_length;
|
||||
}
|
||||
|
||||
// Check depth of recovery.
|
||||
|
@ -145,10 +147,10 @@ bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, PhysicsServer3D::M
|
|||
real_t recovery_length = recovery.length();
|
||||
// Fixes cases where canceling slide causes the motion to go too deep into the ground,
|
||||
// because we're only taking rest information into account and not general recovery.
|
||||
if (recovery_length < (real_t)p_margin + precision) {
|
||||
if (recovery_length < p_parameters.margin + precision) {
|
||||
// Apply adjustment to motion.
|
||||
r_result.travel = motion_normal * projected_length;
|
||||
r_result.remainder = p_motion - r_result.travel;
|
||||
r_result.remainder = p_parameters.motion - r_result.travel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -160,6 +162,7 @@ bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, PhysicsServer3D::M
|
|||
}
|
||||
|
||||
if (!p_test_only) {
|
||||
Transform3D gt = p_parameters.from;
|
||||
gt.origin += r_result.travel;
|
||||
set_global_transform(gt);
|
||||
}
|
||||
|
@ -167,7 +170,7 @@ bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, PhysicsServer3D::M
|
|||
return colliding;
|
||||
}
|
||||
|
||||
bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_motion, const Ref<KinematicCollision3D> &r_collision, real_t p_margin, int p_max_collisions) {
|
||||
bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_linear_velocity, const Ref<KinematicCollision3D> &r_collision, real_t p_margin, int p_max_collisions) {
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||
|
||||
PhysicsServer3D::MotionResult *r = nullptr;
|
||||
|
@ -179,7 +182,9 @@ bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_motion
|
|||
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
|
||||
double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
|
||||
|
||||
return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion * delta, p_margin, r, p_max_collisions);
|
||||
PhysicsServer3D::MotionParameters parameters(p_from, p_linear_velocity * delta, p_margin);
|
||||
|
||||
return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), parameters, r);
|
||||
}
|
||||
|
||||
void PhysicsBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) {
|
||||
|
@ -1124,10 +1129,11 @@ bool CharacterBody3D::move_and_slide() {
|
|||
last_motion = Vector3();
|
||||
|
||||
if (!current_platform_velocity.is_equal_approx(Vector3())) {
|
||||
PhysicsServer3D::MotionParameters parameters(get_global_transform(), current_platform_velocity * delta, margin);
|
||||
parameters.exclude_bodies.insert(platform_rid);
|
||||
|
||||
PhysicsServer3D::MotionResult floor_result;
|
||||
Set<RID> exclude;
|
||||
exclude.insert(platform_rid);
|
||||
if (move_and_collide(current_platform_velocity * delta, floor_result, margin, false, 1, false, false, exclude)) {
|
||||
if (move_and_collide(parameters, floor_result, false, false)) {
|
||||
motion_results.push_back(floor_result);
|
||||
|
||||
CollisionState result_state;
|
||||
|
@ -1181,8 +1187,12 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
|
|||
Vector3 total_travel;
|
||||
|
||||
for (int iteration = 0; iteration < max_slides; ++iteration) {
|
||||
PhysicsServer3D::MotionParameters parameters(get_global_transform(), motion, margin);
|
||||
parameters.max_collisions = 4;
|
||||
|
||||
PhysicsServer3D::MotionResult result;
|
||||
bool collided = move_and_collide(motion, result, margin, false, 4, !sliding_enabled);
|
||||
bool collided = move_and_collide(parameters, result, false, !sliding_enabled);
|
||||
|
||||
last_motion = result.travel;
|
||||
|
||||
if (collided) {
|
||||
|
@ -1411,9 +1421,11 @@ void CharacterBody3D::_move_and_slide_free(double p_delta) {
|
|||
|
||||
bool first_slide = true;
|
||||
for (int iteration = 0; iteration < max_slides; ++iteration) {
|
||||
PhysicsServer3D::MotionResult result;
|
||||
PhysicsServer3D::MotionParameters parameters(get_global_transform(), motion, margin);
|
||||
|
||||
PhysicsServer3D::MotionResult result;
|
||||
bool collided = move_and_collide(parameters, result, false, false);
|
||||
|
||||
bool collided = move_and_collide(motion, result, margin, false, 1, false);
|
||||
last_motion = result.travel;
|
||||
|
||||
if (collided) {
|
||||
|
@ -1462,9 +1474,12 @@ void CharacterBody3D::_snap_on_floor(bool was_on_floor, bool vel_dir_facing_up)
|
|||
// Snap by at least collision margin to keep floor state consistent.
|
||||
real_t length = MAX(floor_snap_length, margin);
|
||||
|
||||
Transform3D gt = get_global_transform();
|
||||
PhysicsServer3D::MotionParameters parameters(get_global_transform(), -up_direction * length, margin);
|
||||
parameters.max_collisions = 4;
|
||||
parameters.collide_separation_ray = true;
|
||||
|
||||
PhysicsServer3D::MotionResult result;
|
||||
if (move_and_collide(-up_direction * length, result, margin, true, 4, false, true)) {
|
||||
if (move_and_collide(parameters, result, true, false)) {
|
||||
CollisionState result_state;
|
||||
// Apply direction for floor only.
|
||||
_set_collision_direction(result, result_state, CollisionState(true, false, false));
|
||||
|
@ -1480,8 +1495,8 @@ void CharacterBody3D::_snap_on_floor(bool was_on_floor, bool vel_dir_facing_up)
|
|||
}
|
||||
}
|
||||
|
||||
gt.origin += result.travel;
|
||||
set_global_transform(gt);
|
||||
parameters.from.origin += result.travel;
|
||||
set_global_transform(parameters.from);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1494,8 +1509,12 @@ bool CharacterBody3D::_on_floor_if_snapped(bool was_on_floor, bool vel_dir_facin
|
|||
// Snap by at least collision margin to keep floor state consistent.
|
||||
real_t length = MAX(floor_snap_length, margin);
|
||||
|
||||
PhysicsServer3D::MotionParameters parameters(get_global_transform(), -up_direction * length, margin);
|
||||
parameters.max_collisions = 4;
|
||||
parameters.collide_separation_ray = true;
|
||||
|
||||
PhysicsServer3D::MotionResult result;
|
||||
if (move_and_collide(-up_direction * length, result, margin, true, 4, false, true)) {
|
||||
if (move_and_collide(parameters, result, true, false)) {
|
||||
CollisionState result_state;
|
||||
// Don't apply direction for any type.
|
||||
_set_collision_direction(result, result_state, CollisionState());
|
||||
|
@ -2002,42 +2021,6 @@ Vector3 KinematicCollision3D::get_collider_velocity(int p_collision_index) const
|
|||
return result.collisions[p_collision_index].collider_velocity;
|
||||
}
|
||||
|
||||
Vector3 KinematicCollision3D::get_best_position() const {
|
||||
return result.collision_count ? get_position() : Vector3();
|
||||
}
|
||||
|
||||
Vector3 KinematicCollision3D::get_best_normal() const {
|
||||
return result.collision_count ? get_normal() : Vector3();
|
||||
}
|
||||
|
||||
Object *KinematicCollision3D::get_best_local_shape() const {
|
||||
return result.collision_count ? get_local_shape() : nullptr;
|
||||
}
|
||||
|
||||
Object *KinematicCollision3D::get_best_collider() const {
|
||||
return result.collision_count ? get_collider() : nullptr;
|
||||
}
|
||||
|
||||
ObjectID KinematicCollision3D::get_best_collider_id() const {
|
||||
return result.collision_count ? get_collider_id() : ObjectID();
|
||||
}
|
||||
|
||||
RID KinematicCollision3D::get_best_collider_rid() const {
|
||||
return result.collision_count ? get_collider_rid() : RID();
|
||||
}
|
||||
|
||||
Object *KinematicCollision3D::get_best_collider_shape() const {
|
||||
return result.collision_count ? get_collider_shape() : nullptr;
|
||||
}
|
||||
|
||||
int KinematicCollision3D::get_best_collider_shape_index() const {
|
||||
return result.collision_count ? get_collider_shape_index() : 0;
|
||||
}
|
||||
|
||||
Vector3 KinematicCollision3D::get_best_collider_velocity() const {
|
||||
return result.collision_count ? get_collider_velocity() : Vector3();
|
||||
}
|
||||
|
||||
void KinematicCollision3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision3D::get_travel);
|
||||
ClassDB::bind_method(D_METHOD("get_remainder"), &KinematicCollision3D::get_remainder);
|
||||
|
@ -2052,29 +2035,6 @@ void KinematicCollision3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_collider_shape", "collision_index"), &KinematicCollision3D::get_collider_shape, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("get_collider_shape_index", "collision_index"), &KinematicCollision3D::get_collider_shape_index, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("get_collider_velocity", "collision_index"), &KinematicCollision3D::get_collider_velocity, DEFVAL(0));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_best_position"), &KinematicCollision3D::get_best_position);
|
||||
ClassDB::bind_method(D_METHOD("get_best_normal"), &KinematicCollision3D::get_best_normal);
|
||||
ClassDB::bind_method(D_METHOD("get_best_local_shape"), &KinematicCollision3D::get_best_local_shape);
|
||||
ClassDB::bind_method(D_METHOD("get_best_collider"), &KinematicCollision3D::get_best_collider);
|
||||
ClassDB::bind_method(D_METHOD("get_best_collider_id"), &KinematicCollision3D::get_best_collider_id);
|
||||
ClassDB::bind_method(D_METHOD("get_best_collider_rid"), &KinematicCollision3D::get_best_collider_rid);
|
||||
ClassDB::bind_method(D_METHOD("get_best_collider_shape"), &KinematicCollision3D::get_best_collider_shape);
|
||||
ClassDB::bind_method(D_METHOD("get_best_collider_shape_index"), &KinematicCollision3D::get_best_collider_shape_index);
|
||||
ClassDB::bind_method(D_METHOD("get_best_collider_velocity"), &KinematicCollision3D::get_best_collider_velocity);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "travel"), "", "get_travel");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "remainder"), "", "get_remainder");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_count"), "", "get_collision_count");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position"), "", "get_best_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "normal"), "", "get_best_normal");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "local_shape"), "", "get_best_local_shape");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_best_collider");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id"), "", "get_best_collider_id");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::RID, "collider_rid"), "", "get_best_collider_rid");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider_shape"), "", "get_best_collider_shape");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape_index"), "", "get_best_collider_shape_index");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collider_velocity"), "", "get_best_collider_velocity");
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
|
|
@ -50,11 +50,11 @@ protected:
|
|||
|
||||
uint16_t locked_axis = 0;
|
||||
|
||||
Ref<KinematicCollision3D> _move(const Vector3 &p_motion, bool p_test_only = false, real_t p_margin = 0.001, int p_max_collisions = 1);
|
||||
Ref<KinematicCollision3D> _move(const Vector3 &p_linear_velocity, bool p_test_only = false, real_t p_margin = 0.001, int p_max_collisions = 1);
|
||||
|
||||
public:
|
||||
bool move_and_collide(const Vector3 &p_motion, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_test_only = false, int p_max_collisions = 1, bool p_cancel_sliding = true, bool p_collide_separation_ray = false, const Set<RID> &p_exclude = Set<RID>());
|
||||
bool test_move(const Transform3D &p_from, const Vector3 &p_motion, const Ref<KinematicCollision3D> &r_collision = Ref<KinematicCollision3D>(), real_t p_margin = 0.001, int p_max_collisions = 1);
|
||||
bool move_and_collide(const PhysicsServer3D::MotionParameters &p_parameters, PhysicsServer3D::MotionResult &r_result, bool p_test_only = false, bool p_cancel_sliding = true);
|
||||
bool test_move(const Transform3D &p_from, const Vector3 &p_linear_velocity, const Ref<KinematicCollision3D> &r_collision = Ref<KinematicCollision3D>(), real_t p_margin = 0.001, int p_max_collisions = 1);
|
||||
|
||||
void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock);
|
||||
bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const;
|
||||
|
@ -487,16 +487,6 @@ public:
|
|||
Object *get_collider_shape(int p_collision_index = 0) const;
|
||||
int get_collider_shape_index(int p_collision_index = 0) const;
|
||||
Vector3 get_collider_velocity(int p_collision_index = 0) const;
|
||||
|
||||
Vector3 get_best_position() const;
|
||||
Vector3 get_best_normal() const;
|
||||
Object *get_best_local_shape() const;
|
||||
Object *get_best_collider() const;
|
||||
ObjectID get_best_collider_id() const;
|
||||
RID get_best_collider_rid() const;
|
||||
Object *get_best_collider_shape() const;
|
||||
int get_best_collider_shape_index() const;
|
||||
Vector3 get_best_collider_velocity() const;
|
||||
};
|
||||
|
||||
class PhysicalBone3D : public PhysicsBody3D {
|
||||
|
|
|
@ -948,7 +948,7 @@ void PhysicsServer2DSW::body_set_pickable(RID p_body, bool p_pickable) {
|
|||
body->set_pickable(p_pickable);
|
||||
}
|
||||
|
||||
bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin, MotionResult *r_result, bool p_collide_separation_ray, const Set<RID> &p_exclude) {
|
||||
bool PhysicsServer2DSW::body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result) {
|
||||
Body2DSW *body = body_owner.get_or_null(p_body);
|
||||
ERR_FAIL_COND_V(!body, false);
|
||||
ERR_FAIL_COND_V(!body->get_space(), false);
|
||||
|
@ -956,7 +956,7 @@ bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from,
|
|||
|
||||
_update_shapes();
|
||||
|
||||
return body->get_space()->test_body_motion(body, p_from, p_motion, p_margin, r_result, p_collide_separation_ray, p_exclude);
|
||||
return body->get_space()->test_body_motion(body, p_parameters, r_result);
|
||||
}
|
||||
|
||||
PhysicsDirectBodyState2D *PhysicsServer2DSW::body_get_direct_state(RID p_body) {
|
||||
|
|
|
@ -246,7 +246,7 @@ public:
|
|||
|
||||
virtual void body_set_pickable(RID p_body, bool p_pickable) override;
|
||||
|
||||
virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_collide_separation_ray = false, const Set<RID> &p_exclude = Set<RID>()) override;
|
||||
virtual bool body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result = nullptr) override;
|
||||
|
||||
// this function only works on physics process, errors and returns null otherwise
|
||||
virtual PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) override;
|
||||
|
|
|
@ -254,9 +254,9 @@ public:
|
|||
|
||||
FUNC2(body_set_pickable, RID, bool);
|
||||
|
||||
bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_collide_separation_ray = false, const Set<RID> &p_exclude = Set<RID>()) override {
|
||||
bool body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result = nullptr) override {
|
||||
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
|
||||
return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_margin, r_result, p_collide_separation_ray, p_exclude);
|
||||
return physics_2d_server->body_test_motion(p_body, p_parameters, r_result);
|
||||
}
|
||||
|
||||
// this function only works on physics process, errors and returns null otherwise
|
||||
|
|
|
@ -525,7 +525,7 @@ int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) {
|
|||
return amount;
|
||||
}
|
||||
|
||||
bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin, PhysicsServer2D::MotionResult *r_result, bool p_collide_separation_ray, const Set<RID> &p_exclude) {
|
||||
bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::MotionParameters &p_parameters, PhysicsServer2D::MotionResult *r_result) {
|
||||
//give me back regular physics engine logic
|
||||
//this is madness
|
||||
//and most people using this function will think
|
||||
|
@ -557,25 +557,25 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
if (!shapes_found) {
|
||||
if (r_result) {
|
||||
*r_result = PhysicsServer2D::MotionResult();
|
||||
r_result->travel = p_motion;
|
||||
r_result->travel = p_parameters.motion;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Undo the currently transform the physics server is aware of and apply the provided one
|
||||
body_aabb = p_from.xform(p_body->get_inv_transform().xform(body_aabb));
|
||||
body_aabb = body_aabb.grow(p_margin);
|
||||
body_aabb = p_parameters.from.xform(p_body->get_inv_transform().xform(body_aabb));
|
||||
body_aabb = body_aabb.grow(p_parameters.margin);
|
||||
|
||||
static const int max_excluded_shape_pairs = 32;
|
||||
ExcludedShapeSW excluded_shape_pairs[max_excluded_shape_pairs];
|
||||
int excluded_shape_pair_count = 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;
|
||||
|
||||
real_t motion_length = p_motion.length();
|
||||
Vector2 motion_normal = p_motion / motion_length;
|
||||
real_t motion_length = p_parameters.motion.length();
|
||||
Vector2 motion_normal = p_parameters.motion / motion_length;
|
||||
|
||||
Transform2D body_transform = p_from;
|
||||
Transform2D body_transform = p_parameters.from;
|
||||
|
||||
bool recovered = false;
|
||||
|
||||
|
@ -612,7 +612,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
const CollisionObject2DSW *col_obj = intersection_query_results[i];
|
||||
if (p_exclude.has(col_obj->get_self())) {
|
||||
if (p_parameters.exclude_bodies.has(col_obj->get_self())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -624,7 +624,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
cbk.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
|
||||
|
||||
real_t owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx);
|
||||
cbk.valid_depth = MAX(owc_margin, p_margin); //user specified, but never less than actual margin or it won't work
|
||||
cbk.valid_depth = MAX(owc_margin, p_parameters.margin); //user specified, but never less than actual margin or it won't work
|
||||
cbk.invalid_by_dir = 0;
|
||||
|
||||
if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
|
||||
|
@ -649,7 +649,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
bool did_collide = false;
|
||||
|
||||
Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
|
||||
if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, p_margin)) {
|
||||
if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, p_parameters.margin)) {
|
||||
did_collide = cbk.passed > current_passed; //more passed, so collision actually existed
|
||||
}
|
||||
|
||||
|
@ -714,7 +714,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
// STEP 2 ATTEMPT MOTION
|
||||
|
||||
Rect2 motion_aabb = body_aabb;
|
||||
motion_aabb.position += p_motion;
|
||||
motion_aabb.position += p_parameters.motion;
|
||||
motion_aabb = motion_aabb.merge(body_aabb);
|
||||
|
||||
int amount = _cull_aabb_for_body(p_body, motion_aabb);
|
||||
|
@ -728,7 +728,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
|
||||
// Colliding separation rays allows to properly snap to the ground,
|
||||
// otherwise it's not needed in regular motion.
|
||||
if (!p_collide_separation_ray && (body_shape->get_type() == PhysicsServer2D::SHAPE_SEPARATION_RAY)) {
|
||||
if (!p_parameters.collide_separation_ray && (body_shape->get_type() == PhysicsServer2D::SHAPE_SEPARATION_RAY)) {
|
||||
// When slide on slope is on, separation ray shape acts like a regular shape.
|
||||
if (!static_cast<SeparationRayShape2DSW *>(body_shape)->get_slide_on_slope()) {
|
||||
continue;
|
||||
|
@ -744,9 +744,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
const CollisionObject2DSW *col_obj = intersection_query_results[i];
|
||||
if (p_exclude.has(col_obj->get_self())) {
|
||||
if (p_parameters.exclude_bodies.has(col_obj->get_self())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int col_shape_idx = intersection_query_subindex_results[i];
|
||||
Shape2DSW *against_shape = col_obj->get_shape(col_shape_idx);
|
||||
|
||||
|
@ -765,7 +766,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
|
||||
Transform2D col_obj_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(col_shape_idx);
|
||||
//test initial overlap, does it collide if going all the way?
|
||||
if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, nullptr, 0)) {
|
||||
if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_parameters.motion, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, nullptr, 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -790,7 +791,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
real_t fraction = low + (hi - low) * fraction_coeff;
|
||||
|
||||
Vector2 sep = motion_normal; //important optimization for this to work fast enough
|
||||
bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * fraction, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, &sep, 0);
|
||||
bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_parameters.motion * fraction, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, &sep, 0);
|
||||
|
||||
if (collided) {
|
||||
hi = fraction;
|
||||
|
@ -827,7 +828,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
cbk.valid_depth = 10e20;
|
||||
|
||||
Vector2 sep = motion_normal; //important optimization for this to work fast enough
|
||||
bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(col_shape_idx), col_obj_shape_xform, Vector2(), PhysicsServer2DSW::_shape_col_cbk, &cbk, &sep, 0);
|
||||
bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_parameters.motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(col_shape_idx), col_obj_shape_xform, Vector2(), PhysicsServer2DSW::_shape_col_cbk, &cbk, &sep, 0);
|
||||
if (!collided || cbk.amount == 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -865,7 +866,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
|
||||
//it collided, let's get the rest info in unsafe advance
|
||||
Transform2D ugt = body_transform;
|
||||
ugt.elements[2] += p_motion * unsafe;
|
||||
ugt.elements[2] += p_parameters.motion * unsafe;
|
||||
|
||||
_RestCallbackData2D rcd;
|
||||
rcd.best_len = 0;
|
||||
|
@ -886,13 +887,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
Transform2D body_shape_xform = ugt * p_body->get_shape_transform(j);
|
||||
Shape2DSW *body_shape = p_body->get_shape(j);
|
||||
|
||||
body_aabb.position += p_motion * unsafe;
|
||||
body_aabb.position += p_parameters.motion * unsafe;
|
||||
|
||||
int amount = _cull_aabb_for_body(p_body, body_aabb);
|
||||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
const CollisionObject2DSW *col_obj = intersection_query_results[i];
|
||||
if (p_exclude.has(col_obj->get_self())) {
|
||||
if (p_parameters.exclude_bodies.has(col_obj->get_self())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -917,7 +918,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
rcd.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
|
||||
|
||||
real_t owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx);
|
||||
rcd.valid_depth = MAX(owc_margin, p_margin); //user specified, but never less than actual margin or it won't work
|
||||
rcd.valid_depth = MAX(owc_margin, p_parameters.margin); //user specified, but never less than actual margin or it won't work
|
||||
|
||||
if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
|
||||
const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
|
||||
|
@ -939,7 +940,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
rcd.object = col_obj;
|
||||
rcd.shape = shape_idx;
|
||||
rcd.local_shape = j;
|
||||
bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), _rest_cbk_result, &rcd, nullptr, p_margin);
|
||||
bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), _rest_cbk_result, &rcd, nullptr, p_parameters.margin);
|
||||
if (!sc) {
|
||||
continue;
|
||||
}
|
||||
|
@ -962,9 +963,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
Vector2 rel_vec = r_result->collision_point - (body->get_transform().get_origin() + body->get_center_of_mass());
|
||||
r_result->collider_velocity = Vector2(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity();
|
||||
|
||||
r_result->travel = safe * p_motion;
|
||||
r_result->remainder = p_motion - safe * p_motion;
|
||||
r_result->travel += (body_transform.get_origin() - p_from.get_origin());
|
||||
r_result->travel = safe * p_parameters.motion;
|
||||
r_result->remainder = p_parameters.motion - safe * p_parameters.motion;
|
||||
r_result->travel += (body_transform.get_origin() - p_parameters.from.get_origin());
|
||||
}
|
||||
|
||||
collided = true;
|
||||
|
@ -972,9 +973,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
}
|
||||
|
||||
if (!collided && r_result) {
|
||||
r_result->travel = p_motion;
|
||||
r_result->travel = p_parameters.motion;
|
||||
r_result->remainder = Vector2();
|
||||
r_result->travel += (body_transform.get_origin() - p_from.get_origin());
|
||||
r_result->travel += (body_transform.get_origin() - p_parameters.from.get_origin());
|
||||
}
|
||||
|
||||
return collided;
|
||||
|
|
|
@ -187,7 +187,7 @@ public:
|
|||
|
||||
int get_collision_pairs() const { return collision_pairs; }
|
||||
|
||||
bool test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin, PhysicsServer2D::MotionResult *r_result, bool p_collide_separation_ray = false, const Set<RID> &p_exclude = Set<RID>());
|
||||
bool test_body_motion(Body2DSW *p_body, const PhysicsServer2D::MotionParameters &p_parameters, PhysicsServer2D::MotionResult *r_result);
|
||||
|
||||
void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); }
|
||||
_FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.is_empty(); }
|
||||
|
|
|
@ -868,7 +868,7 @@ void PhysicsServer3DSW::body_set_ray_pickable(RID p_body, bool p_enable) {
|
|||
body->set_ray_pickable(p_enable);
|
||||
}
|
||||
|
||||
bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin, MotionResult *r_result, int p_max_collisions, bool p_collide_separation_ray, const Set<RID> &p_exclude) {
|
||||
bool PhysicsServer3DSW::body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result) {
|
||||
Body3DSW *body = body_owner.get_or_null(p_body);
|
||||
ERR_FAIL_COND_V(!body, false);
|
||||
ERR_FAIL_COND_V(!body->get_space(), false);
|
||||
|
@ -876,7 +876,7 @@ bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform3D &p_from,
|
|||
|
||||
_update_shapes();
|
||||
|
||||
return body->get_space()->test_body_motion(body, p_from, p_motion, p_margin, r_result, p_max_collisions, p_collide_separation_ray, p_exclude);
|
||||
return body->get_space()->test_body_motion(body, p_parameters, r_result);
|
||||
}
|
||||
|
||||
PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) {
|
||||
|
|
|
@ -242,7 +242,7 @@ public:
|
|||
|
||||
virtual void body_set_ray_pickable(RID p_body, bool p_enable) override;
|
||||
|
||||
virtual bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin = 0.001, MotionResult *r_result = nullptr, int p_max_collisions = 1, bool p_collide_separation_ray = false, const Set<RID> &p_exclude = Set<RID>()) override;
|
||||
virtual bool body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result = nullptr) override;
|
||||
|
||||
// this function only works on physics process, errors and returns null otherwise
|
||||
virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override;
|
||||
|
|
|
@ -253,9 +253,9 @@ public:
|
|||
|
||||
FUNC2(body_set_ray_pickable, RID, bool);
|
||||
|
||||
bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin = 0.001, MotionResult *r_result = nullptr, int p_max_collisions = 1, bool p_collide_separation_ray = false, const Set<RID> &p_exclude = Set<RID>()) override {
|
||||
bool body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result = nullptr) override {
|
||||
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
|
||||
return physics_3d_server->body_test_motion(p_body, p_from, p_motion, p_margin, r_result, p_max_collisions, p_collide_separation_ray, p_exclude);
|
||||
return physics_3d_server->body_test_motion(p_body, p_parameters, r_result);
|
||||
}
|
||||
|
||||
// this function only works on physics process, errors and returns null otherwise
|
||||
|
|
|
@ -620,7 +620,7 @@ int Space3DSW::_cull_aabb_for_body(Body3DSW *p_body, const AABB &p_aabb) {
|
|||
return amount;
|
||||
}
|
||||
|
||||
bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin, PhysicsServer3D::MotionResult *r_result, int p_max_collisions, bool p_collide_separation_ray, const Set<RID> &p_exclude) {
|
||||
bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::MotionParameters &p_parameters, PhysicsServer3D::MotionResult *r_result) {
|
||||
//give me back regular physics engine logic
|
||||
//this is madness
|
||||
//and most people using this function will think
|
||||
|
@ -628,7 +628,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
//this took about a week to get right..
|
||||
//but is it right? who knows at this point..
|
||||
|
||||
ERR_FAIL_INDEX_V(p_max_collisions, PhysicsServer3D::MotionResult::MAX_COLLISIONS, false);
|
||||
ERR_FAIL_INDEX_V(p_parameters.max_collisions, PhysicsServer3D::MotionResult::MAX_COLLISIONS, false);
|
||||
|
||||
if (r_result) {
|
||||
*r_result = PhysicsServer3D::MotionResult();
|
||||
|
@ -652,22 +652,22 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
|
||||
if (!shapes_found) {
|
||||
if (r_result) {
|
||||
r_result->travel = p_motion;
|
||||
r_result->travel = p_parameters.motion;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Undo the currently transform the physics server is aware of and apply the provided one
|
||||
body_aabb = p_from.xform(p_body->get_inv_transform().xform(body_aabb));
|
||||
body_aabb = body_aabb.grow(p_margin);
|
||||
body_aabb = p_parameters.from.xform(p_body->get_inv_transform().xform(body_aabb));
|
||||
body_aabb = body_aabb.grow(p_parameters.margin);
|
||||
|
||||
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;
|
||||
|
||||
real_t motion_length = p_motion.length();
|
||||
Vector3 motion_normal = p_motion / motion_length;
|
||||
real_t motion_length = p_parameters.motion.length();
|
||||
Vector3 motion_normal = p_parameters.motion / motion_length;
|
||||
|
||||
Transform3D body_transform = p_from;
|
||||
Transform3D body_transform = p_parameters.from;
|
||||
|
||||
bool recovered = false;
|
||||
|
||||
|
@ -701,13 +701,13 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
const CollisionObject3DSW *col_obj = intersection_query_results[i];
|
||||
if (p_exclude.has(col_obj->get_self())) {
|
||||
if (p_parameters.exclude_bodies.has(col_obj->get_self())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
if (CollisionSolver3DSW::solve_static(body_shape, body_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 (CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_parameters.margin)) {
|
||||
collided = cbk.amount > 0;
|
||||
}
|
||||
}
|
||||
|
@ -757,7 +757,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
// STEP 2 ATTEMPT MOTION
|
||||
|
||||
AABB motion_aabb = body_aabb;
|
||||
motion_aabb.position += p_motion;
|
||||
motion_aabb.position += p_parameters.motion;
|
||||
motion_aabb = motion_aabb.merge(body_aabb);
|
||||
|
||||
int amount = _cull_aabb_for_body(p_body, motion_aabb);
|
||||
|
@ -771,7 +771,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
|
||||
// Colliding separation rays allows to properly snap to the ground,
|
||||
// otherwise it's not needed in regular motion.
|
||||
if (!p_collide_separation_ray && (body_shape->get_type() == PhysicsServer3D::SHAPE_SEPARATION_RAY)) {
|
||||
if (!p_parameters.collide_separation_ray && (body_shape->get_type() == PhysicsServer3D::SHAPE_SEPARATION_RAY)) {
|
||||
// When slide on slope is on, separation ray shape acts like a regular shape.
|
||||
if (!static_cast<SeparationRayShape3DSW *>(body_shape)->get_slide_on_slope()) {
|
||||
continue;
|
||||
|
@ -783,7 +783,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
Transform3D body_shape_xform_inv = body_shape_xform.affine_inverse();
|
||||
MotionShape3DSW mshape;
|
||||
mshape.shape = body_shape;
|
||||
mshape.motion = body_shape_xform_inv.basis.xform(p_motion);
|
||||
mshape.motion = body_shape_xform_inv.basis.xform(p_parameters.motion);
|
||||
|
||||
bool stuck = false;
|
||||
|
||||
|
@ -792,7 +792,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
const CollisionObject3DSW *col_obj = intersection_query_results[i];
|
||||
if (p_exclude.has(col_obj->get_self())) {
|
||||
if (p_parameters.exclude_bodies.has(col_obj->get_self())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -821,7 +821,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
for (int k = 0; k < 8; k++) { //steps should be customizable..
|
||||
real_t fraction = low + (hi - low) * fraction_coeff;
|
||||
|
||||
mshape.motion = body_shape_xform_inv.basis.xform(p_motion * fraction);
|
||||
mshape.motion = body_shape_xform_inv.basis.xform(p_parameters.motion * fraction);
|
||||
|
||||
Vector3 lA, lB;
|
||||
Vector3 sep = motion_normal; //important optimization for this to work fast enough
|
||||
|
@ -883,13 +883,13 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
|
||||
//it collided, let's get the rest info in unsafe advance
|
||||
Transform3D ugt = body_transform;
|
||||
ugt.origin += p_motion * unsafe;
|
||||
ugt.origin += p_parameters.motion * unsafe;
|
||||
|
||||
_RestResultData results[PhysicsServer3D::MotionResult::MAX_COLLISIONS];
|
||||
|
||||
_RestCallbackData rcd;
|
||||
if (p_max_collisions > 1) {
|
||||
rcd.max_results = p_max_collisions;
|
||||
if (p_parameters.max_collisions > 1) {
|
||||
rcd.max_results = p_parameters.max_collisions;
|
||||
rcd.other_results = results;
|
||||
}
|
||||
|
||||
|
@ -907,20 +907,20 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
Transform3D body_shape_xform = ugt * p_body->get_shape_transform(j);
|
||||
Shape3DSW *body_shape = p_body->get_shape(j);
|
||||
|
||||
body_aabb.position += p_motion * unsafe;
|
||||
body_aabb.position += p_parameters.motion * unsafe;
|
||||
|
||||
int amount = _cull_aabb_for_body(p_body, body_aabb);
|
||||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
const CollisionObject3DSW *col_obj = intersection_query_results[i];
|
||||
if (p_exclude.has(col_obj->get_self())) {
|
||||
if (p_parameters.exclude_bodies.has(col_obj->get_self())) {
|
||||
continue;
|
||||
}
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
rcd.object = col_obj;
|
||||
rcd.shape = shape_idx;
|
||||
bool sc = CollisionSolver3DSW::solve_static(body_shape, body_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 = CollisionSolver3DSW::solve_static(body_shape, body_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_parameters.margin);
|
||||
if (!sc) {
|
||||
continue;
|
||||
}
|
||||
|
@ -948,12 +948,12 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
collision.collider_velocity = body->get_linear_velocity() + (body->get_angular_velocity()).cross(rel_vec);
|
||||
}
|
||||
|
||||
r_result->travel = safe * p_motion;
|
||||
r_result->remainder = p_motion - safe * p_motion;
|
||||
r_result->travel += (body_transform.get_origin() - p_from.get_origin());
|
||||
r_result->travel = safe * p_parameters.motion;
|
||||
r_result->remainder = p_parameters.motion - safe * p_parameters.motion;
|
||||
r_result->travel += (body_transform.get_origin() - p_parameters.from.get_origin());
|
||||
|
||||
r_result->safe_fraction = safe;
|
||||
r_result->unsafe_fraction = unsafe;
|
||||
r_result->collision_safe_fraction = safe;
|
||||
r_result->collision_unsafe_fraction = unsafe;
|
||||
|
||||
r_result->collision_count = rcd.result_count;
|
||||
}
|
||||
|
@ -963,12 +963,12 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
|
|||
}
|
||||
|
||||
if (!collided && r_result) {
|
||||
r_result->travel = p_motion;
|
||||
r_result->travel = p_parameters.motion;
|
||||
r_result->remainder = Vector3();
|
||||
r_result->travel += (body_transform.get_origin() - p_from.get_origin());
|
||||
r_result->travel += (body_transform.get_origin() - p_parameters.from.get_origin());
|
||||
|
||||
r_result->safe_fraction = 1.0;
|
||||
r_result->unsafe_fraction = 1.0;
|
||||
r_result->collision_safe_fraction = 1.0;
|
||||
r_result->collision_unsafe_fraction = 1.0;
|
||||
}
|
||||
|
||||
return collided;
|
||||
|
|
|
@ -207,7 +207,7 @@ public:
|
|||
void set_elapsed_time(ElapsedTime p_time, uint64_t p_msec) { elapsed_time[p_time] = p_msec; }
|
||||
uint64_t get_elapsed_time(ElapsedTime p_time) const { return elapsed_time[p_time]; }
|
||||
|
||||
bool test_body_motion(Body3DSW *p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin, PhysicsServer3D::MotionResult *r_result, int p_max_collisions = 1, bool p_collide_separation_ray = false, const Set<RID> &p_exclude = Set<RID>());
|
||||
bool test_body_motion(Body3DSW *p_body, const PhysicsServer3D::MotionParameters &p_parameters, PhysicsServer3D::MotionResult *r_result);
|
||||
|
||||
Space3DSW();
|
||||
~Space3DSW();
|
||||
|
|
|
@ -412,6 +412,49 @@ void PhysicsDirectSpaceState2D::_bind_methods() {
|
|||
|
||||
///////////////////////////////
|
||||
|
||||
Vector<RID> PhysicsTestMotionParameters2D::get_exclude_bodies() const {
|
||||
Vector<RID> exclude;
|
||||
exclude.resize(parameters.exclude_bodies.size());
|
||||
|
||||
int body_index = 0;
|
||||
for (RID body : parameters.exclude_bodies) {
|
||||
exclude.write[body_index++] = body;
|
||||
}
|
||||
|
||||
return exclude;
|
||||
}
|
||||
|
||||
void PhysicsTestMotionParameters2D::set_exclude_bodies(const Vector<RID> &p_exclude) {
|
||||
for (RID body : p_exclude) {
|
||||
parameters.exclude_bodies.insert(body);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsTestMotionParameters2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_from"), &PhysicsTestMotionParameters2D::get_from);
|
||||
ClassDB::bind_method(D_METHOD("set_from"), &PhysicsTestMotionParameters2D::set_from);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_motion"), &PhysicsTestMotionParameters2D::get_motion);
|
||||
ClassDB::bind_method(D_METHOD("set_motion"), &PhysicsTestMotionParameters2D::set_motion);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_margin"), &PhysicsTestMotionParameters2D::get_margin);
|
||||
ClassDB::bind_method(D_METHOD("set_margin"), &PhysicsTestMotionParameters2D::set_margin);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_collide_separation_ray_enabled"), &PhysicsTestMotionParameters2D::is_collide_separation_ray_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_collide_separation_ray_enabled"), &PhysicsTestMotionParameters2D::set_collide_separation_ray_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_exclude_bodies"), &PhysicsTestMotionParameters2D::get_exclude_bodies);
|
||||
ClassDB::bind_method(D_METHOD("set_exclude_bodies"), &PhysicsTestMotionParameters2D::set_exclude_bodies);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "from"), "set_from", "get_from");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion"), "set_motion", "get_motion");
|
||||
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::ARRAY, "exclude_bodies"), "set_exclude_bodies", "get_exclude_bodies");
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
Vector2 PhysicsTestMotionResult2D::get_travel() const {
|
||||
return result.travel;
|
||||
}
|
||||
|
@ -448,6 +491,10 @@ int PhysicsTestMotionResult2D::get_collider_shape() const {
|
|||
return result.collider_shape;
|
||||
}
|
||||
|
||||
int PhysicsTestMotionResult2D::get_collision_local_shape() const {
|
||||
return result.collision_local_shape;
|
||||
}
|
||||
|
||||
real_t PhysicsTestMotionResult2D::get_collision_depth() const {
|
||||
return result.collision_depth;
|
||||
}
|
||||
|
@ -470,36 +517,23 @@ void PhysicsTestMotionResult2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_collider_rid"), &PhysicsTestMotionResult2D::get_collider_rid);
|
||||
ClassDB::bind_method(D_METHOD("get_collider"), &PhysicsTestMotionResult2D::get_collider);
|
||||
ClassDB::bind_method(D_METHOD("get_collider_shape"), &PhysicsTestMotionResult2D::get_collider_shape);
|
||||
ClassDB::bind_method(D_METHOD("get_collision_local_shape"), &PhysicsTestMotionResult2D::get_collision_local_shape);
|
||||
ClassDB::bind_method(D_METHOD("get_collision_depth"), &PhysicsTestMotionResult2D::get_collision_depth);
|
||||
ClassDB::bind_method(D_METHOD("get_collision_safe_fraction"), &PhysicsTestMotionResult2D::get_collision_safe_fraction);
|
||||
ClassDB::bind_method(D_METHOD("get_collision_unsafe_fraction"), &PhysicsTestMotionResult2D::get_collision_unsafe_fraction);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "travel"), "", "get_travel");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "remainder"), "", "get_remainder");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "collision_point"), "", "get_collision_point");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "collision_normal"), "", "get_collision_normal");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "collider_velocity"), "", "get_collider_velocity");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id", PROPERTY_HINT_OBJECT_ID), "", "get_collider_id");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::RID, "collider_rid"), "", "get_collider_rid");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_collider");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape"), "", "get_collider_shape");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_depth"), "", "get_collision_depth");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_safe_fraction"), "", "get_collision_safe_fraction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_unsafe_fraction"), "", "get_collision_unsafe_fraction");
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin, const Ref<PhysicsTestMotionResult2D> &p_result, bool p_collide_separation_ray, const Vector<RID> &p_exclude) {
|
||||
MotionResult *r = nullptr;
|
||||
bool PhysicsServer2D::_body_test_motion(RID p_body, const Ref<PhysicsTestMotionParameters2D> &p_parameters, const Ref<PhysicsTestMotionResult2D> &p_result) {
|
||||
ERR_FAIL_COND_V(!p_parameters.is_valid(), false);
|
||||
|
||||
MotionResult *result_ptr = nullptr;
|
||||
if (p_result.is_valid()) {
|
||||
r = p_result->get_result_ptr();
|
||||
result_ptr = p_result->get_result_ptr();
|
||||
}
|
||||
Set<RID> exclude;
|
||||
for (int i = 0; i < p_exclude.size(); i++) {
|
||||
exclude.insert(p_exclude[i]);
|
||||
}
|
||||
return body_test_motion(p_body, p_from, p_motion, p_margin, r, p_collide_separation_ray, exclude);
|
||||
|
||||
return body_test_motion(p_body, p_parameters->get_parameters(), result_ptr);
|
||||
}
|
||||
|
||||
void PhysicsServer2D::_bind_methods() {
|
||||
|
@ -626,7 +660,7 @@ void PhysicsServer2D::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("body_set_force_integration_callback", "body", "callable", "userdata"), &PhysicsServer2D::body_set_force_integration_callback, DEFVAL(Variant()));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("body_test_motion", "body", "from", "motion", "margin", "result", "collide_separation_ray", "exclude"), &PhysicsServer2D::_body_test_motion, DEFVAL(0.08), DEFVAL(Variant()), DEFVAL(false), DEFVAL(Array()));
|
||||
ClassDB::bind_method(D_METHOD("body_test_motion", "body", "parameters", "result"), &PhysicsServer2D::_body_test_motion, DEFVAL(Variant()));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("body_get_direct_state", "body"), &PhysicsServer2D::body_get_direct_state);
|
||||
|
||||
|
|
|
@ -198,6 +198,7 @@ public:
|
|||
PhysicsDirectSpaceState2D();
|
||||
};
|
||||
|
||||
class PhysicsTestMotionParameters2D;
|
||||
class PhysicsTestMotionResult2D;
|
||||
|
||||
class PhysicsServer2D : public Object {
|
||||
|
@ -205,7 +206,7 @@ class PhysicsServer2D : public Object {
|
|||
|
||||
static PhysicsServer2D *singleton;
|
||||
|
||||
virtual bool _body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>(), bool p_collide_separation_ray = false, const Vector<RID> &p_exclude = Vector<RID>());
|
||||
virtual bool _body_test_motion(RID p_body, const Ref<PhysicsTestMotionParameters2D> &p_parameters, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>());
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
@ -465,6 +466,21 @@ public:
|
|||
// this function only works on physics process, errors and returns null otherwise
|
||||
virtual PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) = 0;
|
||||
|
||||
struct MotionParameters {
|
||||
Transform2D from;
|
||||
Vector2 motion;
|
||||
real_t margin = 0.08;
|
||||
bool collide_separation_ray = false;
|
||||
Set<RID> exclude_bodies;
|
||||
|
||||
MotionParameters() {}
|
||||
|
||||
MotionParameters(const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin = 0.08) :
|
||||
from(p_from),
|
||||
motion(p_motion),
|
||||
margin(p_margin) {}
|
||||
};
|
||||
|
||||
struct MotionResult {
|
||||
Vector2 travel;
|
||||
Vector2 remainder;
|
||||
|
@ -485,18 +501,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_collide_separation_ray = false, const Set<RID> &p_exclude = Set<RID>()) = 0;
|
||||
|
||||
struct SeparationResult {
|
||||
real_t collision_depth;
|
||||
Vector2 collision_point;
|
||||
Vector2 collision_normal;
|
||||
Vector2 collider_velocity;
|
||||
int collision_local_shape;
|
||||
ObjectID collider_id;
|
||||
RID collider;
|
||||
int collider_shape;
|
||||
};
|
||||
virtual bool body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result = nullptr) = 0;
|
||||
|
||||
/* JOINT API */
|
||||
|
||||
|
@ -579,11 +584,37 @@ public:
|
|||
~PhysicsServer2D();
|
||||
};
|
||||
|
||||
class PhysicsTestMotionParameters2D : public RefCounted {
|
||||
GDCLASS(PhysicsTestMotionParameters2D, RefCounted);
|
||||
|
||||
PhysicsServer2D::MotionParameters parameters;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
const PhysicsServer2D::MotionParameters &get_parameters() const { return parameters; }
|
||||
|
||||
const Transform2D &get_from() const { return parameters.from; }
|
||||
void set_from(const Transform2D &p_from) { parameters.from = p_from; }
|
||||
|
||||
const Vector2 &get_motion() const { return parameters.motion; }
|
||||
void set_motion(const Vector2 &p_motion) { parameters.motion = p_motion; }
|
||||
|
||||
real_t get_margin() const { return parameters.margin; }
|
||||
void set_margin(real_t p_margin) { parameters.margin = p_margin; }
|
||||
|
||||
bool is_collide_separation_ray_enabled() const { return parameters.collide_separation_ray; }
|
||||
void set_collide_separation_ray_enabled(bool p_enabled) { parameters.collide_separation_ray = p_enabled; }
|
||||
|
||||
Vector<RID> get_exclude_bodies() const;
|
||||
void set_exclude_bodies(const Vector<RID> &p_exclude);
|
||||
};
|
||||
|
||||
class PhysicsTestMotionResult2D : public RefCounted {
|
||||
GDCLASS(PhysicsTestMotionResult2D, RefCounted);
|
||||
|
||||
PhysicsServer2D::MotionResult result;
|
||||
friend class PhysicsServer2D;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
@ -601,6 +632,7 @@ public:
|
|||
RID get_collider_rid() const;
|
||||
Object *get_collider() const;
|
||||
int get_collider_shape() const;
|
||||
int get_collision_local_shape() const;
|
||||
real_t get_collision_depth() const;
|
||||
real_t get_collision_safe_fraction() const;
|
||||
real_t get_collision_unsafe_fraction() const;
|
||||
|
|
|
@ -362,6 +362,53 @@ void PhysicsDirectSpaceState3D::_bind_methods() {
|
|||
|
||||
///////////////////////////////
|
||||
|
||||
Vector<RID> PhysicsTestMotionParameters3D::get_exclude_bodies() const {
|
||||
Vector<RID> exclude;
|
||||
exclude.resize(parameters.exclude_bodies.size());
|
||||
|
||||
int body_index = 0;
|
||||
for (RID body : parameters.exclude_bodies) {
|
||||
exclude.write[body_index++] = body;
|
||||
}
|
||||
|
||||
return exclude;
|
||||
}
|
||||
|
||||
void PhysicsTestMotionParameters3D::set_exclude_bodies(const Vector<RID> &p_exclude) {
|
||||
for (RID body : p_exclude) {
|
||||
parameters.exclude_bodies.insert(body);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsTestMotionParameters3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_from"), &PhysicsTestMotionParameters3D::get_from);
|
||||
ClassDB::bind_method(D_METHOD("set_from"), &PhysicsTestMotionParameters3D::set_from);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_motion"), &PhysicsTestMotionParameters3D::get_motion);
|
||||
ClassDB::bind_method(D_METHOD("set_motion"), &PhysicsTestMotionParameters3D::set_motion);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_margin"), &PhysicsTestMotionParameters3D::get_margin);
|
||||
ClassDB::bind_method(D_METHOD("set_margin"), &PhysicsTestMotionParameters3D::set_margin);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_max_collisions"), &PhysicsTestMotionParameters3D::get_max_collisions);
|
||||
ClassDB::bind_method(D_METHOD("set_max_collisions"), &PhysicsTestMotionParameters3D::set_max_collisions);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_collide_separation_ray_enabled"), &PhysicsTestMotionParameters3D::is_collide_separation_ray_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_collide_separation_ray_enabled"), &PhysicsTestMotionParameters3D::set_collide_separation_ray_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_exclude_bodies"), &PhysicsTestMotionParameters3D::get_exclude_bodies);
|
||||
ClassDB::bind_method(D_METHOD("set_exclude_bodies"), &PhysicsTestMotionParameters3D::set_exclude_bodies);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "from"), "set_from", "get_from");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "motion"), "set_motion", "get_motion");
|
||||
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::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");
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
Vector3 PhysicsTestMotionResult3D::get_travel() const {
|
||||
return result.travel;
|
||||
}
|
||||
|
@ -370,12 +417,12 @@ Vector3 PhysicsTestMotionResult3D::get_remainder() const {
|
|||
return result.remainder;
|
||||
}
|
||||
|
||||
real_t PhysicsTestMotionResult3D::get_safe_fraction() const {
|
||||
return result.safe_fraction;
|
||||
real_t PhysicsTestMotionResult3D::get_collision_safe_fraction() const {
|
||||
return result.collision_safe_fraction;
|
||||
}
|
||||
|
||||
real_t PhysicsTestMotionResult3D::get_unsafe_fraction() const {
|
||||
return result.unsafe_fraction;
|
||||
real_t PhysicsTestMotionResult3D::get_collision_unsafe_fraction() const {
|
||||
return result.collision_unsafe_fraction;
|
||||
}
|
||||
|
||||
int PhysicsTestMotionResult3D::get_collision_count() const {
|
||||
|
@ -417,48 +464,21 @@ int PhysicsTestMotionResult3D::get_collider_shape(int p_collision_index) const {
|
|||
return result.collisions[p_collision_index].collider_shape;
|
||||
}
|
||||
|
||||
int PhysicsTestMotionResult3D::get_collision_local_shape(int p_collision_index) const {
|
||||
ERR_FAIL_INDEX_V(p_collision_index, result.collision_count, 0);
|
||||
return result.collisions[p_collision_index].local_shape;
|
||||
}
|
||||
|
||||
real_t PhysicsTestMotionResult3D::get_collision_depth(int p_collision_index) const {
|
||||
ERR_FAIL_INDEX_V(p_collision_index, result.collision_count, 0.0);
|
||||
return result.collisions[p_collision_index].depth;
|
||||
}
|
||||
|
||||
Vector3 PhysicsTestMotionResult3D::get_best_collision_point() const {
|
||||
return result.collision_count ? get_collision_point() : Vector3();
|
||||
}
|
||||
|
||||
Vector3 PhysicsTestMotionResult3D::get_best_collision_normal() const {
|
||||
return result.collision_count ? get_collision_normal() : Vector3();
|
||||
}
|
||||
|
||||
Vector3 PhysicsTestMotionResult3D::get_best_collider_velocity() const {
|
||||
return result.collision_count ? get_collider_velocity() : Vector3();
|
||||
}
|
||||
|
||||
ObjectID PhysicsTestMotionResult3D::get_best_collider_id() const {
|
||||
return result.collision_count ? get_collider_id() : ObjectID();
|
||||
}
|
||||
|
||||
RID PhysicsTestMotionResult3D::get_best_collider_rid() const {
|
||||
return result.collision_count ? get_collider_rid() : RID();
|
||||
}
|
||||
|
||||
Object *PhysicsTestMotionResult3D::get_best_collider() const {
|
||||
return result.collision_count ? get_collider() : nullptr;
|
||||
}
|
||||
|
||||
int PhysicsTestMotionResult3D::get_best_collider_shape() const {
|
||||
return result.collision_count ? get_collider_shape() : 0;
|
||||
}
|
||||
|
||||
real_t PhysicsTestMotionResult3D::get_best_collision_depth() const {
|
||||
return result.collision_count ? get_collision_depth() : 0.0;
|
||||
}
|
||||
|
||||
void PhysicsTestMotionResult3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_travel"), &PhysicsTestMotionResult3D::get_travel);
|
||||
ClassDB::bind_method(D_METHOD("get_remainder"), &PhysicsTestMotionResult3D::get_remainder);
|
||||
ClassDB::bind_method(D_METHOD("get_safe_fraction"), &PhysicsTestMotionResult3D::get_safe_fraction);
|
||||
ClassDB::bind_method(D_METHOD("get_unsafe_fraction"), &PhysicsTestMotionResult3D::get_unsafe_fraction);
|
||||
ClassDB::bind_method(D_METHOD("get_collision_safe_fraction"), &PhysicsTestMotionResult3D::get_collision_safe_fraction);
|
||||
ClassDB::bind_method(D_METHOD("get_collision_unsafe_fraction"), &PhysicsTestMotionResult3D::get_collision_unsafe_fraction);
|
||||
ClassDB::bind_method(D_METHOD("get_collision_count"), &PhysicsTestMotionResult3D::get_collision_count);
|
||||
ClassDB::bind_method(D_METHOD("get_collision_point", "collision_index"), &PhysicsTestMotionResult3D::get_collision_point, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("get_collision_normal", "collision_index"), &PhysicsTestMotionResult3D::get_collision_normal, DEFVAL(0));
|
||||
|
@ -467,44 +487,21 @@ void PhysicsTestMotionResult3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_collider_rid", "collision_index"), &PhysicsTestMotionResult3D::get_collider_rid, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("get_collider", "collision_index"), &PhysicsTestMotionResult3D::get_collider, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("get_collider_shape", "collision_index"), &PhysicsTestMotionResult3D::get_collider_shape, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("get_collision_local_shape", "collision_index"), &PhysicsTestMotionResult3D::get_collision_local_shape, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("get_collision_depth", "collision_index"), &PhysicsTestMotionResult3D::get_collision_depth, DEFVAL(0));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_best_collision_point"), &PhysicsTestMotionResult3D::get_best_collision_point);
|
||||
ClassDB::bind_method(D_METHOD("get_best_collision_normal"), &PhysicsTestMotionResult3D::get_best_collision_normal);
|
||||
ClassDB::bind_method(D_METHOD("get_best_collider_velocity"), &PhysicsTestMotionResult3D::get_best_collider_velocity);
|
||||
ClassDB::bind_method(D_METHOD("get_best_collider_id"), &PhysicsTestMotionResult3D::get_best_collider_id);
|
||||
ClassDB::bind_method(D_METHOD("get_best_collider_rid"), &PhysicsTestMotionResult3D::get_best_collider_rid);
|
||||
ClassDB::bind_method(D_METHOD("get_best_collider"), &PhysicsTestMotionResult3D::get_best_collider);
|
||||
ClassDB::bind_method(D_METHOD("get_best_collider_shape"), &PhysicsTestMotionResult3D::get_best_collider_shape);
|
||||
ClassDB::bind_method(D_METHOD("get_best_collision_depth"), &PhysicsTestMotionResult3D::get_best_collision_depth);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "travel"), "", "get_travel");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "remainder"), "", "get_remainder");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "safe_fraction"), "", "get_safe_fraction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unsafe_fraction"), "", "get_unsafe_fraction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_count"), "", "get_collision_count");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collision_point"), "", "get_best_collision_point");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collision_normal"), "", "get_best_collision_normal");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collider_velocity"), "", "get_best_collider_velocity");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id", PROPERTY_HINT_OBJECT_ID), "", "get_best_collider_id");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::RID, "collider_rid"), "", "get_best_collider_rid");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_best_collider");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape"), "", "get_best_collider_shape");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_depth"), "", "get_best_collision_depth");
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
bool PhysicsServer3D::_body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin, const Ref<PhysicsTestMotionResult3D> &p_result, bool p_collide_separation_ray, const Vector<RID> &p_exclude, int p_max_collisions) {
|
||||
MotionResult *r = nullptr;
|
||||
bool PhysicsServer3D::_body_test_motion(RID p_body, const Ref<PhysicsTestMotionParameters3D> &p_parameters, const Ref<PhysicsTestMotionResult3D> &p_result) {
|
||||
ERR_FAIL_COND_V(!p_parameters.is_valid(), false);
|
||||
|
||||
MotionResult *result_ptr = nullptr;
|
||||
if (p_result.is_valid()) {
|
||||
r = p_result->get_result_ptr();
|
||||
result_ptr = p_result->get_result_ptr();
|
||||
}
|
||||
Set<RID> exclude;
|
||||
for (int i = 0; i < p_exclude.size(); i++) {
|
||||
exclude.insert(p_exclude[i]);
|
||||
}
|
||||
return body_test_motion(p_body, p_from, p_motion, p_margin, r, p_max_collisions, p_collide_separation_ray, exclude);
|
||||
|
||||
return body_test_motion(p_body, p_parameters->get_parameters(), result_ptr);
|
||||
}
|
||||
|
||||
RID PhysicsServer3D::shape_create(ShapeType p_shape) {
|
||||
|
@ -662,7 +659,7 @@ void PhysicsServer3D::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("body_set_ray_pickable", "body", "enable"), &PhysicsServer3D::body_set_ray_pickable);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("body_test_motion", "body", "from", "motion", "margin", "result", "collide_separation_ray", "exclude", "max_collisions"), &PhysicsServer3D::_body_test_motion, DEFVAL(0.001), DEFVAL(Variant()), DEFVAL(false), DEFVAL(Array()), DEFVAL(1));
|
||||
ClassDB::bind_method(D_METHOD("body_test_motion", "body", "parameters", "result"), &PhysicsServer3D::_body_test_motion, DEFVAL(Variant()));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("body_get_direct_state", "body"), &PhysicsServer3D::body_get_direct_state);
|
||||
|
||||
|
|
|
@ -203,6 +203,7 @@ public:
|
|||
virtual ~RenderingServerHandler() {}
|
||||
};
|
||||
|
||||
class PhysicsTestMotionParameters3D;
|
||||
class PhysicsTestMotionResult3D;
|
||||
|
||||
class PhysicsServer3D : public Object {
|
||||
|
@ -210,7 +211,7 @@ class PhysicsServer3D : public Object {
|
|||
|
||||
static PhysicsServer3D *singleton;
|
||||
|
||||
virtual bool _body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin = 0.001, const Ref<PhysicsTestMotionResult3D> &p_result = Ref<PhysicsTestMotionResult3D>(), bool p_collide_separation_ray = false, const Vector<RID> &p_exclude = Vector<RID>(), int p_max_collisions = 1);
|
||||
virtual bool _body_test_motion(RID p_body, const Ref<PhysicsTestMotionParameters3D> &p_parameters, const Ref<PhysicsTestMotionResult3D> &p_result = Ref<PhysicsTestMotionResult3D>());
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
@ -483,6 +484,22 @@ public:
|
|||
// this function only works on physics process, errors and returns null otherwise
|
||||
virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) = 0;
|
||||
|
||||
struct MotionParameters {
|
||||
Transform3D from;
|
||||
Vector3 motion;
|
||||
real_t margin = 0.001;
|
||||
int max_collisions = 1;
|
||||
bool collide_separation_ray = false;
|
||||
Set<RID> exclude_bodies;
|
||||
|
||||
MotionParameters() {}
|
||||
|
||||
MotionParameters(const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin = 0.001) :
|
||||
from(p_from),
|
||||
motion(p_motion),
|
||||
margin(p_margin) {}
|
||||
};
|
||||
|
||||
struct MotionCollision {
|
||||
Vector3 position;
|
||||
Vector3 normal;
|
||||
|
@ -501,15 +518,15 @@ public:
|
|||
struct MotionResult {
|
||||
Vector3 travel;
|
||||
Vector3 remainder;
|
||||
real_t safe_fraction = 0.0;
|
||||
real_t unsafe_fraction = 0.0;
|
||||
real_t collision_safe_fraction = 0.0;
|
||||
real_t collision_unsafe_fraction = 0.0;
|
||||
|
||||
static const int MAX_COLLISIONS = 32;
|
||||
MotionCollision collisions[MAX_COLLISIONS];
|
||||
int collision_count = 0;
|
||||
};
|
||||
|
||||
virtual bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin = 0.001, MotionResult *r_result = nullptr, int p_max_collisions = 1, bool p_collide_separation_ray = false, const Set<RID> &p_exclude = Set<RID>()) = 0;
|
||||
virtual bool body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result = nullptr) = 0;
|
||||
|
||||
/* SOFT BODY */
|
||||
|
||||
|
@ -760,11 +777,40 @@ public:
|
|||
~PhysicsServer3D();
|
||||
};
|
||||
|
||||
class PhysicsTestMotionParameters3D : public RefCounted {
|
||||
GDCLASS(PhysicsTestMotionParameters3D, RefCounted);
|
||||
|
||||
PhysicsServer3D::MotionParameters parameters;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
const PhysicsServer3D::MotionParameters &get_parameters() const { return parameters; }
|
||||
|
||||
const Transform3D &get_from() const { return parameters.from; }
|
||||
void set_from(const Transform3D &p_from) { parameters.from = p_from; }
|
||||
|
||||
const Vector3 &get_motion() const { return parameters.motion; }
|
||||
void set_motion(const Vector3 &p_motion) { parameters.motion = p_motion; }
|
||||
|
||||
real_t get_margin() const { return parameters.margin; }
|
||||
void set_margin(real_t p_margin) { parameters.margin = p_margin; }
|
||||
|
||||
int get_max_collisions() const { return parameters.max_collisions; }
|
||||
void set_max_collisions(int p_max_collisions) { parameters.max_collisions = p_max_collisions; }
|
||||
|
||||
bool is_collide_separation_ray_enabled() const { return parameters.collide_separation_ray; }
|
||||
void set_collide_separation_ray_enabled(bool p_enabled) { parameters.collide_separation_ray = p_enabled; }
|
||||
|
||||
Vector<RID> get_exclude_bodies() const;
|
||||
void set_exclude_bodies(const Vector<RID> &p_exclude);
|
||||
};
|
||||
|
||||
class PhysicsTestMotionResult3D : public RefCounted {
|
||||
GDCLASS(PhysicsTestMotionResult3D, RefCounted);
|
||||
|
||||
PhysicsServer3D::MotionResult result;
|
||||
friend class PhysicsServer3D;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
@ -774,8 +820,8 @@ public:
|
|||
|
||||
Vector3 get_travel() const;
|
||||
Vector3 get_remainder() const;
|
||||
real_t get_safe_fraction() const;
|
||||
real_t get_unsafe_fraction() const;
|
||||
real_t get_collision_safe_fraction() const;
|
||||
real_t get_collision_unsafe_fraction() const;
|
||||
|
||||
int get_collision_count() const;
|
||||
|
||||
|
@ -786,16 +832,8 @@ public:
|
|||
RID get_collider_rid(int p_collision_index = 0) const;
|
||||
Object *get_collider(int p_collision_index = 0) const;
|
||||
int get_collider_shape(int p_collision_index = 0) const;
|
||||
int get_collision_local_shape(int p_collision_index = 0) const;
|
||||
real_t get_collision_depth(int p_collision_index = 0) const;
|
||||
|
||||
Vector3 get_best_collision_point() const;
|
||||
Vector3 get_best_collision_normal() const;
|
||||
Vector3 get_best_collider_velocity() const;
|
||||
ObjectID get_best_collider_id() const;
|
||||
RID get_best_collider_rid() const;
|
||||
Object *get_best_collider() const;
|
||||
int get_best_collider_shape() const;
|
||||
real_t get_best_collision_depth() const;
|
||||
};
|
||||
|
||||
typedef PhysicsServer3D *(*CreatePhysicsServer3DCallback)();
|
||||
|
|
|
@ -208,12 +208,14 @@ void register_server_types() {
|
|||
|
||||
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState2D);
|
||||
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState2D);
|
||||
GDREGISTER_CLASS(PhysicsTestMotionParameters2D);
|
||||
GDREGISTER_CLASS(PhysicsTestMotionResult2D);
|
||||
GDREGISTER_CLASS(PhysicsShapeQueryParameters2D);
|
||||
|
||||
GDREGISTER_CLASS(PhysicsShapeQueryParameters3D);
|
||||
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState3D);
|
||||
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState3D);
|
||||
GDREGISTER_CLASS(PhysicsTestMotionParameters3D);
|
||||
GDREGISTER_CLASS(PhysicsTestMotionResult3D);
|
||||
|
||||
// Physics 2D
|
||||
|
|
Loading…
Reference in New Issue