Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 22 Aug 2001
Offline Last Active Yesterday, 09:37 PM

Posts I've Made

In Topic: MSVC incorrectly matching overload's.

25 June 2014 - 10:03 PM

No need to make all of them explicit, though as a rule of thumb, I'd always make any constructor explicit that takes exactly one parameter, unless I want it to be used behind my back for implicit casts (one has to wonder why explicit isn't the default and implicit is the optional keyword).

In Topic: OpenGL Camera Concept

18 June 2014 - 10:24 PM

Hehe yeah oké smile.png thanks for clarifying. I'll make sure to add some extra statements nevertheless since it's a good insight that an FPS camera is not an all-round camera system with eular angles.


Well, I guess it would work for third person as well. Pretty much any situation where your side to side rotation is always around the global y-axis should be safe and the look-at approach is fine if the rotation around x never goes to or beyond +/-90°.


Btw. there is one downside to storing the orientation as a matrix (or quaternion): floats suck. After a bunch of rotations, the vectors that should be will be no longer normalized and in the case of a matrix, the rotation part will be no long orthogonal on top of it. So every once in a while, the matrix will need to be re-orthonormalized (basically 2 cross products and 3 normalizations. With a quat, that should be only a single normalization.


While this sounds like a great advantage:

-it only needs to be done every once in a while.

-even if done once per frame, it's nothing compared to all the other things going on

-unless your pipeline can natively use quats, you'll still have to convert them to a matrix every frame (so you don't really win anything)

-if you need info from the camera (like view direction for bill boarding), simply reading the 3rd column of the matrix is easier than having to calculate it by transforming 0,0,1 by your stored quat

In Topic: OpenGL Camera Concept

18 June 2014 - 12:46 PM

Hey Trienco,
You're right and make a good point about the tutorials only explaining the concept of a first person camera. I probably should have made it more clear in my post that this explains a first person camera only. I'll be sure to add an extra section to the camera tutorial later explaining its limitations to make things more clear, thanks.

Nah, your tutorial clearly states it's for an FPS style camera (one of the rare cases where even Euler Angles are just fine,  since you'll always rotate in a fixed order). I just pointed out the limitations since the OP didn't specify any particular requirements and I wanted to prevent the usual cycle of using Euler angles -> gimbal lock -> "quaternions are the only way" -> thread asking for help with quaternions -> never realizing that quaternions aren't magic and can't do anything matrices can as well -> continuing the cycle of preaching about how quaternions are the only way to do proper rotations.

In Topic: OpenGL Camera Concept

17 June 2014 - 10:15 PM

With the above tutorial I highly suggest to stop reading at (or skipping) the chapter Euler Angles, unless first person is all you need. Mostly because otherwise it might be 1-2 weeks before a "I have gimbal lock and/or my camera rotation is acting funny"-thread. Also, the assumption that 0,1,0 is always a working approximation for "up" will fail if your camera can be upside down (flight simulator, space game, fancy camera movement in cutscenes).
The easiest way is to store a regular transformation matrix for your camera, treat it like any other object and invert it to get your view matrix:
//Quick inverse (transpose rotation part, multiply translation with transposed rotation)
Matrix Camera::getViewMatrix() 
    return Matrix(
        transformation[0], transformation[4], transformation[8], 0,
        transformation[1], transformation[5], transformation[9], 0,
        transformation[2], transformation[6], transformation[10], 0,
        -(transformation[0]*transformation[12] + transformation[1]*transformation[13] + transformation[2]*transformation[14]),
        -(transformation[4]*transformation[12] + transformation[5]*transformation[13] + transformation[6]*transformation[14]), 
        -(transformation[8]*transformation[12] + transformation[9]*transformation[13] + transformation[10]*transformation[14]), 1);
//Going the matrix route for translation is a bit overkill, but better demonstrates the difference between moving along local or global axes
void Camera::move(float x, float y, float z, bool global, float distance) 
    Matrix translation = Matrix::createTranslation(x,y,z);
    if (global)
        transformation = transformation * translation;
        transformation = translation * transformation;
void Camera::rotate(float deg, float x, float y, float z, bool global)
    Matrix rotation = Matrix::rotationFromAxisAngle(deg, x,y,z);
    if (global) 
        transformation = transformation * rotation;
        transformation = rotation * transformation;

Edit: well, thank the forum gods for deleting everything after the code block when editing.

If whatever matrix library doesn't let you access by index (or has a different memory layout):
0-3: x-axis aka "camera right" (x,y,z,0)
4-7: y-axis aka "camera up" (x,y,z,0)
8-11: z-axis aka "camera forward" (x,y,z,0) (might be backward, depending on handed-ness)
12-15: origin aka "camera position" (x,y,z,1)

If you need zoom, this goes into the projection matrix (simply reduce the fov). Zooming is NOT scaling and NOT "moving closer" (or any other weird thing that causes clipping errors when zooming "too much").

In Topic: Checking if a bit is set in a byte

12 June 2014 - 10:23 PM

Interestingly enough, most people I know who deal with bit fiddling on a daily base don't even really care about binary literals. Using hex numbers is second nature by now and how many people are really going to specify anything beyond 8 bits in a ridiculously long binary representation? In fact, if there are any literals that REALLY need a separator, it's binary ones (it can't get any longer and harder to read than that). I didn't even know those exist and never really missed or needed them, but the first thing about binary literals was "please let me group them, so I won't have to painfully count if it's bit 29 or 30".