From 00f9f334acf035b06ca4381b1af3f3b75af5826a Mon Sep 17 00:00:00 2001 From: divverent Date: Thu, 9 Sep 2010 06:54:58 +0000 Subject: [PATCH] sound occlusion: use PVS by default, make the cvar able to toggle between PVS and LineOfSight occlusion git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10449 d7cf8633-e32d-0410-b094-e92efae38249 --- snd_main.c | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/snd_main.c b/snd_main.c index 52dde53f..b9fe6602 100644 --- a/snd_main.c +++ b/snd_main.c @@ -134,6 +134,8 @@ qboolean snd_threaded = false; qboolean snd_usethreadedmixing = false; vec3_t listener_origin; +static unsigned char *listener_pvs = NULL; +static int listener_pvsbytes = 0; matrix4x4_t listener_matrix[SND_LISTENERS]; mempool_t *snd_mempool; @@ -168,7 +170,7 @@ cvar_t snd_spatialization_min = {CVAR_SAVE, "snd_spatialization_min", "0.70", "m cvar_t snd_spatialization_max = {CVAR_SAVE, "snd_spatialization_max", "0.95", "maximum spatialization of sounds"}; cvar_t snd_spatialization_power = {CVAR_SAVE, "snd_spatialization_power", "0", "exponent of the spatialization falloff curve (0: logarithmic)"}; cvar_t snd_spatialization_control = {CVAR_SAVE, "snd_spatialization_control", "0", "enable spatialization control (headphone friendly mode)"}; -cvar_t snd_spatialization_occlusion = {CVAR_SAVE, "snd_spatialization_occlusion", "1", "enable occlusion testing on spatialized sounds, which simply quiets sounds that are blocked by the world"}; +cvar_t snd_spatialization_occlusion = {CVAR_SAVE, "snd_spatialization_occlusion", "1", "enable occlusion testing on spatialized sounds, which simply quiets sounds that are blocked by the world; 1 enables PVS method, 2 enables LineOfSight method, 3 enables both"}; // Cvars declared in snd_main.h (shared with other snd_*.c files) cvar_t _snd_mixahead = {CVAR_SAVE, "_snd_mixahead", "0.15", "how much sound to mix ahead of time"}; @@ -1406,12 +1408,25 @@ void SND_Spatialize(channel_t *ch, qboolean isstatic) if (snd_spatialization_occlusion.integer) { - if (cl.worldmodel - && cl.worldmodel->brush.TraceLineOfSight - && !cl.worldmodel->brush.TraceLineOfSight(cl.worldmodel, listener_origin, ch->origin)) + qboolean occluded = false; + + if(snd_spatialization_occlusion.integer & 1) + if(listener_pvs) { - vol *= 0.5f; + int cluster = cl.worldmodel->brush.PointInLeaf(cl.worldmodel, ch->origin)->clusterindex; + if(cluster >= 0 && cluster < 8 * listener_pvsbytes && !CHECKPVSBIT(listener_pvs, cluster)) + occluded = true; + } + + if(snd_spatialization_occlusion.integer & 2) + if(!occluded) + if(cl.worldmodel && cl.worldmodel->brush.TraceLineOfSight && !cl.worldmodel->brush.TraceLineOfSight(cl.worldmodel, listener_origin, ch->origin)) + { + occluded = true; } + + if(occluded) + vol *= 0.5f; } ch->listener_volume[i] = (int)bound(0, vol, 255); @@ -1995,6 +2010,26 @@ void S_Update(const matrix4x4_t *listenermatrix) Matrix4x4_Invert_Simple(&basematrix, listenermatrix); Matrix4x4_OriginFromMatrix(listenermatrix, listener_origin); + if (cl.worldmodel && cl.worldmodel->brush.FatPVS && cl.worldmodel->brush.num_pvsclusterbytes && cl.worldmodel->brush.PointInLeaf) + { + if(cl.worldmodel->brush.num_pvsclusterbytes != listener_pvsbytes) + { + if(listener_pvs) + Mem_Free(listener_pvs); + listener_pvsbytes = cl.worldmodel->brush.num_pvsclusterbytes; + listener_pvs = Mem_Alloc(snd_mempool, listener_pvsbytes); + } + cl.worldmodel->brush.FatPVS(cl.worldmodel, listener_origin, 2, listener_pvs, listener_pvsbytes, 0); + } + else + { + if(listener_pvs) + { + Mem_Free(listener_pvs); + listener_pvs = NULL; + } + listener_pvsbytes = 0; + } // calculate the current matrices for (j = 0;j < SND_LISTENERS;j++) -- 2.39.2