1
0
forked from gcdsfh/PMDT

fix name eroor

This commit is contained in:
gcdsfh145
2026-05-03 13:32:50 +08:00
parent 0b6dbde6f5
commit 7699ea3535
3219 changed files with 19 additions and 19 deletions
+703
View File
@@ -0,0 +1,703 @@
#pragma once
#define _USE_MATH_DEFINES
#include <math.h>
#include <iostream>
#define SMALL_float 0.0000000001
/**
* Attempt to include a header file if the file exists.
* If the file does not exist, create a dummy data structure for that type.
* If it cannot be determined if it exists, just attempt to include it.
*/
#ifdef __has_include
# if __has_include("Vector3.hpp")
# include "Vector3.hpp"
# elif !defined(GMATH_VECTOR3)
#define GMATH_VECTOR3
struct Vector3
{
union
{
struct
{
float X;
float Y;
float Z;
};
float data[3];
};
inline Vector3() : X(0), Y(0), Z(0) {}
inline Vector3(float data[]) : X(data[0]), Y(data[1]), Z(data[2])
{}
inline Vector3(float value) : X(value), Y(value), Z(value) {}
inline Vector3(float x, float y) : X(x), Y(y), Z(0) {}
inline Vector3(float x, float y, float z) : X(x), Y(y), Z(z) {}
static inline Vector3 Cross(Vector3 lhs, Vector3 rhs)
{
float x = lhs.Y * rhs.Z - lhs.Z * rhs.Y;
float y = lhs.Z * rhs.X - lhs.X * rhs.Z;
float z = lhs.X * rhs.Y - lhs.Y * rhs.X;
return Vector3(x, y, z);
}
static inline float Dot(Vector3 lhs, Vector3 rhs)
{
return lhs.X * rhs.X + lhs.Y * rhs.Y + lhs.Z * rhs.Z;
}
static inline Vector3 Normalized(Vector3 v)
{
float mag = sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z);
if (mag == 0)
return Vector3::Zero();
return v / mag;
}
static inline Vector3 Orthogonal(Vector3 v)
{
return v.Z < v.X ?
Vector3(v.Y, -v.X, 0) : Vector3(0, -v.Z, v.Y);
}
static inline float SqrMagnitude(Vector3 v)
{
return v.X * v.X + v.Y * v.Y + v.Z * v.Z;
}
};
inline Vector3 operator+(Vector3 lhs, const Vector3 rhs)
{
return Vector3(lhs.X + rhs.X, lhs.Y + rhs.Y, lhs.Z + rhs.Z);
}
inline Vector3 operator*(Vector3 lhs, const float rhs)
{
return Vector3(lhs.X * rhs, lhs.Y * rhs, lhs.Z * rhs);
}
# endif
#else
# include "Vector3.hpp"
#endif
struct Quaternion
{
union
{
struct
{
float X;
float Y;
float Z;
float W;
};
float data[4];
};
/**
* Constructors.
*/
inline Quaternion();
inline Quaternion(float data[]);
inline Quaternion(Vector3 vector, float scalar);
inline Quaternion(float x, float y, float z, float w);
/**
* Constants for common quaternions.
*/
static inline Quaternion Identity();
/**
* Returns the angle between two quaternions.
* The quaternions must be normalized.
* @param a: The first quaternion.
* @param b: The second quaternion.
* @return: A scalar value.
*/
static inline float Angle(Quaternion a, Quaternion b);
/**
* Returns the conjugate of a quaternion.
* @param rotation: The quaternion in question.
* @return: A new quaternion.
*/
static inline Quaternion Conjugate(Quaternion rotation);
/**
* Returns the dot product of two quaternions.
* @param lhs: The left side of the multiplication.
* @param rhs: The right side of the multiplication.
* @return: A scalar value.
*/
static inline float Dot(Quaternion lhs, Quaternion rhs);
/**
* Creates a new quaternion from the angle-axis representation of
* a rotation.
* @param angle: The rotation angle in radians.
* @param axis: The vector about which the rotation occurs.
* @return: A new quaternion.
*/
static inline Quaternion FromAngleAxis(float angle, Vector3 axis);
/**
* Create a new quaternion from the euler angle representation of
* a rotation. The z, x and y values represent rotations about those
* axis in that respective order.
* @param rotation: The x, y and z rotations.
* @return: A new quaternion.
*/
static inline Quaternion FromEuler(Vector3 rotation);
/**
* Create a new quaternion from the euler angle representation of
* a rotation. The z, x and y values represent rotations about those
* axis in that respective order.
* @param x: The rotation about the x-axis in radians.
* @param y: The rotation about the y-axis in radians.
* @param z: The rotation about the z-axis in radians.
* @return: A new quaternion.
*/
static inline Quaternion FromEuler(float x, float y, float z);
/**
* Create a quaternion rotation which rotates "fromVector" to "toVector".
* @param fromVector: The vector from which to start the rotation.
* @param toVector: The vector at which to end the rotation.
* @return: A new quaternion.
*/
static inline Quaternion FromToRotation(Vector3 fromVector,
Vector3 toVector);
/**
* Returns the inverse of a rotation.
* @param rotation: The quaternion in question.
* @return: A new quaternion.
*/
static inline Quaternion Inverse(Quaternion rotation);
/**
* Interpolates between a and b by t, which is clamped to the range [0-1].
* The result is normalized before being returned.
* @param a: The starting rotation.
* @param b: The ending rotation.
* @return: A new quaternion.
*/
static inline Quaternion Lerp(Quaternion a, Quaternion b, float t);
/**
* Interpolates between a and b by t. This normalizes the result when
* complete.
* @param a: The starting rotation.
* @param b: The ending rotation.
* @param t: The interpolation value.
* @return: A new quaternion.
*/
static inline Quaternion LerpUnclamped(Quaternion a, Quaternion b,
float t);
/**
* Creates a rotation with the specified forward direction. This is the
* same as calling LookRotation with (0, 1, 0) as the upwards vector.
* The output is undefined for parallel vectors.
* @param forward: The forward direction to look toward.
* @return: A new quaternion.
*/
static inline Quaternion LookRotation(Vector3 forward);
/**
* Creates a rotation with the specified forward and upwards directions.
* The output is undefined for parallel vectors.
* @param forward: The forward direction to look toward.
* @param upwards: The direction to treat as up.
* @return: A new quaternion.
*/
static inline Quaternion LookRotation(Vector3 forward, Vector3 upwards);
/**
* Returns the norm of a quaternion.
* @param rotation: The quaternion in question.
* @return: A scalar value.
*/
static inline float Norm(Quaternion rotation);
/**
* Returns a quaternion with identical rotation and a norm of one.
* @param rotation: The quaternion in question.
* @return: A new quaternion.
*/
static inline Quaternion Normalized(Quaternion rotation);
/**
* Returns a new Quaternion created by rotating "from" towards "to" by
* "maxRadiansDelta". This will not overshoot, and if a negative delta is
* applied, it will rotate till completely opposite "to" and then stop.
* @param from: The rotation at which to start.
* @param to: The rotation at which to end.
# @param maxRadiansDelta: The maximum number of radians to rotate.
* @return: A new Quaternion.
*/
static inline Quaternion RotateTowards(Quaternion from, Quaternion to,
float maxRadiansDelta);
/**
* Returns a new quaternion interpolated between a and b, using spherical
* linear interpolation. The variable t is clamped to the range [0-1]. The
* resulting quaternion will be normalized.
* @param a: The starting rotation.
* @param b: The ending rotation.
* @param t: The interpolation value.
* @return: A new quaternion.
*/
static inline Quaternion Slerp(Quaternion a, Quaternion b, float t);
/**
* Returns a new quaternion interpolated between a and b, using spherical
* linear interpolation. The resulting quaternion will be normalized.
* @param a: The starting rotation.
* @param b: The ending rotation.
* @param t: The interpolation value.
* @return: A new quaternion.
*/
static inline Quaternion SlerpUnclamped(Quaternion a, Quaternion b,
float t);
/**
* Outputs the angle axis representation of the provided quaternion.
* @param rotation: The input quaternion.
* @param angle: The output angle.
* @param axis: The output axis.
*/
static inline void ToAngleAxis(Quaternion rotation, float &angle,
Vector3 &axis);
/**
* Returns the Euler angle representation of a rotation. The resulting
* vector contains the rotations about the z, x and y axis, in that order.
* @param rotation: The quaternion to convert.
* @return: A new vector.
*/
static inline Vector3 ToEuler(Quaternion rotation);
/**
* Operator overloading.
*/
inline struct Quaternion& operator+=(const float rhs);
inline struct Quaternion& operator-=(const float rhs);
inline struct Quaternion& operator*=(const float rhs);
inline struct Quaternion& operator/=(const float rhs);
inline struct Quaternion& operator+=(const Quaternion rhs);
inline struct Quaternion& operator-=(const Quaternion rhs);
inline struct Quaternion& operator*=(const Quaternion rhs);
};
inline Quaternion operator-(Quaternion rhs);
inline Quaternion operator+(Quaternion lhs, const float rhs);
inline Quaternion operator-(Quaternion lhs, const float rhs);
inline Quaternion operator*(Quaternion lhs, const float rhs);
inline Quaternion operator/(Quaternion lhs, const float rhs);
inline Quaternion operator+(const float lhs, Quaternion rhs);
inline Quaternion operator-(const float lhs, Quaternion rhs);
inline Quaternion operator*(const float lhs, Quaternion rhs);
inline Quaternion operator/(const float lhs, Quaternion rhs);
inline Quaternion operator+(Quaternion lhs, const Quaternion rhs);
inline Quaternion operator-(Quaternion lhs, const Quaternion rhs);
inline Quaternion operator*(Quaternion lhs, const Quaternion rhs);
inline Vector3 operator*(Quaternion lhs, const Vector3 rhs);
inline bool operator==(const Quaternion lhs, const Quaternion rhs);
inline bool operator!=(const Quaternion lhs, const Quaternion rhs);
/*******************************************************************************
* Implementation
*/
Quaternion::Quaternion() : X(0), Y(0), Z(0), W(1) {}
Quaternion::Quaternion(float data[]) : X(data[0]), Y(data[1]), Z(data[2]),
W(data[3]) {}
Quaternion::Quaternion(Vector3 vector, float scalar) : X(vector.X),
Y(vector.Y), Z(vector.Z), W(scalar) {}
Quaternion::Quaternion(float x, float y, float z, float w) : X(x), Y(y),
Z(z), W(w) {}
Quaternion Quaternion::Identity() { return Quaternion(0, 0, 0, 1); }
float Quaternion::Angle(Quaternion a, Quaternion b)
{
float dot = Dot(a, b);
return acos(fmin(fabs(dot), 1)) * 2;
}
Quaternion Quaternion::Conjugate(Quaternion rotation)
{
return Quaternion(-rotation.X, -rotation.Y, -rotation.Z, rotation.W);
}
float Quaternion::Dot(Quaternion lhs, Quaternion rhs)
{
return lhs.X * rhs.X + lhs.Y * rhs.Y + lhs.Z * rhs.Z + lhs.W * rhs.W;
}
Quaternion Quaternion::FromAngleAxis(float angle, Vector3 axis)
{
Quaternion q;
float m = sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
float s = sin(angle / 2) / m;
q.X = axis.X * s;
q.Y = axis.Y * s;
q.Z = axis.Z * s;
q.W = cos(angle / 2);
return q;
}
Quaternion Quaternion::FromEuler(Vector3 rotation)
{
return FromEuler(rotation.X, rotation.Y, rotation.Z);
}
Quaternion Quaternion::FromEuler(float x, float y, float z)
{
float cx = cos(x * 0.5);
float cy = cos(y * 0.5);
float cz = cos(z * 0.5);
float sx = sin(x * 0.5);
float sy = sin(y * 0.5);
float sz = sin(z * 0.5);
Quaternion q;
q.X = cx * sy * sz + cy * cz * sx;
q.Y = cx * cz * sy - cy * sx * sz;
q.Z = cx * cy * sz - cz * sx * sy;
q.W = sx * sy * sz + cx * cy * cz;
return q;
}
Quaternion Quaternion::FromToRotation(Vector3 fromVector, Vector3 toVector)
{
float dot = Vector3::Dot(fromVector, toVector);
float k = sqrt(Vector3::SqrMagnitude(fromVector) *
Vector3::SqrMagnitude(toVector));
if (fabs(dot / k + 1) < 0.00001)
{
Vector3 ortho = Vector3::Orthogonal(fromVector);
return Quaternion(Vector3::Normalized(ortho), 0);
}
Vector3 cross = Vector3::Cross(fromVector, toVector);
return Normalized(Quaternion(cross, dot + k));
}
Quaternion Quaternion::Inverse(Quaternion rotation)
{
float n = Norm(rotation);
return Conjugate(rotation) / (n * n);
}
Quaternion Quaternion::Lerp(Quaternion a, Quaternion b, float t)
{
if (t < 0) return Normalized(a);
else if (t > 1) return Normalized(b);
return LerpUnclamped(a, b, t);
}
Quaternion Quaternion::LerpUnclamped(Quaternion a, Quaternion b, float t)
{
Quaternion quaternion;
if (Dot(a, b) >= 0)
quaternion = a * (1 - t) + b * t;
else
quaternion = a * (1 - t) - b * t;
return Normalized(quaternion);
}
Quaternion Quaternion::LookRotation(Vector3 forward)
{
return LookRotation(forward, Vector3(0, 1, 0));
}
Quaternion Quaternion::LookRotation(Vector3 forward, Vector3 upwards)
{
// Normalize inputs
forward = Vector3::Normalized(forward);
upwards = Vector3::Normalized(upwards);
// Don't allow zero vectors
if (Vector3::SqrMagnitude(forward) < SMALL_float || Vector3::SqrMagnitude(upwards) < SMALL_float)
return Quaternion::Identity();
// Handle alignment with up direction
if (1 - fabs(Vector3::Dot(forward, upwards)) < SMALL_float)
return FromToRotation(Vector3::Forward(), forward);
// Get orthogonal vectors
Vector3 right = Vector3::Normalized(Vector3::Cross(upwards, forward));
upwards = Vector3::Cross(forward, right);
// Calculate rotation
Quaternion quaternion;
float radicand = right.X + upwards.Y + forward.Z;
if (radicand > 0)
{
quaternion.W = sqrt(1.0 + radicand) * 0.5;
float recip = 1.0 / (4.0 * quaternion.W);
quaternion.X = (upwards.Z - forward.Y) * recip;
quaternion.Y = (forward.X - right.Z) * recip;
quaternion.Z = (right.Y - upwards.X) * recip;
}
else if (right.X >= upwards.Y && right.X >= forward.Z)
{
quaternion.X = sqrt(1.0 + right.X - upwards.Y - forward.Z) * 0.5;
float recip = 1.0 / (4.0 * quaternion.X);
quaternion.W = (upwards.Z - forward.Y) * recip;
quaternion.Z = (forward.X + right.Z) * recip;
quaternion.Y = (right.Y + upwards.X) * recip;
}
else if (upwards.Y > forward.Z)
{
quaternion.Y = sqrt(1.0 - right.X + upwards.Y - forward.Z) * 0.5;
float recip = 1.0 / (4.0 * quaternion.Y);
quaternion.Z = (upwards.Z + forward.Y) * recip;
quaternion.W = (forward.X - right.Z) * recip;
quaternion.X = (right.Y + upwards.X) * recip;
}
else
{
quaternion.Z = sqrt(1.0 - right.X - upwards.Y + forward.Z) * 0.5;
float recip = 1.0 / (4.0 * quaternion.Z);
quaternion.Y = (upwards.Z + forward.Y) * recip;
quaternion.X = (forward.X + right.Z) * recip;
quaternion.W = (right.Y - upwards.X) * recip;
}
return quaternion;
}
float Quaternion::Norm(Quaternion rotation)
{
return sqrt(rotation.X * rotation.X +
rotation.Y * rotation.Y +
rotation.Z * rotation.Z +
rotation.W * rotation.W);
}
Quaternion Quaternion::Normalized(Quaternion rotation)
{
return rotation / Norm(rotation);
}
Quaternion Quaternion::RotateTowards(Quaternion from, Quaternion to,
float maxRadiansDelta)
{
float angle = Quaternion::Angle(from, to);
if (angle == 0)
return to;
maxRadiansDelta = fmax(maxRadiansDelta, angle - M_PI);
float t = fmin(1, maxRadiansDelta / angle);
return Quaternion::SlerpUnclamped(from, to, t);
}
Quaternion Quaternion::Slerp(Quaternion a, Quaternion b, float t)
{
if (t < 0) return Normalized(a);
else if (t > 1) return Normalized(b);
return SlerpUnclamped(a, b, t);
}
Quaternion Quaternion::SlerpUnclamped(Quaternion a, Quaternion b, float t)
{
float n1;
float n2;
float n3 = Dot(a, b);
bool flag = false;
if (n3 < 0)
{
flag = true;
n3 = -n3;
}
if (n3 > 0.999999)
{
n2 = 1 - t;
n1 = flag ? -t : t;
}
else
{
float n4 = acos(n3);
float n5 = 1 / sin(n4);
n2 = sin((1 - t) * n4) * n5;
n1 = flag ? -sin(t * n4) * n5 : sin(t * n4) * n5;
}
Quaternion quaternion;
quaternion.X = (n2 * a.X) + (n1 * b.X);
quaternion.Y = (n2 * a.Y) + (n1 * b.Y);
quaternion.Z = (n2 * a.Z) + (n1 * b.Z);
quaternion.W = (n2 * a.W) + (n1 * b.W);
return Normalized(quaternion);
}
void Quaternion::ToAngleAxis(Quaternion rotation, float &angle, Vector3 &axis)
{
if (rotation.W > 1)
rotation = Normalized(rotation);
angle = 2 * acos(rotation.W);
float s = sqrt(1 - rotation.W * rotation.W);
if (s < 0.00001) {
axis.X = 1;
axis.Y = 0;
axis.Z = 0;
} else {
axis.X = rotation.X / s;
axis.Y = rotation.Y / s;
axis.Z = rotation.Z / s;
}
}
Vector3 Quaternion::ToEuler(Quaternion rotation)
{
float sqw = rotation.W * rotation.W;
float sqx = rotation.X * rotation.X;
float sqy = rotation.Y * rotation.Y;
float sqz = rotation.Z * rotation.Z;
// If normalized is one, otherwise is correction factor
float unit = sqx + sqy + sqz + sqw;
float test = rotation.X * rotation.W - rotation.Y * rotation.Z;
Vector3 v;
// Singularity at north pole
if (test > 0.4995f * unit)
{
v.Y = 2 * atan2(rotation.Y, rotation.X);
v.X = M_PI_2;
v.Z = 0;
return v;
}
// Singularity at south pole
if (test < -0.4995f * unit)
{
v.Y = -2 * atan2(rotation.Y, rotation.X);
v.X = -M_PI_2;
v.Z = 0;
return v;
}
// Yaw
v.Y = atan2(2 * rotation.W * rotation.Y + 2 * rotation.Z * rotation.X,
1 - 2 * (rotation.X * rotation.X + rotation.Y * rotation.Y));
// Pitch
v.X = asin(2 * (rotation.W * rotation.X - rotation.Y * rotation.Z));
// Roll
v.Z = atan2(2 * rotation.W * rotation.Z + 2 * rotation.X * rotation.Y,
1 - 2 * (rotation.Z * rotation.Z + rotation.X * rotation.X));
return v;
}
struct Quaternion& Quaternion::operator+=(const float rhs)
{
X += rhs;
Y += rhs;
Z += rhs;
W += rhs;
return *this;
}
struct Quaternion& Quaternion::operator-=(const float rhs)
{
X -= rhs;
Y -= rhs;
Z -= rhs;
W -= rhs;
return *this;
}
struct Quaternion& Quaternion::operator*=(const float rhs)
{
X *= rhs;
Y *= rhs;
Z *= rhs;
W *= rhs;
return *this;
}
struct Quaternion& Quaternion::operator/=(const float rhs)
{
X /= rhs;
Y /= rhs;
Z /= rhs;
W /= rhs;
return *this;
}
struct Quaternion& Quaternion::operator+=(const Quaternion rhs)
{
X += rhs.X;
Y += rhs.Y;
Z += rhs.Z;
W += rhs.W;
return *this;
}
struct Quaternion& Quaternion::operator-=(const Quaternion rhs)
{
X -= rhs.X;
Y -= rhs.Y;
Z -= rhs.Z;
W -= rhs.W;
return *this;
}
struct Quaternion& Quaternion::operator*=(const Quaternion rhs)
{
Quaternion q;
q.W = W * rhs.W - X * rhs.X - Y * rhs.Y - Z * rhs.Z;
q.X = X * rhs.W + W * rhs.X + Y * rhs.Z - Z * rhs.Y;
q.Y = W * rhs.Y - X * rhs.Z + Y * rhs.W + Z * rhs.X;
q.Z = W * rhs.Z + X * rhs.Y - Y * rhs.X + Z * rhs.W;
*this = q;
return *this;
}
Quaternion operator-(Quaternion rhs) { return rhs * -1; }
Quaternion operator+(Quaternion lhs, const float rhs) { return lhs += rhs; }
Quaternion operator-(Quaternion lhs, const float rhs) { return lhs -= rhs; }
Quaternion operator*(Quaternion lhs, const float rhs) { return lhs *= rhs; }
Quaternion operator/(Quaternion lhs, const float rhs) { return lhs /= rhs; }
Quaternion operator+(const float lhs, Quaternion rhs) { return rhs += lhs; }
Quaternion operator-(const float lhs, Quaternion rhs) { return rhs -= lhs; }
Quaternion operator*(const float lhs, Quaternion rhs) { return rhs *= lhs; }
Quaternion operator/(const float lhs, Quaternion rhs) { return rhs /= lhs; }
Quaternion operator+(Quaternion lhs, const Quaternion rhs)
{
return lhs += rhs;
}
Quaternion operator-(Quaternion lhs, const Quaternion rhs)
{
return lhs -= rhs;
}
Quaternion operator*(Quaternion lhs, const Quaternion rhs)
{
return lhs *= rhs;
}
Vector3 operator*(Quaternion lhs, const Vector3 rhs)
{
Vector3 u = Vector3(lhs.X, lhs.Y, lhs.Z);
float s = lhs.W;
return u * (Vector3::Dot(u, rhs) * 2)
+ rhs * (s * s - Vector3::Dot(u, u))
+ Vector3::Cross(u, rhs) * (2.0 * s);
}
bool operator==(const Quaternion lhs, const Quaternion rhs)
{
return lhs.X == rhs.X &&
lhs.Y == rhs.Y &&
lhs.Z == rhs.Z &&
lhs.W == rhs.W;
}
bool operator!=(const Quaternion lhs, const Quaternion rhs)
{
return !(lhs == rhs);
}
+528
View File
@@ -0,0 +1,528 @@
#pragma once
#define _USE_MATH_DEFINES
#include <math.h>
struct Vector2
{
union
{
struct
{
float X;
float Y;
};
float data[2];
};
/**
* Constructors.
*/
inline Vector2();
inline Vector2(float data[]);
inline Vector2(float value);
inline Vector2(float x, float y);
/**
* Constants for common vectors.
*/
static inline Vector2 Zero();
static inline Vector2 One();
static inline Vector2 Right();
static inline Vector2 Left();
static inline Vector2 Up();
static inline Vector2 Down();
//=====𝗦𝗥𝗖==𝗝𝗢𝗜𝗡==𝗧𝗘𝗟𝗘𝗚𝗥𝗔𝗠=@𝗚𝗞𝗣𝗙𝗥𝗘𝗘𝗛𝗔𝗖𝗞𝗦===@GKPHACK===V=2.4==//
static inline float Angle(Vector2 a, Vector2 b);
/**
* Returns a vector with its magnitude clamped to maxLength.
* @param vector: The target vector.
* @param maxLength: The maximum length of the return vector.
* @return: A new vector.
*/
static inline Vector2 ClampMagnitude(Vector2 vector, float maxLength);
/**
* Returns the component of a in the direction of b (scalar projection).
* @param a: The target vector.
* @param b: The vector being compared against.
* @return: A scalar value.
*/
static inline float Component(Vector2 a, Vector2 b);
/**
* Returns the distance between a and b.
* @param a: The first point.
* @param b: The second point.
* @return: A scalar value.
*/
static inline float Distance(Vector2 a, Vector2 b);
/**
* Returns the dot product of two vectors.
* @param lhs: The left side of the multiplication.
* @param rhs: The right side of the multiplication.
* @return: A scalar value.
*/
static inline float Dot(Vector2 lhs, Vector2 rhs);
/**
* Converts a polar representation of a vector into cartesian
* coordinates.
* @param rad: The magnitude of the vector.
* @param theta: The angle from the X axis.
* @return: A new vector.
*/
static inline Vector2 FromPolar(float rad, float theta);
/**
* Returns a vector linearly interpolated between a and b, moving along
* a straight line. The vector is clamped to never go beyond the end points.
* @param a: The starting point.
* @param b: The ending point.
* @param t: The interpolation value [0-1].
* @return: A new vector.
*/
static inline Vector2 Lerp(Vector2 a, Vector2 b, float t);
/**
* Returns a vector linearly interpolated between a and b, moving along
* a straight line.
* @param a: The starting point.
* @param b: The ending point.
* @param t: The interpolation value [0-1] (no actual bounds).
* @return: A new vector.
*/
static inline Vector2 LerpUnclamped(Vector2 a, Vector2 b, float t);
/**
* Returns the magnitude of a vector.
* @param v: The vector in question.
* @return: A scalar value.
*/
static inline float Magnitude(Vector2 v);
/**
* Returns a vector made from the largest components of two other vectors.
* @param a: The first vector.
* @param b: The second vector.
* @return: A new vector.
*/
static inline Vector2 Max(Vector2 a, Vector2 b);
/**
* Returns a vector made from the smallest components of two other vectors.
* @param a: The first vector.
* @param b: The second vector.
* @return: A new vector.
*/
static inline Vector2 Min(Vector2 a, Vector2 b);
/**
* Returns a vector "maxDistanceDelta" units closer to the target. This
* interpolation is in a straight line, and will not overshoot.
* @param current: The current position.
* @param target: The destination position.
* @param maxDistanceDelta: The maximum distance to move.
* @return: A new vector.
*/
static inline Vector2 MoveTowards(Vector2 current, Vector2 target,
float maxDistanceDelta);
/**
* Returns a new vector with magnitude of one.
* @param v: The vector in question.
* @return: A new vector.
*/
static inline Vector2 Normalized(Vector2 v);
/**
* Creates a new coordinate system out of the two vectors.
* Normalizes "normal" and normalizes "tangent" and makes it orthogonal to
* "normal"..
* @param normal: A reference to the first axis vector.
* @param tangent: A reference to the second axis vector.
*/
static inline void OrthoNormalize(Vector2 &normal, Vector2 &tangent);
/**
* Returns the vector projection of a onto b.
* @param a: The target vector.
* @param b: The vector being projected onto.
* @return: A new vector.
*/
static inline Vector2 Project(Vector2 a, Vector2 b);
/**
* Returns a vector reflected about the provided line.
* This behaves as if there is a plane with the line as its normal, and the
* vector comes in and bounces off this plane.
* @param vector: The vector traveling inward at the imaginary plane.
* @param line: The line about which to reflect.
* @return: A new vector pointing outward from the imaginary plane.
*/
static inline Vector2 Reflect(Vector2 vector, Vector2 line);
/**
* Returns the vector rejection of a on b.
* @param a: The target vector.
* @param b: The vector being projected onto.
* @return: A new vector.
*/
static inline Vector2 Reject(Vector2 a, Vector2 b);
/**
* Rotates vector "current" towards vector "target" by "maxRadiansDelta".
* This treats the vectors as directions and will linearly interpolate
* between their magnitudes by "maxMagnitudeDelta". This function does not
* overshoot. If a negative delta is supplied, it will rotate away from
* "target" until it is pointing the opposite direction, but will not
* overshoot that either.
* @param current: The starting direction.
* @param target: The destination direction.
* @param maxRadiansDelta: The maximum number of radians to rotate.
* @param maxMagnitudeDelta: The maximum delta for magnitude interpolation.
* @return: A new vector.
*/
static inline Vector2 RotateTowards(Vector2 current, Vector2 target,
float maxRadiansDelta,
float maxMagnitudeDelta);
/**
* Multiplies two vectors component-wise.
* @param a: The lhs of the multiplication.
* @param b: The rhs of the multiplication.
* @return: A new vector.
*/
static inline Vector2 Scale(Vector2 a, Vector2 b);
/**
* Returns a vector rotated towards b from a by the percent t.
* Since interpolation is done spherically, the vector moves at a constant
* angular velocity. This rotation is clamped to 0 <= t <= 1.
* @param a: The starting direction.
* @param b: The ending direction.
* @param t: The interpolation value [0-1].
*/
static inline Vector2 Slerp(Vector2 a, Vector2 b, float t);
/**
* Returns a vector rotated towards b from a by the percent t.
* Since interpolation is done spherically, the vector moves at a constant
* angular velocity. This rotation is unclamped.
* @param a: The starting direction.
* @param b: The ending direction.
* @param t: The interpolation value [0-1].
*/
static inline Vector2 SlerpUnclamped(Vector2 a, Vector2 b, float t);
/**
* Returns the squared magnitude of a vector.
* This is useful when comparing relative lengths, where the exact length
* is not important, and much time can be saved by not calculating the
* square root.
* @param v: The vector in question.
* @return: A scalar value.
*/
static inline float SqrMagnitude(Vector2 v);
/**
* Calculates the polar coordinate space representation of a vector.
* @param vector: The vector to convert.
* @param rad: The magnitude of the vector.
* @param theta: The angle from the X axis.
*/
static inline void ToPolar(Vector2 vector, float &rad, float &theta);
/**
* Operator overloading.
*/
inline struct Vector2& operator+=(const float rhs);
inline struct Vector2& operator-=(const float rhs);
inline struct Vector2& operator*=(const float rhs);
inline struct Vector2& operator/=(const float rhs);
inline struct Vector2& operator+=(const Vector2 rhs);
inline struct Vector2& operator-=(const Vector2 rhs);
};
inline Vector2 operator-(Vector2 rhs);
inline Vector2 operator+(Vector2 lhs, const float rhs);
inline Vector2 operator-(Vector2 lhs, const float rhs);
inline Vector2 operator*(Vector2 lhs, const float rhs);
inline Vector2 operator/(Vector2 lhs, const float rhs);
inline Vector2 operator+(const float lhs, Vector2 rhs);
inline Vector2 operator-(const float lhs, Vector2 rhs);
inline Vector2 operator*(const float lhs, Vector2 rhs);
inline Vector2 operator/(const float lhs, Vector2 rhs);
inline Vector2 operator+(Vector2 lhs, const Vector2 rhs);
inline Vector2 operator-(Vector2 lhs, const Vector2 rhs);
inline bool operator==(const Vector2 lhs, const Vector2 rhs);
inline bool operator!=(const Vector2 lhs, const Vector2 rhs);
/*******************************************************************************
* Implementation
*/
Vector2::Vector2() : X(0), Y(0) {}
Vector2::Vector2(float data[]) : X(data[0]), Y(data[1]) {}
Vector2::Vector2(float value) : X(value), Y(value) {}
Vector2::Vector2(float x, float y) : X(x), Y(y) {}
Vector2 Vector2::Zero() { return Vector2(0, 0); }
Vector2 Vector2::One() { return Vector2(1, 1); }
Vector2 Vector2::Right() { return Vector2(1, 0); }
Vector2 Vector2::Left() { return Vector2(-1, 0); }
Vector2 Vector2::Up() { return Vector2(0, 1); }
Vector2 Vector2::Down() { return Vector2(0, -1); }
float Vector2::Angle(Vector2 a, Vector2 b)
{
float v = Dot(a, b) / (Magnitude(a) * Magnitude(b));
v = fmax(v, -1.0);
v = fmin(v, 1.0);
return acos(v);
}
Vector2 Vector2::ClampMagnitude(Vector2 vector, float maxLength)
{
float length = Magnitude(vector);
if (length > maxLength)
vector *= maxLength / length;
return vector;
}
float Vector2::Component(Vector2 a, Vector2 b)
{
return Dot(a, b) / Magnitude(b);
}
float Vector2::Distance(Vector2 a, Vector2 b)
{
return Vector2::Magnitude(a - b);
}
float Vector2::Dot(Vector2 lhs, Vector2 rhs)
{
return lhs.X * rhs.X + lhs.Y * rhs.Y;
}
Vector2 Vector2::FromPolar(float rad, float theta)
{
Vector2 v;
v.X = rad * cos(theta);
v.Y = rad * sin(theta);
return v;
}
Vector2 Vector2::Lerp(Vector2 a, Vector2 b, float t)
{
if (t < 0) return a;
else if (t > 1) return b;
return LerpUnclamped(a, b, t);
}
Vector2 Vector2::LerpUnclamped(Vector2 a, Vector2 b, float t)
{
return (b - a) * t + a;
}
float Vector2::Magnitude(Vector2 v)
{
return sqrt(SqrMagnitude(v));
}
Vector2 Vector2::Max(Vector2 a, Vector2 b)
{
float x = a.X > b.X ? a.X : b.X;
float y = a.Y > b.Y ? a.Y : b.Y;
return Vector2(x, y);
}
Vector2 Vector2::Min(Vector2 a, Vector2 b)
{
float x = a.X > b.X ? b.X : a.X;
float y = a.Y > b.Y ? b.Y : a.Y;
return Vector2(x, y);
}
Vector2 Vector2::MoveTowards(Vector2 current, Vector2 target,
float maxDistanceDelta)
{
Vector2 d = target - current;
float m = Magnitude(d);
if (m < maxDistanceDelta || m == 0)
return target;
return current + (d * maxDistanceDelta / m);
}
Vector2 Vector2::Normalized(Vector2 v)
{
float mag = Magnitude(v);
if (mag == 0)
return Vector2::Zero();
return v / mag;
}
void Vector2::OrthoNormalize(Vector2 &normal, Vector2 &tangent)
{
normal = Normalized(normal);
tangent = Reject(tangent, normal);
tangent = Normalized(tangent);
}
Vector2 Vector2::Project(Vector2 a, Vector2 b)
{
float m = Magnitude(b);
return Dot(a, b) / (m * m) * b;
}
Vector2 Vector2::Reflect(Vector2 vector, Vector2 planeNormal)
{
return vector - 2 * Project(vector, planeNormal);
}
Vector2 Vector2::Reject(Vector2 a, Vector2 b)
{
return a - Project(a, b);
}
Vector2 Vector2::RotateTowards(Vector2 current, Vector2 target,
float maxRadiansDelta,
float maxMagnitudeDelta)
{
float magCur = Magnitude(current);
float magTar = Magnitude(target);
float newMag = magCur + maxMagnitudeDelta *
((magTar > magCur) - (magCur > magTar));
newMag = fmin(newMag, fmax(magCur, magTar));
newMag = fmax(newMag, fmin(magCur, magTar));
float totalAngle = Angle(current, target) - maxRadiansDelta;
if (totalAngle <= 0)
return Normalized(target) * newMag;
else if (totalAngle >= M_PI)
return Normalized(-target) * newMag;
float axis = current.X * target.Y - current.Y * target.X;
axis = axis / fabs(axis);
if (!(1 - fabs(axis) < 0.00001))
axis = 1;
current = Normalized(current);
Vector2 newVector = current * cos(maxRadiansDelta) +
Vector2(-current.Y, current.X) * sin(maxRadiansDelta) * axis;
return newVector * newMag;
}
Vector2 Vector2::Scale(Vector2 a, Vector2 b)
{
return Vector2(a.X * b.X, a.Y * b.Y);
}
Vector2 Vector2::Slerp(Vector2 a, Vector2 b, float t)
{
if (t < 0) return a;
else if (t > 1) return b;
return SlerpUnclamped(a, b, t);
}
Vector2 Vector2::SlerpUnclamped(Vector2 a, Vector2 b, float t)
{
float magA = Magnitude(a);
float magB = Magnitude(b);
a /= magA;
b /= magB;
float dot = Dot(a, b);
dot = fmax(dot, -1.0);
dot = fmin(dot, 1.0);
float theta = acos(dot) * t;
Vector2 relativeVec = Normalized(b - a * dot);
Vector2 newVec = a * cos(theta) + relativeVec * sin(theta);
return newVec * (magA + (magB - magA) * t);
}
float Vector2::SqrMagnitude(Vector2 v)
{
return v.X * v.X + v.Y * v.Y;
}
void Vector2::ToPolar(Vector2 vector, float &rad, float &theta)
{
rad = Magnitude(vector);
theta = atan2(vector.Y, vector.X);
}
struct Vector2& Vector2::operator+=(const float rhs)
{
X += rhs;
Y += rhs;
return *this;
}
struct Vector2& Vector2::operator-=(const float rhs)
{
X -= rhs;
Y -= rhs;
return *this;
}
struct Vector2& Vector2::operator*=(const float rhs)
{
X *= rhs;
Y *= rhs;
return *this;
}
struct Vector2& Vector2::operator/=(const float rhs)
{
X /= rhs;
Y /= rhs;
return *this;
}
struct Vector2& Vector2::operator+=(const Vector2 rhs)
{
X += rhs.X;
Y += rhs.Y;
return *this;
}
struct Vector2& Vector2::operator-=(const Vector2 rhs)
{
X -= rhs.X;
Y -= rhs.Y;
return *this;
}
Vector2 operator-(Vector2 rhs) { return rhs * -1; }
Vector2 operator+(Vector2 lhs, const float rhs) { return lhs += rhs; }
Vector2 operator-(Vector2 lhs, const float rhs) { return lhs -= rhs; }
Vector2 operator*(Vector2 lhs, const float rhs) { return lhs *= rhs; }
Vector2 operator/(Vector2 lhs, const float rhs) { return lhs /= rhs; }
Vector2 operator+(const float lhs, Vector2 rhs) { return rhs += lhs; }
Vector2 operator-(const float lhs, Vector2 rhs) { return rhs -= lhs; }
Vector2 operator*(const float lhs, Vector2 rhs) { return rhs *= lhs; }
Vector2 operator/(const float lhs, Vector2 rhs) { return rhs /= lhs; }
Vector2 operator+(Vector2 lhs, const Vector2 rhs) { return lhs += rhs; }
Vector2 operator-(Vector2 lhs, const Vector2 rhs) { return lhs -= rhs; }
bool operator==(const Vector2 lhs, const Vector2 rhs)
{
return lhs.X == rhs.X && lhs.Y == rhs.Y;
}
bool operator!=(const Vector2 lhs, const Vector2 rhs)
{
return !(lhs == rhs);
}
+625
View File
@@ -0,0 +1,625 @@
#pragma once
#define _USE_MATH_DEFINES
#include <math.h>
struct Vector3
{
union
{
struct
{
float X;
float Y;
float Z;
};
float data[3];
};
//=====𝗦𝗥𝗖==𝗝𝗢𝗜𝗡==𝗧𝗘𝗟𝗘𝗚𝗥𝗔𝗠=@𝗚𝗞𝗣𝗙𝗥𝗘𝗘𝗛𝗔𝗖𝗞𝗦===@GKPHACK===V=2.4==//
inline Vector3();
inline Vector3(float data[]);
inline Vector3(float value);
inline Vector3(float x, float y);
inline Vector3(float x, float y, float z);
/**
* Constants for common vectors.
*/
static inline Vector3 Zero();
static inline Vector3 One();
static inline Vector3 Right();
static inline Vector3 Left();
static inline Vector3 Up();
static inline Vector3 Down();
static inline Vector3 Forward();
static inline Vector3 Backward();
/**
* Returns the angle between two vectors in radians.
* @param a: The first vector.
* @param b: The second vector.
* @return: A scalar value.
*/
static inline float Angle(Vector3 a, Vector3 b);
/**
* Returns a vector with its magnitude clamped to maxLength.
* @param vector: The target vector.
* @param maxLength: The maximum length of the return vector.
* @return: A new vector.
*/
static inline Vector3 ClampMagnitude(Vector3 vector, float maxLength);
/**
* Returns the component of a in the direction of b (scalar projection).
* @param a: The target vector.
* @param b: The vector being compared against.
* @return: A scalar value.
*/
static inline float Component(Vector3 a, Vector3 b);
/**
* Returns the cross product of two vectors.
* @param lhs: The left side of the multiplication.
* @param rhs: The right side of the multiplication.
* @return: A new vector.
*/
static inline Vector3 Cross(Vector3 lhs, Vector3 rhs);
/**
* Returns the distance between a and b.
* @param a: The first point.
* @param b: The second point.
* @return: A scalar value.
*/
static inline float Distance(Vector3 a, Vector3 b);
static inline char ToChar(Vector3 a);
/**
* Returns the dot product of two vectors.
* @param lhs: The left side of the multiplication.
* @param rhs: The right side of the multiplication.
* @return: A scalar value.
*/
static inline float Dot(Vector3 lhs, Vector3 rhs);
/**
* Converts a spherical representation of a vector into cartesian
* coordinates.
* This uses the ISO convention (radius r, inclination theta, azimuth phi).
* @param rad: The magnitude of the vector.
* @param theta: The angle in the XY plane from the X axis.
* @param phi: The angle from the positive Z axis to the vector.
* @return: A new vector.
*/
static inline Vector3 FromSpherical(float rad, float theta, float phi);
/**
* Returns a vector linearly interpolated between a and b, moving along
* a straight line. The vector is clamped to never go beyond the end points.
* @param a: The starting point.
* @param b: The ending point.
* @param t: The interpolation value [0-1].
* @return: A new vector.
*/
static inline Vector3 Lerp(Vector3 a, Vector3 b, float t);
/**
* Returns a vector linearly interpolated between a and b, moving along
* a straight line.
* @param a: The starting point.
* @param b: The ending point.
* @param t: The interpolation value [0-1] (no actual bounds).
* @return: A new vector.
*/
static inline Vector3 LerpUnclamped(Vector3 a, Vector3 b, float t);
/**
* Returns the magnitude of a vector.
* @param v: The vector in question.
* @return: A scalar value.
*/
static inline float Magnitude(Vector3 v);
/**
* Returns a vector made from the largest components of two other vectors.
* @param a: The first vector.
* @param b: The second vector.
* @return: A new vector.
*/
static inline Vector3 Max(Vector3 a, Vector3 b);
/**
* Returns a vector made from the smallest components of two other vectors.
* @param a: The first vector.
* @param b: The second vector.
* @return: A new vector.
*/
static inline Vector3 Min(Vector3 a, Vector3 b);
/**
* Returns a vector "maxDistanceDelta" units closer to the target. This
* interpolation is in a straight line, and will not overshoot.
* @param current: The current position.
* @param target: The destination position.
* @param maxDistanceDelta: The maximum distance to move.
* @return: A new vector.
*/
static inline Vector3 MoveTowards(Vector3 current, Vector3 target,
float maxDistanceDelta);
/**
* Returns a new vector with magnitude of one.
* @param v: The vector in question.
* @return: A new vector.
*/
static inline Vector3 Normalized(Vector3 v);
/**
* Returns an arbitrary vector orthogonal to the input.
* This vector is not normalized.
* @param v: The input vector.
* @return: A new vector.
*/
static inline Vector3 Orthogonal(Vector3 v);
/**
* Creates a new coordinate system out of the three vectors.
* Normalizes "normal", normalizes "tangent" and makes it orthogonal to
* "normal" and normalizes "binormal" and makes it orthogonal to both
* "normal" and "tangent".
* @param normal: A reference to the first axis vector.
* @param tangent: A reference to the second axis vector.
* @param binormal: A reference to the third axis vector.
*/
static inline void OrthoNormalize(Vector3 &normal, Vector3 &tangent,
Vector3 &binormal);
/**
* Returns the vector projection of a onto b.
* @param a: The target vector.
* @param b: The vector being projected onto.
* @return: A new vector.
*/
static inline Vector3 Project(Vector3 a, Vector3 b);
/**
* Returns a vector projected onto a plane orthogonal to "planeNormal".
* This can be visualized as the shadow of the vector onto the plane, if
* the light source were in the direction of the plane normal.
* @param vector: The vector to project.
* @param planeNormal: The normal of the plane onto which to project.
* @param: A new vector.
*/
static inline Vector3 ProjectOnPlane(Vector3 vector, Vector3 planeNormal);
/**
* Returns a vector reflected off the plane orthogonal to the normal.
* The input vector is pointed inward, at the plane, and the return vector
* is pointed outward from the plane, like a beam of light hitting and then
* reflecting off a mirror.
* @param vector: The vector traveling inward at the plane.
* @param planeNormal: The normal of the plane off of which to reflect.
* @return: A new vector pointing outward from the plane.
*/
static inline Vector3 Reflect(Vector3 vector, Vector3 planeNormal);
/**
* Returns the vector rejection of a on b.
* @param a: The target vector.
* @param b: The vector being projected onto.
* @return: A new vector.
*/
static inline Vector3 Reject(Vector3 a, Vector3 b);
/**
* Rotates vector "current" towards vector "target" by "maxRadiansDelta".
* This treats the vectors as directions and will linearly interpolate
* between their magnitudes by "maxMagnitudeDelta". This function does not
* overshoot. If a negative delta is supplied, it will rotate away from
* "target" until it is pointing the opposite direction, but will not
* overshoot that either.
* @param current: The starting direction.
* @param target: The destination direction.
* @param maxRadiansDelta: The maximum number of radians to rotate.
* @param maxMagnitudeDelta: The maximum delta for magnitude interpolation.
* @return: A new vector.
*/
static inline Vector3 RotateTowards(Vector3 current, Vector3 target,
float maxRadiansDelta,
float maxMagnitudeDelta);
/**
* Multiplies two vectors element-wise.
* @param a: The lhs of the multiplication.
* @param b: The rhs of the multiplication.
* @return: A new vector.
*/
static inline Vector3 Scale(Vector3 a, Vector3 b);
/**
* Returns a vector rotated towards b from a by the percent t.
* Since interpolation is done spherically, the vector moves at a constant
* angular velocity. This rotation is clamped to 0 <= t <= 1.
* @param a: The starting direction.
* @param b: The ending direction.
* @param t: The interpolation value [0-1].
*/
static inline Vector3 Slerp(Vector3 a, Vector3 b, float t);
/**
* Returns a vector rotated towards b from a by the percent t.
* Since interpolation is done spherically, the vector moves at a constant
* angular velocity. This rotation is unclamped.
* @param a: The starting direction.
* @param b: The ending direction.
* @param t: The interpolation value [0-1].
*/
static inline Vector3 SlerpUnclamped(Vector3 a, Vector3 b, float t);
/**
* Returns the squared magnitude of a vector.
* This is useful when comparing relative lengths, where the exact length
* is not important, and much time can be saved by not calculating the
* square root.
* @param v: The vector in question.
* @return: A scalar value.
*/
static inline float SqrMagnitude(Vector3 v);
/**
* Calculates the spherical coordinate space representation of a vector.
* This uses the ISO convention (radius r, inclination theta, azimuth phi).
* @param vector: The vector to convert.
* @param rad: The magnitude of the vector.
* @param theta: The angle in the XY plane from the X axis.
* @param phi: The angle from the positive Z axis to the vector.
*/
static inline void ToSpherical(Vector3 vector, float &rad, float &theta,
float &phi);
/**
* Operator overloading.
*/
inline struct Vector3& operator+=(const float rhs);
inline struct Vector3& operator-=(const float rhs);
inline struct Vector3& operator*=(const float rhs);
inline struct Vector3& operator/=(const float rhs);
inline struct Vector3& operator+=(const Vector3 rhs);
inline struct Vector3& operator-=(const Vector3 rhs);
};
inline Vector3 operator-(Vector3 rhs);
inline Vector3 operator+(Vector3 lhs, const float rhs);
inline Vector3 operator-(Vector3 lhs, const float rhs);
inline Vector3 operator*(Vector3 lhs, const float rhs);
inline Vector3 operator/(Vector3 lhs, const float rhs);
inline Vector3 operator+(const float lhs, Vector3 rhs);
inline Vector3 operator-(const float lhs, Vector3 rhs);
inline Vector3 operator*(const float lhs, Vector3 rhs);
inline Vector3 operator/(const float lhs, Vector3 rhs);
inline Vector3 operator+(Vector3 lhs, const Vector3 rhs);
inline Vector3 operator-(Vector3 lhs, const Vector3 rhs);
inline bool operator==(const Vector3 lhs, const Vector3 rhs);
inline bool operator!=(const Vector3 lhs, const Vector3 rhs);
/*******************************************************************************
* Implementation
*/
Vector3::Vector3() : X(0), Y(0), Z(0) {}
Vector3::Vector3(float data[]) : X(data[0]), Y(data[1]), Z(data[2]) {}
Vector3::Vector3(float value) : X(value), Y(value), Z(value) {}
Vector3::Vector3(float x, float y) : X(x), Y(y), Z(0) {}
Vector3::Vector3(float x, float y, float z) : X(x), Y(y), Z(z) {}
Vector3 Vector3::Zero() { return Vector3(0, 0, 0); }
Vector3 Vector3::One() { return Vector3(1, 1, 1); }
Vector3 Vector3::Right() { return Vector3(1, 0, 0); }
Vector3 Vector3::Left() { return Vector3(-1, 0, 0); }
Vector3 Vector3::Up() { return Vector3(0, 1, 0); }
Vector3 Vector3::Down() { return Vector3(0, -1, 0); }
Vector3 Vector3::Forward() { return Vector3(0, 0, 1); }
Vector3 Vector3::Backward() { return Vector3(0, 0, -1); }
float Vector3::Angle(Vector3 a, Vector3 b)
{
float v = Dot(a, b) / (Magnitude(a) * Magnitude(b));
v = fmax(v, -1.0);
v = fmin(v, 1.0);
return acos(v);
}
Vector3 Vector3::ClampMagnitude(Vector3 vector, float maxLength)
{
float length = Magnitude(vector);
if (length > maxLength)
vector *= maxLength / length;
return vector;
}
float Vector3::Component(Vector3 a, Vector3 b)
{
return Dot(a, b) / Magnitude(b);
}
Vector3 Vector3::Cross(Vector3 lhs, Vector3 rhs)
{
float x = lhs.Y * rhs.Z - lhs.Z * rhs.Y;
float y = lhs.Z * rhs.X - lhs.X * rhs.Z;
float z = lhs.X * rhs.Y - lhs.Y * rhs.X;
return Vector3(x, y, z);
}
float Vector3::Distance(Vector3 a, Vector3 b)
{
return Vector3::Magnitude(a - b);
}
float Vector3::Dot(Vector3 lhs, Vector3 rhs)
{
return lhs.X * rhs.X + lhs.Y * rhs.Y + lhs.Z * rhs.Z;
}
Vector3 Vector3::FromSpherical(float rad, float theta, float phi)
{
Vector3 v;
v.X = rad * sin(theta) * cos(phi);
v.Y = rad * sin(theta) * sin(phi);
v.Z = rad * cos(theta);
return v;
}
Vector3 Vector3::Lerp(Vector3 a, Vector3 b, float t)
{
if (t < 0) return a;
else if (t > 1) return b;
return LerpUnclamped(a, b, t);
}
Vector3 Vector3::LerpUnclamped(Vector3 a, Vector3 b, float t)
{
return (b - a) * t + a;
}
float Vector3::Magnitude(Vector3 v)
{
return sqrt(SqrMagnitude(v));
}
Vector3 Vector3::Max(Vector3 a, Vector3 b)
{
float x = a.X > b.X ? a.X : b.X;
float y = a.Y > b.Y ? a.Y : b.Y;
float z = a.Z > b.Z ? a.Z : b.Z;
return Vector3(x, y, z);
}
Vector3 Vector3::Min(Vector3 a, Vector3 b)
{
float x = a.X > b.X ? b.X : a.X;
float y = a.Y > b.Y ? b.Y : a.Y;
float z = a.Z > b.Z ? b.Z : a.Z;
return Vector3(x, y, z);
}
Vector3 Vector3::MoveTowards(Vector3 current, Vector3 target,
float maxDistanceDelta)
{
Vector3 d = target - current;
float m = Magnitude(d);
if (m < maxDistanceDelta || m == 0)
return target;
return current + (d * maxDistanceDelta / m);
}
Vector3 Vector3::Normalized(Vector3 v)
{
float mag = Magnitude(v);
if (mag == 0)
return Vector3::Zero();
return v / mag;
}
Vector3 Vector3::Orthogonal(Vector3 v)
{
return v.Z < v.X ? Vector3(v.Y, -v.X, 0) : Vector3(0, -v.Z, v.Y);
}
void Vector3::OrthoNormalize(Vector3 &normal, Vector3 &tangent,
Vector3 &binormal)
{
normal = Normalized(normal);
tangent = ProjectOnPlane(tangent, normal);
tangent = Normalized(tangent);
binormal = ProjectOnPlane(binormal, tangent);
binormal = ProjectOnPlane(binormal, normal);
binormal = Normalized(binormal);
}
Vector3 Vector3::Project(Vector3 a, Vector3 b)
{
float m = Magnitude(b);
return Dot(a, b) / (m * m) * b;
}
Vector3 Vector3::ProjectOnPlane(Vector3 vector, Vector3 planeNormal)
{
return Reject(vector, planeNormal);
}
Vector3 Vector3::Reflect(Vector3 vector, Vector3 planeNormal)
{
return vector - 2 * Project(vector, planeNormal);
}
Vector3 Vector3::Reject(Vector3 a, Vector3 b)
{
return a - Project(a, b);
}
Vector3 Vector3::RotateTowards(Vector3 current, Vector3 target,
float maxRadiansDelta,
float maxMagnitudeDelta)
{
float magCur = Magnitude(current);
float magTar = Magnitude(target);
float newMag = magCur + maxMagnitudeDelta *
((magTar > magCur) - (magCur > magTar));
newMag = fmin(newMag, fmax(magCur, magTar));
newMag = fmax(newMag, fmin(magCur, magTar));
float totalAngle = Angle(current, target) - maxRadiansDelta;
if (totalAngle <= 0)
return Normalized(target) * newMag;
else if (totalAngle >= M_PI)
return Normalized(-target) * newMag;
Vector3 axis = Cross(current, target);
float magAxis = Magnitude(axis);
if (magAxis == 0)
axis = Normalized(Cross(current, current + Vector3(3.95, 5.32, -4.24)));
else
axis /= magAxis;
current = Normalized(current);
Vector3 newVector = current * cos(maxRadiansDelta) +
Cross(axis, current) * sin(maxRadiansDelta);
return newVector * newMag;
}
Vector3 Vector3::Scale(Vector3 a, Vector3 b)
{
return Vector3(a.X * b.X, a.Y * b.Y, a.Z * b.Z);
}
Vector3 Vector3::Slerp(Vector3 a, Vector3 b, float t)
{
if (t < 0) return a;
else if (t > 1) return b;
return SlerpUnclamped(a, b, t);
}
Vector3 Vector3::SlerpUnclamped(Vector3 a, Vector3 b, float t)
{
float magA = Magnitude(a);
float magB = Magnitude(b);
a /= magA;
b /= magB;
float dot = Dot(a, b);
dot = fmax(dot, -1.0);
dot = fmin(dot, 1.0);
float theta = acos(dot) * t;
Vector3 relativeVec = Normalized(b - a * dot);
Vector3 newVec = a * cos(theta) + relativeVec * sin(theta);
return newVec * (magA + (magB - magA) * t);
}
float Vector3::SqrMagnitude(Vector3 v)
{
return v.X * v.X + v.Y * v.Y + v.Z * v.Z;
}
void Vector3::ToSpherical(Vector3 vector, float &rad, float &theta,
float &phi)
{
rad = Magnitude(vector);
float v = vector.Z / rad;
v = fmax(v, -1.0);
v = fmin(v, 1.0);
theta = acos(v);
phi = atan2(vector.Y, vector.X);
}
struct Vector3& Vector3::operator+=(const float rhs)
{
X += rhs;
Y += rhs;
Z += rhs;
return *this;
}
struct Vector3& Vector3::operator-=(const float rhs)
{
X -= rhs;
Y -= rhs;
Z -= rhs;
return *this;
}
struct Vector3& Vector3::operator*=(const float rhs)
{
X *= rhs;
Y *= rhs;
Z *= rhs;
return *this;
}
struct Vector3& Vector3::operator/=(const float rhs)
{
X /= rhs;
Y /= rhs;
Z /= rhs;
return *this;
}
struct Vector3& Vector3::operator+=(const Vector3 rhs)
{
X += rhs.X;
Y += rhs.Y;
Z += rhs.Z;
return *this;
}
struct Vector3& Vector3::operator-=(const Vector3 rhs)
{
X -= rhs.X;
Y -= rhs.Y;
Z -= rhs.Z;
return *this;
}
char Vector3::ToChar(Vector3 a) {
const char* x = (const char*)(int)a.X;
const char* y = (const char*)(int)a.Y;
const char* z = (const char*)(int)a.Z;
char buffer[25];
strncpy(buffer, x, sizeof(buffer));
strncpy(buffer, ", ", sizeof(buffer));
strncpy(buffer, y, sizeof(buffer));
strncpy(buffer, ", ", sizeof(buffer));
strncpy(buffer, z, sizeof(buffer));
strncpy(buffer, ", ", sizeof(buffer));
return buffer[25];
}
Vector3 operator-(Vector3 rhs) { return rhs * -1; }
Vector3 operator+(Vector3 lhs, const float rhs) { return lhs += rhs; }
Vector3 operator-(Vector3 lhs, const float rhs) { return lhs -= rhs; }
Vector3 operator*(Vector3 lhs, const float rhs) { return lhs *= rhs; }
Vector3 operator/(Vector3 lhs, const float rhs) { return lhs /= rhs; }
Vector3 operator+(const float lhs, Vector3 rhs) { return rhs += lhs; }
Vector3 operator-(const float lhs, Vector3 rhs) { return rhs -= lhs; }
Vector3 operator*(const float lhs, Vector3 rhs) { return rhs *= lhs; }
Vector3 operator/(const float lhs, Vector3 rhs) { return rhs /= lhs; }
Vector3 operator+(Vector3 lhs, const Vector3 rhs) { return lhs += rhs; }
Vector3 operator-(Vector3 lhs, const Vector3 rhs) { return lhs -= rhs; }
bool operator==(const Vector3 lhs, const Vector3 rhs)
{
return lhs.X == rhs.X && lhs.Y == rhs.Y && lhs.Z == rhs.Z;
}
bool operator!=(const Vector3 lhs, const Vector3 rhs)
{
return !(lhs == rhs);
}
+142
View File
@@ -0,0 +1,142 @@
TNameEntryArray*GetGNames(){
return(TNameEntryArray*)getPointer(UE4+0x4431AE4);
}
static UEngine *GEngine = 0;
UWorld *GetWorld() {
while (!GEngine) {
GEngine = UObject::FindObject<UEngine>("UAEGameEngine Transient.UAEGameEngine_1");
sleep(1);
}
if (GEngine) {
auto ViewPort = GEngine->GameViewport;
if (ViewPort) {
return ViewPort->World;
} }
return 0;
}
#include <vector>
std::vector<AActor*> getActors()
{
auto World = GetWorld();
if (!World)
return std::vector<AActor*>();
auto PersistentLevel = World->PersistentLevel;
if (!PersistentLevel)
return std::vector<AActor*>();
auto Actors = *(TArray<AActor*> *)((uintptr_t)PersistentLevel + 0x70);
std::vector<AActor*> actors;
for (int i = 0; i < Actors.Num(); i++)
{
auto Actor = Actors[i];
if (Actor)
{
actors.push_back(Actor);
}
}
return actors;
}
struct sRegion {
uintptr_t start, end;
};
std::vector<sRegion> trapRegions;
bool isObjectInvalid(UObject *obj) {
if (!IsPtrValid(obj)) {
return true;
}
if (!IsPtrValid(obj->ClassPrivate)) {
return true;
}
if (obj->InternalIndex <= 0) {
return true;
}
if (obj->NamePrivate.ComparisonIndex <= 0) {
return true;
}
if ((uintptr_t)(obj) % sizeof(uintptr_t) != 0x0 && (uintptr_t)(obj) % sizeof(uintptr_t) != 0x4) {
return true;
}
if (std::any_of(trapRegions.begin(), trapRegions.end(), [obj](sRegion region) { return ((uintptr_t) obj) >= region.start && ((uintptr_t) obj) <= region.end; }) ||
std::any_of(trapRegions.begin(), trapRegions.end(), [obj](sRegion region) { return ((uintptr_t) obj->ClassPrivate) >= region.start && ((uintptr_t) obj->ClassPrivate) <= region.end; })) {
return true;
}
return false;
}
AUAEGameMode *GameMode=0;
ASTExtraPlayerCharacter *PlayerCharacter=0;
ASTExtraPlayerController *PlayerController2=0;
APlayerController *PlayerController=0;
AGameNetworkManager *NetworkManager = 0;
void GetActor(){
auto Actors = getActors();
for (int i = 0; i < Actors.size(); i++) {
auto Actor = Actors[i];
if (isObjectInvalid(Actor))
continue;
if (Actor->IsA(AGameNetworkManager::StaticClass())) {
NetworkManager = (AGameNetworkManager *) Actor;
break;
}
}
}
void (){
auto Actors = getActors();
for (int i = 0; i < Actors.size(); i++) {
auto Actor = Actors[i];
if (Actor->IsA(AUAEGameMode::StaticClass())) {
GameMode = (AUAEGameMode *) Actor;
break;
}
}
for (int i = 0; i < Actors.size(); i++) {
auto Actor = Actors[i];
if (Actor->IsA(ASTExtraPlayerCharacter::StaticClass())) {
PlayerCharacter = (ASTExtraPlayerCharacter *) Actor;
break;
}
}
for (int i = 0; i < Actors.size(); i++) {
auto Actor = Actors[i];
if (Actor->IsA(ASTExtraPlayerController::StaticClass())) {
PlayerController2 = (ASTExtraPlayerController *) Actor;
break;
}
}
for (int i = 0; i < Actors.size(); i++) {
auto Actor = Actors[i];
if (Actor->IsA(APlayerController::StaticClass())) {
PlayerController = (APlayerController *) Actor;
break;
}
}
}
void (){
();
GameMode->bEnableClimbing=true;
GameMode->bEnableDamage=true;
GameMode->bEnableDamage=20;
}
+215
View File
@@ -0,0 +1,215 @@
ASTExtraPlayerCharacter *g_LocalPlayer = 0;
ASTExtraPlayerController *g_LocalController = 0;
// ================= 语言设置和记忆功能 =================
enum class Language {
CHINESE,
ENGLISH
};
static Language currentLanguage = Language::CHINESE;
static const char* LANGUAGE_FILE = "/sdcard/pubg_menu_language.conf";
// 保存语言设置到文件
void SaveLanguageSetting() {
std::ofstream file(LANGUAGE_FILE);
if (file.is_open()) {
file << static_cast<int>(currentLanguage);
file.close();
}
}
// 从文件加载语言设置
void LoadLanguageSetting() {
std::ifstream file(LANGUAGE_FILE);
if (file.is_open()) {
int lang;
file >> lang;
currentLanguage = static_cast<Language>(lang);
file.close();
}
}
// 切换语言
void ToggleLanguage() {
currentLanguage = (currentLanguage == Language::CHINESE) ? Language::ENGLISH : Language::CHINESE;
SaveLanguageSetting();
}
// 多语言文本函数
const char* T(const char* chinese, const char* english) {
return (currentLanguage == Language::CHINESE) ? chinese : english;
}
#define IM_PI 3.14159265358979323846f
#define RAD2DEG(x) ((float)(x) * (float)(180.f / IM_PI))
#define DEG2RAD(x) ((float)(x) * (float)(IM_PI / 180.f))
ImColor 2 = ImColor(46,46,177);
ImColor =ImColor(226,145,163,255);
ImColor = ImColor(ImVec4(36/255.f, 249/255.f, 217/255.f, 255/255.f));
ImColor = ImColor(ImVec4(170/255.f, 203/255.f, 244/255.f, 0.95f));
ImColor = ImColor(ImVec4(255/255.f, 255/255.f, 258/255.f, 0.95f));
ImColor = ImColor(ImVec4(255/255.f, 200/255.f, 250/255.f, 0.95f));
ImColor = ImColor(ImVec4(0/255.f, 0/255.f, 0/255.f, 0.7f));
ImColor = ImColor(ImVec4(0/255.f, 0/255.f, 0/255.f, 0.18f));
ImColor = ImColor(ImVec4(0/255.f, 249/255.f, 0/255.f, 0.35f));
ImColor = ImColor(ImVec4(233/255.f, 55/255.f, 51/255.f, 0.95f));
ImColor 绿 = ImColor(ImVec4(50/255.f, 222/215.f, 50/255.f, 0.95f));
ImColor = ImColor(ImVec4(255/255.f, 255/255.f, 0/255.f, 0.95f));
ImColor = ImColor(ImVec4(255/255.f, 150/255.f, 30/255.f, 0.95f));
ImColor = ImColor(ImVec4(220/255.f, 108/255.f, 1202/255.f, 0.95f));
ImColor = ImColor(ImVec4(169/255.f, 120/255.f, 223/255.f, 0.95f));
ImColor = ImColor(ImVec4(1.0/255.f, 1.0/255.f, 1.0/255.f, 0.0f));
namespace Settings
{
static int Tab = 1;
}
std::string getClipboardTextt() {
if (!g_App)
return "";
auto activity = g_App->activity;
if (!activity)
return "";
auto vm = activity->vm;
if (!vm)
return "";
auto object = activity->clazz;
if (!object)
return "";
std::string result;
JNIEnv *env;
vm->AttachCurrentThread(&env, 0);
{
auto ContextClass = env->FindClass("android/content/Context");
auto getSystemServiceMethod = env->GetMethodID(ContextClass, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
auto str = env->NewStringUTF("clipboard");
auto clipboardManager = env->CallObjectMethod(object, getSystemServiceMethod, str);
env->DeleteLocalRef(str);
auto ClipboardManagerClass = env->FindClass("android/content/ClipboardManager");
auto getText = env->GetMethodID(ClipboardManagerClass, "getText", "()Ljava/lang/CharSequence;");
auto CharSequenceClass = env->FindClass("java/lang/CharSequence");
auto toStringMethod = env->GetMethodID(CharSequenceClass, "toString", "()Ljava/lang/String;");
auto text = env->CallObjectMethod(clipboardManager, getText);
if (text) {
str = (jstring) env->CallObjectMethod(text, toStringMethod);
result = env->GetStringUTFChars(str, 0);
env->DeleteLocalRef(str);
env->DeleteLocalRef(text);
}
env->DeleteLocalRef(CharSequenceClass);
env->DeleteLocalRef(ClipboardManagerClass);
env->DeleteLocalRef(clipboardManager);
env->DeleteLocalRef(ContextClass);
}
vm->DetachCurrentThread();
return result;
}
// 安全写入D内存
void safeWritedword(uintptr_t addr, int value) {
long pageSize = sysconf(_SC_PAGESIZE); // = 4096
uintptr_t pageStart = addr & ~(pageSize - 1);
if (mprotect((void*)(pageStart), pageSize * 2, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) {
perror("mprotect failed");
return;
}
*((int*)addr) = value;
}
FVector WorldToRadar(float Yaw, FVector Origin, FVector LocalOrigin, float PosX, float PosY, Vector3 Size, bool &outbuff) {
bool flag = false;
double num = (double)Yaw;
double num2 = num * 0.017453292519943295;
float num3 = (float)std::cos(num2);
float num4 = (float)std::sin(num2);
float num5 = Origin.X - LocalOrigin.X;
float num6 = Origin.Y - LocalOrigin.Y;
struct FVector Xector;
Xector.X = (num6 * num3 - num5 * num4) / 150.f;
Xector.Y = (num5 * num3 + num6 * num4) / 150.f;
struct FVector Xector2;
Xector2.X = Xector.X + PosX + Size.X / 2.f;
Xector2.Y = -Xector.Y + PosY + Size.Y / 2.f;
bool flag2 = Xector2.X > PosX + Size.X;
if (flag2) {
Xector2.X = PosX + Size.X;
}else{
bool flag3 = Xector2.X < PosX;
if (flag3) {
Xector2.X = PosX;
}
}
bool flag4 = Xector2.Y > PosY + Size.Y;
if (flag4) {
Xector2.Y = PosY + Size.Y;
}else{
bool flag5 = Xector2.Y < PosY;
if (flag5){
Xector2.Y = PosY;
}
}
bool flag6 = Xector2.Y == PosY || Xector2.X == PosX;
if (flag6){
flag = true;
}
outbuff = flag;
return Xector2;
}
void VectorAnglesRadar(Vector3 & forward, FVector & angles) {
if (forward.X == 0.f && forward.Y == 0.f) {
angles.X = forward.Z > 0.f ? -90.f : 90.f;
angles.Y = 0.f;
} else {
angles.X = RAD2DEG(atan2(-forward.Z, forward.Magnitude(forward)));
angles.Y = RAD2DEG(atan2(forward.Y, forward.X));
}
angles.Z = 0.f;
}
void Box4Line(ImDrawList *draw, float thicc, int x, int y, int w, int h, int color) {
int iw = w / 4;
int ih = h / 4;
// top
draw->AddRect(ImVec2(x, y),ImVec2(x + iw, y), color, thicc);
draw->AddRect(ImVec2(x + w - iw, y),ImVec2(x + w, y), color, thicc);
draw->AddRect(ImVec2(x, y),ImVec2(x, y + ih), color, thicc);
draw->AddRect(ImVec2(x + w - 1, y),ImVec2(x + w - 1, y + ih), color, thicc);;
// bottom
draw->AddRect(ImVec2(x, y + h),ImVec2(x + iw, y + h), color, thicc);
draw->AddRect(ImVec2(x + w - iw, y + h),ImVec2(x + w, y + h), color, thicc);
draw->AddRect(ImVec2(x, y + h - ih), ImVec2(x, y + h), color, thicc);
draw->AddRect(ImVec2(x + w - 1, y + h - ih), ImVec2(x + w - 1, y + h), color, thicc);
}
void (float size, float x, float y, ImColor color, ImColor color1, const char* str)
{
ImGui::GetBackgroundDrawList()->AddText(NULL, size, {x-0.8, y-0.8}, color1, str);
ImGui::GetBackgroundDrawList()->AddText(NULL, size, {x+0.8, y+0.8}, color1, str);
ImGui::GetBackgroundDrawList()->AddText(NULL, size, {x, y}, color, str);
}
void RotateTriangle(std::array<Vector3, 3> & points, float rotation) {
const auto points_center = (points.at(0) + points.at(1) + points.at(2)) / 3;
for (auto & point : points) {
point = point - points_center;
const auto temp_x = point.X;
const auto temp_y = point.Y;
const auto theta = DEG2RAD(rotation);
const auto c = cosf(theta);
const auto s = sinf(theta);
point.X = temp_x * c - temp_y * s;
point.Y = temp_x * s + temp_y * c;
point = point + points_center;
}
}
+12
View File
@@ -0,0 +1,12 @@
#include "混淆.h"
size_t& _lxy_oxor_any_::X() {
static size_t x = 0;
return x;
}
size_t& _lxy_oxor_any_::Y() {
static size_t y = 0;
return y;
}
+699
View File
@@ -0,0 +1,699 @@
#ifndef 混淆_H
#define 混淆_H
#if _KERNEL_MODE
#ifndef _VCRUNTIME_DISABLED_WARNINGS
#define _VCRUNTIME_DISABLED_WARNINGS
#endif
#endif
#include <stdint.h>
#if _WIN32 || _WIN64
#if _WIN64
#define 混淆_ENVIRONMENT64
#else
#define 混淆_ENVIRONMENT32
#endif
#endif
#if __GNUC__
#if __x86_64__ || __ppc64__
#define 混淆_ENVIRONMENT64
#else
#define 混淆_ENVIRONMENT32
#endif
#endif
#ifdef _MSC_VER
#define 混淆_FORCEINLINE __forceinline
#else
#define 混淆_FORCEINLINE __attribute__((always_inline)) inline
#endif
#ifdef _DEBUG
#define 混淆
#define oxorvar
#else
#define 混淆(any) _lxy_oxor_any_::oxor_any<decltype(_lxy_oxor_any_::typeofs(any)), _lxy_oxor_any_::array_size(any), __COUNTER__>(any, _lxy_::make_index_sequence<sizeof(decltype(any))>()).get()
#define oxorvar(var) ((var) + 混淆(0))
#endif
namespace _lxy_ {
// https://stackoverflow.com/a/32223343/16602611
template <size_t... Ints>
struct index_sequence {
using type = index_sequence;
using value_type = size_t;
static constexpr size_t size() noexcept { return sizeof...(Ints); }
};
// --------------------------------------------------------------------
template <class Sequence1, class Sequence2>
struct _merge_and_renumber;
template <size_t... I1, size_t... I2>
struct _merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
: index_sequence<I1..., (sizeof...(I1) + I2)...>
{ };
// --------------------------------------------------------------------
template <size_t N>
struct make_index_sequence
: _merge_and_renumber<typename make_index_sequence<N / 2>::type,
typename make_index_sequence<N - N / 2>::type>
{ };
template<> struct make_index_sequence<0> : index_sequence<> { };
template<> struct make_index_sequence<1> : index_sequence<0> { };
}
namespace _lxy_oxor_any_ {
/*
template <size_t ...>
struct indexSequence {
};
template <size_t N, size_t ... Next>
struct indexSequenceHelper : public indexSequenceHelper<N - 1U, N - 1U, Next...> {
};
template <size_t ... Next>
struct indexSequenceHelper<0U, Next ... > {
using type = indexSequence<Next ... >;
};
template <size_t N>
using makeIndexSequence = typename indexSequenceHelper<N>::type;
*/
size_t& X();
size_t& Y();
static constexpr size_t base_key = static_cast<size_t>(
(__TIME__[7] - '0') +
(__TIME__[6] - '0') * 10 +
(__TIME__[4] - '0') * 60 +
(__TIME__[3] - '0') * 600 +
(__TIME__[1] - '0') * 3600 +
(__TIME__[0] - '0') * 36000);
template<uint32_t s, size_t n>
class random_constant_32 {
static constexpr uint32_t x = s ^ (s << 13);
static constexpr uint32_t y = x ^ (x >> 17);
static constexpr uint32_t z = y ^ (y << 5);
public:
static constexpr uint32_t value = random_constant_32<z, n - 1>::value;
};
template<uint32_t s>
class random_constant_32<s, 0> {
public:
static constexpr uint32_t value = s;
};
template<uint64_t s, size_t n>
class random_constant_64 {
static constexpr uint64_t x = s ^ (s << 13);
static constexpr uint64_t y = x ^ (x >> 7);
static constexpr uint64_t z = y ^ (y << 17);
public:
static constexpr uint64_t value = random_constant_64<z, n - 1>::value;
};
template<uint64_t s>
class random_constant_64<s, 0> {
public:
static constexpr uint64_t value = s;
};
#ifdef 混淆_ENVIRONMENT64
#define random_constant random_constant_64
#else
#define random_constant random_constant_32
#endif
template<typename T, size_t size>
static _FORCEINLINE constexpr size_t array_size(const T(&)[size]) { return size; }
template<typename T>
static _FORCEINLINE constexpr size_t array_size(T) { return 0; }
template<typename T, size_t size>
static inline T typeofs(const T(&)[size]);
template<typename T>
static inline T typeofs(T);
template<size_t key>
static _FORCEINLINE constexpr uint8_t encrypt_byte(uint8_t c, size_t i) {
return static_cast<uint8_t>(((c + (key * 7)) ^ (i + key)));
}
template<size_t key>
static _FORCEINLINE constexpr uint8_t decrypt_byte(uint8_t c, size_t i) {
//a ^ b == (a + b) - 2 * (a & b)
size_t a = c;
size_t b = i + key;
//size_t a_xor_b = (a + b) - 2 * (a & b);
size_t a_xor_b = (a + b) - ((a & b) + (b & a));
return static_cast<uint8_t>((a_xor_b)-(key * 7));
}
template<size_t key>
static _FORCEINLINE constexpr size_t limit() {
constexpr size_t bcf_value[] = { 1,2,3,4,5, 6,8,9,10,16, 32,40,64,66,100, 128,512,1000,1024,4096, 'a','z','A','Z','*' };
return bcf_value[key % (sizeof(bcf_value) / sizeof(bcf_value[0]))];
}
template<typename return_type, size_t key, size_t size>
static _FORCEINLINE const return_type decrypt(uint8_t(&buffer)[size]) {
#ifndef 混淆_DISABLE_OBFUSCATION
uint8_t source;
uint8_t decrypted; //do not assign initial value
size_t stack_x;
size_t stack_y;
loc_start_1:
stack_x = X();
stack_y = Y();
loc_start_2:
for (size_t i = 0; i < size; i++) {
source = buffer[i];
loc_start_3:
if (stack_x <= i) {
if (stack_x < stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);//fake
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 1 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_9;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 2 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_8;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 3 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_7;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 4 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_6;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 5 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_5;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 6 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_4;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 7 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_3;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 8 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_2;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 9 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_1;
}
loc_start_4:
if (stack_y <= i) {
if (stack_x < stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);//fake
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 1 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_1;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 2 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_2;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 3 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_3;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 4 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_4;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 5 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_5;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 6 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_6;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 7 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_7;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 8 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_8;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 9 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_9;
}
loc_start_5:
if (stack_x + stack_y <= i) {
if (stack_x < stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key>(source, i);//real
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 1 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_9;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 2 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_8;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 3 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_7;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 4 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_6;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 5 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_5;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 6 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_4;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 7 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_3;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 8 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_2;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 9 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_1;
}
loc_start_6:
if (stack_x + stack_y != limit<key * __COUNTER__>()) {
if (stack_x > stack_y + limit<key * __COUNTER__>()) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 1 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_1;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 2 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_2;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 3 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_3;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 4 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_4;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 5 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_5;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 6 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_6;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 7 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_7;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 8 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_8;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 9 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_9;
}
loc_start_7:
if (stack_x < limit<key * __COUNTER__>()) {
if (stack_x > stack_y + limit<key * __COUNTER__>()) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 1 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_9;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 2 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_8;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 3 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_7;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 4 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_6;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 5 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_5;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 6 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_4;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 7 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_3;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 8 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_2;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>() % 9 + 1) {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_1;
}
loc_start_8:
if (stack_y < limit<key * __COUNTER__>()) {
loc_start_9:
buffer[i] = decrypted;//assign
}
else {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
decrypted += decrypted;
loc_unreachable_1:
buffer[i] = decrypt_byte<key* __COUNTER__>(source, i);
loc_unreachable_2:
stack_y++;
loc_unreachable_3:
i--;
}
}
else {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
decrypted += buffer[i];
loc_unreachable_4:
buffer[i] = decrypt_byte<key* __COUNTER__>(source, i);
buffer[i] += decrypted;
loc_unreachable_5:
stack_x += stack_y;
loc_unreachable_6:
i--;
i -= decrypted;
}
}
else {
//unreachable
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
decrypted -= buffer[i];
loc_unreachable_7:
buffer[i] = decrypt_byte<key* __COUNTER__>(source, i);
stack_y++;
i -= buffer[i];
i -= stack_y;
loc_unreachable_8:
buffer[i] = decrypt_byte<key* __COUNTER__>(source, i);
stack_x++;
i--;
i -= stack_x;
loc_unreachable_9:
i += buffer[i];
i += stack_y;
continue;
}
}
else {
//unreachable
while (true) {
if (stack_x == stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_1;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_2;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_3;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_4;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_5;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_6;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_7;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_8;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_9;
}
else if (stack_x == stack_y + limit<key * __COUNTER__>()) {
continue;
}
else {
stack_x = stack_y + limit<key* __COUNTER__>();
stack_y = stack_x + limit<key* __COUNTER__>();
}
if (stack_x < stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_start_1;
}
else if (stack_x < stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_start_2;
}
else if (stack_x < stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_start_3;
}
else if (stack_x < stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_start_4;
}
else if (stack_x < stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_start_5;
}
else if (stack_x < stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_start_6;
}
else if (stack_x < stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_start_7;
}
else if (stack_x < stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_start_8;
}
else if (stack_x < stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_start_9;
}
else if (stack_x < stack_y + limit<key * __COUNTER__>()) {
continue;
}
else {
stack_x = stack_y + limit<key* __COUNTER__>();
stack_y = stack_x + limit<key* __COUNTER__>();
}
if (stack_x > stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_9;
}
else if (stack_x > stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_8;
}
else if (stack_x > stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_7;
}
else if (stack_x > stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_6;
}
else if (stack_x > stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_5;
}
else if (stack_x > stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_4;
}
else if (stack_x > stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_3;
}
else if (stack_x > stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_2;
}
else if (stack_x > stack_y + limit<key * __COUNTER__>()) {
decrypted = decrypt_byte<key* __COUNTER__>(source, i);
goto loc_unreachable_1;
}
else if (stack_x > stack_y + limit<key * __COUNTER__>()) {
continue;
}
else {
stack_x = stack_y + limit<key* __COUNTER__>();
stack_y = stack_x + limit<key* __COUNTER__>();
}
}
}
}
else {
//unreachable
//Ooops, Decompilation failure:
//401000: stack frame is too big
return reinterpret_cast<return_type>(buffer + ((key * __COUNTER__) % 0x400000 + 0x1400000));
}
}
else {
//unreachable
//Ooops, Decompilation failure:
//401000: stack frame is too big
return reinterpret_cast<return_type>(buffer + ((key * __COUNTER__) % 0x1400000 + 0x400000));
}
}
#else
for (size_t i = 0; i < size; i++) {
buffer[i] = decrypt_byte<key>(buffer[i], i);
}
#endif // 混淆_DISABLE_OBFUSCATION
return reinterpret_cast<return_type>(buffer);
}
static _FORCEINLINE constexpr size_t align(size_t n, size_t a) {
return (n + a - 1) & ~(a - 1);
}
template<typename any_t, size_t ary_size, size_t counter>
class oxor_any {
static constexpr size_t size = align(ary_size * sizeof(any_t), 16)
+ random_constant<counter^ base_key, (counter^ base_key) % 128>::value % (16 + 1);
static constexpr size_t key = random_constant<counter^ base_key, (size^ base_key) % 128>::value;
uint8_t buffer[size];
public:
template<size_t... indices>
_FORCEINLINE constexpr oxor_any(const any_t(&any)[ary_size], _lxy_::index_sequence<indices...>) :
buffer{ encrypt_byte<key>(((uint8_t*)&any)[indices], indices)... } {
}
_FORCEINLINE const any_t* get() { return decrypt<const any_t*, key>(buffer); }
};
template<typename any_t, size_t counter>
class oxor_any<any_t, 0, counter> {
static constexpr size_t size = align(sizeof(any_t), 16)
+ random_constant<counter^ base_key, (counter^ base_key) % 128>::value % (16 + 1);
static constexpr size_t key = random_constant<counter^ base_key, (size^ base_key) % 128>::value;
uint8_t buffer[size];
public:
template<size_t... indices>
_FORCEINLINE constexpr oxor_any(any_t any, _lxy_::index_sequence<indices...>) :
buffer{ encrypt_byte<key>(reinterpret_cast<uint8_t*>(&any)[indices], indices)... } {
}
_FORCEINLINE const any_t get() { return *decrypt<const any_t*, key>(buffer); }
};
}
#endif // 混淆_H