## Converts a position input in viewport coordinates (e.g. from the mouse position input) ## into 3D coordinates (e.g. 3D world coordinates). Useful to get a 3D 'world' position. ## Returns a Vector3.INF if no 3D world coordinates can be determined. @tool class_name GUIDEModifier3DCoordinates extends GUIDEModifier ## The maximum depth of the ray cast used to detect the 3D position. @export var max_depth:float = 1000.0 ## Whether the rays cast should collide with areas. @export var collide_with_areas:bool = false ## Collision mask to use for the ray cast. @export_flags_3d_physics var collision_mask:int func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: # if we collide with nothing, no need to even try if collision_mask == 0: return Vector3.INF if not input.is_finite(): return Vector3.INF var viewport = Engine.get_main_loop().root var camera:Camera3D = viewport.get_camera_3d() if camera == null: return Vector3.INF var input_position:Vector2 = Vector2(input.x, input.y) var from:Vector3 = camera.project_ray_origin(input_position) var to:Vector3 = from + camera.project_ray_normal(input_position) * max_depth var query:= PhysicsRayQueryParameters3D.create(from, to, collision_mask) query.collide_with_areas = collide_with_areas var result = viewport.world_3d.direct_space_state.intersect_ray(query) if result.has("position"): return result.position return Vector3.INF func _editor_name() -> String: return "3D coordinates" func _editor_description() -> String: return "Converts a position input in viewport coordinates (e.g. from the mouse position input)\n" + \ "into 3D coordinates (e.g. 3D world coordinates). Useful to get a 3D 'world' position."