Thread: Hit-box aiming
View Single Post
Hit-box aiming
Old
  (#1)
Immortal_BLG
Member
 
Status: Offline
Posts: 171
Join Date: Nov 2007
Location: Russian Federation
Arrow Hit-box aiming - 04-11-2010

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........................................... ..

Last edited by Immortal_BLG; 05-11-2010 at 01:28..
  
Reply With Quote