3D free camera

Started by
4 comments, last by AticAtac 11 years, 2 months ago

Hi folks,

i am using a SDK which is based on OpenGL ES and provides me a LookAt(from, to, up) function to construct a view matrix for camera.

What i want to achieve is implement a camera which can be moved freely using mouse (looking left/right and up/down) and keyboard (moving foreward/backwar and strafe left/right).

I initially set up the camera matrix with the required vectors (from, to, up) and need to maintain theses vectors while changing the camera orientation (mouse look).

Moving is easy, i can easily change camera location (from), up vector doesn't change.

What i need are code/calculations how to "maintain" the up/to vectors once camera orientation is changed.

any help welcome ;)

Advertisement

"What i need are code/calculations how to "maintain" the up/to vectors once camera orientation is changed."

For a flycam, my recommendation is don't "maintain" the 'up' and 'to' vectors. Maintain heading and pitch angles and use them to construct your 'up' and 'to' vector.

I think this is correct, (but it's untested):

to = from + vector3(cosf(pitch) * sinf(heading), -sinf(pitch), cosf(pitch) * cosf(heading))

up = vector3(sinf(pitch)*sinf(heading), cosf(pitch), sinf(pitch)*cosf(heading));

The "to" vector can be calculated by adding a small value to the camera position that will always be in front of the camera. You just transform the small vector by the camera matrix so its pointing in the correct direction then add it to the camera position, that can be your lookat position. Then you can do some cross products to calculate the correct "up" and "right" vectors.


Vector to(0,0,1);
to = cameraMatrix.TransformVector(to);
Vector lookat = cameraPosition + to;
Vector up(0,1,0);
Vector right = lookat.Cross(up);
up = lookat.Cross(right);

This link may also be useful to you for creating a free camera.

Thx.

I picked the idea of using the 2 angles "pitch" and "roll" and reconstruct the vectors each time from these 2 and used the equations @C0lumbo gave me and it worked well.

I've still got one problem:

using the equations and rendering a quad with an image it seems that the rotation around z-axis is not right, because the image looks like to be rotated 90° to right (around z-axis).

So instead of rendering an image with arrow on it like this

^

|

|

|

its rendered like this:

------>

Here is my camera (view matrix) update code:


float cos_pitch = cosf(pitch);
    float sin_pitch = sinf(pitch);
    float cos_roll = cosf(roll);
    float sin_roll = sinf(roll);

    _forward.x = cos_pitch * sin_roll;
    _forward.y = -sin_pitch;
    _forward.z = cos_pitch * cos_roll;
    _forward.Normalise();

    _up.x = sin_pitch * sin_roll;
    _up.y = cos_pitch;
    _up.z = sin_pitch * cos_roll;
    _up.Normalise();

    _right = _up ^ _forward;    
    if (_right.IsZero())
        _right.x = 1.0f;
    else
        _right.Normalise();
    _up = _forward ^ _right;    

    _view_mat.m[0][0] =  _right.x; _view_mat.m[0][1] = _right.y; _view_mat.m[0][2] =  _right.z;
    _view_mat.m[1][0] =  _up.x; _view_mat.m[1][1] =  _up.y; _view_mat.m[1][2] =  _up.z;
    _view_mat.m[2][0] =  _forward.x; _view_mat.m[2][1] =  _forward.y; _view_mat.m[2][2] = _forward.z;
 

and here is my quad rendering code:


// x,y,z : top left, verts go counter-clockwise
void RenderQuad(float x, float y, float z, float w, float h)
{
    static CIwFVec3 verts[4];
    verts[0] = CIwFVec3(x, y, z);
    verts[1] = CIwFVec3(x, y-h, z);
    verts[2] = CIwFVec3(x+w, y-h, z);
    verts[3] = CIwFVec3(x+w, y, z);
    IwGxSetVertStreamWorldSpace(s_Verts, 4);

    // texture-atlas 512x512 , image on tex-atlas at (0,0) -> (63,63)
    static CIwFVec2 uvs[4];
    uvs[0] = CIwFVec2(0.0f, 0.0f);
    uvs[1] = CIwFVec2(0.0f, 63.0f/512.0f);
    uvs[2] = CIwFVec2(63.0f/512.0f, 63.0f/512.0f);
    uvs[3] = CIwFVec2(63.0f/512.0f, 0.0f);
    IwGxSetUVStream(uvs);

    static uint16 strips[4];
    strips[0] = 0;
    strips[1] = 1;
    strips[2] = 3;
    strips[3] = 2;
    IwGxDrawPrims(IW_GX_QUAD_STRIP, strips, 4);
}

to sum it up:

this is my quad in 3D-space

0---3

| |

| |

1----2

z=0

this is renderd on screen

1---0

| |

| |

2----3

This topic is closed to new replies.

Advertisement