Created
November 1, 2022 05:57
-
-
Save Yagich/751ea2406f4d17d897b5ef83c953b91d to your computer and use it in GitHub Desktop.
a godot 4 function to get MeshInstances under the cursor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func pick(in: Node3D) -> Array: | |
var camera = get_viewport().get_camera_3d() | |
var center_pos = get_viewport().size / 2.0 | |
var mouse_pos = get_viewport().get_mouse_position() | |
var from = camera.project_ray_origin(center_pos) | |
var to = from + camera.project_ray_normal(mouse_pos) * 50.0 | |
var pick_results: Array[MeshInstance3D] = [] | |
for m in in.get_children(): | |
m = m as MeshInstance3D | |
var aabb = m.get_aabb() | |
# avoid using VisualInstance3D.get_transformed_aabb() as it will be | |
# removed in beta 4: https://github.com/godotengine/godot/pull/66940 | |
# probably the most random removal i've seen, lol | |
# also note the order of operation is important: | |
# aabb * m.global_transform produces wrong results | |
# (seems to be inverted) | |
var global_aabb = m.global_transform * aabb | |
# it seems some click-through is still apparent, | |
# maybe using AABB.grow() is appropriate. | |
if global_aabb.intersects_ray(from, to): | |
pick_results.append(m) | |
if pick_results.is_empty(): | |
return [] | |
# sort by distance to the camera, in ascending order | |
pick_results.sort_custom( | |
func(a: MeshInstance3D, b: MeshInstance3D): | |
var cam_pos = camera.global_transform.origin | |
var adist = a.global_transform.origin.distance_squared_to(cam_pos) | |
var bdist = b.global_transform.origin.distance_squared_to(cam_pos) | |
return adist < bdist | |
) | |
# the actual occluded selection is pick_results[0] | |
return pick_results |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment