Skip to content

Conversation

@io-mi
Copy link

@io-mi io-mi commented Dec 12, 2025

This PR refactors the query methods in PhysicsDirectSpaceState2D/3D to use strongly typed result objects instead of allocating result containers on every call. This aligns the API with body_test_motion() in PhysicsServer2D/3D and improves performance, though it is backward-incompatible.

API changes

Old New
Dictionary intersect_ray(parameters: PhysicsRayQueryParameters2D) bool intersect_ray(parameters: PhysicsRayQueryParameters2D, result: PhysicsRayIntersectionResult2D)
Array[Dictionary] intersect_point(parameters: PhysicsPointQueryParameters2D, max_results: int) bool intersect_point(parameters: PhysicsPointQueryParameters2D, result: PhysicsPointIntersectionResult2D)
Array[Dictionary] intersect_shape(parameters: PhysicsShapeQueryParameters2D, max_results: int) bool intersect_shape(parameters: PhysicsShapeQueryParameters2D, result: PhysicsShapeIntersectionResult2D)
PackedFloat32Array cast_motion(parameters: PhysicsShapeQueryParameters2D) bool cast_motion(parameters: PhysicsShapeQueryParameters2D, result: PhysicsShapeCastResult2D)
Array[Vector3] collide_shape(parameters: PhysicsShapeQueryParameters2D, max_results: int) bool collide_shape(parameters: PhysicsShapeQueryParameters2D, result: PhysicsShapeCollisionResult2D)
Dictionary get_rest_info(parameters: PhysicsShapeQueryParameters2D) bool get_rest_info(parameters: PhysicsShapeQueryParameters2D, result: PhysicsShapeRestInfoResult2D)

Equivalent changes are applied to the 3D.

New classes

  • PhysicsRayIntersectionResult2D/3D
  • PhysicsPointIntersectionResult2D/3D
  • PhysicsShapeIntersectionResult2D/3D
  • PhysicsShapeCastResult2D/3D
  • PhysicsShapeCollisionResult2D/3D
  • PhysicsShapeRestInfoResult2D/3D

Motivation

  1. Strongly typed access

The new typed result objects eliminate the need to manually declare types when accessing fields:

var result := PhysicsRayIntersectionResult3D.new()
if world.direct_space_state.intersect_ray(params, result):
    var normal := result.get_normal()
    var position := result.get_position()

Old usage required explicit type annotations:

var result := world.direct_space_state.intersect_ray(params)
if result:
    # Cannot infer the type of "normal"
    # var normal := result["normal"]
    var normal: Vector3 = result["normal"]
  1. Performance

Result objects can be created once and reused:

var result := PhysicsShapeCastResult3D.new()
for i in range(1_000):
    if world.direct_space_state.cast_motion(params, result):
        ...

Avoids per-call result allocation and improves performance.

  1. Consistency

This matches the PhysicsTestMotionResult2D/3D and PhysicsTestMotionParameters2D/3D pattern already used by body_test_motion().

Crude microbenchmark comparisons (3D)

  • intersect_ray()

intersect_ray-old intersect_ray-new

  • intersect_point()

intersect_point-old intersect_point-new

  • intersect_shape()

intersect_shape-old intersect_shape-new

  • cast_motion()

cast_motion-old cast_motion-new

  • collide_shape()

collide_shape-old collide_shape-new

  • get_rest_info()

get_rest_info-old get_rest_info-new

Notes

@io-mi io-mi requested review from a team as code owners December 12, 2025 22:56
@io-mi io-mi force-pushed the feature/directspace-typed-results branch from a8367c9 to bdbead3 Compare December 12, 2025 23:01
@io-mi io-mi requested review from a team as code owners December 12, 2025 23:01
@io-mi io-mi force-pushed the feature/directspace-typed-results branch 2 times, most recently from 5d1900b to e3d2154 Compare December 12, 2025 23:45
@AThousandShips AThousandShips added this to the 4.x milestone Dec 15, 2025
@io-mi io-mi force-pushed the feature/directspace-typed-results branch from e3d2154 to 747916a Compare December 15, 2025 09:36
@io-mi io-mi force-pushed the feature/directspace-typed-results branch from 747916a to bd00fab Compare December 15, 2025 10:47
@AThousandShips
Copy link
Member

Thank you for your contribution!

This is a pretty majorly breaking change, is there a proposal to track this or to evaluate support?

This would benefit from having a proper proposal created here to discuss the details and evaluate support for this, as it would be something that would need good support to justify the changes and the need for them

I'd say backwards compatibility needs to be maintained by creating new methods instead of replacing the existing ones, as this would be very disruptive to anyone using the existing interfaces

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants