   Does picking solve this problem?
  My game is a top down shooter. It's rendered in 3D, but the game logic is deduced to 2D (X and Z axes only). The camera is positioned behind and above the player controlled entity. I want to be able to rotate the player controlled entity to the direction pointed by the mouse. I know how to rotate the object, but I don't know how to get vector in 3D pointed by the mouse. If I can do that, my problem is solved. Can picking help here? Or is there a simpler approach?This is what I'm currently doing:1. Get the xy mouse positions.2. Translate in camera near plane.3. Using the plane normal, get the intersection of the ray (from the translated mouse position) from this plane to the XZ plane of the game.It's not working well. =)   
  I think you should do something like the picking process. If the mouse position in screen coordinates is (x, y), then something like:mouseWorld = (x, y, 0) * inverse(view * proj)should give the position in world space, though I'm not sure what you should use as the third coordinate.Maybe try playing with it a little bit...   ;  do a search for ray picking, should do what youwant. Get a ray fromt he eye position and to where the mouse is pointing. Once you have thaat you can either find where it hits the world or just solve it for y = 0 (easy).Depends what your doing with it, ray picking would be well suited to a "Run to mouse location" type problem. If your wanting to select things then color picking might be faster.This might help, I didn't read all of it thoguh:http://www.mvps.org/directx/articles/rayproj.htm   ;  youre closesplit it up into 2 partsA/ find where on the ground plane the ray iontersects (draw this onscreen for debugging purposes)B/ once u have that, find the normalized vector from that pos to the personfloat ang_dif = atan2f( dir.y, dir.x );float rot_ang = persons_dir_angle - ang_dif; // watch out since you usually want to rotate the smallest distance between the 2 directions;  I've solved it. This is how I did it:  // create mouse range vector  const IMouseHandler* const mouseHandler = this->mouseHandler.get();  const Matrix* const projMatrix = this->projectionMatrix.get();  Vector3D projectedVector;  projectedVector.x = ( ( ( 2.0f * mouseHandler->getX() ) / this->viewPortDimension.getWidth() ) - 1 ) / projMatrix->_11;  projectedVector.y = -( ( ( 2.0f * mouseHandler->getY() ) / this->viewPortDimension.getHeight() ) - 1 ) / projMatrix->_22;  projectedVector.z = 1.0f;  // get tail and delta from inverse of view matrix  this->inverseViewMatrix.identity();  MatrixUtils::inverse( this->viewMatrix.get(), &this->inverseViewMatrix );  Vector3D delta;  delta.x = projectedVector.x * this->inverseViewMatrix._11 + projectedVector.y * this->inverseViewMatrix._21 + projectedVector.z * this->inverseViewMatrix._31;  delta.y = projectedVector.x * this->inverseViewMatrix._12 + projectedVector.y * this->inverseViewMatrix._22 + projectedVector.z * this->inverseViewMatrix._32;  delta.z = projectedVector.x * this->inverseViewMatrix._13 + projectedVector.y * this->inverseViewMatrix._23 + projectedVector.z * this->inverseViewMatrix._33;  ray->setDelta( delta );  ray->setTail( this->inverseViewMatrix.getTranslation() );  // compute the location of the mouse point unto the game area plane    // We look for the value t such that:    // p.n = d, where p = R0 + Rd(t) and Rd is normalized (R is the ray), so we have    // ( R0 + Rd(t) ).n = d    // R0.n + Rd(t).n = d    // Rd(t).n = d - R0.n    // t (Rd.n) = d - R0.n    // t = d - R0.n / Rd.n    Vector3D normalizedDelta( ray.getDelta().normalize() );    // t = ( d - ( tail.n ) ) / delta.n    const Vector3D& n = this->gameAreaPlane.getNormal();    const float d = this->gameAreaPlane.getD();    const float t = ( d - ray.getTail().dotProduct( n ) ) / normalizedDelta.dotProduct( n );    const Vector3D& mousePointToPlane = ray.getTail() + ( normalizedDelta * t );    // Now we have the vector to look at, we rotate to this vector but not here. We request it and let the handler rotate.    ... // rotate to mouse point hereMaybe you got better solutions. But this one works fine.   