|
|
|
|
Reply From: |
gaycodegal |
Another possibility, if by “in the 3d view” you mean say in the presently viewed hemisphere of the camera (meaning in front of the camera or up to 90 degrees in any direction away from the center of view) you can do some vector maths.
If we consider the distance between the camera and a target to be distance_to_camera
var target_pos = target.to_global(Vector3.ZERO)
var camera_pos = camera.to_global(Vector3.ZERO)
# distance from camera to target
var distance_to_camera = camera_pos - target_pos
Then consider if we cast a vector of any positive length directly backwards from the camera (say 1 unit, the length of a normalized vector)
var back_position = camera_pos + camera.get_camera_transform().basis.z
var distance_to_back = back_position - target_position
Alternatively do note that due to the vector difference already calculated the following would also be equivalent
var distance_to_back = camera.get_camera_transform().basis.z + distance_to_camera
We can then notice that if we are facing the target, back_position
must necessarily be further away from the target than camera_pos
, and that if we are facing away from the target back_position
will be closer. Thus
if distance_to_camera.length_squared() < distance_to_back.length_squared():
pass # target is in the visible hemisphere
I’m posting this because my googling led me to this question, but this hemisphere math I came up with was sufficient to my needs. Also note that I used the squared distance because this is quicker to compute and the relative distances will work out fine because if x < y
then x ** 2 < y ** 2
where **
is the power notation.
Also casting a ray from the object to the camera only tells you if there is anything in the way, if the target is bigger than the blockage, it will still be visible even though raycasting may fail.
Edit: I have realized that the maths on this one are slightly different if you need perfect 90 degrees - you have to make sure that both points are equidistant from the center, so you need to use both positive and negative basis.z as your points of reference. That being said, the algorithm as is, is like mostly fine, you just will have a spot slightly behind the user (up to half a unit max), in which things count as visible when they are not actually visible, but then again that might be desirable in your use case, as it was in mine
Thank you, this solution is probably the most performant way to handle it.
-Sarge- | 2023-06-01 10:31