Исходник Multi-threaded multipoints for supremacy // c+p ready

Начинающий
Статус
Оффлайн
Регистрация
15 Окт 2019
Сообщения
23
Реакции[?]
5
Поинты[?]
5K
enjoy :roflanBuldiga::roflanBuldiga:
aimbot.cpp:
#include <vector>
#include <mutex>
#include <future>
#include <thread>
std::mutex points_mutex;  // for thread-safe access to points.

// function to process a range of hitboxes.
void AimPlayer::process_hitbox_range(int start, int end, LagRecord* record, matrix3x4_t* record_matrix, float mindmg, bool force_baim_misses, std::vector<AimPoint_t>& points) {
    const model_t* model = m_player->get_model();
    if (!model) return;

    studiohdr_t* hdr = model_info.get()->GetStudioModel(model);
    if (!hdr) return;

    mstudiohitboxset_t* set = hdr->GetHitboxSet(m_player->hitbox_set());
    if (!set) return;

    // thread-local storage for points.
    std::vector<AimPoint_t> local_points;

    const float head_scale = g_menu.main.aimbot.head_pointscale.get() / 100.f;
    const float body_scale = g_menu.main.aimbot.body_pointscale.get() / 100.f;

    for (int index = start; index < end; ++index) {
        if (!g_aimbot.AllowHitbox(record->m_player, index, mindmg) || (index == HITBOX_HEAD && force_baim_misses))
            continue;

        mstudiobbox_t* bbox = set->GetHitbox(index);
        if (!bbox) continue;

        vec3_t center = (bbox->m_mins + bbox->m_maxs) / 2.f;

        if (bbox->m_radius <= 0.f) {
            if (!m_peek_data.m_filtered && g_menu.main.aimbot.aimbot_optimizations.get(1))
                continue;

            matrix3x4_t rot_matrix, matrix;
            rot_matrix.AngleMatrix(bbox->m_angle);
            math::ConcatTransforms(record_matrix[bbox->m_bone], rot_matrix, matrix);

            vec3_t origin = matrix.GetOrigin();

            if (index == HITBOX_R_FOOT || index == HITBOX_L_FOOT) {
                float d1 = (bbox->m_mins.z - center.z) * 0.875f;
                if (index == HITBOX_L_FOOT) d1 *= -1.f;

                AimPoint_t point;
                point.m_pos = vec3_t(center.x, center.y, center.z + d1);
                point.m_hitbox = index;
                point.m_hitbox_radius = bbox->m_radius;
                point.m_point_safety = 1.f - ((center - bbox->m_maxs).length() / bbox->m_radius);
                local_points.emplace_back(point);

                if (g_menu.main.aimbot.multipoint.get(3)) {
                    float d2 = (bbox->m_mins.x - center.x) * body_scale;
                    float d3 = (bbox->m_maxs.x - center.x) * body_scale;

                    point.m_pos = vec3_t(center.x + d2, center.y, center.z);
                    local_points.emplace_back(point);

                    point.m_pos = vec3_t(center.x + d3, center.y, center.z);
                    local_points.emplace_back(point);
                }
            }

            for (auto& p : local_points) {
                if (!p.m_rotated) {
                    p.m_pos = vec3_t(p.m_pos.dot(matrix[0]), p.m_pos.dot(matrix[1]), p.m_pos.dot(matrix[2])) + origin;
                    p.m_rotated = true;
                }
            }
        }
        else {
            float bs = bbox->m_radius * body_scale;

            if (m_peek_data.m_filtered || !g_menu.main.aimbot.aimbot_optimizations.get(1)) {
                if (g_menu.main.aimbot.multipoint.get(0) && index == HITBOX_HEAD) {
                    const float rotation = 0.70710678f;
                    for (int i = 0; i <= g_menu.main.aimbot.multipoint_intensity.get(); i++) {
                        float hs_width = bbox->m_radius * (head_scale * ((3.f - i) / 3.f));
                        float hs_height = bbox->m_radius * (60 * ((3.f - i) / 3.f));

                        AimPoint_t point;
                        point.m_pos = vec3_t(bbox->m_maxs.x, bbox->m_maxs.y, bbox->m_maxs.z - hs_width);
                        point.m_hitbox = index;
                        point.m_hitbox_radius = bbox->m_radius;
                        local_points.emplace_back(point);

                        point.m_pos = vec3_t(bbox->m_maxs.x, bbox->m_maxs.y, bbox->m_maxs.z + hs_width);
                        local_points.emplace_back(point);

                        point.m_pos = vec3_t(bbox->m_maxs.x + (rotation * hs_height), bbox->m_maxs.y + (-rotation * hs_width), bbox->m_maxs.z);
                        local_points.emplace_back(point);
                    }
                }
                else if (index == HITBOX_BODY || index == HITBOX_PELVIS) {
                    if (g_menu.main.aimbot.multipoint.get(2)) {
                        AimPoint_t point;
                        point.m_pos = vec3_t(center.x, center.y, center.z - bs);
                        point.m_hitbox = index;
                        point.m_hitbox_radius = bbox->m_radius;
                        local_points.emplace_back(point);

                        point.m_pos = vec3_t(center.x, center.y, center.z + bs);
                        local_points.emplace_back(point);
                    }
                }
            }

            AimPoint_t point;
            point.m_pos = center;
            point.m_hitbox = index;
            point.m_hitbox_radius = bbox->m_radius;
            local_points.emplace_back(point);

            vec3_t transformed_center = center;
            math::VectorTransform(transformed_center, record_matrix[bbox->m_bone], transformed_center);

            RayTracer::Hitbox box(bbox->m_mins, bbox->m_maxs, bbox->m_radius);
            RayTracer::Trace trace;
            vec3_t delta = (transformed_center - g_cl.m_shoot_pos).normalized();
            vec3_t max_min = (bbox->m_maxs - bbox->m_mins).normalized();

            if (index == HITBOX_HEAD) {
                RayTracer::TraceFromCenter(RayTracer::Ray(g_cl.m_shoot_pos, transformed_center), box, trace, RayTracer::Flags_RETURNEND);

                AimPoint_t point;
                point.m_pos = trace.m_traceEnd;
                point.m_hitbox = index;
                point.m_hitbox_radius = bbox->m_radius;
                point.m_point_safety = 1.f;
                point.m_rotated = false;

                local_points.emplace_back(point);
            }
            else {
                RayTracer::TraceFromCenter(RayTracer::Ray(g_cl.m_shoot_pos, transformed_center + (max_min * 1000.f)), box, trace, RayTracer::Flags_RETURNEND);

                AimPoint_t point;
                point.m_pos = trace.m_traceEnd;
                point.m_hitbox = index;
                point.m_hitbox_radius = bbox->m_radius;
                point.m_point_safety = 1.f;
                point.m_rotated = false;

                local_points.emplace_back(point);
            }

            for (auto& p : local_points) {
                if (!p.m_rotated) {
                    math::VectorTransform(p.m_pos, record_matrix[bbox->m_bone], p.m_pos);
                    p.m_rotated = true;
                }
            }
        }
    }

    // lock and merge results back into the shared points vector.
    std::lock_guard<std::mutex> lock(points_mutex);
    points.insert(points.end(), local_points.begin(), local_points.end());
}

void AimPlayer::SetupHitboxPoints(LagRecord* record, matrix3x4_t* record_matrix, float mindmg, bool force_baim_misses, std::vector<AimPoint_t>& points) {
    // get number of hardware threads.
    unsigned int num_threads = std::thread::hardware_concurrency();
    if (num_threads == 0) num_threads = 2; // fallback to 2 if hardware_concurrency is unavailable.

    // divide hitboxes into batches.
    int hitbox_count = HITBOX_MAX;
    int hitboxes_per_thread = hitbox_count / num_threads;

    std::vector<std::future<void>> futures;

    // launch threads to process hitbox ranges.
    for (unsigned int i = 0; i < num_threads; ++i) {
        int start = i * hitboxes_per_thread;
        int end = (i == num_threads - 1) ? hitbox_count : start + hitboxes_per_thread;

        // pass the current instance (this) to std::async to call member function.
        futures.push_back(std::async(std::launch::async, &AimPlayer::process_hitbox_range, this, start, end, record, record_matrix, mindmg, force_baim_misses, std::ref(points)));
    }

    // wait for all threads to complete.
    for (auto& future : futures) {
        future.get();
    }
}
raytracer.h:
#pragma once

class RayTracer {
public:
    struct Ray {
        Ray(const vec3_t& direction);
        Ray(const vec3_t& startPoint, const vec3_t& endPoint);
        vec3_t m_startPoint;
        vec3_t m_direction;
        float m_length;
    };

    struct Hitbox {
        Hitbox();
        Hitbox(const vec3_t& mins, const vec3_t& maxs, const float radius);
        Hitbox(const std::tuple<vec3_t, vec3_t, float>& initTuple);
        vec3_t m_mins;
        vec3_t m_maxs;
        float m_radius;
    };

    struct Trace {
        Trace();
        bool m_hit;
        float m_fraction;
        vec3_t m_traceEnd;
        vec3_t m_traceOffset;
    };

    enum Flags {
        Flags_NONE = 0,
        Flags_RETURNEND = (1 << 0),
        Flags_RETURNOFFSET = (1 << 1)
    };

    // this is a specialization that starts from the center, as calculations are much simpler from the center of the hitbox.
    static void TraceFromCenter(const Ray& ray, const Hitbox& hitbox, Trace& trace, int flags = 0);

    // this is for the general case, tracing against the hitbox.
    static void TraceHitbox(const Ray& ray, const Hitbox& hitbox, Trace& trace, int flags = 0);
};
raytracer.cpp:
#include "includes.h"

RayTracer::Ray::Ray(const vec3_t& direction): m_startPoint(), m_direction(direction), m_length(0.f) {}

RayTracer::Ray::Ray(const vec3_t& startPoint, const vec3_t& endPoint): m_startPoint(startPoint) {
    auto vec3_tDiff = endPoint - startPoint;
    m_direction = vec3_tDiff.normalized();
    m_length = vec3_tDiff.length();
}

RayTracer::Hitbox::Hitbox(): m_mins(), m_maxs(), m_radius() {}

RayTracer::Hitbox::Hitbox(const vec3_t& mins, const vec3_t& maxs, const float radius): m_mins(mins), m_maxs(maxs), m_radius(radius) {}

RayTracer::Hitbox::Hitbox(const std::tuple<vec3_t, vec3_t, float>& initTuple): m_mins(std::get<0>(initTuple)), m_maxs(std::get<1>(initTuple)), m_radius(std::get<2>(initTuple)) {}

RayTracer::Trace::Trace(): m_hit(false), m_fraction(0.f), m_traceEnd() {}

void RayTracer::TraceFromCenter(const Ray& ray, const Hitbox& hitbox, Trace& trace, int flags) {
    // we are treating the cylinder as a cylinder y^2+z^2=r^2, in the x-direction, so we will make it the x direction.
    const vec3_t unitDesired(1.f, 0.f, 0.f);
    const matrix3x4_t identityMatrix(
        1.f, 0.f, 0.f, 0.f,
        0.f, 1.f, 0.f, 0.f,
        0.f, 0.f, 1.f, 0.f
    );

    auto center = (hitbox.m_mins + hitbox.m_maxs) / 2.f;

    auto minsOffset = hitbox.m_mins - center;
    auto maxsOffset = hitbox.m_maxs - center;

    auto vecHitbox = maxsOffset - minsOffset;
    auto hitboxLength = vecHitbox.length();

    // now we calculate the transformation matrix to get our normalized hitbox to center.
    auto unitHitbox = vecHitbox / hitboxLength;

    // dot == cos because they are both unit vec3_ts.
    auto dot = unitHitbox.dot(unitDesired);
    auto cross = unitHitbox.cross(unitDesired);

    vec3_t rotatedDirection;

    // if cross is 0, then we don't have to rotate because they are parallel.
    if (cross.length() > 0.f) {
        matrix3x4_t crossMatrix(
            0.f, -cross.z, cross.y, 0.f,
            cross.z, 0.f, -cross.x, 0.f,
            -cross.y, cross.x, 0.f, 0.f
        );

        auto rotationMatrix = identityMatrix + crossMatrix +
            (crossMatrix * crossMatrix) * (1.f / (1.f + dot));

        rotatedDirection = rotationMatrix * ray.m_direction;
    }
    else {
        // cross is 0, they are parallel, if dot is 1.f they are same, else they are opposite.
        if (dot == 1.f)
            rotatedDirection = ray.m_direction;
        else
            rotatedDirection = -ray.m_direction;
    }

    auto a = rotatedDirection.y * rotatedDirection.y +
        rotatedDirection.z * rotatedDirection.z;

    if (a == 0) {
        // the ray goes through both caps, easy case because we don't actually need to trace the ray because they are circles.
        if (rotatedDirection.x > 0) {
            // through the right cap, scale by radius and call it a day.
            auto newLength = minsOffset.length() + hitbox.m_radius;
            auto offset = (minsOffset * (newLength) / minsOffset.length());

            if (flags & Flags_RETURNEND)
                trace.m_traceEnd = center + offset;
            if (flags & Flags_RETURNOFFSET)
                trace.m_traceOffset = offset;
        }
        else {
            // through the left cap, scale by radius again
            auto newLength = maxsOffset.length() + hitbox.m_radius;
            auto offset = (maxsOffset * (newLength) / maxsOffset.length());

            if (flags & Flags_RETURNEND)
                trace.m_traceEnd = center + offset;
            if (flags & Flags_RETURNOFFSET)
                trace.m_traceOffset = offset;
        }
        trace.m_hit = true;
        return;
    }

    // b is always 0 because we start at the origin.

    auto c = -(hitbox.m_radius * hitbox.m_radius);

    // we only care about t1 because we are inside of the surface that we are tracing, so t0 will always be negative.
    // also -4*a*c will always be positive because c is always negative and a is always positive.
    auto t = (sqrtf(-4.f * a * c)) / (2.f * a);

    // virutal direction is in the 3-D plane of x.
    auto virtualPos = rotatedDirection * t;

    auto minsAdjusted = -hitboxLength / 2.f;
    auto maxsAdjusted = hitboxLength / 2.f;

    auto outOfMinsSide = virtualPos.x < minsAdjusted;
    auto outOfMaxsSide = virtualPos.x > maxsAdjusted;

    // we need to trace the spheres on the ends.
    if (outOfMinsSide || outOfMaxsSide) {
        // set our position offset to the opposite side to raytrace the sphere.
        vec3_t offsetPosition(
            (outOfMinsSide) ? -minsAdjusted : -maxsAdjusted, 0.f, 0.f
        );

        // we treat a_s as 1 because for a sphere, it is just the entire unit vec3_t's length, always 1.

        auto b_s = 2.f * (offsetPosition.x * rotatedDirection.x);

        auto c_s = offsetPosition.x * offsetPosition.x -
            hitbox.m_radius * hitbox.m_radius;

        auto operand = sqrtf(b_s * b_s - 4 * c_s);

        t = (-b_s + operand) / 2.f;
    }

    auto offset = ray.m_direction * t;

    if (flags & Flags_RETURNEND)
        trace.m_traceEnd = center + offset;
    if (flags & Flags_RETURNOFFSET)
        trace.m_traceOffset = offset;

    trace.m_hit = true;
}

void RayTracer::TraceHitbox(const Ray& ray, const Hitbox& hitbox, Trace& trace, int flags) {
    trace.m_fraction = 1.f;

    // we are treating the cylinder as a cylinder y^2+z^2=r^2, in the x-direction, so we will make it the x direction.
    const vec3_t unitDesired(1.f, 0.f, 0.f);
    const matrix3x4_t identityMatrix(
        1.f, 0.f, 0.f, 0.f,
        0.f, 1.f, 0.f, 0.f,
        0.f, 0.f, 1.f, 0.f
    );

    auto center = (hitbox.m_mins + hitbox.m_maxs) / 2.f;

    auto minsOffset = hitbox.m_mins - center;
    auto maxsOffset = hitbox.m_maxs - center;

    auto vecHitbox = maxsOffset - minsOffset;
    auto hitboxLength = vecHitbox.length();

    // now we calculate the transformation matrix to get our normalized hitbox to center.
    auto unitHitbox = vecHitbox / hitboxLength;

    // dot == cos because they are both unit vec3_ts.
    auto dot = unitHitbox.dot(unitDesired);
    auto cross = unitHitbox.cross(unitDesired);

    vec3_t rotatedDirection;
    vec3_t rotatedStart;

    // offset the position.
    auto adjustedStart = ray.m_startPoint - center;

    // if cross is 0, then we don't have to rotate because they are parallel.
    if (cross.length() > 0.f) {
        matrix3x4_t crossMatrix(
            0.f, -cross.z, cross.y, 0.f,
            cross.z, 0.f, -cross.x, 0.f,
            -cross.y, cross.x, 0.f, 0.f
        );

        auto rotationMatrix = identityMatrix + crossMatrix +
            (crossMatrix * crossMatrix) * (1.f / (1.f + dot));

        rotatedDirection = rotationMatrix * ray.m_direction;
        rotatedStart = rotationMatrix * adjustedStart;
    }
    else {
        // cross is 0, they are parallel, if dot is 1.f they are same, else they are opposite.
        if (dot > 0.f) {
            rotatedDirection = ray.m_direction;
            rotatedStart = adjustedStart;
        }
        else {
            rotatedDirection = -ray.m_direction;
            rotatedStart = -adjustedStart;
        }
    }

    auto a_c = rotatedDirection.y * rotatedDirection.y +
        rotatedDirection.z * rotatedDirection.z;

    // todo: simv0l - detect the plane!
    // this is INCREDIBLY RARE.
    if (a_c == 0.f) {
        // the ray goes through both caps, easy case because we don't actually need to trace the ray because they are circles.
        if (rotatedDirection.x > 0) {
            // through the right cap, scale by radius and call it a day.
            auto newLength = minsOffset.length() + hitbox.m_radius;
            auto offset = (minsOffset * (newLength) / minsOffset.length());

            if (flags & Flags_RETURNEND)
                trace.m_traceEnd = center + offset;
            if (flags & Flags_RETURNOFFSET)
                trace.m_traceOffset = offset;
        }
        else {
            // through the left cap, scale by radius again.
            auto newLength = maxsOffset.length() + hitbox.m_radius;
            auto offset = (maxsOffset * (newLength) / maxsOffset.length());

            if (flags & Flags_RETURNEND)
                trace.m_traceEnd = center + offset;
            if (flags & Flags_RETURNOFFSET)
                trace.m_traceOffset = offset;
        }
        trace.m_hit = true;
        return;
    }

    constexpr auto a_s = 1.f;

    auto minsAdjusted = -hitboxLength / 2.f;
    auto maxsAdjusted = hitboxLength / 2.f;

    auto minsStart = vec3_t(rotatedStart.x - minsAdjusted, rotatedStart.y, rotatedStart.z);
    auto maxsStart = vec3_t(rotatedStart.x - maxsAdjusted, rotatedStart.y, rotatedStart.z);

    auto b_c = 2.f * (rotatedStart.y * rotatedDirection.y + rotatedStart.z * rotatedDirection.z);

    auto b_smins = 2.f * (minsStart.dot(rotatedDirection));
    auto b_smaxs = 2.f * (maxsStart.dot(rotatedDirection));

    auto c_c = rotatedStart.y * rotatedStart.y + rotatedStart.z * rotatedStart.z - hitbox.m_radius * hitbox.m_radius;

    auto c_smins = minsStart.dot(minsStart) - hitbox.m_radius * hitbox.m_radius;
    auto c_smaxs = maxsStart.dot(maxsStart) - hitbox.m_radius * hitbox.m_radius;

    auto cylOperand = b_c * b_c - 4 * a_c * c_c;
    auto sphMinsOperand = b_smins * b_smins - 4 * a_s * c_smins;
    auto sphMaxsOperand = b_smaxs * b_smaxs - 4 * a_s * c_smaxs;

    auto tCyl = 0.f;
    auto tSphMins = 0.f;
    auto tSphMaxs = 0.f;

    auto cylHit = false;
    auto sphMinsHit = false;
    auto sphMaxsHit = false;

    // if we don't hit, operand is negative.
    if (cylOperand > 0.f) {
        tCyl = (-b_c - sqrtf(cylOperand)) / (2.f * a_c);

        if (tCyl - FLT_EPSILON > 0.f) {
            // make sure we hit within our bounds, and not outside of the cylinder's bore.
            auto virtualPos = rotatedDirection * tCyl;

            auto outOfMinsSide = virtualPos.x < minsAdjusted;
            auto outOfMaxsSide = virtualPos.x > maxsAdjusted;

            if (!outOfMinsSide &&
                !outOfMaxsSide)
                cylHit = true;
        }
    }

    if (sphMinsOperand > 0.f) {
        tSphMins = (-b_smins - sqrtf(sphMinsOperand)) / (2.f * a_s);

        if (tSphMins - FLT_EPSILON > 0.f)
            sphMinsHit = true;
    }

    if (sphMaxsOperand > 0.f) {
        tSphMaxs = (-b_smaxs - sqrtf(sphMaxsOperand)) / (2.f * a_s);

        if (tSphMaxs - FLT_EPSILON > 0.f)
            sphMaxsHit = true;
    }

    // see which one hit first, then return accordingly.
    if (cylHit) {
        trace.m_fraction = tCyl / ray.m_length;
        trace.m_hit = true;
    }
    else if (sphMinsHit) {
        trace.m_fraction = tSphMins / ray.m_length;
        trace.m_hit = true;
    }
    else if (sphMaxsHit) {
        trace.m_fraction = tSphMaxs / ray.m_length;
        trace.m_hit = true;
    }
}
matrix.h:
#pragma once
#include <cstring>

class matrix3x4_t {
public:
    float m_flMatVal[3][4];

    // default constructor.
    __forceinline matrix3x4_t() {
        memset(m_flMatVal, 0, sizeof(m_flMatVal));
    }

    // parameterized constructor.
    __forceinline matrix3x4_t(float m00, float m01, float m02, float m03,
        float m10, float m11, float m12, float m13,
        float m20, float m21, float m22, float m23) {
        m_flMatVal[0][0] = m00; m_flMatVal[0][1] = m01; m_flMatVal[0][2] = m02; m_flMatVal[0][3] = m03;
        m_flMatVal[1][0] = m10; m_flMatVal[1][1] = m11; m_flMatVal[1][2] = m12; m_flMatVal[1][3] = m13;
        m_flMatVal[2][0] = m20; m_flMatVal[2][1] = m21; m_flMatVal[2][2] = m22; m_flMatVal[2][3] = m23;
    }

    // copy constructor.
    matrix3x4_t(const matrix3x4_t& other) {
        memcpy(m_flMatVal, other.m_flMatVal, sizeof(m_flMatVal));
    }

    // copy assignment operator.
    matrix3x4_t& operator=(const matrix3x4_t& other) {
        if (this != &other) {
            memcpy(m_flMatVal, other.m_flMatVal, sizeof(m_flMatVal));
        }
        return *this;
    }

    // set origin of the matrix.
    __forceinline void SetOrigin(const vec3_t& p) {
        m_flMatVal[0][3] = p.x;
        m_flMatVal[1][3] = p.y;
        m_flMatVal[2][3] = p.z;
    }

    // get origin of the matrix.
    __forceinline vec3_t GetOrigin() const {
        return {m_flMatVal[0][3], m_flMatVal[1][3], m_flMatVal[2][3]};
    }

    // matrix from angles.
    void AngleMatrix(const ang_t& angles) {
        float sr, sp, sy, cr, cp, cy;
        DirectX::XMScalarSinCos(&sy, &cy, math::deg_to_rad(angles.y));
        DirectX::XMScalarSinCos(&sp, &cp, math::deg_to_rad(angles.x));
        DirectX::XMScalarSinCos(&sr, &cr, math::deg_to_rad(angles.z));

        // matrix = (yaw * pitch) * roll.
        m_flMatVal[0][0] = cp * cy;
        m_flMatVal[1][0] = cp * sy;
        m_flMatVal[2][0] = -sp;

        float crcy = cr * cy;
        float crsy = cr * sy;
        float srcy = sr * cy;
        float srsy = sr * sy;
        m_flMatVal[0][1] = sp * srcy - crsy;
        m_flMatVal[1][1] = sp * srsy + crcy;
        m_flMatVal[2][1] = sr * cp;

        m_flMatVal[0][2] = (sp * crcy + srsy);
        m_flMatVal[1][2] = (sp * crsy - srcy);
        m_flMatVal[2][2] = cr * cp;

        m_flMatVal[0][3] = 0.0f;
        m_flMatVal[1][3] = 0.0f;
        m_flMatVal[2][3] = 0.0f;
    }

    // addition operator.
    matrix3x4_t operator+(const matrix3x4_t& other) const {
        matrix3x4_t result;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                result.m_flMatVal[i][j] = this->m_flMatVal[i][j] + other.m_flMatVal[i][j];
            }
        }
        return result;
    }

    // multiplication by another matrix (for 3x4 matrices, we only multiply the 3x3 part).
    matrix3x4_t operator*(const matrix3x4_t& other) const {
        matrix3x4_t result;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                result.m_flMatVal[i][j] = 0;
                for (int k = 0; k < 3; k++) {
                    result.m_flMatVal[i][j] += this->m_flMatVal[i][k] * other.m_flMatVal[k][j];
                }
            }
        }
        return result;
    }

    // multiplication by scalar.
    matrix3x4_t operator*(float scalar) const {
        matrix3x4_t result;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                result.m_flMatVal[i][j] = this->m_flMatVal[i][j] * scalar;
            }
        }
        return result;
    }

    // multiply the matrix by a vector.
    vec3_t operator*(const vec3_t& vec) const {
        return vec3_t(
            vec.x * m_flMatVal[0][0] + vec.y * m_flMatVal[0][1] + vec.z * m_flMatVal[0][2] + m_flMatVal[0][3],
            vec.x * m_flMatVal[1][0] + vec.y * m_flMatVal[1][1] + vec.z * m_flMatVal[1][2] + m_flMatVal[1][3],
            vec.x * m_flMatVal[2][0] + vec.y * m_flMatVal[2][1] + vec.z * m_flMatVal[2][2] + m_flMatVal[2][3]
        );
    }

    // array access operator.
    __forceinline float* operator[](int i) {
        return m_flMatVal[i];
    }

    // array access operator (const version).
    __forceinline const float* operator[](int i) const {
        return m_flMatVal[i];
    }

    // base pointer access.
    __forceinline float* Base() {
        return &m_flMatVal[0][0];
    }

    // base pointer access (const version).
    __forceinline const float* Base() const {
        return &m_flMatVal[0][0];
    }

    // get bone position.
    bool get_bone(vec3_t& out, int bone = 0) {
        if (bone < 0 || bone >= 128)
            return false;

        matrix3x4_t* bone_matrix = &this[bone];

        if (!bone_matrix)
            return false;

        out = {bone_matrix->m_flMatVal[0][3], bone_matrix->m_flMatVal[1][3], bone_matrix->m_flMatVal[2][3]};

        return true;
    }
};

// aligned version of matrix3x4_t for specific cases.
class __declspec(align(16)) matrix3x4a_t: public matrix3x4_t {
public:
    __forceinline matrix3x4a_t& operator=(const matrix3x4_t& src) {
        std::memcpy(Base(), src.Base(), sizeof(float) * 3 * 4);
        return *this;
    }
};

// VMatrix class.
class VMatrix {
public:
    float m[4][4];

    // array access operator.
    __forceinline float* operator[](int i) {
        return m[i];
    }

    // array access operator (const version).
    __forceinline const float* operator[](int i) const {
        return m[i];
    }

    // base pointer access.
    __forceinline float* Base() {
        return &m[0][0];
    }

    // base pointer access (const version).
    __forceinline const float* Base() const {
        return &m[0][0];
    }
};
 
Начинающий
Статус
Оффлайн
Регистрация
11 Дек 2023
Сообщения
3
Реакции[?]
1
Поинты[?]
1K
enjoy :roflanBuldiga::roflanBuldiga:
aimbot.cpp:
#include <vector>
#include <mutex>
#include <future>
#include <thread>
std::mutex points_mutex;  // for thread-safe access to points.

// function to process a range of hitboxes.
void AimPlayer::process_hitbox_range(int start, int end, LagRecord* record, matrix3x4_t* record_matrix, float mindmg, bool force_baim_misses, std::vector<AimPoint_t>& points) {
    const model_t* model = m_player->get_model();
    if (!model) return;

    studiohdr_t* hdr = model_info.get()->GetStudioModel(model);
    if (!hdr) return;

    mstudiohitboxset_t* set = hdr->GetHitboxSet(m_player->hitbox_set());
    if (!set) return;

    // thread-local storage for points.
    std::vector<AimPoint_t> local_points;

    const float head_scale = g_menu.main.aimbot.head_pointscale.get() / 100.f;
    const float body_scale = g_menu.main.aimbot.body_pointscale.get() / 100.f;

    for (int index = start; index < end; ++index) {
        if (!g_aimbot.AllowHitbox(record->m_player, index, mindmg) || (index == HITBOX_HEAD && force_baim_misses))
            continue;

        mstudiobbox_t* bbox = set->GetHitbox(index);
        if (!bbox) continue;

        vec3_t center = (bbox->m_mins + bbox->m_maxs) / 2.f;

        if (bbox->m_radius <= 0.f) {
            if (!m_peek_data.m_filtered && g_menu.main.aimbot.aimbot_optimizations.get(1))
                continue;

            matrix3x4_t rot_matrix, matrix;
            rot_matrix.AngleMatrix(bbox->m_angle);
            math::ConcatTransforms(record_matrix[bbox->m_bone], rot_matrix, matrix);

            vec3_t origin = matrix.GetOrigin();

            if (index == HITBOX_R_FOOT || index == HITBOX_L_FOOT) {
                float d1 = (bbox->m_mins.z - center.z) * 0.875f;
                if (index == HITBOX_L_FOOT) d1 *= -1.f;

                AimPoint_t point;
                point.m_pos = vec3_t(center.x, center.y, center.z + d1);
                point.m_hitbox = index;
                point.m_hitbox_radius = bbox->m_radius;
                point.m_point_safety = 1.f - ((center - bbox->m_maxs).length() / bbox->m_radius);
                local_points.emplace_back(point);

                if (g_menu.main.aimbot.multipoint.get(3)) {
                    float d2 = (bbox->m_mins.x - center.x) * body_scale;
                    float d3 = (bbox->m_maxs.x - center.x) * body_scale;

                    point.m_pos = vec3_t(center.x + d2, center.y, center.z);
                    local_points.emplace_back(point);

                    point.m_pos = vec3_t(center.x + d3, center.y, center.z);
                    local_points.emplace_back(point);
                }
            }

            for (auto& p : local_points) {
                if (!p.m_rotated) {
                    p.m_pos = vec3_t(p.m_pos.dot(matrix[0]), p.m_pos.dot(matrix[1]), p.m_pos.dot(matrix[2])) + origin;
                    p.m_rotated = true;
                }
            }
        }
        else {
            float bs = bbox->m_radius * body_scale;

            if (m_peek_data.m_filtered || !g_menu.main.aimbot.aimbot_optimizations.get(1)) {
                if (g_menu.main.aimbot.multipoint.get(0) && index == HITBOX_HEAD) {
                    const float rotation = 0.70710678f;
                    for (int i = 0; i <= g_menu.main.aimbot.multipoint_intensity.get(); i++) {
                        float hs_width = bbox->m_radius * (head_scale * ((3.f - i) / 3.f));
                        float hs_height = bbox->m_radius * (60 * ((3.f - i) / 3.f));

                        AimPoint_t point;
                        point.m_pos = vec3_t(bbox->m_maxs.x, bbox->m_maxs.y, bbox->m_maxs.z - hs_width);
                        point.m_hitbox = index;
                        point.m_hitbox_radius = bbox->m_radius;
                        local_points.emplace_back(point);

                        point.m_pos = vec3_t(bbox->m_maxs.x, bbox->m_maxs.y, bbox->m_maxs.z + hs_width);
                        local_points.emplace_back(point);

                        point.m_pos = vec3_t(bbox->m_maxs.x + (rotation * hs_height), bbox->m_maxs.y + (-rotation * hs_width), bbox->m_maxs.z);
                        local_points.emplace_back(point);
                    }
                }
                else if (index == HITBOX_BODY || index == HITBOX_PELVIS) {
                    if (g_menu.main.aimbot.multipoint.get(2)) {
                        AimPoint_t point;
                        point.m_pos = vec3_t(center.x, center.y, center.z - bs);
                        point.m_hitbox = index;
                        point.m_hitbox_radius = bbox->m_radius;
                        local_points.emplace_back(point);

                        point.m_pos = vec3_t(center.x, center.y, center.z + bs);
                        local_points.emplace_back(point);
                    }
                }
            }

            AimPoint_t point;
            point.m_pos = center;
            point.m_hitbox = index;
            point.m_hitbox_radius = bbox->m_radius;
            local_points.emplace_back(point);

            vec3_t transformed_center = center;
            math::VectorTransform(transformed_center, record_matrix[bbox->m_bone], transformed_center);

            RayTracer::Hitbox box(bbox->m_mins, bbox->m_maxs, bbox->m_radius);
            RayTracer::Trace trace;
            vec3_t delta = (transformed_center - g_cl.m_shoot_pos).normalized();
            vec3_t max_min = (bbox->m_maxs - bbox->m_mins).normalized();

            if (index == HITBOX_HEAD) {
                RayTracer::TraceFromCenter(RayTracer::Ray(g_cl.m_shoot_pos, transformed_center), box, trace, RayTracer::Flags_RETURNEND);

                AimPoint_t point;
                point.m_pos = trace.m_traceEnd;
                point.m_hitbox = index;
                point.m_hitbox_radius = bbox->m_radius;
                point.m_point_safety = 1.f;
                point.m_rotated = false;

                local_points.emplace_back(point);
            }
            else {
                RayTracer::TraceFromCenter(RayTracer::Ray(g_cl.m_shoot_pos, transformed_center + (max_min * 1000.f)), box, trace, RayTracer::Flags_RETURNEND);

                AimPoint_t point;
                point.m_pos = trace.m_traceEnd;
                point.m_hitbox = index;
                point.m_hitbox_radius = bbox->m_radius;
                point.m_point_safety = 1.f;
                point.m_rotated = false;

                local_points.emplace_back(point);
            }

            for (auto& p : local_points) {
                if (!p.m_rotated) {
                    math::VectorTransform(p.m_pos, record_matrix[bbox->m_bone], p.m_pos);
                    p.m_rotated = true;
                }
            }
        }
    }

    // lock and merge results back into the shared points vector.
    std::lock_guard<std::mutex> lock(points_mutex);
    points.insert(points.end(), local_points.begin(), local_points.end());
}

void AimPlayer::SetupHitboxPoints(LagRecord* record, matrix3x4_t* record_matrix, float mindmg, bool force_baim_misses, std::vector<AimPoint_t>& points) {
    // get number of hardware threads.
    unsigned int num_threads = std::thread::hardware_concurrency();
    if (num_threads == 0) num_threads = 2; // fallback to 2 if hardware_concurrency is unavailable.

    // divide hitboxes into batches.
    int hitbox_count = HITBOX_MAX;
    int hitboxes_per_thread = hitbox_count / num_threads;

    std::vector<std::future<void>> futures;

    // launch threads to process hitbox ranges.
    for (unsigned int i = 0; i < num_threads; ++i) {
        int start = i * hitboxes_per_thread;
        int end = (i == num_threads - 1) ? hitbox_count : start + hitboxes_per_thread;

        // pass the current instance (this) to std::async to call member function.
        futures.push_back(std::async(std::launch::async, &AimPlayer::process_hitbox_range, this, start, end, record, record_matrix, mindmg, force_baim_misses, std::ref(points)));
    }

    // wait for all threads to complete.
    for (auto& future : futures) {
        future.get();
    }
}
raytracer.h:
#pragma once

class RayTracer {
public:
    struct Ray {
        Ray(const vec3_t& direction);
        Ray(const vec3_t& startPoint, const vec3_t& endPoint);
        vec3_t m_startPoint;
        vec3_t m_direction;
        float m_length;
    };

    struct Hitbox {
        Hitbox();
        Hitbox(const vec3_t& mins, const vec3_t& maxs, const float radius);
        Hitbox(const std::tuple<vec3_t, vec3_t, float>& initTuple);
        vec3_t m_mins;
        vec3_t m_maxs;
        float m_radius;
    };

    struct Trace {
        Trace();
        bool m_hit;
        float m_fraction;
        vec3_t m_traceEnd;
        vec3_t m_traceOffset;
    };

    enum Flags {
        Flags_NONE = 0,
        Flags_RETURNEND = (1 << 0),
        Flags_RETURNOFFSET = (1 << 1)
    };

    // this is a specialization that starts from the center, as calculations are much simpler from the center of the hitbox.
    static void TraceFromCenter(const Ray& ray, const Hitbox& hitbox, Trace& trace, int flags = 0);

    // this is for the general case, tracing against the hitbox.
    static void TraceHitbox(const Ray& ray, const Hitbox& hitbox, Trace& trace, int flags = 0);
};
raytracer.cpp:
#include "includes.h"

RayTracer::Ray::Ray(const vec3_t& direction): m_startPoint(), m_direction(direction), m_length(0.f) {}

RayTracer::Ray::Ray(const vec3_t& startPoint, const vec3_t& endPoint): m_startPoint(startPoint) {
    auto vec3_tDiff = endPoint - startPoint;
    m_direction = vec3_tDiff.normalized();
    m_length = vec3_tDiff.length();
}

RayTracer::Hitbox::Hitbox(): m_mins(), m_maxs(), m_radius() {}

RayTracer::Hitbox::Hitbox(const vec3_t& mins, const vec3_t& maxs, const float radius): m_mins(mins), m_maxs(maxs), m_radius(radius) {}

RayTracer::Hitbox::Hitbox(const std::tuple<vec3_t, vec3_t, float>& initTuple): m_mins(std::get<0>(initTuple)), m_maxs(std::get<1>(initTuple)), m_radius(std::get<2>(initTuple)) {}

RayTracer::Trace::Trace(): m_hit(false), m_fraction(0.f), m_traceEnd() {}

void RayTracer::TraceFromCenter(const Ray& ray, const Hitbox& hitbox, Trace& trace, int flags) {
    // we are treating the cylinder as a cylinder y^2+z^2=r^2, in the x-direction, so we will make it the x direction.
    const vec3_t unitDesired(1.f, 0.f, 0.f);
    const matrix3x4_t identityMatrix(
        1.f, 0.f, 0.f, 0.f,
        0.f, 1.f, 0.f, 0.f,
        0.f, 0.f, 1.f, 0.f
    );

    auto center = (hitbox.m_mins + hitbox.m_maxs) / 2.f;

    auto minsOffset = hitbox.m_mins - center;
    auto maxsOffset = hitbox.m_maxs - center;

    auto vecHitbox = maxsOffset - minsOffset;
    auto hitboxLength = vecHitbox.length();

    // now we calculate the transformation matrix to get our normalized hitbox to center.
    auto unitHitbox = vecHitbox / hitboxLength;

    // dot == cos because they are both unit vec3_ts.
    auto dot = unitHitbox.dot(unitDesired);
    auto cross = unitHitbox.cross(unitDesired);

    vec3_t rotatedDirection;

    // if cross is 0, then we don't have to rotate because they are parallel.
    if (cross.length() > 0.f) {
        matrix3x4_t crossMatrix(
            0.f, -cross.z, cross.y, 0.f,
            cross.z, 0.f, -cross.x, 0.f,
            -cross.y, cross.x, 0.f, 0.f
        );

        auto rotationMatrix = identityMatrix + crossMatrix +
            (crossMatrix * crossMatrix) * (1.f / (1.f + dot));

        rotatedDirection = rotationMatrix * ray.m_direction;
    }
    else {
        // cross is 0, they are parallel, if dot is 1.f they are same, else they are opposite.
        if (dot == 1.f)
            rotatedDirection = ray.m_direction;
        else
            rotatedDirection = -ray.m_direction;
    }

    auto a = rotatedDirection.y * rotatedDirection.y +
        rotatedDirection.z * rotatedDirection.z;

    if (a == 0) {
        // the ray goes through both caps, easy case because we don't actually need to trace the ray because they are circles.
        if (rotatedDirection.x > 0) {
            // through the right cap, scale by radius and call it a day.
            auto newLength = minsOffset.length() + hitbox.m_radius;
            auto offset = (minsOffset * (newLength) / minsOffset.length());

            if (flags & Flags_RETURNEND)
                trace.m_traceEnd = center + offset;
            if (flags & Flags_RETURNOFFSET)
                trace.m_traceOffset = offset;
        }
        else {
            // through the left cap, scale by radius again
            auto newLength = maxsOffset.length() + hitbox.m_radius;
            auto offset = (maxsOffset * (newLength) / maxsOffset.length());

            if (flags & Flags_RETURNEND)
                trace.m_traceEnd = center + offset;
            if (flags & Flags_RETURNOFFSET)
                trace.m_traceOffset = offset;
        }
        trace.m_hit = true;
        return;
    }

    // b is always 0 because we start at the origin.

    auto c = -(hitbox.m_radius * hitbox.m_radius);

    // we only care about t1 because we are inside of the surface that we are tracing, so t0 will always be negative.
    // also -4*a*c will always be positive because c is always negative and a is always positive.
    auto t = (sqrtf(-4.f * a * c)) / (2.f * a);

    // virutal direction is in the 3-D plane of x.
    auto virtualPos = rotatedDirection * t;

    auto minsAdjusted = -hitboxLength / 2.f;
    auto maxsAdjusted = hitboxLength / 2.f;

    auto outOfMinsSide = virtualPos.x < minsAdjusted;
    auto outOfMaxsSide = virtualPos.x > maxsAdjusted;

    // we need to trace the spheres on the ends.
    if (outOfMinsSide || outOfMaxsSide) {
        // set our position offset to the opposite side to raytrace the sphere.
        vec3_t offsetPosition(
            (outOfMinsSide) ? -minsAdjusted : -maxsAdjusted, 0.f, 0.f
        );

        // we treat a_s as 1 because for a sphere, it is just the entire unit vec3_t's length, always 1.

        auto b_s = 2.f * (offsetPosition.x * rotatedDirection.x);

        auto c_s = offsetPosition.x * offsetPosition.x -
            hitbox.m_radius * hitbox.m_radius;

        auto operand = sqrtf(b_s * b_s - 4 * c_s);

        t = (-b_s + operand) / 2.f;
    }

    auto offset = ray.m_direction * t;

    if (flags & Flags_RETURNEND)
        trace.m_traceEnd = center + offset;
    if (flags & Flags_RETURNOFFSET)
        trace.m_traceOffset = offset;

    trace.m_hit = true;
}

void RayTracer::TraceHitbox(const Ray& ray, const Hitbox& hitbox, Trace& trace, int flags) {
    trace.m_fraction = 1.f;

    // we are treating the cylinder as a cylinder y^2+z^2=r^2, in the x-direction, so we will make it the x direction.
    const vec3_t unitDesired(1.f, 0.f, 0.f);
    const matrix3x4_t identityMatrix(
        1.f, 0.f, 0.f, 0.f,
        0.f, 1.f, 0.f, 0.f,
        0.f, 0.f, 1.f, 0.f
    );

    auto center = (hitbox.m_mins + hitbox.m_maxs) / 2.f;

    auto minsOffset = hitbox.m_mins - center;
    auto maxsOffset = hitbox.m_maxs - center;

    auto vecHitbox = maxsOffset - minsOffset;
    auto hitboxLength = vecHitbox.length();

    // now we calculate the transformation matrix to get our normalized hitbox to center.
    auto unitHitbox = vecHitbox / hitboxLength;

    // dot == cos because they are both unit vec3_ts.
    auto dot = unitHitbox.dot(unitDesired);
    auto cross = unitHitbox.cross(unitDesired);

    vec3_t rotatedDirection;
    vec3_t rotatedStart;

    // offset the position.
    auto adjustedStart = ray.m_startPoint - center;

    // if cross is 0, then we don't have to rotate because they are parallel.
    if (cross.length() > 0.f) {
        matrix3x4_t crossMatrix(
            0.f, -cross.z, cross.y, 0.f,
            cross.z, 0.f, -cross.x, 0.f,
            -cross.y, cross.x, 0.f, 0.f
        );

        auto rotationMatrix = identityMatrix + crossMatrix +
            (crossMatrix * crossMatrix) * (1.f / (1.f + dot));

        rotatedDirection = rotationMatrix * ray.m_direction;
        rotatedStart = rotationMatrix * adjustedStart;
    }
    else {
        // cross is 0, they are parallel, if dot is 1.f they are same, else they are opposite.
        if (dot > 0.f) {
            rotatedDirection = ray.m_direction;
            rotatedStart = adjustedStart;
        }
        else {
            rotatedDirection = -ray.m_direction;
            rotatedStart = -adjustedStart;
        }
    }

    auto a_c = rotatedDirection.y * rotatedDirection.y +
        rotatedDirection.z * rotatedDirection.z;

    // todo: simv0l - detect the plane!
    // this is INCREDIBLY RARE.
    if (a_c == 0.f) {
        // the ray goes through both caps, easy case because we don't actually need to trace the ray because they are circles.
        if (rotatedDirection.x > 0) {
            // through the right cap, scale by radius and call it a day.
            auto newLength = minsOffset.length() + hitbox.m_radius;
            auto offset = (minsOffset * (newLength) / minsOffset.length());

            if (flags & Flags_RETURNEND)
                trace.m_traceEnd = center + offset;
            if (flags & Flags_RETURNOFFSET)
                trace.m_traceOffset = offset;
        }
        else {
            // through the left cap, scale by radius again.
            auto newLength = maxsOffset.length() + hitbox.m_radius;
            auto offset = (maxsOffset * (newLength) / maxsOffset.length());

            if (flags & Flags_RETURNEND)
                trace.m_traceEnd = center + offset;
            if (flags & Flags_RETURNOFFSET)
                trace.m_traceOffset = offset;
        }
        trace.m_hit = true;
        return;
    }

    constexpr auto a_s = 1.f;

    auto minsAdjusted = -hitboxLength / 2.f;
    auto maxsAdjusted = hitboxLength / 2.f;

    auto minsStart = vec3_t(rotatedStart.x - minsAdjusted, rotatedStart.y, rotatedStart.z);
    auto maxsStart = vec3_t(rotatedStart.x - maxsAdjusted, rotatedStart.y, rotatedStart.z);

    auto b_c = 2.f * (rotatedStart.y * rotatedDirection.y + rotatedStart.z * rotatedDirection.z);

    auto b_smins = 2.f * (minsStart.dot(rotatedDirection));
    auto b_smaxs = 2.f * (maxsStart.dot(rotatedDirection));

    auto c_c = rotatedStart.y * rotatedStart.y + rotatedStart.z * rotatedStart.z - hitbox.m_radius * hitbox.m_radius;

    auto c_smins = minsStart.dot(minsStart) - hitbox.m_radius * hitbox.m_radius;
    auto c_smaxs = maxsStart.dot(maxsStart) - hitbox.m_radius * hitbox.m_radius;

    auto cylOperand = b_c * b_c - 4 * a_c * c_c;
    auto sphMinsOperand = b_smins * b_smins - 4 * a_s * c_smins;
    auto sphMaxsOperand = b_smaxs * b_smaxs - 4 * a_s * c_smaxs;

    auto tCyl = 0.f;
    auto tSphMins = 0.f;
    auto tSphMaxs = 0.f;

    auto cylHit = false;
    auto sphMinsHit = false;
    auto sphMaxsHit = false;

    // if we don't hit, operand is negative.
    if (cylOperand > 0.f) {
        tCyl = (-b_c - sqrtf(cylOperand)) / (2.f * a_c);

        if (tCyl - FLT_EPSILON > 0.f) {
            // make sure we hit within our bounds, and not outside of the cylinder's bore.
            auto virtualPos = rotatedDirection * tCyl;

            auto outOfMinsSide = virtualPos.x < minsAdjusted;
            auto outOfMaxsSide = virtualPos.x > maxsAdjusted;

            if (!outOfMinsSide &&
                !outOfMaxsSide)
                cylHit = true;
        }
    }

    if (sphMinsOperand > 0.f) {
        tSphMins = (-b_smins - sqrtf(sphMinsOperand)) / (2.f * a_s);

        if (tSphMins - FLT_EPSILON > 0.f)
            sphMinsHit = true;
    }

    if (sphMaxsOperand > 0.f) {
        tSphMaxs = (-b_smaxs - sqrtf(sphMaxsOperand)) / (2.f * a_s);

        if (tSphMaxs - FLT_EPSILON > 0.f)
            sphMaxsHit = true;
    }

    // see which one hit first, then return accordingly.
    if (cylHit) {
        trace.m_fraction = tCyl / ray.m_length;
        trace.m_hit = true;
    }
    else if (sphMinsHit) {
        trace.m_fraction = tSphMins / ray.m_length;
        trace.m_hit = true;
    }
    else if (sphMaxsHit) {
        trace.m_fraction = tSphMaxs / ray.m_length;
        trace.m_hit = true;
    }
}
matrix.h:
#pragma once
#include <cstring>

class matrix3x4_t {
public:
    float m_flMatVal[3][4];

    // default constructor.
    __forceinline matrix3x4_t() {
        memset(m_flMatVal, 0, sizeof(m_flMatVal));
    }

    // parameterized constructor.
    __forceinline matrix3x4_t(float m00, float m01, float m02, float m03,
        float m10, float m11, float m12, float m13,
        float m20, float m21, float m22, float m23) {
        m_flMatVal[0][0] = m00; m_flMatVal[0][1] = m01; m_flMatVal[0][2] = m02; m_flMatVal[0][3] = m03;
        m_flMatVal[1][0] = m10; m_flMatVal[1][1] = m11; m_flMatVal[1][2] = m12; m_flMatVal[1][3] = m13;
        m_flMatVal[2][0] = m20; m_flMatVal[2][1] = m21; m_flMatVal[2][2] = m22; m_flMatVal[2][3] = m23;
    }

    // copy constructor.
    matrix3x4_t(const matrix3x4_t& other) {
        memcpy(m_flMatVal, other.m_flMatVal, sizeof(m_flMatVal));
    }

    // copy assignment operator.
    matrix3x4_t& operator=(const matrix3x4_t& other) {
        if (this != &other) {
            memcpy(m_flMatVal, other.m_flMatVal, sizeof(m_flMatVal));
        }
        return *this;
    }

    // set origin of the matrix.
    __forceinline void SetOrigin(const vec3_t& p) {
        m_flMatVal[0][3] = p.x;
        m_flMatVal[1][3] = p.y;
        m_flMatVal[2][3] = p.z;
    }

    // get origin of the matrix.
    __forceinline vec3_t GetOrigin() const {
        return {m_flMatVal[0][3], m_flMatVal[1][3], m_flMatVal[2][3]};
    }

    // matrix from angles.
    void AngleMatrix(const ang_t& angles) {
        float sr, sp, sy, cr, cp, cy;
        DirectX::XMScalarSinCos(&sy, &cy, math::deg_to_rad(angles.y));
        DirectX::XMScalarSinCos(&sp, &cp, math::deg_to_rad(angles.x));
        DirectX::XMScalarSinCos(&sr, &cr, math::deg_to_rad(angles.z));

        // matrix = (yaw * pitch) * roll.
        m_flMatVal[0][0] = cp * cy;
        m_flMatVal[1][0] = cp * sy;
        m_flMatVal[2][0] = -sp;

        float crcy = cr * cy;
        float crsy = cr * sy;
        float srcy = sr * cy;
        float srsy = sr * sy;
        m_flMatVal[0][1] = sp * srcy - crsy;
        m_flMatVal[1][1] = sp * srsy + crcy;
        m_flMatVal[2][1] = sr * cp;

        m_flMatVal[0][2] = (sp * crcy + srsy);
        m_flMatVal[1][2] = (sp * crsy - srcy);
        m_flMatVal[2][2] = cr * cp;

        m_flMatVal[0][3] = 0.0f;
        m_flMatVal[1][3] = 0.0f;
        m_flMatVal[2][3] = 0.0f;
    }

    // addition operator.
    matrix3x4_t operator+(const matrix3x4_t& other) const {
        matrix3x4_t result;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                result.m_flMatVal[i][j] = this->m_flMatVal[i][j] + other.m_flMatVal[i][j];
            }
        }
        return result;
    }

    // multiplication by another matrix (for 3x4 matrices, we only multiply the 3x3 part).
    matrix3x4_t operator*(const matrix3x4_t& other) const {
        matrix3x4_t result;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                result.m_flMatVal[i][j] = 0;
                for (int k = 0; k < 3; k++) {
                    result.m_flMatVal[i][j] += this->m_flMatVal[i][k] * other.m_flMatVal[k][j];
                }
            }
        }
        return result;
    }

    // multiplication by scalar.
    matrix3x4_t operator*(float scalar) const {
        matrix3x4_t result;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                result.m_flMatVal[i][j] = this->m_flMatVal[i][j] * scalar;
            }
        }
        return result;
    }

    // multiply the matrix by a vector.
    vec3_t operator*(const vec3_t& vec) const {
        return vec3_t(
            vec.x * m_flMatVal[0][0] + vec.y * m_flMatVal[0][1] + vec.z * m_flMatVal[0][2] + m_flMatVal[0][3],
            vec.x * m_flMatVal[1][0] + vec.y * m_flMatVal[1][1] + vec.z * m_flMatVal[1][2] + m_flMatVal[1][3],
            vec.x * m_flMatVal[2][0] + vec.y * m_flMatVal[2][1] + vec.z * m_flMatVal[2][2] + m_flMatVal[2][3]
        );
    }

    // array access operator.
    __forceinline float* operator[](int i) {
        return m_flMatVal[i];
    }

    // array access operator (const version).
    __forceinline const float* operator[](int i) const {
        return m_flMatVal[i];
    }

    // base pointer access.
    __forceinline float* Base() {
        return &m_flMatVal[0][0];
    }

    // base pointer access (const version).
    __forceinline const float* Base() const {
        return &m_flMatVal[0][0];
    }

    // get bone position.
    bool get_bone(vec3_t& out, int bone = 0) {
        if (bone < 0 || bone >= 128)
            return false;

        matrix3x4_t* bone_matrix = &this[bone];

        if (!bone_matrix)
            return false;

        out = {bone_matrix->m_flMatVal[0][3], bone_matrix->m_flMatVal[1][3], bone_matrix->m_flMatVal[2][3]};

        return true;
    }
};

// aligned version of matrix3x4_t for specific cases.
class __declspec(align(16)) matrix3x4a_t: public matrix3x4_t {
public:
    __forceinline matrix3x4a_t& operator=(const matrix3x4_t& src) {
        std::memcpy(Base(), src.Base(), sizeof(float) * 3 * 4);
        return *this;
    }
};

// VMatrix class.
class VMatrix {
public:
    float m[4][4];

    // array access operator.
    __forceinline float* operator[](int i) {
        return m[i];
    }

    // array access operator (const version).
    __forceinline const float* operator[](int i) const {
        return m[i];
    }

    // base pointer access.
    __forceinline float* Base() {
        return &m[0][0];
    }

    // base pointer access (const version).
    __forceinline const float* Base() const {
        return &m[0][0];
    }
};
give me the m_peek_data class as well as where it is used!
 
get good get legendware
Участник
Статус
Оффлайн
Регистрация
22 Сен 2020
Сообщения
434
Реакции[?]
200
Поинты[?]
47K
aint no way bro multithreading the generation of points :whyRly: then running the hitscan on a single thread :forsenGun::FailFish:
 
Начинающий
Статус
Оффлайн
Регистрация
15 Окт 2019
Сообщения
23
Реакции[?]
5
Поинты[?]
5K
Начинающий
Статус
Оффлайн
Регистрация
28 Дек 2019
Сообщения
74
Реакции[?]
6
Поинты[?]
9K
вы надоели свои супримаси кидать кидайте сразу сурсом пасты своей а не частями а чо
 
Начинающий
Статус
Оффлайн
Регистрация
15 Окт 2019
Сообщения
23
Реакции[?]
5
Поинты[?]
5K

Вложения

Сверху Снизу