• Create Account

## 3D free camera

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

5 replies to this topic

### #1AticAtac  Members

334
Like
0Likes
Like

Posted 22 January 2013 - 03:10 PM

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 ;)

### #2C0lumbo  Members

4073
Like
1Likes
Like

Posted 22 January 2013 - 04:05 PM

"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):

### #3Nyssa  Members

426
Like
0Likes
Like

Posted 23 January 2013 - 03:11 AM

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.

Edited by Nyssa, 23 January 2013 - 03:19 AM.

### #4AticAtac  Members

334
Like
0Likes
Like

Posted 23 January 2013 - 06:51 AM

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.

### #5AticAtac  Members

334
Like
0Likes
Like

Posted 26 January 2013 - 01:07 PM

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;
}


### #6AticAtac  Members

334
Like
0Likes
Like

Posted 26 January 2013 - 02:09 PM

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

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.