-
Автор темы
- #1
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
168.352 // world bone pos
109.24
-------------
6.6453e+35 // w2s
1.31722e-43
109.24
-------------
6.6453e+35 // w2s
1.31722e-43
cryengine_matrix4x4_t:
struct cryengine_matrix4x4_t {
float m00, m01, m02, m03;
float m10, m11, m12, m13;
float m20, m21, m22, m23;
float m30, m31, m32, m33;
cryengine_matrix4x4_t() = default;
void set_identity() {
m00 = 1;
m01 = 0;
m02 = 0;
m03 = 0;
m10 = 0;
m11 = 1;
m12 = 0;
m13 = 0;
m20 = 0;
m21 = 0;
m22 = 1;
m23 = 0;
m30 = 0;
m31 = 0;
m32 = 0;
m33 = 1;
}
void sanitaze() {
if (!std::isfinite(m00))
m00 = 0.f;
if (!std::isfinite(m01))
m01 = 0.f;
if (!std::isfinite(m02))
m02 = 0.f;
if (!std::isfinite(m03))
m03 = 0.f;
if (!std::isfinite(m10))
m10 = 0.f;
if (!std::isfinite(m11))
m11 = 0.f;
if (!std::isfinite(m12))
m12 = 0.f;
if (!std::isfinite(m13))
m13 = 0.f;
if (!std::isfinite(m20))
m20 = 0.f;
if (!std::isfinite(m21))
m21 = 0.f;
if (!std::isfinite(m22))
m22 = 0.f;
if (!std::isfinite(m23))
m23 = 0.f;
if (!std::isfinite(m30))
m30 = 0.f;
if (!std::isfinite(m31))
m31 = 0.f;
if (!std::isfinite(m32))
m32 = 0.f;
if (!std::isfinite(m33))
m33 = 0.f;
}
};
viewport_t:
struct viewport_t {
int x, y, w, h;
};
CRenderer:
class CRenderer {
public:
viewport_t m_pViewPort() {
return ReadProcessMemoryDriver<viewport_t>((DWORD64)this + 0x14B718);
}
int GetWidth()
{
return ReadProcessMemoryDriver<int>((DWORD64)this + 0x14B7F8);
}
int GetHeight()
{
return ReadProcessMemoryDriver<int>((DWORD64)this + 0x14B7FC);
}
cryengine_matrix4x4_t m_matViewTop() {
auto m_matView = ReadProcessMemoryDriver<std::uintptr_t>(ReadProcessMemoryDriver<std::uintptr_t>(reinterpret_cast<std::uintptr_t>(this) + 0x328 + 0xF38));
return ReadProcessMemoryDriver<cryengine_matrix4x4_t>(m_matView); // m_matView->m_pTop
}
cryengine_matrix4x4_t m_matProjTop() {
auto m_matProj = ReadProcessMemoryDriver<std::uintptr_t>(ReadProcessMemoryDriver<std::uintptr_t>(reinterpret_cast<std::uintptr_t>(this) + 0x328 + 0xF40));
return ReadProcessMemoryDriver<cryengine_matrix4x4_t>(m_matProj); // m_matProj->m_pTop
}
};
project_to_screen_t:
struct project_to_screen_t {
float ptx, pty, ptz; // project_to_N
float sx, sy, sz; // screen_N
};
mathVec4Transform:
inline void mathVec4Transform(float out[4], const float m[16],
const float in[4]) {
#define M(row, col) m[col * 4 + row]
out[0] =
M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];
out[1] =
M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3];
out[2] =
M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3];
out[3] =
M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];
#undef M
}
mathVec3Project:
inline float mathVec3Project(Vec3& pvWin, const Vec3& pvObj,
const viewport_t pViewport,
const cryengine_matrix4x4_t* pProjection,
const cryengine_matrix4x4_t* pView,
const cryengine_matrix4x4_t* pWorld) {
// [USER=496893]@xRef[/USER]
// https://github.com/MergHQ/CRYENGINE/blob/8b63f61c6bb186fbee254b793775856468df47c5/Code/CryEngine/CryCommon/CryMath/Cry_XOptimise.h#L310
Vec4 in{}, out{};
in.x = pvObj.x;
in.y = pvObj.y;
in.z = pvObj.z;
in.w = 1.0f;
mathVec4Transform(
reinterpret_cast<float*>(&out),
const_cast<float*>(reinterpret_cast<const float*>(pWorld)),
reinterpret_cast<float*>(&in));
mathVec4Transform(reinterpret_cast<float*>(&in),
const_cast<float*>(reinterpret_cast<const float*>(pView)),
reinterpret_cast<float*>(&out));
mathVec4Transform(
reinterpret_cast<float*>(&out),
const_cast<float*>(reinterpret_cast<const float*>(pProjection)),
reinterpret_cast<float*>(&in));
if (out.w == 0.f)
return 0.f;
out.x /= out.w;
out.y /= out.w;
out.z /= out.w;
pvWin.x = pViewport.x + (1.f + out.x) * pViewport.w / 2.f;
pvWin.y = pViewport.y + (1.f - out.y) * pViewport.h / 2.f;
pvWin.z = out.z;
return out.w;
}
ProjectToScreenInternal_Rebuild:
bool ProjectToScreenInternal_Rebuild(CRenderer* _this, float ptx, float pty,
float ptz, float& sx, float& sy,
float& sz) {
// [USER=496893]@xRef[/USER]: 48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 48 89 7C 24 20 41 56 48
// 81 EC A0 00 00 00 48 8B 99
Vec3 out{};
Vec3 in = { ptx, pty, ptz };
auto viewport = _this->m_pViewPort();
auto matrix_view = _this->m_matViewTop();
auto matrix_projection = _this->m_matProjTop();
cryengine_matrix4x4_t matrix_world{};
matrix_view.sanitaze();
matrix_projection.sanitaze();
matrix_world.set_identity();
if (mathVec3Project(out, in, viewport, &matrix_projection, &matrix_view,
&matrix_world) == 0.f)
return false;
sx = out.x * 100.f / viewport.w;
sy = out.y * 100.f / viewport.h;
sz = out.z;
return true;
}
world_to_screen:
bool world_to_screen(const Vec3 in, Vec3 out) {
project_to_screen_t pts{ in.x, in.y, in.z, out.x, out.y, out.z };
CRenderer* pRenderer = CGameStartup::pEnv()->GetCRenderer();
if (!ProjectToScreenInternal_Rebuild(pRenderer, pts.ptx, pts.pty, pts.ptz, pts.sx, pts.sy, pts.sz))
return false;
if (pts.sz > 1.f) // behind camera
return false;
out.x = pts.sx * (pRenderer->GetHeight() / 100.f);
out.y = pts.sy * (pRenderer->GetWidth() / 100.f);
return true;
};