-
Автор темы
- #1
C++:
std::vector <scan_point> aim::get_points(adjust_data* record, int hitbox)
{
std::vector <scan_point> points; //-V827
auto model = record->player->GetModel();
if (!model)
return points;
auto hdr = m_modelinfo()->GetStudioModel(model);
if (!hdr)
return points;
auto set = hdr->pHitboxSet(record->player->m_nHitboxSet());
if (!set)
return points;
auto bbox = set->pHitbox(hitbox);
if (!bbox)
return points;
auto center = (bbox->bbmin + bbox->bbmax) * 0.5f;
if (bbox->radius <= 0.0f)
{
// references:
// https://developer.valvesoftware.com/wiki/Rotation_Tutorial
// CBaseAnimating::GetHitboxBonePosition
// CBaseAnimating::DrawServerHitboxes
// convert rotation angle to a matrix.
matrix3x4_t rot_matrix;
math::AngleMatrix(bbox->rotation, rot_matrix);
// apply the rotation to the entity input space (local).
matrix3x4_t mat;
math::ConcatTransforms(record->matrixes_data.main[bbox->bone], rot_matrix, mat);
// extract origin from matrix.
Vector origin = mat.GetOrigin();
// compute raw center point.
Vector center = (bbox->bbmin + bbox->bbmax) / 2.f;
if (hitbox == HITBOX_RIGHT_FOOT || hitbox == HITBOX_LEFT_FOOT)
{
float d1 = (bbox->bbmin.z - center.z) * 0.875f;
// invert.
if (hitbox == HITBOX_LEFT_FOOT)
d1 *= -1.f;
// side is more optimal then center.
points.emplace_back(scan_point(Vector(center.x, center.y, center.z + d1), hitbox, false));
float d2 = (bbox->bbmin.x - center.x) * 0.5f;
float d3 = (bbox->bbmax.x - center.x) * 0.5f;
// heel.
points.emplace_back(scan_point(Vector(center.x + d2, center.y, center.z), hitbox, false));
// toe.
points.emplace_back(scan_point(Vector(center.x + d3, center.y, center.z), hitbox, false));
}
else
points.emplace_back(scan_point(center, hitbox, true));
// nothing to do here we are done.
if (points.empty())
return points;
for (auto& p : points)
{
// VectorRotate.
// rotate point by angle stored in matrix.
p.point = { p.point.Dot(mat[0]), p.point.Dot(mat[1]), p.point.Dot(mat[2]) };
// transform point to world space.
p.point += origin;
}
}
else
{
// compute raw center point.
Vector max = bbox->bbmax;
Vector min = bbox->bbmin;
Vector center = (bbox->bbmin + bbox->bbmax) / 2.f;
// head has 5 points.
if (hitbox == HITBOX_HEAD) {
// add center.
float r = bbox->radius * GetHeadScale(record->player);
points.emplace_back(scan_point(center, hitbox, true));
if (true) {
// rotation matrix 45 degrees.
// https://math.stackexchange.com/questions/383321/rotating-x-y-points-45-degrees
// std::cos( deg_to_rad( 45.f ) )
constexpr float rotation = 0.70710678f;
// top/back 45 deg.
// this is the best spot to shoot at.
points.emplace_back(scan_point(Vector{ max.x + (rotation * r * 0.7f), max.y + (-rotation * r * 0.7f), max.z }, hitbox, false));
Vector right{ max.x, max.y, max.z + r };
// right.
points.emplace_back(scan_point(right, hitbox, false));
Vector left{ max.x, max.y, max.z - r };
// left.
points.emplace_back(scan_point(left, hitbox, false));
// back.
points.emplace_back(scan_point(Vector{ max.x, max.y - r, max.z }, hitbox, false));
// get animstate ptr.
c_baseplayeranimationstate* state = record->player->get_animation_state();
// add this point only under really specific circumstances.
// if we are standing still and have the lowest possible pitch pose.
if (state && record->player->m_vecVelocity().Length() <= 0.1f && record->player->m_angEyeAngles().x <= 75.f) {
// bottom point.
points.emplace_back(scan_point(Vector{ max.x - r, max.y, max.z }, hitbox, false));
}
}
}
// body has 5 points.
else {
float r = bbox->radius * GetBodyScale(record->player);
if (hitbox == HITBOX_STOMACH) {
// center.
points.emplace_back(scan_point(center, hitbox, true));
points.emplace_back(scan_point(Vector(center.x, center.y, min.z + r), hitbox, false));
points.emplace_back(scan_point(Vector(center.x, center.y, max.z - r), hitbox, false));
// back.
points.emplace_back(scan_point(Vector{ center.x, max.y - r, center.z }, hitbox, true));
}
else if (hitbox == HITBOX_PELVIS || hitbox == HITBOX_UPPER_CHEST) {
points.emplace_back(scan_point(center, hitbox, true));
// left & right points
points.emplace_back(scan_point(Vector(center.x, center.y, max.z + r), hitbox, false));
points.emplace_back(scan_point(Vector(center.x, center.y, min.z - r), hitbox, false));
}
// other stomach/chest hitboxes have 2 points.
else if (hitbox == HITBOX_LOWER_CHEST || hitbox == HITBOX_CHEST) {
// left & right points
points.emplace_back(scan_point(Vector(center.x, center.y, max.z + r), hitbox, false));
points.emplace_back(scan_point(Vector(center.x, center.y, min.z - r), hitbox, false));
// add extra point on back.
points.emplace_back(scan_point(Vector{ center.x, max.y - r, center.z }, hitbox, false));
}
else if (hitbox == HITBOX_RIGHT_CALF || hitbox == HITBOX_LEFT_CALF) {
// add center.
points.emplace_back(scan_point(center, hitbox, true));
// half bottom.
points.emplace_back(scan_point(Vector{ max.x - (bbox->radius / 2.f), max.y, max.z }, hitbox, false));
}
else if (hitbox == HITBOX_RIGHT_THIGH || hitbox == HITBOX_LEFT_THIGH) {
// add center.
points.emplace_back(scan_point(center, hitbox, true));
// bottom point (knees)
points.emplace_back(scan_point(Vector{ max.x + (bbox->radius / 3.f), max.y, max.z }, hitbox, false));
}
// arms get only one point.
else if (hitbox == HITBOX_RIGHT_UPPER_ARM || hitbox == HITBOX_LEFT_UPPER_ARM) {
// elbow.
points.emplace_back(scan_point(Vector{ max.x + (bbox->radius / 2.f), center.y, center.z }, hitbox, false));
}
}
// nothing left to do here.
if (points.empty())
return points;
for (auto& point : points)
math::vector_transform(point.point, record->matrixes_data.main[bbox->bone], point.point);
}
return points;
}