Backtrack performance fix, Profiler fixed

For future reference: SetupBones is very very slow
This commit is contained in:
TotallyNotElite 2019-01-18 22:53:47 +01:00
parent 482459bf33
commit 934901db27
5 changed files with 47 additions and 59 deletions

File diff suppressed because one or more lines are too long

View File

@ -44,9 +44,6 @@ void EntityHitboxCache::InvalidateCache()
void EntityHitboxCache::Update() void EntityHitboxCache::Update()
{ {
InvalidateCache(); InvalidateCache();
if (CE_BAD(parent_ref))
if (GetHitbox(0))
return;
} }
void EntityHitboxCache::Init() void EntityHitboxCache::Init()
@ -103,7 +100,7 @@ bool EntityHitboxCache::VisibilityCheck(int id)
return m_VisCheck[id]; return m_VisCheck[id];
} }
static settings::Int setupbones_time{ "source.setupbones-time", "0" }; static settings::Int setupbones_time{ "source.setupbones-time", "1" };
static std::mutex setupbones_mutex; static std::mutex setupbones_mutex;
@ -155,34 +152,32 @@ void EntityHitboxCache::Reset()
CachedHitbox *EntityHitboxCache::GetHitbox(int id) CachedHitbox *EntityHitboxCache::GetHitbox(int id)
{ {
if (m_CacheValidationFlags[id])
return &m_CacheInternal[id];
mstudiobbox_t *box; mstudiobbox_t *box;
if (!m_bInit) if (!m_bInit)
Init(); Init();
if (id < 0 || id >= m_nNumHitboxes) if (id < 0 || id >= m_nNumHitboxes)
return 0; return nullptr;
if (!m_bSuccess) if (!m_bSuccess)
return 0; return nullptr;
if (CE_BAD(parent_ref)) if (CE_BAD(parent_ref))
return 0; return nullptr;
typedef int (*InvalidateBoneCache_t)(IClientEntity *); auto model = (const model_t *) RAW_ENT(parent_ref)->GetModel();
static uintptr_t addr = gSignatures.GetClientSignature("55 8B 0D ? ? ? ? 89 E5 8B 45 ? 8D 51");
static InvalidateBoneCache_t InvalidateBoneCache = InvalidateBoneCache_t(addr);
InvalidateBoneCache(RAW_ENT(parent_ref));
auto model = (model_t *) RAW_ENT(parent_ref)->GetModel();
if (!model) if (!model)
return 0; return nullptr;
auto shdr = g_IModelInfo->GetStudiomodel(model); auto shdr = g_IModelInfo->GetStudiomodel(model);
if (!shdr) if (!shdr)
return 0; return nullptr;
auto set = shdr->pHitboxSet(CE_INT(parent_ref, netvar.iHitboxSet)); auto set = shdr->pHitboxSet(CE_INT(parent_ref, netvar.iHitboxSet));
if (!dynamic_cast<mstudiohitboxset_t *>(set)) if (!dynamic_cast<mstudiohitboxset_t *>(set))
return 0; return nullptr;
box = set->pHitbox(id); box = set->pHitbox(id);
if (!box) if (!box)
return 0; return nullptr;
if (box->bone < 0 || box->bone >= MAXSTUDIOBONES) if (box->bone < 0 || box->bone >= MAXSTUDIOBONES)
return 0; return nullptr;
VectorTransform(box->bbmin, GetBones()[box->bone], m_CacheInternal[id].min); VectorTransform(box->bbmin, GetBones()[box->bone], m_CacheInternal[id].min);
VectorTransform(box->bbmax, GetBones()[box->bone], m_CacheInternal[id].max); VectorTransform(box->bbmax, GetBones()[box->bone], m_CacheInternal[id].max);
m_CacheInternal[id].bbox = box; m_CacheInternal[id].bbox = box;

View File

@ -75,7 +75,7 @@ void Init()
{ {
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
for (int j = 0; j < 66; j++) for (int j = 0; j < 66; j++)
EmptyBacktrackData(headPositions[i][j]); headPositions[i][j] = {};
} }
int BestTick = -1; int BestTick = -1;
@ -107,23 +107,21 @@ static void Run()
CUserCmd *cmd = current_user_cmd; CUserCmd *cmd = current_user_cmd;
float bestFov = 99999; float bestFov = 99999;
float prev_distance = 9999; float prev_distance = 9999;
std::pair<int, int> bestEntBestTick = getBestEntBestTick();
auto bestEntBestTick = getBestEntBestTick(); BestTick = bestEntBestTick.second;
BestTick = bestEntBestTick.second; iBestTarget = bestEntBestTick.first;
iBestTarget = bestEntBestTick.first; // Fill backtrack data (stored in headPositions)
for (int i = 1; i < g_IEngine->GetMaxClients(); i++) for (int i = 1; i < g_IEngine->GetMaxClients(); i++)
{ {
CachedEntity *pEntity = ENTITY(i); CachedEntity *pEntity = ENTITY(i);
if (CE_BAD(pEntity) || !pEntity->m_bAlivePlayer()) if (CE_BAD(pEntity) || !pEntity->m_bAlivePlayer())
{ {
for (BacktrackData &btd : headPositions[i]) for (BacktrackData &btd : headPositions[i])
EmptyBacktrackData(btd); btd.simtime = FLT_MAX;
continue; continue;
} }
if (pEntity->m_iTeam() == LOCAL_E->m_iTeam()) if (!pEntity->m_bEnemy())
continue; continue;
if (pEntity->m_Type() != ENTITY_PLAYER) if (pEntity->m_Type() != ENTITY_PLAYER)
continue; continue;
@ -131,26 +129,24 @@ static void Run()
continue; continue;
if (HasCondition<TFCond_HalloweenGhostMode>(pEntity)) if (HasCondition<TFCond_HalloweenGhostMode>(pEntity))
continue; continue;
auto &hbd = headPositions[i][cmd->command_number % getTicks()];
float _viewangles = CE_VECTOR(pEntity, netvar.m_angEyeAngles).y; float _viewangles = CE_VECTOR(pEntity, netvar.m_angEyeAngles).y;
float viewangles = (_viewangles > 180) ? _viewangles - 360 : _viewangles; hbd.viewangles = (_viewangles > 180) ? _viewangles - 360 : _viewangles;
float simtime = CE_FLOAT(pEntity, netvar.m_flSimulationTime); hbd.simtime = CE_FLOAT(pEntity, netvar.m_flSimulationTime);
Vector ent_orig = pEntity->InternalEntity()->GetAbsOrigin(); hbd.entorigin = pEntity->InternalEntity()->GetAbsOrigin();
std::array<hitboxData, 18> hbdArray; hbd.tickcount = cmd->tick_count;
for (size_t i = 0; i < hbdArray.max_size(); i++)
for (size_t i = 0; i < 18; i++)
{ {
hbdArray.at(i).center = pEntity->hitboxes.GetHitbox(i)->center; hbd.hitboxes[i].center = pEntity->hitboxes.GetHitbox(i)->center;
hbdArray.at(i).min = pEntity->hitboxes.GetHitbox(i)->min; hbd.hitboxes[i].min = pEntity->hitboxes.GetHitbox(i)->min;
hbdArray.at(i).max = pEntity->hitboxes.GetHitbox(i)->max; hbd.hitboxes[i].max = pEntity->hitboxes.GetHitbox(i)->max;
} }
hitboxData collidable{}; hbd.collidable.min = RAW_ENT(pEntity)->GetCollideable()->OBBMins() + hbd.entorigin;
{ hbd.collidable.max = RAW_ENT(pEntity)->GetCollideable()->OBBMaxs() + hbd.entorigin;
collidable.min = RAW_ENT(pEntity)->GetCollideable()->OBBMins() + ent_orig; hbd.collidable.center = (hbd.collidable.min + hbd.collidable.max) / 2;
collidable.max = RAW_ENT(pEntity)->GetCollideable()->OBBMaxs() + ent_orig;
collidable.center = (collidable.min + collidable.max) / 2;
}
auto hdr = g_IModelInfo->GetStudiomodel(RAW_ENT(pEntity)->GetModel());
headPositions[i][cmd->command_number % getTicks()] = BacktrackData{ cmd->tick_count, hbdArray, collidable, viewangles, simtime, ent_orig, cmd->command_number % getTicks() };
} }
if (iBestTarget != -1 && CanShoot()) if (iBestTarget != -1 && CanShoot())
{ {
CachedEntity *tar = ENTITY(iBestTarget); CachedEntity *tar = ENTITY(iBestTarget);

View File

@ -117,8 +117,6 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, CUs
} }
ret = original::CreateMove(this_, input_sample_time, cmd); ret = original::CreateMove(this_, input_sample_time, cmd);
PROF_SECTION(CreateMove);
if (!cmd) if (!cmd)
{ {
g_Settings.is_create_move = false; g_Settings.is_create_move = false;
@ -146,7 +144,7 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, CUs
return true; return true;
} }
// PROF_BEGIN(); PROF_SECTION(CreateMove);
if (current_user_cmd && current_user_cmd->command_number) if (current_user_cmd && current_user_cmd->command_number)
last_cmd_number = current_user_cmd->command_number; last_cmd_number = current_user_cmd->command_number;

View File

@ -6,24 +6,23 @@ namespace EC
struct EventCallbackData struct EventCallbackData
{ {
explicit EventCallbackData(const EventFunction &function, std::string name, enum ec_priority priority) : function{ function }, priority{ int(priority) }, event_name{ name }, section{ name } explicit EventCallbackData(const EventFunction &function, std::string name, enum ec_priority priority) : function{ function }, priority{ int(priority) }, section{ name }, event_name{ name }
{ {
section.m_name = name;
} }
EventFunction function; EventFunction function;
int priority; int priority;
mutable ProfilerSection section; ProfilerSection section;
std::string event_name; std::string event_name;
bool operator<(const EventCallbackData &other) const
{
return priority < other.priority;
}
}; };
// Ordered set to always keep priorities correct
static std::multiset<EventCallbackData> events[ec_types::EcTypesSize]; static std::vector<EventCallbackData> events[ec_types::EcTypesSize];
void Register(enum ec_types type, const EventFunction &function, const std::string &name, enum ec_priority priority) void Register(enum ec_types type, const EventFunction &function, const std::string &name, enum ec_priority priority)
{ {
events[type].insert(EventCallbackData(function, name, priority)); events[type].emplace_back(function, name, priority);
// Order vector to always keep priorities correct
std::sort(events[type].begin(), events[type].end(), [](EventCallbackData &a, EventCallbackData &b) { return a.priority < b.priority; });
} }
void Unregister(enum ec_types type, const std::string &name) void Unregister(enum ec_types type, const std::string &name)
@ -39,11 +38,11 @@ void Unregister(enum ec_types type, const std::string &name)
void run(ec_types type) void run(ec_types type)
{ {
const auto &set = events[type]; auto &vector = events[type];
for (auto &i : set) for (auto &i : vector)
{ {
#if ENABLE_PROFILER #if ENABLE_PROFILER
ProfilerNode node(i.section); volatile ProfilerNode node(i.section);
#endif #endif
i.function(); i.function();
} }