3D velocity and acceleration can be represented as 3D vectors. And you should use that instead of handling each case separately. As we know, position vector changes by velocity vector times some delta time. So does the Velocity by acceleration. AKA
dv = a*dt; dPos = dv * dt. What you want to do would be
// assume [wasd] is your controller, and [wasd]Pressed() return 1 if key is pressed and 0 otherwise
Vec3 forward = Camera.forward()
Vec3 right = Camera.right();
acceleration = (forward - forward.y) * (wPressed()-sPressed()) + Camera.right() * (dPressed - aPressed()); // here we build direction of acceleration
velocity += normalize(acceleration)*accel *dt;
position += velocity * dt;
You have to take into account that constructing velocity/accelration from separate axes will give faster movement/acceleration while moving diagonally, so you always want to normalize the vector and multiply by magnitude. This solution also takes into consideration situations when multiple keys are pressed at once (left+right would result in no sideways movement).
This solution assumes that gravity and ground is down (0,-1,0). Otherwise you have to simply subtract from the forward vector the vector that is projected onto the normal to the ground.
But this sounds like you lack the physics engine that manages gravity and collisions... ?
@EDIT by question's author
Anyways, this form can be rewritten to match your second example as follows:
auto const f = get_facing();
auto const a = get_acceleration();
auto const abs_a = a.x * get_right()
+ a.y * get_up()
- a.z * glm::vec3(f.x, 0.0f, f.z);
^ That's not true. First of all - you messed up
z components. Second - what do
get_acceleration/facing/right/up return? Naming of those functions is obscure and I don't understand what they return. You have to name your functions so that they names describe best their functionality, and don't be afraid of longer names like
Also don't be afraid of commenting your code. If you have
forward-forwad.y you, of course CAN replace it by
glm::vec3(forward.x, 0, forward.y), but... it's longer... and harder to modify in the future... Just put a comment in code that
//zero UP acceleration to disable flying
If your UP vector is not (0,1,0) then you have to reinvent the logic.
forward - proj(forward, UP) would be enough for my solution. I insist that you try my solution, because it is extendable if you want to, for example, have different speeds for walking forward, backward or strafing. You would just do
acceleration = normalize((forward - forward.y)) * (wPressed()*wSpeed()-sPressed()*sSpeed()) + normalize(Camera.right()) * (dPressed*dSpeed() - aPressed()*aSpeed()); // here we build direction of acceleration
velocity += acceleration *dt;
position += velocity * dt;
Don't forget about normalizing vectors to have uniform behavior when looking at horizon and looking up.