Initial hitbox drawing implementation

Currently only hooked up to lag compensation code. Will be hooked up to 'sv_showhitboxes' in the future (drawing hitboxes of all animating).
This commit is contained in:
Kawe Mazidjatari 2023-01-23 02:22:51 +01:00
parent 502a1d2324
commit 094a6e4fa5
2 changed files with 135 additions and 0 deletions

View File

@ -0,0 +1,91 @@
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: Base class for all animating characters and objects.
//
//===========================================================================//
#include "core/stdafx.h"
#include "baseanimating.h"
#include "engine/modelinfo.h"
#include "public/idebugoverlay.h"
static Vector3D hullcolor[8] =
{
Vector3D(1.0, 1.0, 1.0),
Vector3D(1.0, 0.5, 0.5),
Vector3D(0.5, 1.0, 0.5),
Vector3D(1.0, 1.0, 0.5),
Vector3D(0.5, 0.5, 1.0),
Vector3D(1.0, 0.5, 1.0),
Vector3D(0.5, 1.0, 1.0),
Vector3D(1.0, 1.0, 1.0)
};
//-----------------------------------------------------------------------------
// Purpose: Send the current hitboxes for this model to the client ( to compare with
// r_drawentities 3 client side boxes ).
// WARNING: This uses a ton of bandwidth, only use on a listen server
//-----------------------------------------------------------------------------
void CBaseAnimating::DrawServerHitboxes(float duration /*= 0.0f*/)
{
if (!m_pStudioHdr && g_pModelInfoServer->GetModel(m_nModelIndex))
{
UpdateModelPtr();
if (!m_pStudioHdr)
{
return;
}
}
mstudiohitboxset_t* set = m_pStudioHdr->pHitboxSet(m_nHitboxSet);
if (!set)
return;
matrix3x4_t transforms;
int r = 0;
int g = 0;
int b = 255;
for (int i = 0; i < set->numhitboxes; i++)
{
mstudiobbox_t* pBox = set->pHitbox(i);
int j = (pBox->group % 8);
r = (int)(255.0f * hullcolor[j][0]);
g = (int)(255.0f * hullcolor[j][1]);
b = (int)(255.0f * hullcolor[j][2]);
HitboxToWorldTransforms(pBox->bone, &transforms);
g_pDebugOverlay->AddBoxOverlay(transforms, pBox->bbmin, pBox->bbmax, r, g, b, 0, true, duration);
}
}
void CBaseAnimating::HitboxToWorldTransforms(uint32_t iBone, matrix3x4_t* transforms)
{
const static int index = 285;
CallVFunc<void>(index, this, iBone, transforms);
}
//-----------------------------------------------------------------------------
// Purpose: sets studio pointer to an updated studiomdl cache
//-----------------------------------------------------------------------------
void CBaseAnimating::UpdateModelPtr()
{
// Populates the 'm_pStudioHdr' field.
v_CBaseAnimating__UpdateModelPtr(this);
}
void DrawServerHitboxes(CBaseAnimating* thisp, float duration)
{
thisp->DrawServerHitboxes(duration);
}
void BaseAnimating_Attach()
{
DetourAttach(&v_CBaseAnimating__DrawServerHitboxes, &DrawServerHitboxes);
}
void BaseAnimating_Detach()
{
DetourDetach(&v_CBaseAnimating__DrawServerHitboxes, &DrawServerHitboxes);
}

View File

@ -16,6 +16,15 @@
class CBaseAnimating : public CBaseEntity
{
public:
void DrawServerHitboxes(float duration = 0.0f);
void UpdateModelPtr();
void HitboxToWorldTransforms(uint32_t iBone, matrix3x4_t* transforms);
float GetModelScale() const { return m_flModelScale; }
protected:
char gap_b04[8]; // Aligns properly in IDA and generated code after setting from 12 to 8.
bool m_markedForServerInterpolation;
bool m_animRemoveFromServerInterpolationNextFrame;
@ -126,5 +135,40 @@ class CBaseAnimating : public CBaseEntity
char gap_11E4[12]; // TODO: this might belong to CBaseAnimatingOverlay!
};
inline CMemory p_CBaseAnimating__UpdateModelPtr;
inline auto v_CBaseAnimating__UpdateModelPtr = p_CBaseAnimating__UpdateModelPtr.RCast<CBaseAnimating* (*)(CBaseAnimating* thisp)>();
inline CMemory p_CBaseAnimating__DrawServerHitboxes;
inline auto v_CBaseAnimating__DrawServerHitboxes = p_CBaseAnimating__DrawServerHitboxes.RCast<void (*)(CBaseAnimating* thisp, float duration)>();
void BaseAnimating_Attach();
void BaseAnimating_Detach();
///////////////////////////////////////////////////////////////////////////////
class VBaseAnimating : public IDetour
{
virtual void GetAdr(void) const
{
spdlog::debug("| FUN: CBaseAnimating::UpdateModelPtr : {:#18x} |\n", p_CBaseAnimating__UpdateModelPtr.GetPtr());
spdlog::debug("| FUN: CBaseAnimating::DrawServerHitboxes : {:#18x} |\n", p_CBaseAnimating__DrawServerHitboxes.GetPtr());
spdlog::debug("+----------------------------------------------------------------+\n");
}
virtual void GetFun(void) const
{
p_CBaseAnimating__UpdateModelPtr = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 41 56 48 83 EC 20 0F BF 41 58");
v_CBaseAnimating__UpdateModelPtr = p_CBaseAnimating__UpdateModelPtr.RCast<CBaseAnimating* (*)(CBaseAnimating* thisp)>();
p_CBaseAnimating__DrawServerHitboxes = g_GameDll.FindPatternSIMD("41 57 48 81 EC ?? ?? ?? ?? 48 83 B9 ?? ?? ?? ?? ?? 4C 8B F9"); // !FIXME NOT COMPAT WITH S0~S2!
v_CBaseAnimating__DrawServerHitboxes = p_CBaseAnimating__DrawServerHitboxes.RCast<void (*)(CBaseAnimating* thisp, float duration)>();
}
virtual void GetVar(void) const { }
virtual void GetCon(void) const { }
virtual void Attach(void) const { }
virtual void Detach(void) const { }
};
///////////////////////////////////////////////////////////////////////////////
REGISTER(VBaseAnimating);
#endif // BASEANIMATING_H