I am trying to rotate a line to point to the mouse's world coordinates (rather where the mouse lies on the plane where y=0).
I am running into a couple of problems though:
- Whilst it follows the mouse the line doesn't always lie directly beneath the cursor, which is what I would expect to see. It seems to be perfect when the position is at the origin and less accurate the further away from the origin I get.
- The rotation doesn't go from 0 - 360, rather 0 - 180. I think the solution here is to use a dot product but the first problem is preventing me from fixing this problem.
Here's where I calculate the angle by which to rotate:
Calculating mouse position
Vector3 near, far, dir;
unproject(*mouse_, near, far);
dir = near - far;
normalize(dir);
float t = -near.y / dir.y;
Vector3 point = near + (t * dir); //where the mouse lies on the plane y=0
I'm almost certain the above is correct as when I draw a point at point
the rendered point is directly beneath the cursor on the plane y=0
Calculating angle between the line and the point.
rotation_.y = angleBetween(position_ - dir_, position_ - point);
rotation_.y = radToDeg(rotation_.y);
position_
is where I want the line to start from. Which is the player's position at the moment.
dir_
is the direction of the line, set to and never changed Vector3(0.0f, 0.0f, 5.0f);
float angleBetween(const Vector3& a, const Vector3& b) {
float cosTheta = dot(a, b) / (length(a) * length(b));
return acos(cosTheta);
}
Here's how I am drawing the line:
glPushMatrix();
glTranslatef(position_.x, position_.y, position_.z);
glRotatef(rotation_.x, 1.0f, 0.0f, 0.0f);
glRotatef(rotation_.y, 0.0f, 1.0f, 0.0f);
glRotatef(rotation_.z, 0.0f, 0.0f, 1.0f);
glDisable(GL_LIGHTING);
glLineWidth(3.0f);
glColor3f(0.0f, 1.0f, 1.0f);
glBegin(GL_LINES);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3fv(end_.toArray().data()); //toArray() returns and std::array of the vector
glEnd();
glPopMatrix();
And just in case it matters, for the camera I do:
void Camera::transform() {
gluLookAt(position_.x, position_.y, position_.z,
target_.x, target_.y, target_.z,
0.0f, 1.0f, 0.0f);
}
target_
is also the player's position.
I hope this is enough information.