.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   General Bot Coding (http://forums.bots-united.com/forumdisplay.php?f=24)
-   -   Hit-box aiming (http://forums.bots-united.com/showthread.php?t=8090)

Immortal_BLG 04-11-2010 16:15

Hit-box aiming
 
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 :D
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........................................... ..:crying:

passguy 04-02-2011 12:24

Re: Hit-box aiming
 
hey, i have recently joined this forum, while browsing various threads, i found this one,,,,really useful,,,,,,,,thanks


All times are GMT +2. The time now is 08:20.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.