A solution that would work in all cases would be inverse kinematics. You may want to look it up, but that is quite a complex topic.
Here is a general solution for your special problem:
I don't really understand how the TopDondur
and Berrels
are related (or even what TopDondur
is supposed to be) so I will for sake of simplicity assume only on "character". I will also assume that orientations are handled as a R3 matrix (you won't get far with angle + axis).
This is basically what I call a "look at" problem and you can solve it similarly to the function with that same name (gluLookAt
). For this you need a position, a target vector and an up vector. And we basically already have everything:
vec3 position = // given by the gunner
vec3 target = // given by the target
vec3 up = vec(0, 0, 1); // I assume that
vec3 forward = normalize(target - position);
vec3 side = normalize(cross(forward, up));
// ensure that up really is orthogonal to side and up
up = cross(side, forward);
mat3 orientation = mat3(forward, side, up);
Now you have the orientation to face the target. The cheap way would be to automatically apply the orientation to the gunner. You can interpolate the current orientation to "slowly" match the target orientation.
You may want to look at the Matrix and Quaternion FAQ on how to get from an angle axis to a R3 matrix and back. When interpolating you may want to go over quaternions for smooth interpolation.
An alternative would be to convert both the current orientation and the target vector to spherical coordinates. This gives you more fine control over "horizontal" and "vertical" movement. This may be of importance, since you state that you only allow movement along the Y-axis.