forked from gcdsfh/PMDT
fix name eroor
This commit is contained in:
Executable
+703
@@ -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);
|
||||
}
|
||||
Executable
+528
@@ -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);
|
||||
}
|
||||
Executable
+625
@@ -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);
|
||||
}
|
||||
Executable
+142
@@ -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;
|
||||
}
|
||||
Executable
+215
@@ -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;
|
||||
}
|
||||
}
|
||||
Executable
+12
@@ -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;
|
||||
}
|
||||
Executable
+699
@@ -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
|
||||
Reference in New Issue
Block a user