Angle between two Vectors split up into x,y,z components
Hello, I am developing an application for the HoloLens which is testing different aids to guide the users visual attention. The user finds himself in a environment with objects floating around him, where he has to find the next target object out of all the target objects.
What i want to do is calculate the angle between the main cameras forward (the direction the player is currentlylooking) and a target object the player has to look at next. I need to calculate this once before every target object. Then i want to track how much rotation the user is actually doing. I want those optimal and real angles split up into x,y,z components so I can compare the different guiding methods in respect to the axes.
My idea was to project the forward and target vector into the corresponding planes and then calculate the angle. As the user cant rotate himself around the x-axis, just move his head up and down, i nedd to correct for impossible x-axis angles. To do this I multiply the y component of the camera's forward by (-1) if the forward and target vector point in different quadrants. So for the initial rotation on the x-axis rotation i would do the following:
//calculate Vectors for target and camera forward
Vector3 targetDir = target.position - camera.position;
Vector3 forward = camera.forward;
//project the Vectors into the yz-plane and calculate the angle
Vector3 TargetProj = Vector3.ProjectOnPlane(targetDir, Vector3.right);
Vector3 ForwardProj = Vector3.ProjectOnPlane(forward, Vector3.right);
//compensate for impossible rotation maneuvers
if ((TargetProj.z < 0 && ForwardProj.z > 0) | (TargetProj.z > 0 && ForwardProj.z < 0))
{
ForwardProj.y = ForwardProj.y * (-1);
}
float angleX = Vector3.Angle(TargetProj, ForwardProj);
For the actual rotation the user is doing i would calculate the difference between updates on the cameras forward vector projected on the yz-plane:
void Update(){
float angleX;
Vector3 newForwardX = Vector3.ProjectOnPlane(forward_new, Vector3.right);
Vector3 oldForwardX = Vector3.ProjectOnPlane(forward_old, Vector3.right);
//compensate for impossible rotation maneuvers
if ((TargetProj.z < 0 && ForwardProj.z > 0) | (TargetProj.z > 0 && ForwardProj.z < 0))
{
ForwardProj.y = ForwardProj.y * (-1);
}
float angle_x = Vector3.Angle(newForwardX, oldForwardX);
angle_x = Mathf.Abs(angle_x);
angleX +=angle_x;
forward_old=forward_new;
}
In the following picture the blue line is the cameras forward, the yellow line is the target vector. The green objects form a tunnel, to guid the user to the next target. After clicking on the target, the next target is activated and i need to calculate the inital, optimal, rotation in x,y,z and record the actual rotation in x,y,z. The problem is that when the user is moving his head to turn to the target and he isnt keeping his head level with the ground, the projection of vectors changes and the angle gets totally wrong.
Has anybody done something similar or can offer any help? Thank you!