Sign in to follow this  

Help with Camera math

This topic is 2053 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Here is my camera code, and I do not know for sure what I need to do to make the camera move forward after the rotations... What happens is if I rotate and use say "s" to move forward after I rotate "s" will move backwards and "w" will move forward... I am not sure what to do to fix this? I can't imagine this is a simple fix e.g. - vs. + value in the calculation.

[code]
template<class T>
class Camera
{
private:
cml::matrix44f_c matrix, matrixAvatarTranslation, projection;
T xPos, yPos, zPos, xRot, yRot, prevX, prevY;
T radius;//our radius distance from our object
bool mouseMove;

public:
explicit Camera(T r = 10)
{
xPos = yPos = zPos = xRot = yRot = prevX = prevY = 0;
radius = r;
mouseMove = false;
matrix.identity();
matrixAvatarTranslation.identity();
projection.identity();
}
~Camera(){}
inline void UpdatePerspective(unsigned int width, unsigned int height,
T nearPlane = 3,
T farPlane = 100,
T fov = 60)
{
glMatrixMode(GL_PROJECTION);
cml::matrix_perspective_yfov_RH(projection, cml::rad(fov),
static_cast<T>(width) / static_cast<T>(height),
nearPlane, farPlane,
cml::z_clip_neg_one);
glLoadMatrixf(projection.data());
glMatrixMode(GL_MODELVIEW);
}
inline void UpdateViewport(unsigned int width, unsigned int height)
{
glViewport(0, 0, width, height);
}
inline void Update(void)
{
cml::matrix44f_c rot, trans;
trans.identity();
rot.identity();
cml::matrix_translation(trans, T(0), T(0), -radius);
cml::matrix_rotation_world_axis(rot, 0, cml::rad(xRot));
matrixAvatarTranslation = trans * rot;

cml::matrix_translation(trans, -xPos, T(0), -zPos);
cml::matrix_rotation_world_axis(rot, 1, cml::rad(yRot));
matrix = matrixAvatarTranslation * rot * trans;
//glMatrixMode(GL_MODELVIEW);
//glLoadMatrixf(matrix.data());
}
inline void MouseMovement(int x, int y)
{
if(mouseMove)
{
T diffX = static_cast<T>(x - prevX); //check the difference between the current x and the last x position
T diffY = static_cast<T>(y - prevY); //check the difference between the current y and the last y position
prevX = static_cast<T>(x); //set prevX to the current x position
prevY = static_cast<T>(y); //set prevY to the current y position
xRot += diffY; //set the xrot to xrot with the addition of the difference in the y position
yRot += diffX; //set the xrot to yrot with the addition of the difference in the x position
}
}
inline bool IsMouseMove(void)
{
return mouseMove;
}
inline void SetMouseMove(bool b)
{
mouseMove = b;
}
inline const cml::matrix44f_c& GetTransform(void) const
{
return matrix;
}
inline void SetTransform(const cml::matrix44f_c& m)
{
matrix = m;
}
inline const cml::matrix44f_c& GetTransformAvatar(void) const
{
return matrixAvatarTranslation;
}
inline void SetTransformAvatar(const cml::matrix44f_c& m)
{
matrixAvatarTranslation = m;
}
inline T GetRadius(void)
{
return radius;
}
inline T GetRotateX(void)
{
return xRot;
}
inline T GetRotateY(void)
{
return yRot;
}
inline T GetPositionX(void)
{
return xPos;
}
inline T GetPositionY(void)
{
return yPos;
}
inline T GetPositionZ(void)
{
return zPos;
}
inline void Move(T t)
{
T yRotRad = static_cast<T>(yRot / cml::constants<T>::deg_per_rad());
T xRotRad = static_cast<T>(xRot / cml::constants<T>::deg_per_rad());
xPos -= static_cast<T>(sin(yRotRad) * t);
zPos += static_cast<T>(cos(yRotRad) * t);
yPos += static_cast<T>(sin(xRotRad) * t);
}
inline void Strafe(T t)
{
T yRotRad = static_cast<T>(yRot / cml::constants<T>::deg_per_rad());
xPos += static_cast<T>(cos(yRotRad) * t);
zPos += static_cast<T>(sin(yRotRad) * t);
}
inline void Rotate(T t)
{
xRot += t;
if(xRot > 360)
{
xRot -= 360;
return;
}
if(xRot < -360)
{
xRot += 360;
return;
}
}
};

[/code]

Share this post


Link to post
Share on other sites
I am not an expert, but I have wrestled with this in the distant past. With matrix math it's usually the order that you do things. Maybe apply the move before the rotation?

Share this post


Link to post
Share on other sites
[CODE]
cml::matrix44f_c rot, trans;
trans.identity();
rot.identity();
cml::matrix_translation(trans, T(0), T(0), -radius);
cml::matrix_rotation_world_axis(rot, 0, cml::rad(xRot));
matrixAvatarTranslation = trans * rot;
[/CODE]
With this code you seem to rotate your camera around the avatar ..
[CODE]
cml::matrix_translation(trans, -xPos, T(0), -zPos);
cml::matrix_rotation_world_axis(rot, 1, cml::rad(yRot));
matrix = matrixAvatarTranslation * rot * trans;
[/CODE]
Here you want to move the camera to the avatars world position and rotate the camera relative to the avatar orientation ?

Here's my approach:
[CODE]
Tc = camera translation (radius), iTc = inverse(Tc) =-radius
Rc = camera rotation around avatar
Ta = avatar translation/position in world, iTa = inverse(Ta)
Ra = avatar orientation/look at

From a logical approach (hope I make no misstake now, I have not slept much):
Starting at the origin. First you need to rotate the camera around its origin at distance radius (move away from origin)
final = Rc * iTc
then you need to rotate the avatar
final = Ra * Rc * iTc
eventually move the camera to the avatar world position
final = Ta * Ra * Rc * iTc
It seems, that you are applying the transformations from the right, therefore:
final = iTc * Rc * Ra * Ta

As you can see, the first part is correct (iTc*Rc) , but the second part should look like Ra * Ta:

cml::matrix_translation(trans,xPos, T(0), zPos); // <= no wrong direction
[/CODE] Edited by Ashaman73

Share this post


Link to post
Share on other sites
[b] [url="http://www.gamedev.net/user/112074-ashaman73/"]Ashaman73[/url] Not sure I am following your code example, I think you are assuming I have a clue where final is... I assume it's a matrix4x4 and [/b]

Tc = camera translation (radius), iTc = inverse(Tc) =-radius

how can I assign a radius to a matrix4x4? I never seen this syntax before...

Thanks!

Share this post


Link to post
Share on other sites
[quote name='MARS_999' timestamp='1336138682' post='4937370']
how can I assign a radius to a matrix4x4? I never seen this syntax before..
[/quote]
You already did :-)
cml::matrix_translation(trans, T(0), T(0), -radius);
I think, that this call creates a 4x4 translation matrix from the vector (0,0,-radius), in the same way that this call
cml::matrix_rotation_world_axis(rot, 1, cml::rad(yRot))
creates a rotation matrix.

Sorry if I confuse you [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] Edited by Ashaman73

Share this post


Link to post
Share on other sites

This topic is 2053 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this