diff --git a/src/audio/audio.c b/src/audio/audio.c index eb2e80cd..786762bb 100644 --- a/src/audio/audio.c +++ b/src/audio/audio.c @@ -1,5 +1,7 @@ #include "audio/audio.h" #include "loaders/source.h" +#include "math/vec3.h" +#include "math/quat.h" #include "util.h" #include #include @@ -8,12 +10,6 @@ static AudioState state; static LPALCRESETDEVICESOFT alcResetDeviceSOFT; -static void cross(float ux, float uy, float uz, float vx, float vy, float vz, float* x, float* y, float* z) { - *x = uy * vz - uz * vy; - *y = ux * vz - uz * vx; - *z = ux * vy - uy * vx; -} - void lovrAudioInit() { ALCdevice* device = alcOpenDevice(NULL); if (!device) { @@ -35,6 +31,9 @@ void lovrAudioInit() { state.device = device; state.context = context; vec_init(&state.sources); + + vec3_set(state.position, 0, 0, 0); + quat_set(state.orientation, 0, 0, 0, -1); } void lovrAudioDestroy() { @@ -73,29 +72,7 @@ void lovrAudioAdd(Source* source) { } void lovrAudioGetOrientation(float* angle, float* ax, float* ay, float* az) { - float v[6]; - alGetListenerfv(AL_ORIENTATION, v); - float cx, cy, cz; - cross(v[0], v[1], v[2], v[3], v[4], v[5], &cx, &cy, &cz); - float w = 1 + v[0] * v[3] + v[1] * v[4] + v[2] * v[5]; - float len = sqrt(cx * cx + cy * cy + cz * cz + w * w); - if (len != 1) { - cx /= len; - cy /= len; - cz /= len; - w /= len; - } - *angle = 2 * acos(w); - float s = sqrt(1 - w * w); - if (s < .001) { - *ax = cx; - *ay = cy; - *az = cz; - } else { - *ax = cx / s; - *ay = cy / s; - *az = cz / s; - } + quat_getAngleAxis(state.orientation, angle, ax, ay, az); } void lovrAudioGetPosition(float* x, float* y, float* z) { @@ -135,52 +112,23 @@ void lovrAudioRewind() { } } -// Help void lovrAudioSetOrientation(float angle, float ax, float ay, float az) { - // Quaternion - float cos2 = cos(angle / 2.f); - float sin2 = sin(angle / 2.f); - float qx = sin2 * ax; - float qy = sin2 * ay; - float qz = sin2 * az; - float s = cos2; + // Rotate the unit forward/up vectors by the quaternion derived from the specified angle/axis + float f[3] = { 0, 0, -1 }; + float u[3] = { 0, 1, 0 }; + float axis[3] = { ax, ay, az }; + quat_fromAngleAxis(state.orientation, angle, axis); + vec3_rotate(f, state.orientation); + vec3_rotate(u, state.orientation); - float vx, vy, vz, qdotv, qdotq, a, b, c, cx, cy, cz; - - // Forward - vx = 0; - vy = 0; - vz = -1; - qdotv = qx * vx + qy * vy + qz * vz; - qdotq = qx * qx + qy * qy + qz * qz; - a = 2 * qdotv; - b = s * s - qdotq; - c = 2 * s; - cross(qx, qy, qz, vx, vy, vz, &cx, &cy, &cz); - float fx = a * qx + b * vx + c * cx; - float fy = a * qy + b * vy + c * cy; - float fz = a * qz + b * vz + c * cz; - - // Up - vx = 0; - vy = 1; - vz = 0; - qdotv = qx * vx + qy * vy + qz * vz; - qdotq = qx * qx + qy * qy + qz * qz; - a = 2 * qdotv; - b = s * s - qdotq; - c = 2 * s; - cross(qx, qy, qz, vx, vy, vz, &cx, &cy, &cz); - float ux = a * qx + b * vx + c * cx; - float uy = a * qy + b * vy + c * cy; - float uz = a * qz + b * vz + c * cz; - - ALfloat orientation[6] = { fx, fy, fz, ux, uy, uz }; + // Pass the rotated orientation vectors to OpenAL + ALfloat orientation[6] = { f[0], f[1], f[2], u[0], u[1], u[2] }; alListenerfv(AL_ORIENTATION, orientation); } void lovrAudioSetPosition(float x, float y, float z) { + vec3_set(state.position, x, y, z); alListener3f(AL_POSITION, x, y, z); } diff --git a/src/audio/audio.h b/src/audio/audio.h index d7a43b9b..9b98dc7d 100644 --- a/src/audio/audio.h +++ b/src/audio/audio.h @@ -11,6 +11,8 @@ typedef struct { ALCdevice* device; ALCcontext* context; vec_void_t sources; + float position[3]; + float orientation[4]; } AudioState; #endif diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index 6cb32836..5aebae8e 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -415,16 +415,13 @@ void lovrGraphicsTriangle(DrawMode mode, float* points) { vec_pusharr(&state.shapeData, points, 9); lovrGraphicsDrawPrimitive(GL_LINE_LOOP, NULL, 0, 0, 0); } else { - float n[3] = { - points[1] * points[5] - points[2] * points[4], - points[2] * points[3] - points[0] * points[5], - points[0] * points[4] - points[1] * points[3] - }; + float normal[3]; + vec3_cross(vec3_init(normal, &points[0]), &points[3]); float data[18] = { - points[0], points[1], points[2], n[0], n[1], n[2], - points[3], points[4], points[5], n[0], n[1], n[2], - points[6], points[7], points[8], n[0], n[1], n[2] + points[0], points[1], points[2], normal[0], normal[1], normal[2], + points[3], points[4], points[5], normal[0], normal[1], normal[2], + points[6], points[7], points[8], normal[0], normal[1], normal[2] }; vec_clear(&state.shapeData); @@ -437,7 +434,7 @@ void lovrGraphicsPlane(DrawMode mode, Texture* texture, float x, float y, float // Normalize the normal vector float len = sqrt(nx * nx + ny * ny + nz + nz); - if (len != 1) { + if (len != 0) { len = 1 / len; nx *= len; ny *= len;