How to do basic angle restrictions on making an eye follow a target in 3D?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By dodgyville

Hi,

I have my eyeball object rotating to follow a target in a really basic 3D scene. I would like to add functionality where if the target is too far away or angle too large, rotate eye back to default. I think I can handle the rotate back to default (moving the rotation out of the transform and into its own values) and if the length is too large (using direction.length()) but I don’t know an easy way to get the total angle from the eyeball to the target.

For example, how do I calculate if the target is more than 60 degrees from the default rest position (0,0,0) of the eye?

func _process(delta):
    var eye = get_node("MeshInstanceEye")
    var target = get_node("Position3DTarget")   
    
    var eye_t = eye.get_global_transform()
    var target_t = eye.get_global_transform()
        
    # make eye follow target
    var direction = eye.transform.origin - target.transform.origin
    
    # TODO: if target too far away or angle too large, rotate eye back to default
    
    eye.transform = eye_t.looking_at(direction, Vector3(0, 1, 0))
:bust_in_silhouette: Reply From: SIsilicon

Well, you could try using vector3’s dot function, and then acos the result. This would the angle between two vectors angle = acos(a.dot(b)). It will always give an angle between 0(Parallel in same direction) and PI(same but in opposite directions). So in your case you’ll need-

#-a vector point in from eye to target-
var pointing = -distance.normalized() #you have it already just reversed.

#-and the z-direction of your eye's rest transform.
var Z-dir = rest_transform.basis[2]

#Finally you do what I said before.
var angle = acos(pointing.dot(Z-dir))

Do what ever you need to do with it.

Additional note for OP: You can read about the dot product here.

Calinou | 2018-05-14 06:37