void CGameStudioModelRenderer::StudioSetupBones(void) { int i; double f; mstudiobone_t *pbones; mstudioseqdesc_t *pseqdesc; mstudioanim_t *panim; static float pos[MAXSTUDIOBONES][3]; static vec4_t q[MAXSTUDIOBONES]; float bonematrix[3][4]; static float pos2[MAXSTUDIOBONES][3]; static vec4_t q2[MAXSTUDIOBONES]; static float pos3[MAXSTUDIOBONES][3]; static vec4_t q3[MAXSTUDIOBONES]; static float pos4[MAXSTUDIOBONES][3]; static vec4_t q4[MAXSTUDIOBONES]; if (!m_pCurrentEntity->player) { CStudioModelRenderer::StudioSetupBones(); return; } if (m_pCurrentEntity->curstate.sequence >= m_pStudioHeader->numseq) m_pCurrentEntity->curstate.sequence = 0; pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->curstate.sequence; panim = StudioGetAnim(m_pRenderModel, pseqdesc); f = StudioEstimateFrame(pseqdesc); if (m_pPlayerInfo->gaitsequence == ANIM_WALK_SEQUENCE) { if (m_pCurrentEntity->curstate.blending[0] <= 26) { m_pCurrentEntity->curstate.blending[0] = 0; m_pCurrentEntity->latched.prevseqblending[0] = m_pCurrentEntity->curstate.blending[0]; } else { m_pCurrentEntity->curstate.blending[0] -= 26; m_pCurrentEntity->latched.prevseqblending[0] = m_pCurrentEntity->curstate.blending[0]; } } if (pseqdesc->numblends == 9) { float s = m_pCurrentEntity->curstate.blending[0]; float t = m_pCurrentEntity->curstate.blending[1]; if (s <= 127.0) { s = (s * 2.0); if (t <= 127.0) { t = (t * 2.0); StudioCalcRotations(pos, q, pseqdesc, panim, f); panim = LookupAnimation(pseqdesc, 1); StudioCalcRotations(pos2, q2, pseqdesc, panim, f); panim = LookupAnimation(pseqdesc, 3); StudioCalcRotations(pos3, q3, pseqdesc, panim, f); panim = LookupAnimation(pseqdesc, 4); StudioCalcRotations(pos4, q4, pseqdesc, panim, f); } else { t = 2.0 * (t - 127.0); panim = LookupAnimation(pseqdesc, 3); StudioCalcRotations(pos, q, pseqdesc, panim, f); panim = LookupAnimation(pseqdesc, 4); StudioCalcRotations(pos2, q2, pseqdesc, panim, f); panim = LookupAnimation(pseqdesc, 6); StudioCalcRotations(pos3, q3, pseqdesc, panim, f); panim = LookupAnimation(pseqdesc, 7); StudioCalcRotations(pos4, q4, pseqdesc, panim, f); } } else { s = 2.0 * (s - 127.0); if (t <= 127.0) { t = (t * 2.0); panim = LookupAnimation(pseqdesc, 1); StudioCalcRotations(pos, q, pseqdesc, panim, f); panim = LookupAnimation(pseqdesc, 2); StudioCalcRotations(pos2, q2, pseqdesc, panim, f); panim = LookupAnimation(pseqdesc, 4); StudioCalcRotations(pos3, q3, pseqdesc, panim, f); panim = LookupAnimation(pseqdesc, 5); StudioCalcRotations(pos4, q4, pseqdesc, panim, f); } else { t = 2.0 * (t - 127.0); panim = LookupAnimation(pseqdesc, 4); StudioCalcRotations(pos, q, pseqdesc, panim, f); panim = LookupAnimation(pseqdesc, 5); StudioCalcRotations(pos2, q2, pseqdesc, panim, f); panim = LookupAnimation(pseqdesc, 7); StudioCalcRotations(pos3, q3, pseqdesc, panim, f); panim = LookupAnimation(pseqdesc, 8); StudioCalcRotations(pos4, q4, pseqdesc, panim, f); } } s /= 255.0; t /= 255.0; StudioSlerpBones(q, pos, q2, pos2, s); StudioSlerpBones(q3, pos3, q4, pos4, s); StudioSlerpBones(q, pos, q3, pos3, t); } else { StudioCalcRotations(pos, q, pseqdesc, panim, f); } if (m_fDoInterp && m_pCurrentEntity->latched.sequencetime && (m_pCurrentEntity->latched.sequencetime + 0.2 > m_clTime) && (m_pCurrentEntity->latched.prevsequence < m_pStudioHeader->numseq)) { static float pos1b[MAXSTUDIOBONES][3]; static vec4_t q1b[MAXSTUDIOBONES]; float s = m_pCurrentEntity->latched.prevseqblending[0]; float t = m_pCurrentEntity->latched.prevseqblending[1]; pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->latched.prevsequence; panim = StudioGetAnim(m_pRenderModel, pseqdesc); if (pseqdesc->numblends == 9) { if (s <= 127.0) { s = (s * 2.0); if (t <= 127.0) { t = (t * 2.0); StudioCalcRotations(pos1b, q1b, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); panim = LookupAnimation(pseqdesc, 1); StudioCalcRotations(pos2, q2, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); panim = LookupAnimation(pseqdesc, 3); StudioCalcRotations(pos3, q3, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); panim = LookupAnimation(pseqdesc, 4); StudioCalcRotations(pos4, q4, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); } else { t = 2.0 * (t - 127.0); panim = LookupAnimation(pseqdesc, 3); StudioCalcRotations(pos1b, q1b, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); panim = LookupAnimation(pseqdesc, 4); StudioCalcRotations(pos2, q2, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); panim = LookupAnimation(pseqdesc, 6); StudioCalcRotations(pos3, q3, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); panim = LookupAnimation(pseqdesc, 7); StudioCalcRotations(pos4, q4, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); } } else { s = 2.0 * (s - 127.0); if (t <= 127.0) { t = (t * 2.0); panim = LookupAnimation(pseqdesc, 1); StudioCalcRotations(pos1b, q1b, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); panim = LookupAnimation(pseqdesc, 2); StudioCalcRotations(pos2, q2, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); panim = LookupAnimation(pseqdesc, 4); StudioCalcRotations(pos3, q3, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); panim = LookupAnimation(pseqdesc, 5); StudioCalcRotations(pos4, q4, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); } else { t = 2.0 * (t - 127.0); panim = LookupAnimation(pseqdesc, 4); StudioCalcRotations(pos1b, q1b, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); panim = LookupAnimation(pseqdesc, 5); StudioCalcRotations(pos2, q2, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); panim = LookupAnimation(pseqdesc, 7); StudioCalcRotations(pos3, q3, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); panim = LookupAnimation(pseqdesc, 8); StudioCalcRotations(pos4, q4, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); } } s /= 255.0; t /= 255.0; StudioSlerpBones(q1b, pos1b, q2, pos2, s); StudioSlerpBones(q3, pos3, q4, pos4, s); StudioSlerpBones(q1b, pos1b, q3, pos3, t); } else { StudioCalcRotations(pos1b, q1b, pseqdesc, panim, m_pCurrentEntity->latched.prevframe); } s = 1.0 - (m_clTime - m_pCurrentEntity->latched.sequencetime) / 0.2; StudioSlerpBones(q, pos, q1b, pos1b, s); } else { m_pCurrentEntity->latched.prevframe = f; } pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex); if (m_pPlayerInfo && (m_pCurrentEntity->curstate.sequence < ANIM_FIRST_DEATH_SEQUENCE || m_pCurrentEntity->curstate.sequence > ANIM_LAST_DEATH_SEQUENCE) && (m_pCurrentEntity->curstate.sequence < ANIM_FIRST_EMOTION_SEQUENCE || m_pCurrentEntity->curstate.sequence > ANIM_LAST_EMOTION_SEQUENCE) && m_pCurrentEntity->curstate.sequence != ANIM_SWIM_1 && m_pCurrentEntity->curstate.sequence != ANIM_SWIM_2) { int copy = 1; if (m_pPlayerInfo->gaitsequence >= m_pStudioHeader->numseq) m_pPlayerInfo->gaitsequence = 0; pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex ) + m_pPlayerInfo->gaitsequence; panim = StudioGetAnim(m_pRenderModel, pseqdesc); StudioCalcRotations(pos2, q2, pseqdesc, panim, m_pPlayerInfo->gaitframe); for (i = 0; i < m_pStudioHeader->numbones; i++) { if (!strcmp(pbones[i].name, "Bip01 Spine")) copy = 0; else if (!strcmp(pbones[pbones[i].parent].name, "Bip01 Pelvis")) copy = 1; if (copy) { memcpy(pos[i], pos2[i], sizeof(pos[i])); memcpy(q[i], q2[i], sizeof(q[i])); } } } for (i = 0; i < m_pStudioHeader->numbones; i++) { QuaternionMatrix(q[i], bonematrix); bonematrix[0][3] = pos[i][0]; bonematrix[1][3] = pos[i][1]; bonematrix[2][3] = pos[i][2]; if (pbones[i].parent == -1) { if (IEngineStudio.IsHardware()) { ConcatTransforms((*m_protationmatrix), bonematrix, (*m_pbonetransform)[i]); MatrixCopy((*m_pbonetransform)[i], (*m_plighttransform)[i]); } else { ConcatTransforms((*m_paliastransform), bonematrix, (*m_pbonetransform)[i]); ConcatTransforms((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]); } StudioFxTransform(m_pCurrentEntity, (*m_pbonetransform)[i]); } else { ConcatTransforms((*m_pbonetransform)[pbones[i].parent], bonematrix, (*m_pbonetransform)[i]); ConcatTransforms((*m_plighttransform)[pbones[i].parent], bonematrix, (*m_plighttransform)[i]); } } }
/* <16247> ../cstrike/dlls/animation.cpp:1115 */ void SV_StudioSetupBones(model_t *pModel, float frame, int sequence, const vec_t *angles, const vec_t *origin, const byte *pcontroller, const byte *pblending, int iBone, const edict_t *pEdict) { int i, j; float_precision f; float subframe; float adj[MAXSTUDIOCONTROLLERS]; mstudiobone_t *pbones; mstudioseqdesc_t *pseqdesc; mstudioanim_t *panim; float bonematrix[3][4]; int chain[MAXSTUDIOBONES]; int chainlength; vec3_t temp_angles; static float pos[MAXSTUDIOBONES][3], pos2[MAXSTUDIOBONES][3]; static float q[MAXSTUDIOBONES][4], q2[MAXSTUDIOBONES][4]; g_pstudiohdr = (studiohdr_t *)IEngineStudio.Mod_Extradata(pModel); // Bound sequence number if (sequence < 0 || sequence >= g_pstudiohdr->numseq) sequence = 0; pbones = (mstudiobone_t *)((byte *)g_pstudiohdr + g_pstudiohdr->boneindex); pseqdesc = (mstudioseqdesc_t *)((byte *)g_pstudiohdr + g_pstudiohdr->seqindex) + sequence; panim = StudioGetAnim(pModel, pseqdesc); if (iBone < -1 || iBone >= g_pstudiohdr->numbones) iBone = 0; if (iBone == -1) { chainlength = g_pstudiohdr->numbones; for (i = 0; i < chainlength; i++) chain[(chainlength - i) - 1] = i; } else { chainlength = 0; for (i = iBone; i != -1; i = pbones[i].parent) chain[chainlength++] = i; } f = StudioEstimateFrame(frame, pseqdesc); subframe = (int)f; f -= subframe; StudioCalcBoneAdj(0, adj, pcontroller, pcontroller, 0); StudioCalcRotations(pbones, chain, chainlength, adj, pos, q, pseqdesc, panim, subframe, f); if (pseqdesc->numblends != 9) { if (pseqdesc->numblends > 1) { float b = (float_precision)pblending[0] / 255.0f; pseqdesc = (mstudioseqdesc_t *)((byte *)g_pstudiohdr + g_pstudiohdr->seqindex) + sequence; panim = StudioGetAnim(pModel, pseqdesc); panim += g_pstudiohdr->numbones; StudioCalcRotations(pbones, chain, chainlength, adj, pos2, q2, pseqdesc, panim, subframe, f); StudioSlerpBones(q, pos, q2, pos2, b); } } // This game knows how to do nine way blending else { static float pos3[MAXSTUDIOBONES][3], pos4[MAXSTUDIOBONES][3]; static float q3[MAXSTUDIOBONES][4], q4[MAXSTUDIOBONES][4]; float_precision s, t; s = GetPlayerYaw(pEdict); t = GetPlayerPitch(pEdict); // Blending is 0-127 == Left to Middle, 128 to 255 == Middle to right if (s <= 127.0f) { // Scale 0-127 blending up to 0-255 s = (s * 2.0f); if (t <= 127.0f) { t = (t * 2.0f); StudioCalcRotations(pbones, chain, chainlength, adj, pos, q, pseqdesc, panim, subframe, f); panim = LookupAnimation(pModel, pseqdesc, 1); StudioCalcRotations(pbones, chain, chainlength, adj, pos2, q2, pseqdesc, panim, subframe, f); panim = LookupAnimation(pModel, pseqdesc, 3); StudioCalcRotations(pbones, chain, chainlength, adj, pos3, q3, pseqdesc, panim, subframe, f); panim = LookupAnimation(pModel, pseqdesc, 4); StudioCalcRotations(pbones, chain, chainlength, adj, pos4, q4, pseqdesc, panim, subframe, f); } else { t = 2.0f * (t - 127.0f); panim = LookupAnimation(pModel, pseqdesc, 3); StudioCalcRotations(pbones, chain, chainlength, adj, pos, q, pseqdesc, panim, subframe, f); panim = LookupAnimation(pModel, pseqdesc, 4); StudioCalcRotations(pbones, chain, chainlength, adj, pos2, q2, pseqdesc, panim, subframe, f); panim = LookupAnimation(pModel, pseqdesc, 6); StudioCalcRotations(pbones, chain, chainlength, adj, pos3, q3, pseqdesc, panim, subframe, f); panim = LookupAnimation(pModel, pseqdesc, 7); StudioCalcRotations(pbones, chain, chainlength, adj, pos4, q4, pseqdesc, panim, subframe, f); } } else { // Scale 127-255 blending up to 0-255 s = 2.0f * (s - 127.0f); if (t <= 127.0f) { t = (t * 2.0f); panim = LookupAnimation(pModel, pseqdesc, 1); StudioCalcRotations(pbones, chain, chainlength, adj, pos, q, pseqdesc, panim, subframe, f); panim = LookupAnimation(pModel, pseqdesc, 2); StudioCalcRotations(pbones, chain, chainlength, adj, pos2, q2, pseqdesc, panim, subframe, f); panim = LookupAnimation(pModel, pseqdesc, 4); StudioCalcRotations(pbones, chain, chainlength, adj, pos3, q3, pseqdesc, panim, subframe, f); panim = LookupAnimation(pModel, pseqdesc, 5); StudioCalcRotations(pbones, chain, chainlength, adj, pos4, q4, pseqdesc, panim, subframe, f); } else { t = 2.0f * (t - 127.0f); panim = LookupAnimation(pModel, pseqdesc, 4); StudioCalcRotations(pbones, chain, chainlength, adj, pos, q, pseqdesc, panim, subframe, f); panim = LookupAnimation(pModel, pseqdesc, 5); StudioCalcRotations(pbones, chain, chainlength, adj, pos2, q2, pseqdesc, panim, subframe, f); panim = LookupAnimation(pModel, pseqdesc, 7); StudioCalcRotations(pbones, chain, chainlength, adj, pos3, q3, pseqdesc, panim, subframe, f); panim = LookupAnimation(pModel, pseqdesc, 8); StudioCalcRotations(pbones, chain, chainlength, adj, pos4, q4, pseqdesc, panim, subframe, f); } } // Normalize interpolant s /= 255.0f; t /= 255.0f; // Spherically interpolate the bones StudioSlerpBones(q, pos, q2, pos2, s); StudioSlerpBones(q3, pos3, q4, pos4, s); StudioSlerpBones(q, pos, q3, pos3, t); } if (pseqdesc->numblends == 9 && sequence < ANIM_FIRST_DEATH_SEQUENCE && sequence != ANIM_SWIM_1 && sequence != ANIM_SWIM_2) { int copy = 1; int gaitsequence = GetPlayerGaitsequence(pEdict); // calc gait animation if (gaitsequence < 0 || gaitsequence >= g_pstudiohdr->numseq) gaitsequence = 0; pseqdesc = (mstudioseqdesc_t *)((byte *)g_pstudiohdr + g_pstudiohdr->seqindex) + gaitsequence; panim = StudioGetAnim(pModel, pseqdesc); StudioCalcRotations(pbones, chain, chainlength, adj, pos2, q2, pseqdesc, panim, 0, 0); for (i = 0; i < g_pstudiohdr->numbones; i++) { if (!Q_strcmp(pbones[i].name, "Bip01 Spine")) { copy = 0; } else if (!Q_strcmp(pbones[pbones[i].parent].name, "Bip01 Pelvis")) { copy = 1; } if (copy) { Q_memcpy(pos[i], pos2[i], sizeof(pos[i])); Q_memcpy(q[i], q2[i], sizeof(q[i])); } } } VectorCopy(angles, temp_angles); if (pEdict != NULL) { temp_angles[1] = UTIL_GetPlayerGaitYaw(ENTINDEX(pEdict)); if (temp_angles[1] < 0) temp_angles[1] += 360.0f; } AngleMatrix(temp_angles, (*g_pRotationMatrix)); (*g_pRotationMatrix)[0][3] = origin[0]; (*g_pRotationMatrix)[1][3] = origin[1]; (*g_pRotationMatrix)[2][3] = origin[2]; for (i = chainlength - 1; i >= 0; i--) { j = chain[i]; QuaternionMatrix(q[j], bonematrix); bonematrix[0][3] = pos[j][0]; bonematrix[1][3] = pos[j][1]; bonematrix[2][3] = pos[j][2]; if (pbones[j].parent == -1) ConcatTransforms((*g_pRotationMatrix), bonematrix, (*g_pBoneTransform)[j]); else ConcatTransforms((*g_pBoneTransform)[pbones[j].parent], bonematrix, (*g_pBoneTransform)[j]); } }