The camera is finally working correctly after the change to column-major, fixing a few degree-to-radian conversions that were missed, and now translation acts in local space (later I'll separate it to local and world space to allow for easier camera positioning). Still need to fix lookAt and mess around with the controls, but overall it seems to work fairly well for now.