Skip to content

Instantly share code, notes, and snippets.

@gszauer
Last active October 8, 2019 22:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gszauer/c12f5fc0faeb5f21062399d965c8ace0 to your computer and use it in GitHub Desktop.
Save gszauer/c12f5fc0faeb5f21062399d965c8ace0 to your computer and use it in GitHub Desktop.
OrbitCamera
// https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
float getRoll(const quat& q) {
// roll (x-axis rotation)
float sinr_cosp = 2.0f * (q.w * q.x + q.y * q.z);
float cosr_cosp = 1.0f - 2.0f * (q.x * q.x + q.y * q.y);
return atan2(sinr_cosp, cosr_cosp);
}
float getPitch(const quat& q) {
// pitch (y-axis rotation)
float sinp =+ 2.0f * (q.w * q.y - q.z * q.x);
if (fabs(sinp) >= 1) {
return copysign(3.14159265359f / 2.0f, sinp); // use 90 degrees if out of range
}
return asin(sinp);
}
float getYaw(const quat& q) {
// yaw (z-axis rotation)
float siny_cosp = +2.0 * (q.w * q.z + q.x * q.y);
float cosy_cosp = +1.0 - 2.0 * (q.y * q.y + q.z * q.z);
return atan2(siny_cosp, cosy_cosp);
}
struct SceneCamera {
vec3 position;
float yaw;
float pitch;
float panSpeed;
float zoomSpeed;
float rotateSpeed;
};
SceneCamera SceneCameraInit(const vec3& position, const vec3& target) {
SceneCamera result;
result.position = position;
quat rotation = lookRotation(target - position, vec3(0, 1, 0));
camera.yaw = getYaw(rotation) * QUAT_RAD2DEG;
camera.pitch = getPitch(rotation) * QUAT_RAD2DEG;
result.panSpeed = 1.0f;
result.zoomSpeed = 1.0f;
result.rotateSpeed = 1.0f;
return result;
}
void SceneCameraPan(Camera& camera, const vec2& normalizedMouseDelta) {
quat yRot = angleAxis(yaw * QUAT_DEG2RAD, vec3(0, 1, 0));
quat xRot = angleAxis(pitch * QUAT_DEG2RAD, vec3(1, 0, 0));
quat rotation = yRot * xRot;
vec3 delta = vec3(normalizedMouse.x, -normalizedMouse.y, 0.0f);
delta = rotation * delta;
camera.position += delta * camera.panSpeed;
}
void SceneCameraZoom(Camera& camera, float direction) {
quat yRot = angleAxis(yaw * QUAT_DEG2RAD, vec3(0, 1, 0));
quat xRot = angleAxis(pitch * QUAT_DEG2RAD, vec3(1, 0, 0));
quat rotation = yRot * xRot;
vec3 forward = rotation * vec3(0, 0, 1);
camera.position += forward * camera.zoomSpeed * direction;
}
void SceneCameraRotate(Camera& camera, const vec2& normalizedMouse) {
camera.yaw += normalizedMouse.x * rotateSpeed;
camera.pitch += normalizedMouse.y * rotateSpeed;
while (yaw > 360.0f) { yaw -= 360.0f; }
while (yaw < 0.0f) { yaw += 360.0f; }
while (pitch > 360.0f) { pitch -= 360.0f; }
while (pitch < 0.0f) { pitch += 360.0f }
}
mat4 SceneCameraGetLookAtMatrix(const Camera& camera) {
quat yRot = angleAxis(yaw * QUAT_DEG2RAD, vec3(0, 1, 0));
quat xRot = angleAxis(pitch * QUAT_DEG2RAD, vec3(1, 0, 0));
quat rotation = yRot * xRot;
vec3 forward = rotation * vec3(0, 0, 1);
vec3 up = rotation * vec3(0, 1, 0);
return lookAt(position, position + forward, up);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment