I'M REALLY ABOUT THIS SHIT

This commit is contained in:
2023-12-22 03:10:35 -06:00
parent 1a99352fb3
commit 81075d2a14
3 changed files with 189 additions and 95 deletions

View File

@@ -50,8 +50,9 @@ namespace LinearAlgebra
class Vector2 {
public:
Vector2();
// Constructs a new Vector2 with the value (X, Y)
Vector2(float X, float Y);
Vector2(const Vector2& rhs);
Vector2(const Vector2& rhs); // Copy Constructor
Vector2(Vector2&&) = default; // Move Constructor
float getX() const { return x; }
float getY() const { return y; }
@@ -59,22 +60,21 @@ public:
void setX(float newX) { x = newX;}
void setY(float newY) { y = newY; }
#endif
float operator[](std::size_t index)
{
assert(index < 2);
if (index == 0) return x;
if (index == 1) return y;
return 0;
}
float operator[](std::size_t index);
bool IsWithinMarginOfError(const Vector2& rhs, float margin=0.001f) const;
bool operator == (const Vector2& rhs) const;
bool operator != (const Vector2& rhs) const;
Vector2 min(const Vector2& min) const;
static Vector2 min(const Vector2& value, const Vector2& minimum);
Vector2 max(const Vector2& max) const;
Vector2 clamp(const Vector2& min, const Vector2& max) const;
static Vector2 clamp(const Vector2& min, const Vector2& middle, const Vector2& max);
// Returns the magnitude between the two vectors.
float distance(const Vector2& to) const;
static float distance(const Vector2& from, const Vector2& to);
float length() const;
float lengthSquared() const;
// Returns the length of the vector, which is sqrt(x^2 + y^2)
@@ -86,34 +86,59 @@ public:
float dot(const Vector2& rhs) const;
// Projects one vector onto another and returns the result. (IDK)
Vector2 project(const Vector2& rhs) const;
// @see project
static Vector2 project(const Vector2& lhs, const Vector2& rhs) { return lhs.project(rhs); }
// Returns a copy of this vector, resized to have a magnitude of 1, while preserving "direction"
Vector2 normalize() const;
// Linearly interpolates between two points.
// Interpolates between the points and b by the interpolant t.
// The parameter is (TODO: SHOULD BE!) clamped to the range[0, 1].
// This is most commonly used to find a point some fraction of the wy along a line between two endpoints (eg. to move an object gradually between those points).
static Vector2 lerp(const Vector2& lhs, const Vector2& rhs, float alpha) { return lhs.lerp(rhs, alpha); }
Vector2 lerp(const Vector2& rhs, float alpha) const;
// @see lerp
static Vector2 lerp(const Vector2& lhs, const Vector2& rhs, float alpha) { return lhs.lerp(rhs, alpha); }
float angleBetween(const Vector2& rhs) const
{
auto numer = this->dot(rhs);
auto denom = this->magnitude() * rhs.magnitude();
return std::acos(numer / denom);
}
static float angleBetween(const Vector2& lhs, const Vector2& rhs) { }
// Adds two vectors.
Vector2 operator +(const Vector2& rhs) const;
Vector2 add(const Vector2& rhs) const;
static Vector2 add(const Vector2& lhs, const Vector2& rhs);
// Subtracts two vectors.
Vector2 operator -(const Vector2& rhs) const;
Vector2 sub(const Vector2& rhs) const;
static Vector2 sub(const Vector2& lhs, const Vector2& rhs);
// Multiplies this vector by a scalar value.
Vector2 operator *(float rhs) const;
Vector2 mul(float scalar) const;
// Divides this vector by a scalar.
Vector2 operator /(float rhs) const;
Vector2 div(float scalar) const;
// Unary operator +
Vector2 operator +() const; // TODO: Implement
Vector2 operator -() const;
// Assigns a vector to another
Vector2& operator=(const Vector2&v);
Vector2& operator+=(const Vector2& rhs);
Vector2& operator-=(const Vector2& rhs);
Vector2& operator+=(const Vector2& rhs); // Adds a vector to this vector, in-place.
Vector2& operator-=(const Vector2& rhs); // Subtracts a vector from this vector, in-place
Vector2& operator*=(float scalar);
Vector2& operator/=(float scalar);
Vector2 add(const Vector2& rhs) const;
Vector2 sub(const Vector2& rhs) const;
public:
#if MUTABLE
float x = 0;
@@ -188,6 +213,7 @@ public:
class Vector4 {
public:
Vector4();
Vector4(const Vector3& xyz, float w = 0);
Vector4(float X, float Y, float Z, float W);
Vector4(const Vector4& copy) = default;
Vector4(Vector4&& move) = default;
@@ -241,87 +267,7 @@ public:
#endif
};
class Quaternion : public Vector4
{
public:
Quaternion() {}
Quaternion(const Quaternion& rhs) = default;
explicit Quaternion(Matrix3x3& rotationMtrx) {}
explicit Quaternion(Matrix4x4& rotationMtrx) {}
// @note The input data is not normalized after construction, this has to be done manually.
Quaternion(float x, float y, float z, float w);
// Constructs this quaternion by specifying a rotation axis and the amount of rotation to be performed about that axis
// @param rotationAxis The normalized rotation axis to rotate about. If using Vector4 version of the constructor, the w component of this vector must be 0.
Quaternion(const Vector3& rotationAxis, float rotationAngleBetween) { SetFromAxisAngle(rotationAxis, rotationAngleBetween); }
Quaternion(const Vector4& rotationAxis, float rotationAngleBetween) { SetFromAxisAngle(rotationAxis, rotationAngleBetween); }
//void Inverse();
Quaternion Inverse() const;
//void Normalize();
Quaternion Normalize() const;
Vector3 GetWorldX() const { return Transform(1.f, 0.f, 0.f); }
Vector3 GetWorldY() const { return Transform(0.f, 1.f, 0.f); }
Vector3 GetWorldZ() const { return Transform(0.f, 0.f, 1.f); }
Matrix3x3 ToMatrix3x3() const;
Vector3 Transform(const Vector3& vec) const
{
Matrix3x3 mat = this->ToMatrix3x3();
return mat * vec;
}
Vector3 Transform(float X, float Y, float Z) const
{
}
Vector4 Transform(const Vector4& vec) const
{
}
Vector4 Transform(float X, float Y, float Z, float W) const
{
}
Quaternion GetInverse() const;
Quaternion Lerp(const Quaternion& b, float t) const
{
float angle = this->dot(b);
if (angle >= 0.f) // Make sure we rotate the shorter arc
return (*this * (1.f - t) + b * t).Normalize();
else
return (*this * (t - 1.f) + b * t).Normalize();
}
Quaternion Slerp(const Quaternion& target) const;
void SetFromAxisAngle(const Vector3& axis, float angle)
{
float sinz, cosz;
}
void SetFromAxisAngle(const Vector4& axis, float angle)
{
}
static Quaternion LookAt(const Vector3& position, const Vector3& direction, const Vector3& axisUp);
// Multiplies two quaternions together.
// The product q1 * q2 returns a quaternion that concatenates the two orientation rotations.
// The rotation q2 is applied first before q1.
Quaternion operator * (const Quaternion& rhs) const;
// Transforms the given vector by this Quaternion.
Vector3 operator * (const Vector3& rhs) const;
Vector4 operator * (const Vector4& rhs) const;
// Divides a quaternion by another. Divison "a / b" results in a quaternion that rotates the orientation b to coincide with orientation of
Quaternion operator / (const Quaternion& rhs) const;
Quaternion operator +() const { return *this; }
};
// Essential Reading:
@@ -392,12 +338,22 @@ class Matrix3x3 {
public:
static const Matrix3x3 Zero;
static const Matrix3x3 Identity;
Matrix3x3();
Matrix3x3(const Vector3& r1, const Vector3& r2, const Vector3& r3);
Vector3 GetRow() const;
Vector3 GetColumn() const;
float At(int x, int y) const;
// Creates a new M3x3 that rotates about the given axis by the given angle
static Matrix3x3 RotateAxisAngle(const Vector3& rhs);
Vector3 operator[] (float index) const;
Vector3 operator * (const Vector3& rhs) const;
Matrix3x3 operator * (const Matrix3x3& rhs) const;
protected:
float elems[3][3];
};
@@ -454,7 +410,93 @@ struct Movement {
EulerAngle angle;
Position position;
};
class Quaternion : public Vector4
{
public:
Quaternion() {}
Quaternion(const Quaternion& rhs) = default;
explicit Quaternion(Matrix3x3& rotationMtrx) {}
explicit Quaternion(Matrix4x4& rotationMtrx) {}
// @note The input data is not normalized after construction, this has to be done manually.
Quaternion(float x, float y, float z, float w);
// Constructs this quaternion by specifying a rotation axis and the amount of rotation to be performed about that axis
// @param rotationAxis The normalized rotation axis to rotate about. If using Vector4 version of the constructor, the w component of this vector must be 0.
Quaternion(const Vector3& rotationAxis, float rotationAngleBetween) { SetFromAxisAngle(rotationAxis, rotationAngleBetween); }
Quaternion(const Vector4& rotationAxis, float rotationAngleBetween) { SetFromAxisAngle(rotationAxis, rotationAngleBetween); }
//void Inverse();
Quaternion Inverse() const;
//void Normalize();
Quaternion Normalize() const;
Vector3 GetWorldX() const { return Transform(1.f, 0.f, 0.f); }
Vector3 GetWorldY() const { return Transform(0.f, 1.f, 0.f); }
Vector3 GetWorldZ() const { return Transform(0.f, 0.f, 1.f); }
Matrix3x3 ToMatrix3x3() const;
Vector3 Transform(const Vector3& vec) const
{
Matrix3x3 mat = this->ToMatrix3x3();
return mat * vec;
}
Vector3 Transform(float X, float Y, float Z) const
{
return Transform(Vector3{X, Y, Z});
}
// Note: We only transform the x,y,z components of 4D vectors, w is left untouched
Vector4 Transform(const Vector4& vec) const
{
return Vector4(Transform(vec.x, vec.y, vec.z), vec.w);
}
Vector4 Transform(float X, float Y, float Z, float W) const
{
return Transform(Vector4(X, Y, Z, W));
}
Quaternion GetInverse() const;
Quaternion Lerp(const Quaternion& b, float t) const
{
float angle = this->dot(b);
if (angle >= 0.f) // Make sure we rotate the shorter arc
return (*this * (1.f - t) + b * t).Normalize();
else
return (*this * (t - 1.f) + b * t).Normalize();
}
Quaternion Slerp(const Quaternion& target) const;
void SetFromAxisAngle(const Vector3& axis, float angle)
{
float sinz, cosz;
}
void SetFromAxisAngle(const Vector4& axis, float angle)
{
}
static Quaternion LookAt(const Vector3& position, const Vector3& direction, const Vector3& axisUp);
// Multiplies two quaternions together.
// The product q1 * q2 returns a quaternion that concatenates the two orientation rotations.
// The rotation q2 is applied first before q1.
Quaternion operator * (const Quaternion& rhs) const;
Quaternion operator * (float scalar) const
{
return Quaternion(x * scalar, y * scalar, z * scalar, w * scalar);
}
// Transforms the given vector by this Quaternion.
Vector3 operator * (const Vector3& rhs) const;
Vector4 operator * (const Vector4& rhs) const;
// Divides a quaternion by another. Divison "a / b" results in a quaternion that rotates the orientation b to coincide with orientation of
Quaternion operator / (const Quaternion& rhs) const;
Quaternion operator +(const Quaternion& rhs) const;
Quaternion operator +() const { return *this; }
Quaternion operator -() const;
};
inline namespace VectorMath {
inline float distance(Position sP, Position eP) {

View File

@@ -69,9 +69,9 @@ void Engine::initVideo()
SDL_SetWindowResizable(this->window,SDL_FALSE);
this->glContext = SDL_GL_CreateContext(window);
if (Engine::getGLVersion() < 1.4f) {
if (Engine::getGLVersion() < 1.5f) {
std::cerr << "Driver OpenGL version: " << Engine::getGLVersion() << std::endl;
std::cerr << "OpenGL >= 1.4 is required." << std::endl;
std::cerr << "OpenGL >= 1.5 is required." << std::endl;
exit(1);
}

View File

@@ -15,6 +15,14 @@ namespace LinearAlgebra {
Vector2::Vector2(const Vector2& rhs): x(rhs.x), y(rhs.y)
{}
float Vector2::operator[](std::size_t index)
{
assert(index < 2);
if (index == 0) return x;
if (index == 1) return y;
return 0;
}
bool Vector2::IsWithinMarginOfError(const Vector2& rhs, float margin) const
{
return this->distance(rhs) <= margin;
@@ -476,6 +484,50 @@ EulerAngle EulerAngle::movementAngle() const
return a;
}
Vector3 Matrix3x3::operator*(const Vector3& rhs) const
{
return {
At(0,0) * rhs.x + At(0, 1) * rhs.y + At(0, 2) * rhs.z,
At(1, 0) * rhs.x + At(1, 1) * rhs.y + At(1, 2) * rhs.z,
At(2, 0) * rhs.x + At(2, 1) * rhs.y + At(2,2) * rhs.z
};
}
Matrix3x3 Matrix3x3::operator*(const Matrix3x3& rhs) const
{
//Matrix3x3 r;
auto m00 = At(0, 0) * rhs.At(0, 0) + At(0, 1) * rhs.At(1, 0) + At(0, 2) * rhs.At(2, 0);
auto m01 = At(0, 0) * rhs.At(0, 1) + At(0, 1) * rhs.At(1, 1) + At(0, 2) * rhs.At(2, 1);
auto m02 = At(0, 0) * rhs.At(0, 2) + At(0, 1) * rhs.At(1, 2) + At(0, 2) * rhs.At(2, 2);
auto m10 = At(1, 0) * rhs.At(0, 0) + At(1, 1) * rhs.At(1, 0) + At(1, 2) * rhs.At(2, 0);
auto m11 = At(1, 0) * rhs.At(0, 1) + At(1, 1) * rhs.At(1, 1) + At(1, 2) * rhs.At(2, 1);
auto m12 = At(1, 0) * rhs.At(0, 2) + At(1, 1) * rhs.At(1, 2) + At(1, 2) * rhs.At(2,2);
auto m20 = At(2, 0) * rhs.At(0, 0) + At(2, 1) * rhs.At(1, 0) + At(2,2) * rhs.At(2, 0);
auto m21 = At(2, 0) * rhs.At(0, 1) + At(2, 1) * rhs.At(1, 1) + At(2,2) * rhs.At(2, 1);
auto m22 = At(2, 0) * rhs.At(0, 2) + At(2, 1) * rhs.At(1, 2) + At(2,2) * rhs.At(2,2);
return Matrix3x3({m00, m01, m02}, {m10, m11, m12}, {m20, m21, m22});
}
Quaternion Quaternion::operator-() const
{
return {-x, -y, -z, -w};
}
#pragma endregion
#pragma region Matrix2x2
#pragma endregion
#pragma region Matrix3x3
#pragma endregion
}