ioquake3 resync to revision 3522 from 3511.

Fix axis returned by IQM's LerpTag
Calculate bounds for unanimated IQM models
Fix loading favorites as initial source in server browser
Improve finding obelisk entitynum for bot AI
Fix SDL audio playback with surround sound
Fix predicting entity origin on rotating mover
Allow binds to use hex values for all key codes
Disable pulseaudio capture regardless of SDL version
Fix SDL audio playback with 16-bit stereo sound
Make s_info command display channels instead of stereo
Fix cross-compiling using mingw-w64 on Ubuntu 18.04
This commit is contained in:
zturtleman 2018-10-16 17:48:51 +00:00
parent d0f6099cc1
commit 6bc3b33eab
11 changed files with 251 additions and 160 deletions

View file

@ -44,7 +44,7 @@ ifndef BUILD_DEFINES
endif
# ioquake3 svn version that this is based on
IOQ3_REVISION = 3444
IOQ3_REVISION = 3522
#############################################################################
#
@ -292,7 +292,17 @@ bin_path=$(shell which $(1) 2> /dev/null)
# set PKG_CONFIG_PATH or PKG_CONFIG to influence this, e.g.
# PKG_CONFIG_PATH=/opt/cross/i386-mingw32msvc/lib/pkgconfig or
# PKG_CONFIG=arm-linux-gnueabihf-pkg-config
ifeq ($(CROSS_COMPILING),0)
PKG_CONFIG ?= pkg-config
else
ifneq ($(PKG_CONFIG_PATH),)
PKG_CONFIG ?= pkg-config
else
# Don't use host pkg-config when cross-compiling.
# (unknown-pkg-config is meant to be a non-existant command.)
PKG_CONFIG ?= unknown-pkg-config
endif
endif
ifneq ($(call bin_path, $(PKG_CONFIG)),)
CURL_CFLAGS ?= $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl)
@ -1394,6 +1404,7 @@ endif
@echo " COMPILE_PLATFORM: $(COMPILE_PLATFORM)"
@echo " COMPILE_ARCH: $(COMPILE_ARCH)"
@echo " HAVE_VM_COMPILED: $(HAVE_VM_COMPILED)"
@echo " PKG_CONFIG: $(PKG_CONFIG)"
@echo " CC: $(CC)"
ifeq ($(PLATFORM),mingw32)
@echo " WINDRES: $(WINDRES)"

View file

@ -844,6 +844,44 @@ static void CG_Portal( centity_t *cent ) {
}
/*
================
CG_CreateRotationMatrix
================
*/
void CG_CreateRotationMatrix(vec3_t angles, vec3_t matrix[3]) {
AngleVectors(angles, matrix[0], matrix[1], matrix[2]);
VectorInverse(matrix[1]);
}
/*
================
CG_TransposeMatrix
================
*/
void CG_TransposeMatrix(vec3_t matrix[3], vec3_t transpose[3]) {
int i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
transpose[i][j] = matrix[j][i];
}
}
}
/*
================
CG_RotatePoint
================
*/
void CG_RotatePoint(vec3_t point, vec3_t matrix[3]) {
vec3_t tvec;
VectorCopy(point, tvec);
point[0] = DotProduct(matrix[0], tvec);
point[1] = DotProduct(matrix[1], tvec);
point[2] = DotProduct(matrix[2], tvec);
}
/*
=========================
CG_AdjustPositionForMover
@ -855,6 +893,8 @@ void CG_AdjustPositionForMover(const vec3_t in, int moverNum, int fromTime, int
centity_t *cent;
vec3_t oldOrigin, origin, deltaOrigin;
vec3_t oldAngles, angles, deltaAngles;
vec3_t matrix[3], transpose[3];
vec3_t org, org2, move2;
if ( moverNum <= 0 || moverNum >= ENTITYNUM_MAX_NORMAL ) {
VectorCopy( in, out );
@ -878,9 +918,17 @@ void CG_AdjustPositionForMover(const vec3_t in, int moverNum, int fromTime, int
VectorSubtract( origin, oldOrigin, deltaOrigin );
VectorSubtract( angles, oldAngles, deltaAngles );
// origin change when on a rotating object
CG_CreateRotationMatrix( deltaAngles, transpose );
CG_TransposeMatrix( transpose, matrix );
VectorSubtract( in, oldOrigin, org );
VectorCopy( org, org2 );
CG_RotatePoint( org2, matrix );
VectorSubtract( org2, org, move2 );
VectorAdd( deltaOrigin, move2, deltaOrigin );
VectorAdd( in, deltaOrigin, out );
VectorAdd( angles_in, deltaAngles, angles_out );
// FIXME: origin change when on a rotating object
}

View file

@ -825,6 +825,7 @@ to be configured even if they don't have defined names.
*/
int Key_StringToKeynum( char *str ) {
keyname_t *kn;
int n;
if ( !str || !str[0] ) {
return -1;
@ -834,13 +835,10 @@ int Key_StringToKeynum( char *str ) {
}
// check for hex code
if ( strlen( str ) == 4 ) {
int n = Com_HexStrToInt( str );
if ( n >= 0 ) {
n = Com_HexStrToInt( str );
if ( n >= 0 && n < MAX_KEYS ) {
return n;
}
}
// scan for a text match
for ( kn=keynames ; kn->name ; kn++ ) {

View file

@ -98,7 +98,7 @@ void S_Base_SoundInfo(void) {
if (!s_soundStarted) {
Com_Printf ("sound system not started\n");
} else {
Com_Printf("%5d stereo\n", dma.channels - 1);
Com_Printf("%5d channels\n", dma.channels);
Com_Printf("%5d samples\n", dma.samples);
Com_Printf("%5d samplebits (%s)\n", dma.samplebits, dma.isfloat ? "float" : "int");
Com_Printf("%5d submission_chunk\n", dma.submission_chunk);
@ -1242,9 +1242,6 @@ void S_GetSoundtime(void)
int samplepos;
static int buffers;
static int oldsamplepos;
int fullsamples;
fullsamples = dma.samples / dma.channels;
if( CL_VideoRecording( ) )
{
@ -1268,13 +1265,13 @@ void S_GetSoundtime(void)
if (s_paintedtime > 0x40000000)
{ // time to chop things off to avoid 32 bit limits
buffers = 0;
s_paintedtime = fullsamples;
s_paintedtime = dma.fullsamples;
S_Base_StopAllSounds ();
}
}
oldsamplepos = samplepos;
s_soundtime = buffers*fullsamples + samplepos/dma.channels;
s_soundtime = buffers*dma.fullsamples + samplepos/dma.channels;
#if 0
// check to make sure that we haven't overshot
@ -1295,7 +1292,6 @@ void S_GetSoundtime(void)
void S_Update_(void) {
unsigned endtime;
int samps;
static float lastTime = 0.0f;
float ma, op;
float thisTime, sane;
@ -1339,9 +1335,8 @@ void S_Update_(void) {
& ~(dma.submission_chunk-1);
// never mix more than the complete buffer
samps = dma.samples >> (dma.channels-1);
if (endtime - s_soundtime > samps)
endtime = s_soundtime + samps;
if (endtime - s_soundtime > dma.fullsamples)
endtime = s_soundtime + dma.fullsamples;

View file

@ -65,6 +65,7 @@ typedef struct sfx_s {
typedef struct {
int channels;
int samples; // mono samples in buffer
int fullsamples; // samples with all channels in buffer (samples divided by channels)
int submission_chunk; // don't mix less than this #
int samplebits;
int isfloat;

View file

@ -119,24 +119,24 @@ void S_TransferStereo16 (unsigned long *pbuf, int endtime)
while (ls_paintedtime < endtime)
{
// handle recirculating buffer issues
lpos = ls_paintedtime & ((dma.samples>>1)-1);
lpos = ls_paintedtime % dma.fullsamples;
snd_out = (short *) pbuf + (lpos<<1);
snd_out = (short *) pbuf + (lpos<<1); // lpos * dma.channels
snd_linear_count = (dma.samples>>1) - lpos;
snd_linear_count = dma.fullsamples - lpos;
if (ls_paintedtime + snd_linear_count > endtime)
snd_linear_count = endtime - ls_paintedtime;
snd_linear_count <<= 1;
snd_linear_count <<= 1; // snd_linear_count *= dma.channels
// write a linear blast of samples
S_WriteLinearBlastStereo16 ();
snd_p += snd_linear_count;
ls_paintedtime += (snd_linear_count>>1);
ls_paintedtime += (snd_linear_count>>1); // snd_linear_count / dma.channels
if( CL_VideoRecording( ) )
CL_WriteAVIAudioFrame( (byte *)snd_out, snd_linear_count << 1 );
CL_WriteAVIAudioFrame( (byte *)snd_out, snd_linear_count << 1 ); // snd_linear_count * (dma.samplebits/8)
}
}
@ -150,18 +150,16 @@ void S_TransferPaintBuffer(int endtime)
{
int out_idx;
int count;
int out_mask;
int *p;
int step;
int val;
int i;
unsigned long *pbuf;
pbuf = (unsigned long *)dma.buffer;
if ( s_testsound->integer ) {
int i;
// write a fixed sine wave
count = (endtime - s_paintedtime);
for (i=0 ; i<count ; i++)
@ -177,53 +175,73 @@ void S_TransferPaintBuffer(int endtime)
{ // general case
p = (int *) paintbuffer;
count = (endtime - s_paintedtime) * dma.channels;
out_mask = dma.samples - 1;
out_idx = s_paintedtime * dma.channels & out_mask;
step = 3 - dma.channels;
out_idx = (s_paintedtime * dma.channels) % dma.samples;
step = 3 - MIN(dma.channels, 2);
if ((dma.isfloat) && (dma.samplebits == 32))
{
float *out = (float *) pbuf;
while (count--)
for (i=0 ; i<count ; i++)
{
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{
val = *p >> 8;
p+= step;
}
if (val > 0x7fff)
val = 0x7fff;
else if (val < -32767) /* clamp to one less than max to make division max out at -1.0f. */
val = -32767;
out[out_idx] = ((float) val) / 32767.0f;
out_idx = (out_idx + 1) & out_mask;
out_idx = (out_idx + 1) % dma.samples;
}
}
else if (dma.samplebits == 16)
{
short *out = (short *) pbuf;
while (count--)
for (i=0 ; i<count ; i++)
{
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{
val = *p >> 8;
p+= step;
}
if (val > 0x7fff)
val = 0x7fff;
else if (val < -32768)
val = -32768;
out[out_idx] = val;
out_idx = (out_idx + 1) & out_mask;
out_idx = (out_idx + 1) % dma.samples;
}
}
else if (dma.samplebits == 8)
{
unsigned char *out = (unsigned char *) pbuf;
while (count--)
for (i=0 ; i<count ; i++)
{
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{
val = *p >> 8;
p+= step;
}
if (val > 0x7fff)
val = 0x7fff;
else if (val < -32768)
val = -32768;
out[out_idx] = (val>>8) + 128;
out_idx = (out_idx + 1) & out_mask;
out_idx = (out_idx + 1) % dma.samples;
}
}
}

View file

@ -5445,7 +5445,33 @@ void BotSetEntityNumForGoal(bot_goal_t *goal, char *classname) {
if ( !ent->inuse ) {
continue;
}
if ( !Q_stricmp(ent->classname, classname) ) {
if ( Q_stricmp(ent->classname, classname) != 0 ) {
continue;
}
VectorSubtract(goal->origin, ent->s.origin, dir);
if (VectorLengthSquared(dir) < Square(10)) {
goal->entitynum = i;
return;
}
}
}
/*
==================
BotSetEntityNumForGoalWithActivator
==================
*/
void BotSetEntityNumForGoalWithActivator(bot_goal_t *goal, char *classname) {
gentity_t *ent;
int i;
vec3_t dir;
ent = &g_entities[0];
for (i = 0; i < level.num_entities; i++, ent++) {
if ( !ent->inuse || !ent->activator ) {
continue;
}
if ( Q_stricmp(ent->activator->classname, classname) != 0 ) {
continue;
}
VectorSubtract(goal->origin, ent->s.origin, dir);
@ -5526,21 +5552,21 @@ void BotSetupDeathmatchAI(void) {
else if (gametype == GT_OBELISK) {
if (trap_BotGetLevelItemGoal(-1, "Red Obelisk", &redobelisk) < 0)
BotAI_Print(PRT_WARNING, "Overload without Red Obelisk\n");
BotSetEntityNumForGoal(&redobelisk, "team_redobelisk");
BotSetEntityNumForGoalWithActivator(&redobelisk, "team_redobelisk");
if (trap_BotGetLevelItemGoal(-1, "Blue Obelisk", &blueobelisk) < 0)
BotAI_Print(PRT_WARNING, "Overload without Blue Obelisk\n");
BotSetEntityNumForGoal(&blueobelisk, "team_blueobelisk");
BotSetEntityNumForGoalWithActivator(&blueobelisk, "team_blueobelisk");
}
else if (gametype == GT_HARVESTER) {
if (trap_BotGetLevelItemGoal(-1, "Red Obelisk", &redobelisk) < 0)
BotAI_Print(PRT_WARNING, "Harvester without Red Obelisk\n");
BotSetEntityNumForGoal(&redobelisk, "team_redobelisk");
BotSetEntityNumForGoalWithActivator(&redobelisk, "team_redobelisk");
if (trap_BotGetLevelItemGoal(-1, "Blue Obelisk", &blueobelisk) < 0)
BotAI_Print(PRT_WARNING, "Harvester without Blue Obelisk\n");
BotSetEntityNumForGoal(&blueobelisk, "team_blueobelisk");
BotSetEntityNumForGoalWithActivator(&blueobelisk, "team_blueobelisk");
if (trap_BotGetLevelItemGoal(-1, "Neutral Obelisk", &neutralobelisk) < 0)
BotAI_Print(PRT_WARNING, "Harvester without Neutral Obelisk\n");
BotSetEntityNumForGoal(&neutralobelisk, "team_neutralobelisk");
BotSetEntityNumForGoalWithActivator(&neutralobelisk, "team_neutralobelisk");
}
#endif

View file

@ -104,6 +104,7 @@ MULTIPLAYER MENU (SERVER BROWSER)
#define UIAS_GLOBAL4 5
#define UIAS_GLOBAL5 6
#define UIAS_FAVORITES 7
#define UIAS_NUM_SOURCES 8
#define UI_MAX_MASTER_SERVERS 6
@ -112,6 +113,7 @@ MULTIPLAYER MENU (SERVER BROWSER)
#define SORT_CLIENTS 2
#define SORT_GAME 3
#define SORT_PING 4
#define SORT_NUM_SORTS 5
#define GAMES_ALL 0
// STONELANCE
@ -129,6 +131,7 @@ MULTIPLAYER MENU (SERVER BROWSER)
#define GAMES_TEAM_RACING_DM 6
#define GAMES_TEAMPLAY 7
#define GAMES_CTF 8
#define GAMES_NUM_GAMES 9
// END
static const char *master_items[] = {
@ -1303,7 +1306,7 @@ int ArenaServers_SetType( int type )
char masterstr[2], cvarname[sizeof("sv_master1")];
int direction;
if (type == g_servertype || type == ((g_servertype+1) % (ARRAY_LEN(master_items)-1))) {
if (type == g_servertype || type == ((g_servertype+1) % UIAS_NUM_SOURCES)) {
direction = 1;
} else {
direction = -1;
@ -1906,16 +1909,12 @@ static void ArenaServers_MenuInit( void ) {
ArenaServers_LoadFavorites();
g_arenaservers.master.curvalue = g_servertype = Com_Clamp( 0, 6, ui_browserMaster.integer );
g_arenaservers.master.curvalue = g_servertype = Com_Clamp( 0, UIAS_NUM_SOURCES-1, ui_browserMaster.integer );
// STONELANCE
// g_gametype = Com_Clamp( 0, 4, ui_browserGameType.integer );
g_gametype = Com_Clamp( 0, GT_MAX_GAME_TYPE, ui_browserGameType.integer );
// END
g_gametype = Com_Clamp( 0, GAMES_NUM_GAMES-1, ui_browserGameType.integer );
g_arenaservers.gametype.curvalue = g_gametype;
g_sortkey = Com_Clamp( 0, 4, ui_browserSortKey.integer );
g_sortkey = Com_Clamp( 0, SORT_NUM_SORTS-1, ui_browserSortKey.integer );
g_arenaservers.sortkey.curvalue = g_sortkey;
g_fullservers = Com_Clamp( 0, 1, ui_browserShowFull.integer );

View file

@ -58,11 +58,6 @@ static void Matrix34Multiply( float *a, float *b, float *out ) {
out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10];
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
}
static void Matrix34Multiply_OnlySetOrigin( float *a, float *b, float *out ) {
out[ 3] = a[0] * b[3] + a[1] * b[7] + a[ 2] * b[11] + a[ 3];
out[ 7] = a[4] * b[3] + a[5] * b[7] + a[ 6] * b[11] + a[ 7];
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
}
static void InterpolateMatrix( float *a, float *b, float lerp, float *mat ) {
float unLerp = 1.0f - lerp;
@ -571,6 +566,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
}
if( header->ofs_bounds ) {
size += header->num_frames * 6 * sizeof(float); // model bounds
} else if( header->num_meshes && header->num_frames == 0 ) {
size += 6 * sizeof(float); // model bounds
}
mod->type = MOD_IQM;
@ -646,6 +643,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
if( header->ofs_bounds ) {
iqmData->bounds = (float*)dataPtr;
dataPtr += header->num_frames * 6 * sizeof(float); // model bounds
} else if( header->num_meshes && header->num_frames == 0 ) {
iqmData->bounds = (float*)dataPtr;
dataPtr += 6 * sizeof(float); // model bounds
}
if( header->num_meshes )
@ -912,6 +912,15 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
bounds++;
}
}
else if( header->num_meshes && header->num_frames == 0 )
{
mat = iqmData->bounds;
ClearBounds( &iqmData->bounds[0], &iqmData->bounds[3] );
for ( i = 0 ; i < header->num_vertexes ; i++ ) {
AddPointToBounds( &iqmData->positions[i*3], &iqmData->bounds[0], &iqmData->bounds[3] );
}
}
return qtrue;
}
@ -1124,18 +1133,6 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
int *joint = data->jointParents;
int i;
if ( data->num_poses == 0 ) {
for( i = 0; i < data->num_joints; i++, joint++ ) {
if( *joint >= 0 ) {
Matrix34Multiply( mat + 12 * *joint,
identityMatrix, mat + 12*i );
} else {
Com_Memcpy( mat + 12*i, identityMatrix, 12 * sizeof(float) );
}
}
return;
}
if ( oldframe == frame ) {
mat1 = data->poseMats + 12 * data->num_poses * frame;
for( i = 0; i < data->num_poses; i++, joint++ ) {
@ -1171,6 +1168,11 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
float *mat1;
int i;
if ( data->num_poses == 0 ) {
Com_Memcpy( mat, data->jointMats, data->num_joints * 12 * sizeof(float) );
return;
}
ComputePoseMats( data, frame, oldframe, backlerp, mat );
for( i = 0; i < data->num_joints; i++ ) {
@ -1179,7 +1181,7 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
Com_Memcpy(outmat, mat1, sizeof(outmat));
Matrix34Multiply_OnlySetOrigin( outmat, data->jointMats + 12 * i, mat1 );
Matrix34Multiply( outmat, data->jointMats + 12*i, mat1 );
}
}
@ -1194,7 +1196,7 @@ Compute vertices for this model surface
void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
srfIQModel_t *surf = (srfIQModel_t *)surface;
iqmData_t *data = surf->data;
float jointMats[IQM_MAX_JOINTS * 12];
float poseMats[IQM_MAX_JOINTS * 12];
float influenceVtxMat[SHADER_MAX_VERTEXES * 12];
float influenceNrmMat[SHADER_MAX_VERTEXES * 9];
int i;
@ -1235,7 +1237,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
if ( data->num_poses > 0 ) {
// compute interpolated joint matrices
ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
ComputePoseMats( data, frame, oldframe, backlerp, poseMats );
// compute vertex blend influence matricies
for( i = 0; i < surf->num_influences; i++ ) {
@ -1273,32 +1275,32 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
} else {
// compute the vertex matrix by blending the up to
// four blend weights
vtxMat[0] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 0];
vtxMat[1] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 1];
vtxMat[2] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 2];
vtxMat[3] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 3];
vtxMat[4] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 4];
vtxMat[5] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 5];
vtxMat[6] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 6];
vtxMat[7] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 7];
vtxMat[8] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 8];
vtxMat[9] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 9];
vtxMat[10] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10];
vtxMat[11] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11];
vtxMat[0] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 0];
vtxMat[1] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 1];
vtxMat[2] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 2];
vtxMat[3] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 3];
vtxMat[4] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 4];
vtxMat[5] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 5];
vtxMat[6] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 6];
vtxMat[7] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 7];
vtxMat[8] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 8];
vtxMat[9] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 9];
vtxMat[10] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10];
vtxMat[11] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11];
for( j = 1; j < numWeights; j++ ) {
vtxMat[0] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 0];
vtxMat[1] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 1];
vtxMat[2] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 2];
vtxMat[3] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 3];
vtxMat[4] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 4];
vtxMat[5] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 5];
vtxMat[6] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 6];
vtxMat[7] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 7];
vtxMat[8] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 8];
vtxMat[9] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 9];
vtxMat[10] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 10];
vtxMat[11] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 11];
vtxMat[0] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 0];
vtxMat[1] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 1];
vtxMat[2] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 2];
vtxMat[3] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 3];
vtxMat[4] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 4];
vtxMat[5] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 5];
vtxMat[6] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 6];
vtxMat[7] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 7];
vtxMat[8] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 8];
vtxMat[9] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 9];
vtxMat[10] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 10];
vtxMat[11] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 11];
}
}

View file

@ -58,11 +58,6 @@ static void Matrix34Multiply( float *a, float *b, float *out ) {
out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10];
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
}
static void Matrix34Multiply_OnlySetOrigin( float *a, float *b, float *out ) {
out[ 3] = a[0] * b[3] + a[1] * b[7] + a[ 2] * b[11] + a[ 3];
out[ 7] = a[4] * b[3] + a[5] * b[7] + a[ 6] * b[11] + a[ 7];
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
}
static void InterpolateMatrix( float *a, float *b, float lerp, float *mat ) {
float unLerp = 1.0f - lerp;
@ -574,6 +569,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
}
if( header->ofs_bounds ) {
size += header->num_frames * 6 * sizeof(float); // model bounds
} else if( header->num_meshes && header->num_frames == 0 ) {
size += 6 * sizeof(float); // model bounds
}
mod->type = MOD_IQM;
@ -649,6 +646,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
if( header->ofs_bounds ) {
iqmData->bounds = (float*)dataPtr;
dataPtr += header->num_frames * 6 * sizeof(float); // model bounds
} else if( header->num_meshes && header->num_frames == 0 ) {
iqmData->bounds = (float*)dataPtr;
dataPtr += 6 * sizeof(float); // model bounds
}
if( header->num_meshes )
@ -915,6 +915,15 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
bounds++;
}
}
else if( header->num_meshes && header->num_frames == 0 )
{
mat = iqmData->bounds;
ClearBounds( &iqmData->bounds[0], &iqmData->bounds[3] );
for ( i = 0 ; i < header->num_vertexes ; i++ ) {
AddPointToBounds( &iqmData->positions[i*3], &iqmData->bounds[0], &iqmData->bounds[3] );
}
}
// Create VAO surfaces
if ( iqmData->num_surfaces && iqmData->num_joints <= glRefConfig.glslMaxAnimatedBones )
@ -1302,18 +1311,6 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
int *joint = data->jointParents;
int i;
if ( data->num_poses == 0 ) {
for( i = 0; i < data->num_joints; i++, joint++ ) {
if( *joint >= 0 ) {
Matrix34Multiply( mat + 12 * *joint,
identityMatrix, mat + 12*i );
} else {
Com_Memcpy( mat + 12*i, identityMatrix, 12 * sizeof(float) );
}
}
return;
}
if ( oldframe == frame ) {
mat1 = data->poseMats + 12 * data->num_poses * frame;
for( i = 0; i < data->num_poses; i++, joint++ ) {
@ -1349,6 +1346,11 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
float *mat1;
int i;
if ( data->num_poses == 0 ) {
Com_Memcpy( mat, data->jointMats, data->num_joints * 12 * sizeof(float) );
return;
}
ComputePoseMats( data, frame, oldframe, backlerp, mat );
for( i = 0; i < data->num_joints; i++ ) {
@ -1357,7 +1359,7 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
Com_Memcpy(outmat, mat1, sizeof(outmat));
Matrix34Multiply_OnlySetOrigin( outmat, data->jointMats + 12 * i, mat1 );
Matrix34Multiply( outmat, data->jointMats + 12*i, mat1 );
}
}
@ -1372,7 +1374,7 @@ Compute vertices for this model surface
void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
srfIQModel_t *surf = (srfIQModel_t *)surface;
iqmData_t *data = surf->data;
float jointMats[IQM_MAX_JOINTS * 12];
float poseMats[IQM_MAX_JOINTS * 12];
float influenceVtxMat[SHADER_MAX_VERTEXES * 12];
float influenceNrmMat[SHADER_MAX_VERTEXES * 9];
int i;
@ -1417,7 +1419,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
if ( data->num_poses > 0 ) {
// compute interpolated joint matrices
ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
ComputePoseMats( data, frame, oldframe, backlerp, poseMats );
// compute vertex blend influence matricies
for( i = 0; i < surf->num_influences; i++ ) {
@ -1455,32 +1457,32 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
} else {
// compute the vertex matrix by blending the up to
// four blend weights
vtxMat[0] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 0];
vtxMat[1] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 1];
vtxMat[2] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 2];
vtxMat[3] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 3];
vtxMat[4] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 4];
vtxMat[5] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 5];
vtxMat[6] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 6];
vtxMat[7] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 7];
vtxMat[8] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 8];
vtxMat[9] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 9];
vtxMat[10] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10];
vtxMat[11] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11];
vtxMat[0] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 0];
vtxMat[1] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 1];
vtxMat[2] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 2];
vtxMat[3] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 3];
vtxMat[4] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 4];
vtxMat[5] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 5];
vtxMat[6] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 6];
vtxMat[7] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 7];
vtxMat[8] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 8];
vtxMat[9] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 9];
vtxMat[10] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10];
vtxMat[11] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11];
for( j = 1; j < numWeights; j++ ) {
vtxMat[0] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 0];
vtxMat[1] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 1];
vtxMat[2] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 2];
vtxMat[3] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 3];
vtxMat[4] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 4];
vtxMat[5] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 5];
vtxMat[6] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 6];
vtxMat[7] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 7];
vtxMat[8] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 8];
vtxMat[9] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 9];
vtxMat[10] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 10];
vtxMat[11] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 11];
vtxMat[0] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 0];
vtxMat[1] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 1];
vtxMat[2] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 2];
vtxMat[3] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 3];
vtxMat[4] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 4];
vtxMat[5] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 5];
vtxMat[6] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 6];
vtxMat[7] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 7];
vtxMat[8] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 8];
vtxMat[9] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 9];
vtxMat[10] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 10];
vtxMat[11] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 11];
}
}

View file

@ -188,9 +188,6 @@ qboolean SNDDMA_Init(void)
SDL_AudioSpec desired;
SDL_AudioSpec obtained;
int tmp;
#ifdef USE_SDL_AUDIO_CAPTURE
SDL_version sdlVersion;
#endif
if (snd_inited)
return qtrue;
@ -267,20 +264,15 @@ qboolean SNDDMA_Init(void)
if (!tmp)
tmp = (obtained.samples * obtained.channels) * 10;
if (tmp & (tmp - 1)) // not a power of two? Seems to confuse something.
{
int val = 1;
while (val < tmp)
val <<= 1;
tmp = val;
}
// samples must be divisible by number of channels
tmp -= tmp % obtained.channels;
dmapos = 0;
dma.samplebits = SDL_AUDIO_BITSIZE(obtained.format);
dma.isfloat = SDL_AUDIO_ISFLOAT(obtained.format);
dma.channels = obtained.channels;
dma.samples = tmp;
dma.fullsamples = dma.samples / dma.channels;
dma.submission_chunk = 1;
dma.speed = obtained.freq;
dmasize = (dma.samples * (dma.samplebits/8));
@ -289,11 +281,10 @@ qboolean SNDDMA_Init(void)
#ifdef USE_SDL_AUDIO_CAPTURE
// !!! FIXME: some of these SDL_OpenAudioDevice() values should be cvars.
s_sdlCapture = Cvar_Get( "s_sdlCapture", "1", CVAR_ARCHIVE | CVAR_LATCH );
// !!! FIXME: hopefully pulseaudio capture will be fixed in SDL 2.0.9... https://bugzilla.libsdl.org/show_bug.cgi?id=4087
SDL_GetVersion(&sdlVersion);
if (sdlVersion.major == 2 && sdlVersion.minor == 0 && sdlVersion.patch < 9 && Q_stricmp(SDL_GetCurrentAudioDriver(), "pulseaudio") == 0)
// !!! FIXME: pulseaudio capture records audio the entire time the program is running. https://bugzilla.libsdl.org/show_bug.cgi?id=4087
if (Q_stricmp(SDL_GetCurrentAudioDriver(), "pulseaudio") == 0)
{
Com_Printf("SDL audio capture support disabled (pulseaudio capture does not work correctly with SDL %d.%d.%d)\n", sdlVersion.major, sdlVersion.minor, sdlVersion.patch);
Com_Printf("SDL audio capture support disabled for pulseaudio (https://bugzilla.libsdl.org/show_bug.cgi?id=4087)\n");
}
else if (!s_sdlCapture->integer)
{