0

i need a non-language specific algorithm for a 3rd person camera. what im having trouble with is how to keep the camera behind the object and keep the camera's rotation the same as the objects rotation. any ideas?

Example:

UpdateCamera(camera, target){
    offset = vector(0,height,distance);
    cameraPos = targetPos+offset;
    camAngle = ?????;
}

i know it won't be that simple but im sure you'll get the gist of it.

ddan
  • 295
  • 1
  • 5
  • 17
  • 3rd person cameras are quite complicated to fully explain in a StackOverflow answer -- you might want to get hold of books called "3D Games: Real-Time Rendering and Software Technology" and "3D Games: Animation and Advanced Real-Time Rendering" though, I remember one of those containing a decent description of how to do it. – Stuart Golodetz Dec 15 '11 at 00:53
  • See here: http://www.amazon.co.uk/Games-Real-Time-Rendering-Technology-Real-time/dp/0201619210 and http://www.amazon.co.uk/3D-Games-Animation-Real-time-Rendering/dp/0201787067 – Stuart Golodetz Dec 15 '11 at 00:55
  • thanks for the answer... i understand that a full 3rd person camera is pretty extensive, but what about using the target as a pivot point for the camera? it dosn't seem like that it self would be too extensive, but that could just be me being naive. – ddan Dec 15 '11 at 01:11
  • Possible Duplicates, http://stackoverflow.com/q/8160607/380384, http://stackoverflow.com/q/6171092/380384 – John Alexiou Dec 15 '11 at 01:14
  • @ja72: It's definitely not a duplicate of the first one you reference. – Stuart Golodetz Dec 15 '11 at 01:42
  • @stuart golodetz awesome looking books btw – ddan Dec 15 '11 at 04:19
  • @ja72 the second post is a good one, but i was looking for the guts of the lookAt() function as well. – ddan Dec 15 '11 at 04:20

1 Answers1

0

At its absolute simplest, suppose you have a simple NUV camera class like this:

/// <summary>
/// An instance of this class represents a camera for a 3D view.
/// Cameras are defined with a position and three mutually-orthogonal
/// axes, namely N (points in the direction faced by the camera),
/// U (points to the left of the camera) and V (points to the top
/// of the camera).
/// </summary>
sealed class Camera
{
    //#################### PRIVATE VARIABLES ####################
    #region

    private Vector3 m_n;
    private Vector3 m_position;
    private Vector3 m_u;
    private Vector3 m_v;

    #endregion

    //#################### PROPERTIES ####################
    #region

    /// <summary>
    /// The position of the camera.
    /// </summary>
    public Vector3 Position { get { return m_position; } }

    /// <summary>
    /// A vector pointing in the direction faced by the camera.
    /// </summary>
    public Vector3 N { get { return m_n; } }

    /// <summary>
    /// A vector pointing to the left of the camera.
    /// </summary>
    public Vector3 U { get { return m_u; } }

    /// <summary>
    /// A vector pointing to the top of the camera.
    /// </summary>
    public Vector3 V { get { return m_v; } }

    #endregion

    //#################### CONSTRUCTORS ####################
    #region

    /// <summary>
    /// Constructs a new camera.
    /// </summary>
    /// <param name="position">The position of the camera.</param>
    /// <param name="look">A vector pointing in the direction faced by the camera.</param>
    /// <param name="up">The "up" direction for the camera.</param>
    public Camera(Vector3 position, Vector3 look, Vector3 up)
    {
        m_position = position;

        m_n = look;
        m_n.Normalize();

        m_v = up;
        m_v.Normalize();

        m_u = Vector3.Cross(m_v, m_n);
        m_u.Normalize();
    }

    #endregion

    //#################### PUBLIC METHODS ####################
    #region

    /// <summary>
    /// Moves the camera by the specified displacement in the n direction.
    /// </summary>
    /// <param name="delta">The displacement by which to move.</param>
    public void MoveN(float delta)
    {
        m_position += delta * m_n;
    }

    /// <summary>
    /// Moves the camera by the specified displacement in the u direction.
    /// </summary>
    /// <param name="delta">The displacement by which to move.</param>
    public void MoveU(float delta)
    {
        m_position += delta * m_u;
    }

    /// <summary>
    /// Moves the camera by the specified displacement in the v direction.
    /// </summary>
    /// <param name="delta">The displacement by which to move.</param>
    public void MoveV(float delta)
    {
        m_position += delta * m_v;
    }

    /// <summary>
    /// Rotates the camera anticlockwise by the specified angle about the specified axis.
    /// </summary>
    /// <param name="axis">The axis about which to rotate.</param>
    /// <param name="angle">The angle by which to rotate (in radians).</param>
    public void Rotate(Vector3 axis, float angle)
    {
        // Note: We try and optimise things a little by observing that there's no point rotating an axis about itself.
        if(axis != m_n) m_n = MathUtil.RotateAboutAxis(m_n, angle, axis);
        if(axis != m_u) m_u = MathUtil.RotateAboutAxis(m_u, angle, axis);
        if(axis != m_v) m_v = MathUtil.RotateAboutAxis(m_v, angle, axis);
    }

    #endregion
}

Now, each frame:

1) Get the position pp and direction pdir of the player.
2) Recreate your camera with position = pp - offset * pdir, look = pdir and up = something sensible (e.g. (0,0,1)).

Stuart Golodetz
  • 20,238
  • 4
  • 51
  • 80