Paranoia2/utils/p2vis/soundpvs.cpp
2020-08-31 19:50:41 +03:00

161 lines
3.1 KiB
C++

/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "qvis.h"
#include "threads.h"
/*
Some textures (sky, water, slime, lava) are considered ambient sound emiters.
Find an aproximate distance to the nearest emiter of each class for each leaf.
*/
/*
====================
SurfaceBBox
====================
*/
void SurfaceBBox( dface_t *s, vec3_t mins, vec3_t maxs )
{
int e, vi;
vec3_t v;
ClearBounds( mins, maxs );
for( int i = 0; i < s->numedges; i++ )
{
e = g_dsurfedges[s->firstedge + i];
if( e >= 0 ) vi = g_dedges[e].v[0];
else vi = g_dedges[-e].v[1];
VectorCopy( g_dvertexes[vi].point, v );
AddPointToBounds( v, mins, maxs );
}
}
/*
====================
CalcAmbientSounds
====================
*/
static void CalcAmbientSounds( int leafnum, int threadnum = -1 )
{
int j, k, l;
int ambient_type;
dleaf_t *leaf, *hit;
byte vis[(MAX_MAP_LEAFS + 7) / 8];
vec_t dists[NUM_AMBIENTS];
vec_t d, maxd, vol;
vec3_t mins, maxs;
dface_t *surf;
leaf = &g_dleafs[leafnum+1];
// clear ambients
for( j = 0; j < NUM_AMBIENTS; j++ )
dists[j] = BOGUS_RANGE;
DecompressVis( &g_dvisdata[leaf->visofs], vis );
for( j = 0; j < g_numvisleafs; j++ )
{
if( !CHECKVISBIT( vis, j ))
continue;
// check this leaf for sound textures
hit = &g_dleafs[j+1];
for( k = 0; k < hit->nummarksurfaces; k++ )
{
surf = &g_dfaces[g_dmarksurfaces[hit->firstmarksurface + k]];
const char *texname = GetTextureByTexinfo( surf->texinfo );
if( !Q_strnicmp( texname, "sky", 3 ))
{
ambient_type = AMBIENT_SKY;
}
else if( texname[0] == '!' )
{
if( !Q_strnicmp( texname, "!water", 6 ))
{
ambient_type = AMBIENT_WATER;
}
else if( !Q_strnicmp( texname, "!04water", 8 ))
{
ambient_type = AMBIENT_WATER;
}
else if( !Q_strnicmp( texname, "!slime", 6 ))
{
ambient_type = AMBIENT_SLIME;
}
else if( !Q_strnicmp( texname, "!lava", 6 ))
{
ambient_type = AMBIENT_LAVA;
}
else
{
continue;
}
}
else
{
continue;
}
// find distance from source leaf to polygon
SurfaceBBox( surf, mins, maxs );
maxd = 0;
for( l = 0; l < 3; l++ )
{
if( mins[l] > leaf->maxs[l] )
d = mins[l] - leaf->maxs[l];
else if( maxs[l] < leaf->mins[l] )
d = leaf->mins[l] - mins[l];
else d = 0;
maxd = Q_max( d, maxd );
}
dists[ambient_type] = Q_min( maxd, dists[ambient_type] );
}
}
for( j = 0; j < NUM_AMBIENTS; j++ )
{
// remap to quake range
dists[j] = RemapVal( dists[j], 0.0, 65536.0, 0.0f, 512.0f );
if( dists[j] < 100 )
{
vol = 1.0;
}
else
{
vol = 1.0 - dists[j] * 0.002;
vol = bound( 0.0, vol, 1.0 );
}
leaf->ambient_level[j] = vol * 255;
}
}
/*
====================
CalcAmbientSounds
====================
*/
void CalcAmbientSounds( void )
{
MsgDev( D_REPORT, "---- Calc Ambient Sounds ----\n" );
RunThreadsOnIndividual( g_numvisleafs, true, CalcAmbientSounds );
}