mirror of
https://github.com/godotengine/godot.git
synced 2024-11-11 06:33:10 +00:00
Merge pull request #53280 from nekomatata/test-body-motion-parameters
This commit is contained in:
commit
5b270278c8
@ -14,43 +14,74 @@
|
|||||||
<return type="float" />
|
<return type="float" />
|
||||||
<argument index="0" name="up_direction" type="Vector2" default="Vector2(0, -1)" />
|
<argument index="0" name="up_direction" type="Vector2" default="Vector2(0, -1)" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</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>
|
</class>
|
||||||
|
@ -15,108 +15,89 @@
|
|||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<argument index="1" name="up_direction" type="Vector3" default="Vector3(0, 1, 0)" />
|
<argument index="1" name="up_direction" type="Vector3" default="Vector3(0, 1, 0)" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_collider" qualifiers="const">
|
<method name="get_collider" qualifiers="const">
|
||||||
<return type="Object" />
|
<return type="Object" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_collider_id" qualifiers="const">
|
<method name="get_collider_id" qualifiers="const">
|
||||||
<return type="int" />
|
<return type="int" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_collider_rid" qualifiers="const">
|
<method name="get_collider_rid" qualifiers="const">
|
||||||
<return type="RID" />
|
<return type="RID" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_collider_shape" qualifiers="const">
|
<method name="get_collider_shape" qualifiers="const">
|
||||||
<return type="Object" />
|
<return type="Object" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_collider_shape_index" qualifiers="const">
|
<method name="get_collider_shape_index" qualifiers="const">
|
||||||
<return type="int" />
|
<return type="int" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_collider_velocity" qualifiers="const">
|
<method name="get_collider_velocity" qualifiers="const">
|
||||||
<return type="Vector3" />
|
<return type="Vector3" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_local_shape" qualifiers="const">
|
<method name="get_local_shape" qualifiers="const">
|
||||||
<return type="Object" />
|
<return type="Object" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_normal" qualifiers="const">
|
<method name="get_normal" qualifiers="const">
|
||||||
<return type="Vector3" />
|
<return type="Vector3" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_position" qualifiers="const">
|
<method name="get_position" qualifiers="const">
|
||||||
<return type="Vector3" />
|
<return type="Vector3" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</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>
|
</class>
|
||||||
|
@ -584,14 +584,10 @@
|
|||||||
<method name="body_test_motion">
|
<method name="body_test_motion">
|
||||||
<return type="bool" />
|
<return type="bool" />
|
||||||
<argument index="0" name="body" type="RID" />
|
<argument index="0" name="body" type="RID" />
|
||||||
<argument index="1" name="from" type="Transform2D" />
|
<argument index="1" name="parameters" type="PhysicsTestMotionParameters2D" />
|
||||||
<argument index="2" name="motion" type="Vector2" />
|
<argument index="2" name="result" type="PhysicsTestMotionResult2D" default="null" />
|
||||||
<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="[]" />
|
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="capsule_shape_create">
|
<method name="capsule_shape_create">
|
||||||
|
@ -577,15 +577,10 @@
|
|||||||
<method name="body_test_motion">
|
<method name="body_test_motion">
|
||||||
<return type="bool" />
|
<return type="bool" />
|
||||||
<argument index="0" name="body" type="RID" />
|
<argument index="0" name="body" type="RID" />
|
||||||
<argument index="1" name="from" type="Transform3D" />
|
<argument index="1" name="parameters" type="PhysicsTestMotionParameters3D" />
|
||||||
<argument index="2" name="motion" type="Vector3" />
|
<argument index="2" name="result" type="PhysicsTestMotionResult3D" default="null" />
|
||||||
<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" />
|
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="box_shape_create">
|
<method name="box_shape_create">
|
||||||
|
29
doc/classes/PhysicsTestMotionParameters2D.xml
Normal file
29
doc/classes/PhysicsTestMotionParameters2D.xml
Normal file
@ -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>
|
32
doc/classes/PhysicsTestMotionParameters3D.xml
Normal file
32
doc/classes/PhysicsTestMotionParameters3D.xml
Normal file
@ -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" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<class name="PhysicsTestMotionResult2D" inherits="RefCounted" version="4.0">
|
<class name="PhysicsTestMotionResult2D" inherits="RefCounted" version="4.0">
|
||||||
<brief_description>
|
<brief_description>
|
||||||
|
Result from a 2D body motion test.
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
|
This class contains the motion and collision result from [method PhysicsServer2D.body_test_motion].
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<members>
|
<methods>
|
||||||
<member name="collider" type="Object" setter="" getter="get_collider">
|
<method name="get_collider" qualifiers="const">
|
||||||
</member>
|
<return type="Object" />
|
||||||
<member name="collider_id" type="int" setter="" getter="get_collider_id" default="0">
|
<description>
|
||||||
</member>
|
Returns the colliding body's attached [Object], if a collision occured.
|
||||||
<member name="collider_rid" type="RID" setter="" getter="get_collider_rid">
|
</description>
|
||||||
</member>
|
</method>
|
||||||
<member name="collider_shape" type="int" setter="" getter="get_collider_shape" default="0">
|
<method name="get_collider_id" qualifiers="const">
|
||||||
</member>
|
<return type="int" />
|
||||||
<member name="collider_velocity" type="Vector2" setter="" getter="get_collider_velocity" default="Vector2(0, 0)">
|
<description>
|
||||||
</member>
|
Returns the unique instance ID of the colliding body's attached [Object], if a collision occured. See [method Object.get_instance_id].
|
||||||
<member name="collision_depth" type="float" setter="" getter="get_collision_depth" default="0.0">
|
</description>
|
||||||
</member>
|
</method>
|
||||||
<member name="collision_normal" type="Vector2" setter="" getter="get_collision_normal" default="Vector2(0, 0)">
|
<method name="get_collider_rid" qualifiers="const">
|
||||||
</member>
|
<return type="RID" />
|
||||||
<member name="collision_point" type="Vector2" setter="" getter="get_collision_point" default="Vector2(0, 0)">
|
<description>
|
||||||
</member>
|
Returns the colliding body's [RID] used by the [PhysicsServer2D], if a collision occured.
|
||||||
<member name="collision_safe_fraction" type="float" setter="" getter="get_collision_safe_fraction" default="0.0">
|
</description>
|
||||||
</member>
|
</method>
|
||||||
<member name="collision_unsafe_fraction" type="float" setter="" getter="get_collision_unsafe_fraction" default="0.0">
|
<method name="get_collider_shape" qualifiers="const">
|
||||||
</member>
|
<return type="int" />
|
||||||
<member name="remainder" type="Vector2" setter="" getter="get_remainder" default="Vector2(0, 0)">
|
<description>
|
||||||
</member>
|
Returns the colliding body's shape index, if a collision occured. See [CollisionObject2D].
|
||||||
<member name="travel" type="Vector2" setter="" getter="get_travel" default="Vector2(0, 0)">
|
</description>
|
||||||
</member>
|
</method>
|
||||||
</members>
|
<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>
|
</class>
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<class name="PhysicsTestMotionResult3D" inherits="RefCounted" version="4.0">
|
<class name="PhysicsTestMotionResult3D" inherits="RefCounted" version="4.0">
|
||||||
<brief_description>
|
<brief_description>
|
||||||
|
Result from a 3D body motion test.
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
|
This class contains the motion and collision result from [method PhysicsServer3D.body_test_motion].
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
@ -11,77 +13,94 @@
|
|||||||
<return type="Object" />
|
<return type="Object" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<description>
|
||||||
|
Returns the colliding body's attached [Object] given a collision index (the deepest collision by default), if a collision occured.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_collider_id" qualifiers="const">
|
<method name="get_collider_id" qualifiers="const">
|
||||||
<return type="int" />
|
<return type="int" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_collider_rid" qualifiers="const">
|
<method name="get_collider_rid" qualifiers="const">
|
||||||
<return type="RID" />
|
<return type="RID" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_collider_shape" qualifiers="const">
|
<method name="get_collider_shape" qualifiers="const">
|
||||||
<return type="int" />
|
<return type="int" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<description>
|
||||||
|
Returns the colliding body's shape index given a collision index (the deepest collision by default), if a collision occured. See [CollisionObject3D].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_collider_velocity" qualifiers="const">
|
<method name="get_collider_velocity" qualifiers="const">
|
||||||
<return type="Vector3" />
|
<return type="Vector3" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_collision_depth" qualifiers="const">
|
<method name="get_collision_depth" qualifiers="const">
|
||||||
<return type="float" />
|
<return type="float" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_collision_normal" qualifiers="const">
|
<method name="get_collision_normal" qualifiers="const">
|
||||||
<return type="Vector3" />
|
<return type="Vector3" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_collision_point" qualifiers="const">
|
<method name="get_collision_point" qualifiers="const">
|
||||||
<return type="Vector3" />
|
<return type="Vector3" />
|
||||||
<argument index="0" name="collision_index" type="int" default="0" />
|
<argument index="0" name="collision_index" type="int" default="0" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</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>
|
</class>
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
<return type="Vector2i" />
|
<return type="Vector2i" />
|
||||||
<argument index="0" name="body" type="RID" />
|
<argument index="0" name="body" type="RID" />
|
||||||
<description>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_layer_name" qualifiers="const">
|
<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) {
|
Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_linear_velocity, bool p_test_only, real_t p_margin) {
|
||||||
PhysicsServer2D::MotionResult result;
|
|
||||||
|
|
||||||
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
|
// 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();
|
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.
|
// 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) {
|
if (motion_cache.is_null() || motion_cache->reference_get_count() > 1) {
|
||||||
motion_cache.instantiate();
|
motion_cache.instantiate();
|
||||||
@ -74,18 +75,18 @@ Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_motion, bool p_t
|
|||||||
return Ref<KinematicCollision2D>();
|
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()) {
|
if (is_only_update_transform_changes_enabled()) {
|
||||||
ERR_PRINT("Move functions do not work together with 'sync to physics' option. Please read the documentation.");
|
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,
|
// Restore direction of motion to be along original motion,
|
||||||
// in order to avoid sliding due to recovery,
|
// in order to avoid sliding due to recovery,
|
||||||
// but only if collision depth is low enough to avoid tunneling.
|
// but only if collision depth is low enough to avoid tunneling.
|
||||||
if (p_cancel_sliding) {
|
if (p_cancel_sliding) {
|
||||||
real_t motion_length = p_motion.length();
|
real_t motion_length = p_parameters.motion.length();
|
||||||
real_t precision = 0.001;
|
real_t precision = 0.001;
|
||||||
|
|
||||||
if (colliding) {
|
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.
|
// 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);
|
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;
|
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.
|
// When motion is null, recovery is the resulting motion.
|
||||||
Vector2 motion_normal;
|
Vector2 motion_normal;
|
||||||
if (motion_length > CMP_EPSILON) {
|
if (motion_length > CMP_EPSILON) {
|
||||||
motion_normal = p_motion / motion_length;
|
motion_normal = p_parameters.motion / motion_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check depth of recovery.
|
// 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();
|
real_t recovery_length = recovery.length();
|
||||||
// Fixes cases where canceling slide causes the motion to go too deep into the ground,
|
// 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.
|
// 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.
|
// Apply adjustment to motion.
|
||||||
r_result.travel = motion_normal * projected_length;
|
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) {
|
if (!p_test_only) {
|
||||||
|
Transform2D gt = p_parameters.from;
|
||||||
gt.elements[2] += r_result.travel;
|
gt.elements[2] += r_result.travel;
|
||||||
set_global_transform(gt);
|
set_global_transform(gt);
|
||||||
}
|
}
|
||||||
@ -127,7 +129,7 @@ bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, PhysicsServer2D::M
|
|||||||
return colliding;
|
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);
|
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||||
|
|
||||||
PhysicsServer2D::MotionResult *r = nullptr;
|
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.
|
// 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();
|
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() {
|
TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() {
|
||||||
@ -1083,10 +1087,11 @@ bool CharacterBody2D::move_and_slide() {
|
|||||||
on_wall = false;
|
on_wall = false;
|
||||||
|
|
||||||
if (!current_platform_velocity.is_equal_approx(Vector2())) {
|
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;
|
PhysicsServer2D::MotionResult floor_result;
|
||||||
Set<RID> exclude;
|
if (move_and_collide(parameters, floor_result, false, false)) {
|
||||||
exclude.insert(platform_rid);
|
|
||||||
if (move_and_collide(current_platform_velocity * delta, floor_result, margin, false, false, false, exclude)) {
|
|
||||||
motion_results.push_back(floor_result);
|
motion_results.push_back(floor_result);
|
||||||
_set_collision_direction(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;
|
Vector2 last_travel;
|
||||||
|
|
||||||
for (int iteration = 0; iteration < max_slides; ++iteration) {
|
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;
|
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;
|
last_motion = result.travel;
|
||||||
|
|
||||||
if (collided) {
|
if (collided) {
|
||||||
@ -1283,9 +1290,11 @@ void CharacterBody2D::_move_and_slide_free(double p_delta) {
|
|||||||
|
|
||||||
bool first_slide = true;
|
bool first_slide = true;
|
||||||
for (int iteration = 0; iteration < max_slides; ++iteration) {
|
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;
|
last_motion = result.travel;
|
||||||
|
|
||||||
if (collided) {
|
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.
|
// Snap by at least collision margin to keep floor state consistent.
|
||||||
real_t length = MAX(floor_snap_length, margin);
|
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;
|
PhysicsServer2D::MotionResult result;
|
||||||
if (move_and_collide(-up_direction * length, result, margin, true, false, true)) {
|
if (move_and_collide(parameters, result, true, false)) {
|
||||||
bool apply = true;
|
|
||||||
if (result.get_angle(up_direction) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
|
if (result.get_angle(up_direction) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
|
||||||
on_floor = true;
|
on_floor = true;
|
||||||
floor_normal = result.collision_normal;
|
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();
|
result.travel = Vector2();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
apply = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (apply) {
|
parameters.from.elements[2] += result.travel;
|
||||||
gt.elements[2] += result.travel;
|
set_global_transform(parameters.from);
|
||||||
set_global_transform(gt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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.
|
// Snap by at least collision margin to keep floor state consistent.
|
||||||
real_t length = MAX(floor_snap_length, margin);
|
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;
|
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) {
|
if (result.get_angle(up_direction) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
|
||||||
return true;
|
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"), &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_shape_index"), &KinematicCollision2D::get_collider_shape_index);
|
||||||
ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicCollision2D::get_collider_velocity);
|
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> 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:
|
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 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_motion, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08);
|
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();
|
TypedArray<PhysicsBody2D> get_collision_exceptions();
|
||||||
void add_collision_exception_with(Node *p_node); //must be physicsbody
|
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());
|
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) {
|
Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_linear_velocity, bool p_test_only, real_t p_margin, int p_max_collisions) {
|
||||||
PhysicsServer3D::MotionResult result;
|
|
||||||
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
|
// 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();
|
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.
|
// 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) {
|
if (motion_cache.is_null() || motion_cache->reference_get_count() > 1) {
|
||||||
motion_cache.instantiate();
|
motion_cache.instantiate();
|
||||||
@ -111,23 +114,22 @@ Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_motion, bool p_t
|
|||||||
return Ref<KinematicCollision3D>();
|
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) {
|
bool PhysicsBody3D::move_and_collide(const PhysicsServer3D::MotionParameters &p_parameters, PhysicsServer3D::MotionResult &r_result, bool p_test_only, bool p_cancel_sliding) {
|
||||||
Transform3D gt = get_global_transform();
|
bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), p_parameters, &r_result);
|
||||||
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);
|
|
||||||
|
|
||||||
// Restore direction of motion to be along original motion,
|
// Restore direction of motion to be along original motion,
|
||||||
// in order to avoid sliding due to recovery,
|
// in order to avoid sliding due to recovery,
|
||||||
// but only if collision depth is low enough to avoid tunneling.
|
// but only if collision depth is low enough to avoid tunneling.
|
||||||
if (p_cancel_sliding) {
|
if (p_cancel_sliding) {
|
||||||
real_t motion_length = p_motion.length();
|
real_t motion_length = p_parameters.motion.length();
|
||||||
real_t precision = 0.001;
|
real_t precision = 0.001;
|
||||||
|
|
||||||
if (colliding) {
|
if (colliding) {
|
||||||
// Can't just use margin as a threshold because collision depth is calculated on unsafe motion,
|
// 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.
|
// 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;
|
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.
|
// When motion is null, recovery is the resulting motion.
|
||||||
Vector3 motion_normal;
|
Vector3 motion_normal;
|
||||||
if (motion_length > CMP_EPSILON) {
|
if (motion_length > CMP_EPSILON) {
|
||||||
motion_normal = p_motion / motion_length;
|
motion_normal = p_parameters.motion / motion_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check depth of recovery.
|
// 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();
|
real_t recovery_length = recovery.length();
|
||||||
// Fixes cases where canceling slide causes the motion to go too deep into the ground,
|
// 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.
|
// 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.
|
// Apply adjustment to motion.
|
||||||
r_result.travel = motion_normal * projected_length;
|
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) {
|
if (!p_test_only) {
|
||||||
|
Transform3D gt = p_parameters.from;
|
||||||
gt.origin += r_result.travel;
|
gt.origin += r_result.travel;
|
||||||
set_global_transform(gt);
|
set_global_transform(gt);
|
||||||
}
|
}
|
||||||
@ -167,7 +170,7 @@ bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, PhysicsServer3D::M
|
|||||||
return colliding;
|
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);
|
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||||
|
|
||||||
PhysicsServer3D::MotionResult *r = nullptr;
|
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
|
// 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();
|
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) {
|
void PhysicsBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) {
|
||||||
@ -1124,10 +1129,11 @@ bool CharacterBody3D::move_and_slide() {
|
|||||||
last_motion = Vector3();
|
last_motion = Vector3();
|
||||||
|
|
||||||
if (!current_platform_velocity.is_equal_approx(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;
|
PhysicsServer3D::MotionResult floor_result;
|
||||||
Set<RID> exclude;
|
if (move_and_collide(parameters, floor_result, false, false)) {
|
||||||
exclude.insert(platform_rid);
|
|
||||||
if (move_and_collide(current_platform_velocity * delta, floor_result, margin, false, 1, false, false, exclude)) {
|
|
||||||
motion_results.push_back(floor_result);
|
motion_results.push_back(floor_result);
|
||||||
|
|
||||||
CollisionState result_state;
|
CollisionState result_state;
|
||||||
@ -1181,8 +1187,12 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
|
|||||||
Vector3 total_travel;
|
Vector3 total_travel;
|
||||||
|
|
||||||
for (int iteration = 0; iteration < max_slides; ++iteration) {
|
for (int iteration = 0; iteration < max_slides; ++iteration) {
|
||||||
|
PhysicsServer3D::MotionParameters parameters(get_global_transform(), motion, margin);
|
||||||
|
parameters.max_collisions = 4;
|
||||||
|
|
||||||
PhysicsServer3D::MotionResult result;
|
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;
|
last_motion = result.travel;
|
||||||
|
|
||||||
if (collided) {
|
if (collided) {
|
||||||
@ -1411,9 +1421,11 @@ void CharacterBody3D::_move_and_slide_free(double p_delta) {
|
|||||||
|
|
||||||
bool first_slide = true;
|
bool first_slide = true;
|
||||||
for (int iteration = 0; iteration < max_slides; ++iteration) {
|
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;
|
last_motion = result.travel;
|
||||||
|
|
||||||
if (collided) {
|
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.
|
// Snap by at least collision margin to keep floor state consistent.
|
||||||
real_t length = MAX(floor_snap_length, margin);
|
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;
|
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;
|
CollisionState result_state;
|
||||||
// Apply direction for floor only.
|
// Apply direction for floor only.
|
||||||
_set_collision_direction(result, result_state, CollisionState(true, false, false));
|
_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;
|
parameters.from.origin += result.travel;
|
||||||
set_global_transform(gt);
|
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.
|
// Snap by at least collision margin to keep floor state consistent.
|
||||||
real_t length = MAX(floor_snap_length, margin);
|
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;
|
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;
|
CollisionState result_state;
|
||||||
// Don't apply direction for any type.
|
// Don't apply direction for any type.
|
||||||
_set_collision_direction(result, result_state, CollisionState());
|
_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;
|
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() {
|
void KinematicCollision3D::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision3D::get_travel);
|
ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision3D::get_travel);
|
||||||
ClassDB::bind_method(D_METHOD("get_remainder"), &KinematicCollision3D::get_remainder);
|
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", "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_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_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;
|
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:
|
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 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_motion, const Ref<KinematicCollision3D> &r_collision = Ref<KinematicCollision3D>(), real_t p_margin = 0.001, int p_max_collisions = 1);
|
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);
|
void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock);
|
||||||
bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const;
|
bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const;
|
||||||
@ -487,16 +487,6 @@ public:
|
|||||||
Object *get_collider_shape(int p_collision_index = 0) const;
|
Object *get_collider_shape(int p_collision_index = 0) const;
|
||||||
int get_collider_shape_index(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_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 {
|
class PhysicalBone3D : public PhysicsBody3D {
|
||||||
|
@ -948,7 +948,7 @@ void PhysicsServer2DSW::body_set_pickable(RID p_body, bool p_pickable) {
|
|||||||
body->set_pickable(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);
|
Body2DSW *body = body_owner.get_or_null(p_body);
|
||||||
ERR_FAIL_COND_V(!body, false);
|
ERR_FAIL_COND_V(!body, false);
|
||||||
ERR_FAIL_COND_V(!body->get_space(), 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();
|
_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) {
|
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 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
|
// this function only works on physics process, errors and returns null otherwise
|
||||||
virtual PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) override;
|
virtual PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) override;
|
||||||
|
@ -254,9 +254,9 @@ public:
|
|||||||
|
|
||||||
FUNC2(body_set_pickable, RID, bool);
|
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);
|
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
|
// 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;
|
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
|
//give me back regular physics engine logic
|
||||||
//this is madness
|
//this is madness
|
||||||
//and most people using this function will think
|
//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 (!shapes_found) {
|
||||||
if (r_result) {
|
if (r_result) {
|
||||||
*r_result = PhysicsServer2D::MotionResult();
|
*r_result = PhysicsServer2D::MotionResult();
|
||||||
r_result->travel = p_motion;
|
r_result->travel = p_parameters.motion;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Undo the currently transform the physics server is aware of and apply the provided one
|
// 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 = p_parameters.from.xform(p_body->get_inv_transform().xform(body_aabb));
|
||||||
body_aabb = body_aabb.grow(p_margin);
|
body_aabb = body_aabb.grow(p_parameters.margin);
|
||||||
|
|
||||||
static const int max_excluded_shape_pairs = 32;
|
static const int max_excluded_shape_pairs = 32;
|
||||||
ExcludedShapeSW excluded_shape_pairs[max_excluded_shape_pairs];
|
ExcludedShapeSW excluded_shape_pairs[max_excluded_shape_pairs];
|
||||||
int excluded_shape_pair_count = 0;
|
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();
|
real_t motion_length = p_parameters.motion.length();
|
||||||
Vector2 motion_normal = p_motion / motion_length;
|
Vector2 motion_normal = p_parameters.motion / motion_length;
|
||||||
|
|
||||||
Transform2D body_transform = p_from;
|
Transform2D body_transform = p_parameters.from;
|
||||||
|
|
||||||
bool recovered = false;
|
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++) {
|
for (int i = 0; i < amount; i++) {
|
||||||
const CollisionObject2DSW *col_obj = intersection_query_results[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;
|
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();
|
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);
|
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;
|
cbk.invalid_by_dir = 0;
|
||||||
|
|
||||||
if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
|
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;
|
bool did_collide = false;
|
||||||
|
|
||||||
Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
|
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
|
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
|
// STEP 2 ATTEMPT MOTION
|
||||||
|
|
||||||
Rect2 motion_aabb = body_aabb;
|
Rect2 motion_aabb = body_aabb;
|
||||||
motion_aabb.position += p_motion;
|
motion_aabb.position += p_parameters.motion;
|
||||||
motion_aabb = motion_aabb.merge(body_aabb);
|
motion_aabb = motion_aabb.merge(body_aabb);
|
||||||
|
|
||||||
int amount = _cull_aabb_for_body(p_body, motion_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,
|
// Colliding separation rays allows to properly snap to the ground,
|
||||||
// otherwise it's not needed in regular motion.
|
// 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.
|
// When slide on slope is on, separation ray shape acts like a regular shape.
|
||||||
if (!static_cast<SeparationRayShape2DSW *>(body_shape)->get_slide_on_slope()) {
|
if (!static_cast<SeparationRayShape2DSW *>(body_shape)->get_slide_on_slope()) {
|
||||||
continue;
|
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++) {
|
for (int i = 0; i < amount; i++) {
|
||||||
const CollisionObject2DSW *col_obj = intersection_query_results[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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int col_shape_idx = intersection_query_subindex_results[i];
|
int col_shape_idx = intersection_query_subindex_results[i];
|
||||||
Shape2DSW *against_shape = col_obj->get_shape(col_shape_idx);
|
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);
|
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?
|
//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;
|
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;
|
real_t fraction = low + (hi - low) * fraction_coeff;
|
||||||
|
|
||||||
Vector2 sep = motion_normal; //important optimization for this to work fast enough
|
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) {
|
if (collided) {
|
||||||
hi = fraction;
|
hi = fraction;
|
||||||
@ -827,7 +828,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||||||
cbk.valid_depth = 10e20;
|
cbk.valid_depth = 10e20;
|
||||||
|
|
||||||
Vector2 sep = motion_normal; //important optimization for this to work fast enough
|
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) {
|
if (!collided || cbk.amount == 0) {
|
||||||
continue;
|
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
|
//it collided, let's get the rest info in unsafe advance
|
||||||
Transform2D ugt = body_transform;
|
Transform2D ugt = body_transform;
|
||||||
ugt.elements[2] += p_motion * unsafe;
|
ugt.elements[2] += p_parameters.motion * unsafe;
|
||||||
|
|
||||||
_RestCallbackData2D rcd;
|
_RestCallbackData2D rcd;
|
||||||
rcd.best_len = 0;
|
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);
|
Transform2D body_shape_xform = ugt * p_body->get_shape_transform(j);
|
||||||
Shape2DSW *body_shape = p_body->get_shape(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);
|
int amount = _cull_aabb_for_body(p_body, body_aabb);
|
||||||
|
|
||||||
for (int i = 0; i < amount; i++) {
|
for (int i = 0; i < amount; i++) {
|
||||||
const CollisionObject2DSW *col_obj = intersection_query_results[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;
|
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();
|
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);
|
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) {
|
if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
|
||||||
const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
|
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.object = col_obj;
|
||||||
rcd.shape = shape_idx;
|
rcd.shape = shape_idx;
|
||||||
rcd.local_shape = j;
|
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) {
|
if (!sc) {
|
||||||
continue;
|
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());
|
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->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->travel = safe * p_parameters.motion;
|
||||||
r_result->remainder = p_motion - safe * p_motion;
|
r_result->remainder = p_parameters.motion - safe * p_parameters.motion;
|
||||||
r_result->travel += (body_transform.get_origin() - p_from.get_origin());
|
r_result->travel += (body_transform.get_origin() - p_parameters.from.get_origin());
|
||||||
}
|
}
|
||||||
|
|
||||||
collided = true;
|
collided = true;
|
||||||
@ -972,9 +973,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!collided && r_result) {
|
if (!collided && r_result) {
|
||||||
r_result->travel = p_motion;
|
r_result->travel = p_parameters.motion;
|
||||||
r_result->remainder = Vector2();
|
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;
|
return collided;
|
||||||
|
@ -187,7 +187,7 @@ public:
|
|||||||
|
|
||||||
int get_collision_pairs() const { return collision_pairs; }
|
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); }
|
void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); }
|
||||||
_FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.is_empty(); }
|
_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);
|
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);
|
Body3DSW *body = body_owner.get_or_null(p_body);
|
||||||
ERR_FAIL_COND_V(!body, false);
|
ERR_FAIL_COND_V(!body, false);
|
||||||
ERR_FAIL_COND_V(!body->get_space(), 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();
|
_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) {
|
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 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
|
// this function only works on physics process, errors and returns null otherwise
|
||||||
virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override;
|
virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override;
|
||||||
|
@ -253,9 +253,9 @@ public:
|
|||||||
|
|
||||||
FUNC2(body_set_ray_pickable, RID, bool);
|
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);
|
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
|
// 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;
|
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
|
//give me back regular physics engine logic
|
||||||
//this is madness
|
//this is madness
|
||||||
//and most people using this function will think
|
//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..
|
//this took about a week to get right..
|
||||||
//but is it right? who knows at this point..
|
//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) {
|
if (r_result) {
|
||||||
*r_result = PhysicsServer3D::MotionResult();
|
*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 (!shapes_found) {
|
||||||
if (r_result) {
|
if (r_result) {
|
||||||
r_result->travel = p_motion;
|
r_result->travel = p_parameters.motion;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Undo the currently transform the physics server is aware of and apply the provided one
|
// 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 = p_parameters.from.xform(p_body->get_inv_transform().xform(body_aabb));
|
||||||
body_aabb = body_aabb.grow(p_margin);
|
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();
|
real_t motion_length = p_parameters.motion.length();
|
||||||
Vector3 motion_normal = p_motion / motion_length;
|
Vector3 motion_normal = p_parameters.motion / motion_length;
|
||||||
|
|
||||||
Transform3D body_transform = p_from;
|
Transform3D body_transform = p_parameters.from;
|
||||||
|
|
||||||
bool recovered = false;
|
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++) {
|
for (int i = 0; i < amount; i++) {
|
||||||
const CollisionObject3DSW *col_obj = intersection_query_results[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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int shape_idx = intersection_query_subindex_results[i];
|
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;
|
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
|
// STEP 2 ATTEMPT MOTION
|
||||||
|
|
||||||
AABB motion_aabb = body_aabb;
|
AABB motion_aabb = body_aabb;
|
||||||
motion_aabb.position += p_motion;
|
motion_aabb.position += p_parameters.motion;
|
||||||
motion_aabb = motion_aabb.merge(body_aabb);
|
motion_aabb = motion_aabb.merge(body_aabb);
|
||||||
|
|
||||||
int amount = _cull_aabb_for_body(p_body, motion_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,
|
// Colliding separation rays allows to properly snap to the ground,
|
||||||
// otherwise it's not needed in regular motion.
|
// 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.
|
// When slide on slope is on, separation ray shape acts like a regular shape.
|
||||||
if (!static_cast<SeparationRayShape3DSW *>(body_shape)->get_slide_on_slope()) {
|
if (!static_cast<SeparationRayShape3DSW *>(body_shape)->get_slide_on_slope()) {
|
||||||
continue;
|
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();
|
Transform3D body_shape_xform_inv = body_shape_xform.affine_inverse();
|
||||||
MotionShape3DSW mshape;
|
MotionShape3DSW mshape;
|
||||||
mshape.shape = body_shape;
|
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;
|
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++) {
|
for (int i = 0; i < amount; i++) {
|
||||||
const CollisionObject3DSW *col_obj = intersection_query_results[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;
|
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..
|
for (int k = 0; k < 8; k++) { //steps should be customizable..
|
||||||
real_t fraction = low + (hi - low) * fraction_coeff;
|
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 lA, lB;
|
||||||
Vector3 sep = motion_normal; //important optimization for this to work fast enough
|
Vector3 sep = motion_normal; //important optimization for this to work fast enough
|
||||||
@ -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
|
//it collided, let's get the rest info in unsafe advance
|
||||||
Transform3D ugt = body_transform;
|
Transform3D ugt = body_transform;
|
||||||
ugt.origin += p_motion * unsafe;
|
ugt.origin += p_parameters.motion * unsafe;
|
||||||
|
|
||||||
_RestResultData results[PhysicsServer3D::MotionResult::MAX_COLLISIONS];
|
_RestResultData results[PhysicsServer3D::MotionResult::MAX_COLLISIONS];
|
||||||
|
|
||||||
_RestCallbackData rcd;
|
_RestCallbackData rcd;
|
||||||
if (p_max_collisions > 1) {
|
if (p_parameters.max_collisions > 1) {
|
||||||
rcd.max_results = p_max_collisions;
|
rcd.max_results = p_parameters.max_collisions;
|
||||||
rcd.other_results = results;
|
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);
|
Transform3D body_shape_xform = ugt * p_body->get_shape_transform(j);
|
||||||
Shape3DSW *body_shape = p_body->get_shape(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);
|
int amount = _cull_aabb_for_body(p_body, body_aabb);
|
||||||
|
|
||||||
for (int i = 0; i < amount; i++) {
|
for (int i = 0; i < amount; i++) {
|
||||||
const CollisionObject3DSW *col_obj = intersection_query_results[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;
|
continue;
|
||||||
}
|
}
|
||||||
int shape_idx = intersection_query_subindex_results[i];
|
int shape_idx = intersection_query_subindex_results[i];
|
||||||
|
|
||||||
rcd.object = col_obj;
|
rcd.object = col_obj;
|
||||||
rcd.shape = shape_idx;
|
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) {
|
if (!sc) {
|
||||||
continue;
|
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);
|
collision.collider_velocity = body->get_linear_velocity() + (body->get_angular_velocity()).cross(rel_vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
r_result->travel = safe * p_motion;
|
r_result->travel = safe * p_parameters.motion;
|
||||||
r_result->remainder = p_motion - safe * p_motion;
|
r_result->remainder = p_parameters.motion - safe * p_parameters.motion;
|
||||||
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 = safe;
|
r_result->collision_safe_fraction = safe;
|
||||||
r_result->unsafe_fraction = unsafe;
|
r_result->collision_unsafe_fraction = unsafe;
|
||||||
|
|
||||||
r_result->collision_count = rcd.result_count;
|
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) {
|
if (!collided && r_result) {
|
||||||
r_result->travel = p_motion;
|
r_result->travel = p_parameters.motion;
|
||||||
r_result->remainder = Vector3();
|
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->collision_safe_fraction = 1.0;
|
||||||
r_result->unsafe_fraction = 1.0;
|
r_result->collision_unsafe_fraction = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return collided;
|
return collided;
|
||||||
|
@ -207,7 +207,7 @@ public:
|
|||||||
void set_elapsed_time(ElapsedTime p_time, uint64_t p_msec) { elapsed_time[p_time] = p_msec; }
|
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]; }
|
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();
|
||||||
~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 {
|
Vector2 PhysicsTestMotionResult2D::get_travel() const {
|
||||||
return result.travel;
|
return result.travel;
|
||||||
}
|
}
|
||||||
@ -448,6 +491,10 @@ int PhysicsTestMotionResult2D::get_collider_shape() const {
|
|||||||
return result.collider_shape;
|
return result.collider_shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PhysicsTestMotionResult2D::get_collision_local_shape() const {
|
||||||
|
return result.collision_local_shape;
|
||||||
|
}
|
||||||
|
|
||||||
real_t PhysicsTestMotionResult2D::get_collision_depth() const {
|
real_t PhysicsTestMotionResult2D::get_collision_depth() const {
|
||||||
return result.collision_depth;
|
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_rid"), &PhysicsTestMotionResult2D::get_collider_rid);
|
||||||
ClassDB::bind_method(D_METHOD("get_collider"), &PhysicsTestMotionResult2D::get_collider);
|
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_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_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_safe_fraction"), &PhysicsTestMotionResult2D::get_collision_safe_fraction);
|
||||||
ClassDB::bind_method(D_METHOD("get_collision_unsafe_fraction"), &PhysicsTestMotionResult2D::get_collision_unsafe_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) {
|
bool PhysicsServer2D::_body_test_motion(RID p_body, const Ref<PhysicsTestMotionParameters2D> &p_parameters, const Ref<PhysicsTestMotionResult2D> &p_result) {
|
||||||
MotionResult *r = nullptr;
|
ERR_FAIL_COND_V(!p_parameters.is_valid(), false);
|
||||||
|
|
||||||
|
MotionResult *result_ptr = nullptr;
|
||||||
if (p_result.is_valid()) {
|
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++) {
|
return body_test_motion(p_body, p_parameters->get_parameters(), result_ptr);
|
||||||
exclude.insert(p_exclude[i]);
|
|
||||||
}
|
|
||||||
return body_test_motion(p_body, p_from, p_motion, p_margin, r, p_collide_separation_ray, exclude);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsServer2D::_bind_methods() {
|
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_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);
|
ClassDB::bind_method(D_METHOD("body_get_direct_state", "body"), &PhysicsServer2D::body_get_direct_state);
|
||||||
|
|
||||||
|
@ -198,6 +198,7 @@ public:
|
|||||||
PhysicsDirectSpaceState2D();
|
PhysicsDirectSpaceState2D();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PhysicsTestMotionParameters2D;
|
||||||
class PhysicsTestMotionResult2D;
|
class PhysicsTestMotionResult2D;
|
||||||
|
|
||||||
class PhysicsServer2D : public Object {
|
class PhysicsServer2D : public Object {
|
||||||
@ -205,7 +206,7 @@ class PhysicsServer2D : public Object {
|
|||||||
|
|
||||||
static PhysicsServer2D *singleton;
|
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:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
@ -465,6 +466,21 @@ public:
|
|||||||
// this function only works on physics process, errors and returns null otherwise
|
// this function only works on physics process, errors and returns null otherwise
|
||||||
virtual PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) = 0;
|
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 {
|
struct MotionResult {
|
||||||
Vector2 travel;
|
Vector2 travel;
|
||||||
Vector2 remainder;
|
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;
|
virtual bool body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result = nullptr) = 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;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* JOINT API */
|
/* JOINT API */
|
||||||
|
|
||||||
@ -579,11 +584,37 @@ public:
|
|||||||
~PhysicsServer2D();
|
~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 {
|
class PhysicsTestMotionResult2D : public RefCounted {
|
||||||
GDCLASS(PhysicsTestMotionResult2D, RefCounted);
|
GDCLASS(PhysicsTestMotionResult2D, RefCounted);
|
||||||
|
|
||||||
PhysicsServer2D::MotionResult result;
|
PhysicsServer2D::MotionResult result;
|
||||||
friend class PhysicsServer2D;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
@ -601,6 +632,7 @@ public:
|
|||||||
RID get_collider_rid() const;
|
RID get_collider_rid() const;
|
||||||
Object *get_collider() const;
|
Object *get_collider() const;
|
||||||
int get_collider_shape() const;
|
int get_collider_shape() const;
|
||||||
|
int get_collision_local_shape() const;
|
||||||
real_t get_collision_depth() const;
|
real_t get_collision_depth() const;
|
||||||
real_t get_collision_safe_fraction() const;
|
real_t get_collision_safe_fraction() const;
|
||||||
real_t get_collision_unsafe_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 {
|
Vector3 PhysicsTestMotionResult3D::get_travel() const {
|
||||||
return result.travel;
|
return result.travel;
|
||||||
}
|
}
|
||||||
@ -370,12 +417,12 @@ Vector3 PhysicsTestMotionResult3D::get_remainder() const {
|
|||||||
return result.remainder;
|
return result.remainder;
|
||||||
}
|
}
|
||||||
|
|
||||||
real_t PhysicsTestMotionResult3D::get_safe_fraction() const {
|
real_t PhysicsTestMotionResult3D::get_collision_safe_fraction() const {
|
||||||
return result.safe_fraction;
|
return result.collision_safe_fraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
real_t PhysicsTestMotionResult3D::get_unsafe_fraction() const {
|
real_t PhysicsTestMotionResult3D::get_collision_unsafe_fraction() const {
|
||||||
return result.unsafe_fraction;
|
return result.collision_unsafe_fraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PhysicsTestMotionResult3D::get_collision_count() const {
|
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;
|
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 {
|
real_t PhysicsTestMotionResult3D::get_collision_depth(int p_collision_index) const {
|
||||||
ERR_FAIL_INDEX_V(p_collision_index, result.collision_count, 0.0);
|
ERR_FAIL_INDEX_V(p_collision_index, result.collision_count, 0.0);
|
||||||
return result.collisions[p_collision_index].depth;
|
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() {
|
void PhysicsTestMotionResult3D::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_travel"), &PhysicsTestMotionResult3D::get_travel);
|
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_remainder"), &PhysicsTestMotionResult3D::get_remainder);
|
||||||
ClassDB::bind_method(D_METHOD("get_safe_fraction"), &PhysicsTestMotionResult3D::get_safe_fraction);
|
ClassDB::bind_method(D_METHOD("get_collision_safe_fraction"), &PhysicsTestMotionResult3D::get_collision_safe_fraction);
|
||||||
ClassDB::bind_method(D_METHOD("get_unsafe_fraction"), &PhysicsTestMotionResult3D::get_unsafe_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_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_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));
|
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_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", "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_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_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) {
|
bool PhysicsServer3D::_body_test_motion(RID p_body, const Ref<PhysicsTestMotionParameters3D> &p_parameters, const Ref<PhysicsTestMotionResult3D> &p_result) {
|
||||||
MotionResult *r = nullptr;
|
ERR_FAIL_COND_V(!p_parameters.is_valid(), false);
|
||||||
|
|
||||||
|
MotionResult *result_ptr = nullptr;
|
||||||
if (p_result.is_valid()) {
|
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++) {
|
return body_test_motion(p_body, p_parameters->get_parameters(), result_ptr);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RID PhysicsServer3D::shape_create(ShapeType p_shape) {
|
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_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);
|
ClassDB::bind_method(D_METHOD("body_get_direct_state", "body"), &PhysicsServer3D::body_get_direct_state);
|
||||||
|
|
||||||
|
@ -203,6 +203,7 @@ public:
|
|||||||
virtual ~RenderingServerHandler() {}
|
virtual ~RenderingServerHandler() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PhysicsTestMotionParameters3D;
|
||||||
class PhysicsTestMotionResult3D;
|
class PhysicsTestMotionResult3D;
|
||||||
|
|
||||||
class PhysicsServer3D : public Object {
|
class PhysicsServer3D : public Object {
|
||||||
@ -210,7 +211,7 @@ class PhysicsServer3D : public Object {
|
|||||||
|
|
||||||
static PhysicsServer3D *singleton;
|
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:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
@ -483,6 +484,22 @@ public:
|
|||||||
// this function only works on physics process, errors and returns null otherwise
|
// this function only works on physics process, errors and returns null otherwise
|
||||||
virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) = 0;
|
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 {
|
struct MotionCollision {
|
||||||
Vector3 position;
|
Vector3 position;
|
||||||
Vector3 normal;
|
Vector3 normal;
|
||||||
@ -501,15 +518,15 @@ public:
|
|||||||
struct MotionResult {
|
struct MotionResult {
|
||||||
Vector3 travel;
|
Vector3 travel;
|
||||||
Vector3 remainder;
|
Vector3 remainder;
|
||||||
real_t safe_fraction = 0.0;
|
real_t collision_safe_fraction = 0.0;
|
||||||
real_t unsafe_fraction = 0.0;
|
real_t collision_unsafe_fraction = 0.0;
|
||||||
|
|
||||||
static const int MAX_COLLISIONS = 32;
|
static const int MAX_COLLISIONS = 32;
|
||||||
MotionCollision collisions[MAX_COLLISIONS];
|
MotionCollision collisions[MAX_COLLISIONS];
|
||||||
int collision_count = 0;
|
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 */
|
/* SOFT BODY */
|
||||||
|
|
||||||
@ -760,11 +777,40 @@ public:
|
|||||||
~PhysicsServer3D();
|
~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 {
|
class PhysicsTestMotionResult3D : public RefCounted {
|
||||||
GDCLASS(PhysicsTestMotionResult3D, RefCounted);
|
GDCLASS(PhysicsTestMotionResult3D, RefCounted);
|
||||||
|
|
||||||
PhysicsServer3D::MotionResult result;
|
PhysicsServer3D::MotionResult result;
|
||||||
friend class PhysicsServer3D;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
@ -774,8 +820,8 @@ public:
|
|||||||
|
|
||||||
Vector3 get_travel() const;
|
Vector3 get_travel() const;
|
||||||
Vector3 get_remainder() const;
|
Vector3 get_remainder() const;
|
||||||
real_t get_safe_fraction() const;
|
real_t get_collision_safe_fraction() const;
|
||||||
real_t get_unsafe_fraction() const;
|
real_t get_collision_unsafe_fraction() const;
|
||||||
|
|
||||||
int get_collision_count() const;
|
int get_collision_count() const;
|
||||||
|
|
||||||
@ -786,16 +832,8 @@ public:
|
|||||||
RID get_collider_rid(int p_collision_index = 0) const;
|
RID get_collider_rid(int p_collision_index = 0) const;
|
||||||
Object *get_collider(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_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;
|
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)();
|
typedef PhysicsServer3D *(*CreatePhysicsServer3DCallback)();
|
||||||
|
@ -208,12 +208,14 @@ void register_server_types() {
|
|||||||
|
|
||||||
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState2D);
|
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState2D);
|
||||||
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState2D);
|
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState2D);
|
||||||
|
GDREGISTER_CLASS(PhysicsTestMotionParameters2D);
|
||||||
GDREGISTER_CLASS(PhysicsTestMotionResult2D);
|
GDREGISTER_CLASS(PhysicsTestMotionResult2D);
|
||||||
GDREGISTER_CLASS(PhysicsShapeQueryParameters2D);
|
GDREGISTER_CLASS(PhysicsShapeQueryParameters2D);
|
||||||
|
|
||||||
GDREGISTER_CLASS(PhysicsShapeQueryParameters3D);
|
GDREGISTER_CLASS(PhysicsShapeQueryParameters3D);
|
||||||
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState3D);
|
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState3D);
|
||||||
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState3D);
|
GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState3D);
|
||||||
|
GDREGISTER_CLASS(PhysicsTestMotionParameters3D);
|
||||||
GDREGISTER_CLASS(PhysicsTestMotionResult3D);
|
GDREGISTER_CLASS(PhysicsTestMotionResult3D);
|
||||||
|
|
||||||
// Physics 2D
|
// Physics 2D
|
||||||
|
Loading…
Reference in New Issue
Block a user