Code:
/* DESCRIPTION: SV_StudioSetupBones
// Location: SDK, as SetupBones
// PATH: An annoying API.
//
// This 'sets up' bones. I'm starting to get the picture, but I don't know
// enough to describe what's actualy going on.
*/
void SV_StudioSetupBones(model_t * arg_0, float arg_4, int arg_8_sequence,
vec3_t arg_C, vec3_t arg_10, byte * arg_14,
byte * arg_18, int arg_1C, edict_t * unused) {
int i, j, var_270, var_26C[0x80];
float var_c, var_10, var_30[8];
vec_t bonematrix[3][4];
mstudiobone_t *pbones;
mstudioseqdesc_t *pseqdesc;
mstudioanim_t *panim;
#define MAXSTUDIOBONES 128
static vec3_t pos[MAXSTUDIOBONES];
static vec4_t q[MAXSTUDIOBONES];
static vec3_t pos2[MAXSTUDIOBONES];
static vec4_t q2[MAXSTUDIOBONES];
var_270 = 0;
if(arg_8_sequence < 0 || arg_8_sequence >= pstudiohdr->numseq) {
Con_Printf("%s: Sequence %i/%i out of range for model %s.\n", __FUNCTION__, arg_8_sequence, pstudiohdr->numseq, pstudiohdr->name);
arg_8_sequence = 0;
}
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + arg_8_sequence;
pbones = (mstudiobone_t *)((byte *)pstudiohdr + pstudiohdr->boneindex);
panim = R_GetAnim(arg_0, pseqdesc);
if(arg_1C < -1 || arg_1C >= pstudiohdr->numbones) { arg_1C = 0; }
if(arg_1C == -1) {
var_270 = pstudiohdr->numbones;
for(i = 0; i < pstudiohdr->numbones; i++) {
var_26C[(var_270 - i) - 1] = i;
}
}
else {
for(i = arg_1C; i != -1; i = pbones[i].parent) {
var_26C[var_270] = i;
var_270++;
}
}
if(pseqdesc->numframes > 1) {
var_c = (pseqdesc->numframes - 1) * arg_4 / 256.0;
}
else {
var_c = 0;
}
var_10 = var_c - (int)var_c; //so, the decimal part.
R_StudioCalcBoneAdj(0, var_30, arg_14, arg_14, 0);
for(j = var_270 - 1; j >= 0; j--) {
i = var_26C[j];
R_StudioCalcBoneQuaterion((int)var_c, var_10, &(pbones[i]), &(panim[i]), var_30, q[i]);
R_StudioCalcBonePosition((int)var_c, var_10, &(pbones[i]), &(panim[i]), var_30, pos[i]);
}
if(pseqdesc->numblends > 1) {
//Waitaminute, why are we doing this over again?
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + arg_8_sequence;
panim = R_GetAnim(arg_0, pseqdesc);
panim += pstudiohdr->numbones;
for(j = var_270 - 1; j >= 0; j--) {
i = var_26C[j];
R_StudioCalcBoneQuaterion((int)var_c, var_10, &(pbones[i]), &(panim[i]), var_30, q2[i]);
R_StudioCalcBonePosition((int)var_c, var_10, &(pbones[i]), &(panim[i]), var_30, pos2[i]);
}
R_StudioSlerpBones(q, pos, q2, pos2, ((float)(arg_18[0])) / 255.0);
}
AngleMatrix(arg_C, rotationmatrix);
rotationmatrix[0][3] = arg_10[0];
rotationmatrix[1][3] = arg_10[1];
rotationmatrix[2][3] = arg_10[2];
for(j = var_270 - 1; j >= 0; j--) {
i = var_26C[j];
QuaternionMatrix(q[i], bonematrix);
bonematrix[0][3] = pos[i][0];
bonematrix[1][3] = pos[i][0];
bonematrix[2][3] = pos[i][0];
//These two both pop up annoying errors about incompatible pointer types. I don't see the flaw, and the right address is definitely being passed.
if(pbones[i].parent == -1) {
R_ConcatTransforms(rotationmatrix, bonematrix, bonetransform[i]);
}
else {
R_ConcatTransforms(bonetransform[pbones[i].parent], bonematrix, bonetransform[i]);
}
}
}
Seems to be called from [FM_/EngFunc_]GetBonePosition and from [FM_/EngFunc_]GetAttachment