3rd person camera

Member
Posts: 45
Joined: 2006.11
Post: #1
I've written this very simple function to set the model-view as a third person camera. Here is the function:
Code:
void SetCamera3rdPerson(Vec3 _object, float _distance, float angle2, float angle1)
{
    float l = _distance * cos(angle1);
    Vec3 cameraPos(l * cos(angle2), l * sin(angle2), _distance * cos(angle1));
    Vec3 cameraForward(_object.x() - cameraPos.x(), _object.y() - cameraPos.y(), _object.z() - cameraPos.x());
    Vec3 worldUp(0.0, 0.0, 1.0);
    Vec3 cameraRight = worldUp ^ cameraForward;
    Vec3 cameraUp = worldUp ^ cameraRight;
    gluLookAt(_object.x() + cameraPos.x(), _object.y() + cameraPos.y(), _object.z() + cameraPos.z(),
              _object.x(), _object.y(), _object.z(),
              cameraUp.x(), cameraUp.y(), cameraUp.z());
}

however it doesn't seem to be working. angle1 is pitch and angle2 is yaw. Object is the position of the object to look at and distance is the distance away from the object. This function was previously written for the default OpenGL coordinate system of {0.0, 1.0, 0.0} being "up" but for this application, {0.0, 0.0, 1.0} is "up".
Quote this message in a reply
Member
Posts: 164
Joined: 2002.04
Post: #2
It would help if you could tell us what is not working about it; it looks to me that cameraUp should be cameraForward ^ cameraRight though.

I would skip all of that and do something like this:

glTranslatef(-target.x,-target.y,-target.z);
glRotate(angle2,0,0,1);
glRotate(angle1,1,0,0);
glTranslatef(0,cameradist,0);
Quote this message in a reply
Member
Posts: 45
Joined: 2006.11
Post: #3
OK, here is the updated code. The reason I'm doing it this way is because I need to know the position of the camera, cameraRight, CameraUp, and CameraForward for other things (like colliding with the terrain, using the forward to point projectiles, etc...), not just rotating the camera into place.

Here is the updated Recalc function. It seems to be working fine for getting the camera in the right place, but suddenly all attempts to find a ray intersection with the terrain using the camera's position and forward vector return positive, even when there is no intersection.

Code:
        void Recalc()
        {
            if(m_Terrain)
            {
                float cz, l;
                if(m_Pitch > M_PI) m_Pitch = M_PI;
                if(m_Pitch < -M_PI) m_Pitch = -M_PI;
                if(m_Pitch < 0.0)
                {
                    cz = -(m_FollowDistance * sin(-m_Pitch));
                    l = m_FollowDistance * cos(-m_Pitch);
                }
                else
                {
                    cz = m_FollowDistance * sin(m_Pitch);
                    l = m_FollowDistance * cos(m_Pitch);
                }
                
                m_CameraPosition = osg::Vec3(l * cos(m_Yaw), l * sin(m_Yaw), cz);
                m_CameraLookForward = osg::Vec3(-m_CameraPosition.x(), -m_CameraPosition.y(), -m_CameraPosition.z());
                m_CameraLookForward.normalize();
                
                osg::Vec3 objectToCamera(m_CameraPosition);
                objectToCamera.normalize();
                float ix, iy, iz;
                float d = m_Terrain->IntersectRay(m_ObjectPosition.x(), m_ObjectPosition.y(), m_ObjectPosition.z() + m_Height,
                                                  objectToCamera.x(), objectToCamera.y(), objectToCamera.z(),
                                                  ix, iy, iz);
                if(d > 0.0 && d < m_FollowDistance)
                    m_CameraPosition = osg::Vec3(ix, iy, iz) + (m_CameraLookForward * 2.0);
                else
                {
                    m_CameraPosition += m_ObjectPosition;
                    m_CameraPosition.z() += m_Height;
                }
                static osg::Vec3 worldUp(0.0, 0.0, 1.0);
                
                if(m_Pitch > 0.0)
                    m_CameraLookRight = m_CameraLookForward ^ worldUp;
                else
                    m_CameraLookRight = worldUp ^ m_CameraLookForward;
                    
                m_CameraLookUp = worldUp ^ m_CameraLookRight; //cameraRight ^ worldUp;
                
                dirty = false;
            }
        }
Quote this message in a reply
Member
Posts: 45
Joined: 2006.11
Post: #4
AHA! m_Terrain->IntersectRay is returning "inf" rather than a negative number like it is supposed to when there is no intersection.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  First Person Objects (Gun) in OpenGL mikey 21 9,774 Jun 3, 2009 11:01 AM
Last Post: mikey
  Third Person Control PAD Games 4 2,980 Jun 22, 2005 01:59 AM
Last Post: PAD Games