2
0
mirror of https://github.com/rehlds/rehlds.git synced 2025-02-08 11:32:19 +03:00

Hitbox tracking

This commit is contained in:
dreamstalker 2015-07-08 23:50:25 +04:00
parent 9cbc891694
commit 5b50c6fb89
9 changed files with 275 additions and 3 deletions

View File

@ -185,6 +185,7 @@
<ClCompile Include="..\public\utlbuffer.cpp" /> <ClCompile Include="..\public\utlbuffer.cpp" />
<ClCompile Include="..\rehlds\FlightRecorderImpl.cpp" /> <ClCompile Include="..\rehlds\FlightRecorderImpl.cpp" />
<ClCompile Include="..\rehlds\flight_recorder.cpp" /> <ClCompile Include="..\rehlds\flight_recorder.cpp" />
<ClCompile Include="..\rehlds\math_utils.cpp" />
<ClCompile Include="..\rehlds\rehlds_api_impl.cpp" /> <ClCompile Include="..\rehlds\rehlds_api_impl.cpp" />
<ClCompile Include="..\rehlds\rehlds_interfaces_impl.cpp" /> <ClCompile Include="..\rehlds\rehlds_interfaces_impl.cpp" />
<ClCompile Include="..\rehlds\hookchains_impl.cpp" /> <ClCompile Include="..\rehlds\hookchains_impl.cpp" />
@ -269,6 +270,14 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Play|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Play|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Swds Play|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Swds Play|Win32'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\unittests\math_util_tests.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Swds|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Play|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Record|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Play|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Swds Play|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Swds Play|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\unittests\rehlds_tests_shared.cpp" /> <ClCompile Include="..\unittests\rehlds_tests_shared.cpp" />
<ClCompile Include="..\unittests\struct_offsets_tests.cpp"> <ClCompile Include="..\unittests\struct_offsets_tests.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@ -538,6 +547,7 @@
<ClInclude Include="..\rehlds\FlightRecorderImpl.h" /> <ClInclude Include="..\rehlds\FlightRecorderImpl.h" />
<ClInclude Include="..\rehlds\flight_recorder.h" /> <ClInclude Include="..\rehlds\flight_recorder.h" />
<ClInclude Include="..\rehlds\hookchains_impl.h" /> <ClInclude Include="..\rehlds\hookchains_impl.h" />
<ClInclude Include="..\rehlds\math_utils.h" />
<ClInclude Include="..\rehlds\platform.h" /> <ClInclude Include="..\rehlds\platform.h" />
<ClInclude Include="..\rehlds\precompiled.h" /> <ClInclude Include="..\rehlds\precompiled.h" />
<ClInclude Include="..\rehlds\RehldsRuntimeConfig.h" /> <ClInclude Include="..\rehlds\RehldsRuntimeConfig.h" />
@ -833,7 +843,7 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>REHLDS_FIXES;REHLDS_FLIGHT_REC;REHLDS_OPT_PEDANTIC;REHLDS_SELF;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>REHLDS_FLIGHT_REC;REHLDS_OPT_PEDANTIC;REHLDS_SELF;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FloatingPointModel>Precise</FloatingPointModel> <FloatingPointModel>Precise</FloatingPointModel>
<AdditionalOptions>/arch:IA32 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/arch:IA32 %(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>

View File

@ -346,6 +346,12 @@
<ClCompile Include="..\rehlds\rehlds_security.cpp"> <ClCompile Include="..\rehlds\rehlds_security.cpp">
<Filter>rehlds</Filter> <Filter>rehlds</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\rehlds\math_utils.cpp">
<Filter>rehlds</Filter>
</ClCompile>
<ClCompile Include="..\unittests\math_util_tests.cpp">
<Filter>unittests</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\hookers\memory.h"> <ClInclude Include="..\hookers\memory.h">
@ -1065,6 +1071,9 @@
<ClInclude Include="..\rehlds\rehlds_security.h"> <ClInclude Include="..\rehlds\rehlds_security.h">
<Filter>rehlds</Filter> <Filter>rehlds</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\rehlds\math_utils.h">
<Filter>rehlds</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\linux\appversion.sh"> <None Include="..\linux\appversion.sh">

View File

@ -35,7 +35,7 @@
#include "model.h" #include "model.h"
#define REHLDS_API_VERSION_MAJOR 1 #define REHLDS_API_VERSION_MAJOR 1
#define REHLDS_API_VERSION_MINOR 2 #define REHLDS_API_VERSION_MINOR 3
//Steam_NotifyClientConnect hook //Steam_NotifyClientConnect hook
typedef IHookChain<qboolean, IGameClient*, const void*, unsigned int> IRehldsHook_Steam_NotifyClientConnect; typedef IHookChain<qboolean, IGameClient*, const void*, unsigned int> IRehldsHook_Steam_NotifyClientConnect;
@ -199,6 +199,7 @@ struct RehldsFuncs_t {
void(*MSG_WriteBitVec3Coord)(const float *fa); void(*MSG_WriteBitVec3Coord)(const float *fa);
void(*MSG_EndBitWriting)(sizebuf_t *buf); void(*MSG_EndBitWriting)(sizebuf_t *buf);
void*(*SZ_GetSpace)(sizebuf_t *buf, int length); void*(*SZ_GetSpace)(sizebuf_t *buf, int length);
bool(*GetHitboxCorners)(int hitboxId, float* /* [8*3] */ corners);
}; };
class IRehldsApi { class IRehldsApi {

View File

@ -0,0 +1,81 @@
#include "precompiled.h"
double CalculateDeterminant(matrix33_t &matrix) {
return
matrix[0][0] * matrix[1][1] * matrix[2][2]
- matrix[0][0] * matrix[1][2] * matrix[2][1]
+ matrix[1][0] * matrix[2][1] * matrix[0][2]
- matrix[1][0] * matrix[2][2] * matrix[0][1]
+ matrix[2][0] * matrix[0][1] * matrix[1][2]
- matrix[2][0] * matrix[0][2] * matrix[1][1];
}
equation_sys_resolve_res ResolveEq3Sys(equation3_t* eqs, double* res) {
matrix33_t mainDtMtx = {
{ eqs[0].a, eqs[0].b, eqs[0].c },
{ eqs[1].a, eqs[1].b, eqs[1].c },
{ eqs[2].a, eqs[2].b, eqs[2].c }
};
matrix33_t dtxMtx = {
{ eqs[0].h, eqs[0].b, eqs[0].c },
{ eqs[1].h, eqs[1].b, eqs[1].c },
{ eqs[2].h, eqs[2].b, eqs[2].c }
};
matrix33_t dtyMtx = {
{ eqs[0].a, eqs[0].h, eqs[0].c },
{ eqs[1].a, eqs[1].h, eqs[1].c },
{ eqs[2].a, eqs[2].h, eqs[2].c }
};
matrix33_t dtzMtx = {
{ eqs[0].a, eqs[0].b, eqs[0].h },
{ eqs[1].a, eqs[1].b, eqs[1].h },
{ eqs[2].a, eqs[2].b, eqs[2].h }
};
double mainDt = CalculateDeterminant(mainDtMtx);
double dtx = CalculateDeterminant(dtxMtx);
double dty = CalculateDeterminant(dtyMtx);
double dtz = CalculateDeterminant(dtzMtx);
if (abs(mainDt) > 0.000001) {
res[0] = dtx / mainDt;
res[1] = dty / mainDt;
res[2] = dtz / mainDt;
return EQSR_1;
}
return (abs(dtx) > 0.000001) ? EQSR_NONE : EQSR_INF;
}
plane_itx_res CalcPlanesIntersection(mplane_t* p1, mplane_t* p2, mplane_t* p3, float* res) {
equation3_t eqs[] = {
{ p1->normal[0], p1->normal[1], p1->normal[2], p1->dist },
{ p2->normal[0], p2->normal[1], p2->normal[2], p2->dist },
{ p3->normal[0], p3->normal[1], p3->normal[2], p3->dist },
};
double dblRes[3];
auto resKind = ResolveEq3Sys(eqs, dblRes);
switch (resKind) {
case EQSR_1:
res[0] = dblRes[0];
res[1] = dblRes[1];
res[2] = dblRes[2];
return PIR_1;
case EQSR_INF:
return PIR_INF;
case EQSR_NONE:
return PIR_NONE;
default:
rehlds_syserror(__FUNCTION__": invalid resKind %d", resKind);
return PIR_NONE;
}
}

View File

@ -0,0 +1,28 @@
#pragma once
#include "engine.h"
typedef float matrix33_t[3][3];
//ax + by + cz = h
struct equation3_t {
double a, b, c, h;
};
enum equation_sys_resolve_res {
EQSR_1,
EQSR_NONE,
EQSR_INF,
};
enum plane_itx_res {
PIR_1,
PIR_NONE,
PIR_INF,
};
extern double CalculateDeterminant(matrix33_t &matrix);
extern equation_sys_resolve_res ResolveEq3Sys(equation3_t* eqs, double* res);
extern plane_itx_res CalcPlanesIntersection(mplane_t* p1, mplane_t* p2, mplane_t* p3, float* res);

View File

@ -19,6 +19,8 @@
#include "RehldsRuntimeConfig.h" #include "RehldsRuntimeConfig.h"
#include "rehlds_debug.h" #include "rehlds_debug.h"
#include "math_utils.h"
#ifdef HOOK_ENGINE #ifdef HOOK_ENGINE
#include "hooker.h" #include "hooker.h"
#endif #endif
@ -35,6 +37,7 @@
#include "iosutil.h" #include "iosutil.h"
//testsuite //testsuite
#include "testsuite.h" #include "testsuite.h"
#include "funccalls.h" #include "funccalls.h"

View File

@ -65,6 +65,52 @@ DLL_FUNCTIONS* EXT_FUNC GetEntityInterface_api() {
return &gEntityInterface; return &gEntityInterface;
} }
bool EXT_FUNC GetHitboxCorners(int hitboxId, float* /* [8*3] */ corners) {
mplane_t* right = &studio_planes[hitboxId * 6 + 0 * 2 + 0];
mplane_t* left = &studio_planes[hitboxId * 6 + 0 * 2 + 1];
mplane_t* rear = &studio_planes[hitboxId * 6 + 1 * 2 + 0];
mplane_t* front = &studio_planes[hitboxId * 6 + 1 * 2 + 1];
mplane_t* top = &studio_planes[hitboxId * 6 + 2 * 2 + 0];
mplane_t* bottom = &studio_planes[hitboxId * 6 + 2 * 2 + 1];
float p[3];
if (PIR_1 != CalcPlanesIntersection(left, front, bottom, p))
return false;
corners[0 * 3 + 0] = p[0]; corners[0 * 3 + 1] = p[1]; corners[0 * 3 + 1] = p[2];
if (PIR_1 != CalcPlanesIntersection(left, front, top, p))
return false;
corners[1 * 3 + 0] = p[0]; corners[1 * 3 + 1] = p[1]; corners[1 * 3 + 1] = p[2];
if (PIR_1 != CalcPlanesIntersection(right, front, top, p))
return false;
corners[2 * 3 + 0] = p[0]; corners[2 * 3 + 1] = p[1]; corners[2 * 3 + 1] = p[2];
if (PIR_1 != CalcPlanesIntersection(right, front, bottom, p))
return false;
corners[3 * 3 + 0] = p[0]; corners[3 * 3 + 1] = p[1]; corners[3 * 3 + 1] = p[2];
if (PIR_1 != CalcPlanesIntersection(left, rear, bottom, p))
return false;
corners[4 * 3 + 0] = p[0]; corners[4 * 3 + 1] = p[1]; corners[4 * 3 + 1] = p[2];
if (PIR_1 != CalcPlanesIntersection(left, rear, top, p))
return false;
corners[5 * 3 + 0] = p[0]; corners[5 * 3 + 1] = p[1]; corners[5 * 3 + 1] = p[2];
if (PIR_1 != CalcPlanesIntersection(right, rear, top, p))
return false;
corners[6 * 3 + 0] = p[0]; corners[6 * 3 + 1] = p[1]; corners[6 * 3 + 1] = p[2];
if (PIR_1 != CalcPlanesIntersection(right, rear, bottom, p))
return false;
corners[7 * 3 + 0] = p[0]; corners[7 * 3 + 1] = p[1]; corners[7 * 3 + 1] = p[2];
return true;
}
CRehldsServerStatic g_RehldsServerStatic; CRehldsServerStatic g_RehldsServerStatic;
CRehldsServerData g_RehldsServerData; CRehldsServerData g_RehldsServerData;
CRehldsHookchains g_RehldsHookchains; CRehldsHookchains g_RehldsHookchains;
@ -99,7 +145,8 @@ RehldsFuncs_t g_RehldsApiFuncs =
&MSG_WriteBits, &MSG_WriteBits,
&MSG_WriteBitVec3Coord, &MSG_WriteBitVec3Coord,
&MSG_EndBitWriting, &MSG_EndBitWriting,
&SZ_GetSpace &SZ_GetSpace,
&GetHitboxCorners
}; };
sizebuf_t* EXT_FUNC GetNetMessage_api() sizebuf_t* EXT_FUNC GetNetMessage_api()

View File

@ -31,6 +31,8 @@
#include "rehlds_api.h" #include "rehlds_api.h"
#include "rehlds_interfaces_impl.h" #include "rehlds_interfaces_impl.h"
extern bool GetHitboxCorners(int hitboxId, float* /* [8*3] */ corners);
//Steam_NotifyClientConnect //Steam_NotifyClientConnect
typedef IHookChainImpl<qboolean, IGameClient*, const void*, unsigned int> CRehldsHook_Steam_NotifyClientConnect; typedef IHookChainImpl<qboolean, IGameClient*, const void*, unsigned int> CRehldsHook_Steam_NotifyClientConnect;
typedef IHookChainRegistryImpl<qboolean, IGameClient*, const void*, unsigned int> CRehldsHookRegistry_Steam_NotifyClientConnect; typedef IHookChainRegistryImpl<qboolean, IGameClient*, const void*, unsigned int> CRehldsHookRegistry_Steam_NotifyClientConnect;

View File

@ -0,0 +1,91 @@
#include "precompiled.h"
#include "rehlds_tests_shared.h"
#include "cppunitlite/TestHarness.h"
TEST(CalculateDeterminant, MathUtils, 1000) {
struct testdata_t {
matrix33_t mtx;
double d;
};
testdata_t testdata[] = {
{
{
{ 2.0, 5.0, -2.0 },
{ 3.0, 8.0, 0.0 },
{ 1.0, 3.0, 5.0 },
},
3.0
},
{
{
{ 4.0, -3.0, 2.0 },
{ 6.0, 11.0, 1.0 },
{ 0.0, 3.0, 0.0 },
},
24.0
}
};
for (int i = 0; i < ARRAYSIZE(testdata); i++) {
testdata_t* t = &testdata[i];
double dt = CalculateDeterminant(t->mtx);
DOUBLES_EQUAL("Determinant mismatch", t->d, dt, 0.001);
}
}
TEST(ResolveEq3Sys, MathUtils, 1000) {
struct testdata_t {
equation3_t eqs[3];
equation_sys_resolve_res resKind;
double res[3];
};
testdata_t testdata[] = {
{
{
{ 3.0, 4.0, 2.0, 5.0 },
{ 5.0, -6.0, -4.0, -3.0 },
{ -4.0, 5.0, 3.0, 1.0 }
},
EQSR_1,
{ 1.0, -2.0, 5.0 }
},
{
{
{ 1.0, 1.0, 1.0, 5.0 },
{ 1.0, -1.0, 1.0, 1.0 },
{ 1.0, 0.0, 1.0, 2.0 }
},
EQSR_NONE,
{ 0.0, 0.0, 0.0 }
},
{
{
{ 1.0, 1.0, 1.0, 5.0 },
{ 1.0, -1.0, 1.0, 1.0 },
{ 1.0, 0.0, 1.0, 3.0 }
},
EQSR_INF,
{ 0.0, 0.0, 0.0 }
}
};
for (int i = 0; i < ARRAYSIZE(testdata); i++) {
testdata_t* t = &testdata[i];
double res[3];
equation_sys_resolve_res resKind = ResolveEq3Sys(t->eqs, res);
UINT32_EQUALS("resKind mismatch", (uint32)t->resKind, (uint32)resKind);
if (resKind == EQSR_1) {
DOUBLES_EQUAL("res[0] mismatch", t->res[0], res[0], 0.00001);
DOUBLES_EQUAL("res[1] mismatch", t->res[1], res[1], 0.00001);
DOUBLES_EQUAL("res[2] mismatch", t->res[2], res[2], 0.00001);
}
}
}