mirror of
https://github.com/rehlds/rehlds.git
synced 2025-02-08 03:22:17 +03:00
Hitbox tracking
This commit is contained in:
parent
9cbc891694
commit
5b50c6fb89
@ -185,6 +185,7 @@
|
||||
<ClCompile Include="..\public\utlbuffer.cpp" />
|
||||
<ClCompile Include="..\rehlds\FlightRecorderImpl.cpp" />
|
||||
<ClCompile Include="..\rehlds\flight_recorder.cpp" />
|
||||
<ClCompile Include="..\rehlds\math_utils.cpp" />
|
||||
<ClCompile Include="..\rehlds\rehlds_api_impl.cpp" />
|
||||
<ClCompile Include="..\rehlds\rehlds_interfaces_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 Swds Play|Win32'">true</ExcludedFromBuild>
|
||||
</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\struct_offsets_tests.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
@ -538,6 +547,7 @@
|
||||
<ClInclude Include="..\rehlds\FlightRecorderImpl.h" />
|
||||
<ClInclude Include="..\rehlds\flight_recorder.h" />
|
||||
<ClInclude Include="..\rehlds\hookchains_impl.h" />
|
||||
<ClInclude Include="..\rehlds\math_utils.h" />
|
||||
<ClInclude Include="..\rehlds\platform.h" />
|
||||
<ClInclude Include="..\rehlds\precompiled.h" />
|
||||
<ClInclude Include="..\rehlds\RehldsRuntimeConfig.h" />
|
||||
@ -833,7 +843,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<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>
|
||||
<AdditionalOptions>/arch:IA32 %(AdditionalOptions)</AdditionalOptions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
|
@ -346,6 +346,12 @@
|
||||
<ClCompile Include="..\rehlds\rehlds_security.cpp">
|
||||
<Filter>rehlds</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\rehlds\math_utils.cpp">
|
||||
<Filter>rehlds</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\unittests\math_util_tests.cpp">
|
||||
<Filter>unittests</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\hookers\memory.h">
|
||||
@ -1065,6 +1071,9 @@
|
||||
<ClInclude Include="..\rehlds\rehlds_security.h">
|
||||
<Filter>rehlds</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\rehlds\math_utils.h">
|
||||
<Filter>rehlds</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\linux\appversion.sh">
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "model.h"
|
||||
|
||||
#define REHLDS_API_VERSION_MAJOR 1
|
||||
#define REHLDS_API_VERSION_MINOR 2
|
||||
#define REHLDS_API_VERSION_MINOR 3
|
||||
|
||||
//Steam_NotifyClientConnect hook
|
||||
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_EndBitWriting)(sizebuf_t *buf);
|
||||
void*(*SZ_GetSpace)(sizebuf_t *buf, int length);
|
||||
bool(*GetHitboxCorners)(int hitboxId, float* /* [8*3] */ corners);
|
||||
};
|
||||
|
||||
class IRehldsApi {
|
||||
|
81
rehlds/rehlds/math_utils.cpp
Normal file
81
rehlds/rehlds/math_utils.cpp
Normal 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;
|
||||
}
|
||||
}
|
28
rehlds/rehlds/math_utils.h
Normal file
28
rehlds/rehlds/math_utils.h
Normal 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);
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "RehldsRuntimeConfig.h"
|
||||
#include "rehlds_debug.h"
|
||||
|
||||
#include "math_utils.h"
|
||||
|
||||
#ifdef HOOK_ENGINE
|
||||
#include "hooker.h"
|
||||
#endif
|
||||
@ -35,6 +37,7 @@
|
||||
|
||||
#include "iosutil.h"
|
||||
|
||||
|
||||
//testsuite
|
||||
#include "testsuite.h"
|
||||
#include "funccalls.h"
|
||||
|
@ -65,6 +65,52 @@ DLL_FUNCTIONS* EXT_FUNC GetEntityInterface_api() {
|
||||
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;
|
||||
CRehldsServerData g_RehldsServerData;
|
||||
CRehldsHookchains g_RehldsHookchains;
|
||||
@ -99,7 +145,8 @@ RehldsFuncs_t g_RehldsApiFuncs =
|
||||
&MSG_WriteBits,
|
||||
&MSG_WriteBitVec3Coord,
|
||||
&MSG_EndBitWriting,
|
||||
&SZ_GetSpace
|
||||
&SZ_GetSpace,
|
||||
&GetHitboxCorners
|
||||
};
|
||||
|
||||
sizebuf_t* EXT_FUNC GetNetMessage_api()
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "rehlds_api.h"
|
||||
#include "rehlds_interfaces_impl.h"
|
||||
|
||||
extern bool GetHitboxCorners(int hitboxId, float* /* [8*3] */ corners);
|
||||
|
||||
//Steam_NotifyClientConnect
|
||||
typedef IHookChainImpl<qboolean, IGameClient*, const void*, unsigned int> CRehldsHook_Steam_NotifyClientConnect;
|
||||
typedef IHookChainRegistryImpl<qboolean, IGameClient*, const void*, unsigned int> CRehldsHookRegistry_Steam_NotifyClientConnect;
|
||||
|
91
rehlds/unittests/math_util_tests.cpp
Normal file
91
rehlds/unittests/math_util_tests.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user