From 97152d066cee622aa2efa7e4fecb24b75dd44e56 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Fri, 30 Jan 2026 23:07:23 +0900 Subject: [PATCH] 3d audio --- engine/data/shader/shadow.fs | 1 + engine/include/GearSrc/Math.h | 1 + engine/include/GearSrc/TypeDefs.h | 6 +++++- engine/src/client.c | 6 +++--- engine/src/gl/gl_camera.c | 2 +- engine/src/math.c | 8 +++++++- engine/src/model.c | 8 ++++---- engine/src/sound/sound.c | 6 ++++++ engine/src/sound/soundengine.c | 30 ++++++++++++++++++++++++++++-- 9 files changed, 56 insertions(+), 12 deletions(-) diff --git a/engine/data/shader/shadow.fs b/engine/data/shader/shadow.fs index c93f836..83400b2 100644 --- a/engine/data/shader/shadow.fs +++ b/engine/data/shader/shadow.fs @@ -73,4 +73,5 @@ void main(void){ } gl_FragColor = ambient * shadow_coef * c + (1.0 - ambient) * c; + gl_FragColor.a = vColor.a; } diff --git a/engine/include/GearSrc/Math.h b/engine/include/GearSrc/Math.h index c0f8d97..9464a0c 100644 --- a/engine/include/GearSrc/Math.h +++ b/engine/include/GearSrc/Math.h @@ -23,6 +23,7 @@ GSDECL void GSMathRowToColumn3x3(GSMatrix3x3 out, GSMatrix3x3 in); GSDECL void GSMath3x3To4x4(GSMatrix4x4 out, GSMatrix3x3 in); GSDECL GSNumber GSMathCot(GSNumber x); GSDECL GSNumber GSMathClosestPOT(GSNumber x); +GSDECL GSNumber GSMathLength3(GSVector3 vec); #define GSMathColumnToRow4x4 GSMathRowToColumn4x4 #define GSMathColumnToRow3x3 GSMathRowToColumn3x3 diff --git a/engine/include/GearSrc/TypeDefs.h b/engine/include/GearSrc/TypeDefs.h index 17ee0b1..f054227 100644 --- a/engine/include/GearSrc/TypeDefs.h +++ b/engine/include/GearSrc/TypeDefs.h @@ -260,6 +260,10 @@ struct _GSSound { GSSoundResetCallback reset; GSSoundReadCallback read; GSSoundCloseCallback close; + + GSVector3 position; + GSBool is_3d; + GSNumber volume; }; struct _GSSoundDriver { @@ -324,7 +328,7 @@ struct _GSClient { int glyph_bold_height; GSVector3 look_at; - GSVector3 camera; + GSVector3 position; GSVector4 light0; GSSkyBox skybox; GSBool skybox_enabled; diff --git a/engine/src/client.c b/engine/src/client.c index 2002207..7504b7f 100644 --- a/engine/src/client.c +++ b/engine/src/client.c @@ -36,9 +36,9 @@ GSClient GSClientCreate(GSEngine engine) { client->engine = engine; - client->camera[0] = 0; - client->camera[1] = 1.5; - client->camera[2] = 5; + client->position[0] = 0; + client->position[1] = 1.5; + client->position[2] = 5; client->look_at[0] = 0; client->look_at[1] = 1; diff --git a/engine/src/gl/gl_camera.c b/engine/src/gl/gl_camera.c index a0b2e23..26a9124 100644 --- a/engine/src/gl/gl_camera.c +++ b/engine/src/gl/gl_camera.c @@ -25,7 +25,7 @@ void GSGLCameraPerspective(GSGL gl, GSNumber width, GSNumber height) { } void GSGLCameraSet(GSGL gl) { - GSGLCameraLookAt(gl, gl->engine->client->camera, gl->engine->client->look_at); + GSGLCameraLookAt(gl, gl->engine->client->position, gl->engine->client->look_at); } void GSGLCameraLookAt(GSGL gl, GSVector3 camera, GSVector3 look_at) { diff --git a/engine/src/math.c b/engine/src/math.c index a45621c..74c33a7 100644 --- a/engine/src/math.c +++ b/engine/src/math.c @@ -15,7 +15,7 @@ GSNumber GSMathInner3(GSVector3 v0, GSVector3 v1) { return r; } -void GSMathNormalize3(GSVector3 vec) { +GSNumber GSMathLength3(GSVector3 vec) { GSNumber l = 0; int i; @@ -23,6 +23,12 @@ void GSMathNormalize3(GSVector3 vec) { l = sqrt(l); + return l; +} + +void GSMathNormalize3(GSVector3 vec) { + GSNumber l = GSMathLength3(vec); + if(l > 0) { l = (GSNumber)1 / l; } else { diff --git a/engine/src/model.c b/engine/src/model.c index 04f89a8..127429a 100644 --- a/engine/src/model.c +++ b/engine/src/model.c @@ -48,8 +48,8 @@ static void parse_obj(GSModel model, char* txt) { if(dm > v1) dm = v1; if(um < v1) um = v1; - if(bm > v2) bm = v2; - if(fm < v2) fm = v2; + if(fm > v2) fm = v2; + if(bm < v2) bm = v2; arrput(model->vertex, v0); arrput(model->vertex, v1); @@ -71,7 +71,7 @@ static void parse_obj(GSModel model, char* txt) { float sc = 0; float lr = fabs(lm - rm); float ud = fabs(um - dm); - float bf = fabs(bm - fm); + float bf = fabs(fm - bm); if(sc < lr) sc = lr; if(sc < ud) sc = ud; @@ -137,7 +137,7 @@ static void parse_obj(GSModel model, char* txt) { if(arrlen(model->vertex) > varr[i] * 3) { face.vertex[i][0] = (model->vertex[varr[i] * 3 + 0] - lm - lr / 2) / sc; face.vertex[i][1] = (model->vertex[varr[i] * 3 + 1] - dm - ud / 2) / sc; - face.vertex[i][2] = -(model->vertex[varr[i] * 3 + 2] - bm - bf / 2) / sc; + face.vertex[i][2] = -(model->vertex[varr[i] * 3 + 2] - fm - bf / 2) / sc; } if(arrlen(model->texcoord) > tarr[i] * 2) { diff --git a/engine/src/sound/sound.c b/engine/src/sound/sound.c index 51ba1d1..4858677 100644 --- a/engine/src/sound/sound.c +++ b/engine/src/sound/sound.c @@ -22,6 +22,12 @@ GSSound GSSoundNew(GSSoundEngine sengine) { sound->from_samplerate = 0; sound->from_channel = 2; + sound->is_3d = 0; + sound->position[0] = 0; + sound->position[1] = 0; + sound->position[2] = 0; + sound->volume = 1.0; + ma_mutex_init(&sound->mutex); GSSoundEngineLock(sengine); diff --git a/engine/src/sound/soundengine.c b/engine/src/sound/soundengine.c index ae945f8..65391fa 100644 --- a/engine/src/sound/soundengine.c +++ b/engine/src/sound/soundengine.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,29 @@ static void read_callback(void* opaque, GSI16* out, int frame) { memset(result, 0, sizeof(*result) * f * sengine->sound[i]->from_channel); s = sengine->sound[i]->read(sengine->sound[i], result, f); if(s > 0) { - int j; + int j; + GSNumber la = 1, ra = 1; + + if(sengine->sound[i]->is_3d) { + GSNumber angle; + GSNumber v; + GSNumber d; + GSVector3 r; + GSNumber lf, rf; + + GSMathSubtract3(r, sengine->sound[i]->position, sengine->engine->client->position); + + angle = atan2(r[2], r[0]); + v = cos(angle); + + lf = 1.0 - v; + rf = 1.0 + v; + + d = GSMathLength3(r) / 4; + + la = 1.0 / (1.0 + lf + d * d); + ra = 1.0 / (1.0 + rf + d * d); + } if(sengine->sound[i]->from_samplerate > 0) { ma_uint64 fin = f; @@ -62,7 +85,10 @@ static void read_callback(void* opaque, GSI16* out, int frame) { ma_channel_converter_process_pcm_frames(&sengine->sound[i]->converter, result3, result2, frame); } - for(j = 0; j < s * 2; j++) buffer[j] += (GSNumber)result3[j] / 32767; + for(j = 0; j < s * 2; j += 2) { + buffer[j + 0] += (GSNumber)result3[j + 0] / 32767 * la * sengine->sound[i]->volume; + buffer[j + 1] += (GSNumber)result3[j + 1] / 32767 * ra * sengine->sound[i]->volume; + } if(result3 != result2) free(result3); if(result2 != result) free(result2);