Hello!
Code:
enum PlayerBodyPart_t
{
PlayerBodyPart_Generic, // None.
PlayerBodyPart_Head,
PlayerBodyPart_Chest,
PlayerBodyPart_Stomach,
PlayerBodyPart_LeftArm,
PlayerBodyPart_RightArm,
PlayerBodyPart_LeftLeg,
PlayerBodyPart_RightLeg,
PlayerBodyPart_Shield
};
typedef float RotationMatrix_t[3u][4u];
typedef float BoneTransformMatrix_t[Constants::MaximumStudioBones][3u][4u];
typedef Vector Angles;
struct sv_blending_interface_s;
struct server_studio_api_s;
typedef BOOL (FAR *BlendAPI_t) (int version, sv_blending_interface_s **interface, server_studio_api_s *studio, RotationMatrix_t *const rotationMatrix, BoneTransformMatrix_t *const boneTransform);
const BoneTransformMatrix_t *g_boneTransformMatrix; // bone transformation matrix
EXPORT BOOL Server_GetBlendingInterface (int version, sv_blending_interface_s **interface, server_studio_api_s *studio, RotationMatrix_t *const rotationMatrix, BoneTransformMatrix_t *const boneTransform)
{
// call the function that provides the blending interface on request
const BOOL result ((*reinterpret_cast <BlendAPI_t> (GetProcAddress (GetModuleHandle ("mp.dll"), "Server_GetBlendingInterface"))) (version, interface, studio, rotationMatrix, boneTransform));
g_boneTransformMatrix = boneTransform;
return result;
}
void R_StudioPlayerBlend (const mstudioseqdesc_t &seqdesc, int &blend, float &pitch)
{
// Player specific data
// Determine pitch and blending amounts for players
// calc up/down pointing
blend = static_cast <int> (pitch * 3.0f);
if (blend < seqdesc.blendstart[0u])
{
pitch -= seqdesc.blendstart[0u] * (1.0f / 3.0f);
blend = 0;
}
else if (blend > seqdesc.blendend[0u])
{
pitch -= seqdesc.blendend[0u] * (1.0f / 3.0f);
blend = 255;
}
else
{
if (seqdesc.blendend[0u] - seqdesc.blendstart[0u] < 0.1f) // catch qc error
blend = 127;
else
blend = static_cast <int> (255 * (blend - seqdesc.blendstart[0u]) / (seqdesc.blendend[0u] - seqdesc.blendstart[0u]));
pitch = 0.0f;
}
}
void StudioSetupBones (const edict_t *const entity, const char boneID = -1/*-1 - setup all bones - as I understand....*/)
{
// This function setup the bones for an 'entity'.
Angles originalModelAngles (entity->v.angles);
const studiohdr_t *const studioHeader (static_cast <studiohdr_t *> (GET_MODEL_PTR (entity)));
const mstudioseqdesc_t *const sequenceDescription (reinterpret_cast <const mstudioseqdesc_t *> (reinterpret_cast <const unsigned char *> (studioHeader) + studioHeader->seqindex));
int blend;
// Fix the model angles pitch component (without it for example head hit-box position is wrong when ent->v.angles.x is -30 or 30)
R_StudioPlayerBlend (sequenceDescription[entity->v.sequence], blend, entity->v.angles.x);
// Revert
entity->v.angles.pitch = -entity->v.angles.pitch;
// I'm not sure that it(change entity controller and blending) needed, but in SV_HullForStudioModel() this exists...
unsigned char originalController[4u];
unsigned char originalBlending[2u];
reinterpret_cast <int *> (originalController) = reinterpret_cast <int *> (entity->v.controller);
reinterpret_cast <short *> (originalBlending) = reinterpret_cast <short *> (entity->v.blending);
unsigned char controller[4u] = {127u, 127u, 127u, 127u};
unsigned char blending[2u] = {static_cast <unsigned char> (blend), 0u}; /// @warning I'M NOT SURE THAT THIS IS RIGHT DECOMPILED, BUT...
reinterpret_cast <int *> (entity->v.controller) = reinterpret_cast <int *> (controller);
reinterpret_cast <short *> (entity->v.blending) = reinterpret_cast <short *> (blending);
// We call this function, cuz this function calls SV_StudioSetupBones() and pass first argument(model_t), that we can't pass, cuz we don't have sv.models pointer....
GET_BONE_POSITION (entity, boneID, NULL, NULL);
// Restore all...
entity->v.angles = originalModelAngles;
reinterpret_cast <int *> (entity->v.controller) = reinterpret_cast <int *> (originalController);
reinterpret_cast <short *> (entity->v.blending) = reinterpret_cast <short *> (originalBlending);
}
const Vector GetHitBoxPositionOfEdict (const edict_t *const edict, const PlayerBodyPart_t bodyPart)
{
const studiohdr_t *const studioHeader (static_cast <studiohdr_t *> (GET_MODEL_PTR (edict)));
const mstudiobbox_t *const pbboxes (reinterpret_cast <const mstudiobbox_t *> (reinterpret_cast <const unsigned char *> (studioHeader) + studioHeader->hitboxindex));
const mstudiobbox_t *bbox (NULL);
for (unsigned char hitBoxIndex (0u); hitBoxIndex < studioHeader->numhitboxes; ++hitBoxIndex)
{
bbox = pbboxes + hitBoxIndex;
if (bbox->group == bodyPart)
break;
}
// Reliability check.
assert (bbox != NULL);
// Update 'g_boneTransformMatrix' before using it !!!
StudioSetupBones (edict, static_cast <char> (bbox->bone));
Vector hitBoxCenter;
VectorTransform ((bbox->bbmin + bbox->bbmax) * 0.5f, (*g_boneTransformMatrix)[bbox->bone], hitBoxCenter);
return hitBoxCenter;
}
Code, how looks pfnGetBonePosition() function - BONUS
Code:
void GetBonePosition (edict_t *edict, int boneID, float *origin, float *angles)
{
pstudiohdr = Mod_Extradata (sv.models[edict->v.modelindex]);
(*g_pSvBlendingAPI->SV_StudioSetupBones)
(
edict->variables.frame,
edict->variables.sequence,
edict->variables.angles,
edict->variables.origin,
edict->variables.controller,
edict->variables.blending,
boneID,
edict
);
if (origin != NULL)
{
origin[0] = (*bonetransform)[boneID][0][3];
origin[1] = (*bonetransform)[boneID][1][3];
origin[2] = (*bonetransform)[boneID][2][3];
}
// ABOUT HOW 'angles' ASSIGNED - NOTHING! 0_o
}
//----- (01D7B260) --------------------------------------------------------
int __cdecl GetBonePosition(int a1, int a2, int a3)
{
int result; // eax@1
int v4; // esi@1
v4 = a1;
dword_2090F98 = sub_1D5AEF0(*(&dword_2167790 + *(_DWORD *)(a1 + 308)));
result = (*((int (__cdecl **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD))off_1E5D2E8 + 1))(
*(&dword_2167790 + *(_DWORD *)(v4 + 308)),
*(_DWORD *)(v4 + 432),
*(_DWORD *)(v4 + 424),
v4 + 208,
v4 + 136,
v4 + 444,
v4 + 448,
a2,
v4);
if ( a3 )
{
*(_DWORD *)a3 = LODWORD(flt_2545A2C[12 * a2]);
result = flt_2545A4C[12 * a2];
*(_DWORD *)(a3 + 4) = LODWORD(flt_2545A3C[12 * a2]);
*(_DWORD *)(a3 + 8) = result;
}
return result;
}
Something isn't clear? Write, - I will try to explain....
P.S. SORRY FOR BAD ENGLISH........................................... ..