Rebekah Rowe 0606ca3008
Initial Client Implimented in GUI.
The code is implimented in this commit and is launchable with the BUILD_CLIENT compile option.
Everything should be launchable by running the one function within
src/nyqubel-client/client.hpp: start_nyqubel_client()
2024-02-13 10:47:58 -05:00

476 lines
12 KiB
C++

/*
* Nekohook: Free, fast and modular cheat software
* Copyright (C) 2018 Rebekah Rowe
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <array>
#include <algorithm>
#include <glm/detail/qualifier.hpp>
#include <glm/fwd.hpp>
#include <stdexcept>
#include <glm/glm.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/geometric.hpp>
namespace qubel::geo {
namespace internal {
#if true // NEKOHOOK_GFX == opengl
template <int _dim_length, typename T>
using BVec = glm::vec<_dim_length, T>;
template <typename T>
using BVec2 = glm::vec<2, T>;
template <typename T>
using BVec3 = glm::vec<3, T>;
using Vec2 = glm::vec2;
using Vec3 = glm::vec3;
using DVec3 = glm::dvec3;
using IVec2 = glm::ivec2;
using UVec2 = glm::uvec2;
constexpr float F_PI = glm::pi<float>();
template <class... T>
auto Distance(T... in) { return glm::distance(in...); }
template <typename T>
auto GetMaskOfVec2(const T& src, glm::bvec2 mask) {
T ret = { 0, 0 };
if (mask.x)
ret.x = src.x;
if (mask.y)
ret.y = src.y;
return ret;
}
#endif
template <typename T, int _length>
class BoxBase;
template <typename T>
class BoxBase<T, 2> {
static_assert(T::length() == 2);
protected:
BoxBase() { }
BoxBase(T _first, T _second)
: first(_first)
, second(_second) { }
public:
// TODO, rotation around origin?
// Data
union {
T first, origin;
};
union {
T second, size;
};
T GetMax() const { return this->origin + this->size; }
T GetSize() const { return this->size; }
T GetPoint(int idx) const {
switch (idx) {
case 0:
return this->origin;
case 1:
return { this->origin.x + this->size.x, this->origin.y };
case 2:
return { this->origin.x, this->origin.y + this->size.y };
case 3:
return this->origin + this->size;
default:
throw std::logic_error("Unknown point idx: " + std::to_string(idx));
}
}
std::array<T, 4> GetPoints() const {
T max = this->GetMax();
return {
this->origin,
{ max.x, this->origin.y },
{ this->origin.x, max.y },
max
};
}
bool Contains(T in) const {
if (in.x > this->origin.x && in.y > this->origin.y) {
T max = this->GetMax();
return (in.x < max.x && in.x < max.y);
}
return false;
}
bool SegmentIntersects(T src, T dest) const {
if ((dest.x > this->min.x && src.x > this->min.x) && (dest.y > this->min.y && src.y > this->min.y)) {
T max = this->GetMax();
return (dest.x < max.x && src.x < max.x) || (dest.y < max.y && src.y < max.y);
}
return false;
}
enum class Direction {
kUp,
kDown,
kLeft,
kRight,
kPosX = kRight,
kPosY = kDown,
kNegX = kLeft,
kNegY = kUp
};
void Expand(Direction dir, int amt) { // TODO: Bitmongering(nopey)
switch (dir) {
case Direction::kUp:
this->origin.y -= amt;
case Direction::kDown:
this->size.y += amt;
break;
case Direction::kLeft:
this->origin.x -= amt;
case Direction::kRight:
this->size.x += amt;
break;
default:
assert(false);
}
}
void ExpandTo(T v) {
if (this->origin.x > v.x)
this->Expand(Direction::kNegX, this->origin.x - v.x);
if (this->origin.y > v.y)
this->Expand(Direction::kNegY, this->origin.y - v.y);
T t_max = this->GetMax();
if (t_max.x < v.x)
this->Expand(Direction::kPosX, v.x - this->origin.x);
if (t_max.y < v.y)
this->Expand(Direction::kPosY, v.y - this->origin.y);
}
// TODO: Center around
};
template <typename T>
class BoxBase<T, 3> {
static_assert(T::length() == 3);
protected:
BoxBase() { }
BoxBase(T _first, T _second)
: first(_first)
, second(_second) { }
public:
// Data
union {
T first, min;
};
union {
T second, max;
};
auto operator[](const int idx) const {
return this->data.at(idx);
}
// Utility functions
T GetSize() const { return this->max - this->min; }
T& GetMax() const { return this->max; }
T GetPoint(int idx) const {
switch (idx) {
case 0:
return this->min;
case 1:
return { this->max.x, this->min.y, this->min.z };
case 2:
return { this->max.x, this->max.y, this->min.z };
case 3:
return { this->min.x, this->max.y, this->max.z };
case 4:
return { this->min.x, this->min.y, this->max.z };
case 5:
return { this->max.x, this->min.y, this->max.z };
case 6:
return { this->min.x, this->max.y, this->min.z };
case 7:
return this->max;
default:
throw std::logic_error("GetPoint() is only available for 2 and 3 axis vectors");
}
}
std::array<T, 8> GetPoints() const {
return {
this->min,
{ this->max.x, this->min.y, this->min.z },
{ this->max.x, this->max.y, this->min.z },
{ this->min.x, this->max.y, this->max.z },
{ this->min.x, this->min.y, this->max.z },
{ this->max.x, this->min.y, this->max.z },
{ this->min.x, this->max.y, this->min.z },
this->max
};
}
bool Contains(T i) const {
if (i.x > this->min.x || i.y > this->min.y || i.z > this->min.z)
if (i.x < this->max.x || i.y < this->max.y || i.z < this->max.z)
return false;
return true;
}
// Credits to cathook
bool LineIntersects(T src, T dst) const {
if (dst.x < this->min.x && src.x < this->min.x)
return false;
if (dst.y < this->min.y && src.y < this->min.y)
return false;
if (dst.z < this->min.z && src.z < this->min.z)
return false;
if (dst.x > this->max.x && src.x > this->max.x)
return false;
if (dst.y > this->max.y && src.y > this->max.y)
return false;
if (dst.z > this->max.z && src.z > this->max.z)
return false;
return true;
}
enum Direction {
kUp,
kDown,
kLeft,
kRight,
kForward,
kBackward,
kPosX = kUp,
kPosY = kLeft,
kPosZ = kForward,
kNegX = kDown,
kNegY = kRight,
kNegZ = kBackward
};
void Expand(Direction dir, int amt) {
switch (dir) {
case Direction::kUp:
this->max.y += amt;
break;
case Direction::kDown:
this->min.y -= amt;
break;
case Direction::kLeft:
this->min.x += amt;
break;
case Direction::kRight:
this->min.x -= amt;
break;
case Direction::kForward:
this->min.z += amt;
break;
case Direction::kBackward:
this->max.z -= amt;
break;
default:
assert(false);
}
}
};
template <typename T>
class Box : public BoxBase<T, T::length()> {
using Parent = BoxBase<T, T::length()>;
public:
using Direction = typename Parent::Direction;
Box() { }
Box(T _first, T _second)
: Parent(_first, _second) { }
Box(std::pair<T, T> v)
: Box(v.first, v.second) { }
template <typename TT>
Box(TT v)
: Box(v.first, v.second) {
static_assert(!std::is_same_v<std::pair<T, T>, TT>);
}
template <typename TT>
Box<T>& operator=(TT v) { *this = Box<T>(v.first, v.second); }
// Unary arithmetic operators
bool operator==(T v) const {
return this->first == v.first && this->second == v.second;
}
bool operator!=(T v) const {
return !(*this == v);
}
Box<T> operator+(T v) const {
return { this->min + v, this->max + v };
}
Box<T> operator-(T v) const {
return { this->min - v, this->max - v };
}
Box<T> operator*(typename T::value_type v) const {
T center = this->GetCenter();
T size = (this->GetSize() * v) / typename T::value_type(2);
return { center - size, center + size };
}
Box<T> operator/(typename T::value_type v) const {
T center = this->GetCenter();
T delta = (this->GetSize() / v) / typename T::value_type(2);
return { center - delta, center + delta };
}
Box<T>& operator/=(typename T::value_type v) {
return *this = *this / v;
}
// Utility functions
T GetCenter() const { return (this->first + this->second) / typename T::value_type(2); }
void Expand(std::initializer_list<Direction> dirs, int amt) {
auto end = dirs.end();
for (auto i = dirs.begin(); i != end; i++)
this->Expand(*i, amt);
}
void Shrink(Direction dir, int amt) { this->Expand(dir, -amt); }
};
template <int T_length>
class AngleBase;
template <>
class AngleBase<1> {
float data;
protected:
template <typename... T>
AngleBase(T... args)
: data(args...) { }
public:
operator float() const {
return this->data;
}
operator float&() {
return this->data;
}
};
template <>
class AngleBase<2> : public Vec2 {
using Vec2::Vec2;
using Parent = Vec2;
protected:
template <typename... T>
AngleBase(T... args)
: Vec2(args...) {
static_assert(!(std::is_same_v<Vec2, T> || ...));
}
public:
using Vec2::operator=;
template <class T>
AngleBase operator-(T in) { return *this - Vec2(in); }
template <class T>
AngleBase operator+(T in) { return *this + Vec2(in); }
AngleBase<2>& Clamp();
AngleBase<2> Clamp() const;
AngleBase<2> GetDelta(const AngleBase<2>& other_angles) const;
float GetFov(const Vec3& view_src, const Vec3& dest_point) const;
float GetFov(const AngleBase<2>& pointed_angle) const;
static AngleBase<2> PointTo(const Vec3& src_point, const Vec3& dest_point);
};
template <int T_Length>
using Angle = AngleBase<T_Length>;
using Angle1 = Angle<1>;
using Angle2 = Angle<2>;
template <typename T_Origin, typename T_Angle>
class Ray {
private:
const T_Origin origin;
const T_Angle angle;
public:
Ray(T_Origin origin, T_Angle angle)
: origin(origin)
, angle(angle) { }
std::pair<T_Origin, T_Origin> Cast(float dist);
};
template <typename T>
class Segment : public std::pair<T, T> {
public:
using Parent = std::pair<T, T>;
using Parent::Parent;
using Parent::operator=;
template <typename TT>
Segment(Ray<T, TT> r, float dist = 8192.0f)
: Parent(r.Cast(dist)) { }
Segment(const std::pair<T, T>& p)
: Parent(p) { }
Segment(std::pair<T, T>&& p)
: Parent(std::move(p)) { }
Segment(std::pair<T, T> p)
: Parent(std::move(p)) { }
};
} // namespace internal
using Vec3 = internal::Vec3;
using Vec2 = internal::Vec2;
// idk if these should be in here, but its too useful not to...
using DVec3 = internal::DVec3;
using IVec2 = internal::IVec2;
using UVec2 = internal::UVec2;
///
template <class... T>
auto Distance(T... in) { return internal::Distance(in...); }
template <class T>
auto GetMaskOfVec2(const T& src, glm::bvec2 mask) { return internal::GetMaskOfVec2(src, mask); }
template <class T>
using Box = internal::Box<T>;
template <int T>
using Angle = internal::AngleBase<T>;
template <typename T_Origin, typename T_Angle>
using Ray = internal::Ray<T_Origin, T_Angle>;
template <typename T>
using Segment = internal::Segment<T>;
using Segment2 = internal::Segment<Vec2>;
using Segment3 = internal::Segment<Vec3>;
template <class T_Vec, class T_Float>
using Sphereoid = std::pair<T_Vec, T_Float>;
} // namespace qubel::geo