Begin documentation effort for Vector classes

This commit is contained in:
2023-12-20 00:00:24 -06:00
parent 21a5ce7bd8
commit 8ca0efed57
5 changed files with 143 additions and 65 deletions

View File

@@ -12,17 +12,17 @@ public:
{
}
Angle angle = {0,0,0}; //Pitch Yaw Roll, The orientation of the entity in the world,
Angle velAngle = {0,0,0}; //The angle of an entities velocity.
EulerAngle angle = {0,0,0}; //Pitch Yaw Roll, The orientation of the entity in the world,
EulerAngle velAngle = {0,0,0}; //The angle of an entities velocity.
glm::vec3 Velocity;
Vector3 upVector = {0.0f,1.0f,0.0f};
ScriptedMove scriptedMove;
void move(Angle a, float speed);
Angle fAngle(); // forward angle
Angle bAngle(); // back angle
Angle lAngle(); // left angle
Angle rAngle(); // right angle
void move(EulerAngle a, float speed);
EulerAngle fAngle(); // forward angle
EulerAngle bAngle(); // back angle
EulerAngle lAngle(); // left angle
EulerAngle rAngle(); // right angle
void doScriptedMovement();
Position simulateMove(Angle a, float speed);
Position simulateMove(EulerAngle a, float speed);
};

View File

@@ -21,7 +21,7 @@ public:
//We will probably end up having a different camera point class controlled by the "world".
Position cameraPoint (float distance) {
Position behindPosition = this->position;
Angle reverseDirection = this->bAngle();
EulerAngle reverseDirection = this->bAngle();
behindPosition.x -= reverseDirection.pitch * distance;
behindPosition.y -= reverseDirection.yaw * distance;
behindPosition.z -= reverseDirection.roll * distance;

View File

@@ -7,6 +7,14 @@
#include <glm/glm.hpp>
#include <glm/ext/scalar_constants.hpp>
class Spring
{
};
inline float lerp(float a, float b, float t) {
}
@@ -27,6 +35,13 @@ inline float lerp(float a, float b, float t) {
#define IMMUTABLE !MUTABLE
#endif
class Vector2;
class Vector3;
class Vector4;
class EulerAngle;
class AxisAngle;
class CoordinateFrame;
class Vector2 {
public:
Vector2() : x(0), y(0) {}
@@ -56,16 +71,42 @@ public:
float length() const;
float lengthSquared() const;
float magnitude() const;
// Returns a float value equal to the magnitudes of the two vectors multiplied together and then multiplied by the cosine of the angle between them.
// For normalized vectors, dot returns 1 if they point in exactly the same direction,
// -1 if they point in completely opposite directions,
// and 0 if the vectors are perpendicular.
static float dot(const Vector2& lhs, const Vector2& rhs) { return lhs.dot(rhs); }
float dot(const Vector2& rhs) const;
// Projects one vector onto another and returns the result. (IDK)
Vector2 project(const Vector2& rhs) const;
// 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;
Vector2 operator+(const Vector2& rhs) const;
Vector2 operator-(const Vector2& rhs) const;
Vector2 operator*(float rhs) const;
Vector2 operator/(float rhs) const;
Vector2 operator+() const; // TODO: Implement
Vector2 operator-() const;
float angleBetween(const Vector2& rhs) const
{
auto numer = this->dot(rhs);
auto denom = this->magnitude() * rhs.magnitude();
return std::acos(numer / denom);
}
Vector2 operator +(const Vector2& rhs) const;
Vector2 operator -(const Vector2& rhs) const;
Vector2 operator *(float rhs) const;
Vector2 operator /(float rhs) const;
Vector2 operator +() const; // TODO: Implement
Vector2 operator -() const;
Vector2& operator=(const Vector2&v);
Vector2& operator+=(const Vector2& rhs);
Vector2& operator-=(const Vector2& rhs);
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;
@@ -182,38 +223,28 @@ public:
#endif
};
class Quaternion : Vector4
{
};
// Essential Reading:
// http://www.essentialmath.com/GDC2012/GDC2012_JMV_Rotations.pdf
class Angle {
class EulerAngle {
public:
EulerAngle();
static EulerAngle FromRadians(float radians);
static EulerAngle FromDegrees(float degrees);
// TODO: Implement separate upper and lower bounds
// Preserves internal value of euler angles, normalizes and clamps the output.
// This does not solve gimbal lock!!!
float GetPitch(float pitch_limit) const { return std::clamp( std::remainderf(pitch,360.f), -pitch_limit, pitch_limit); }
float GetYaw(float yaw_limit) const { return std::clamp(std::remainderf(yaw, 360.f), -yaw_limit, yaw_limit); }
float GetRoll(float roll_limit) const { return std::clamp(std::remainderf(roll, 360.f), -roll_limit, roll_limit); }
float pitch;
float yaw;
float roll;
bool operator==(const Angle& a) const {
return (pitch == a.pitch) && (yaw == a.yaw) && (roll == a.roll);
}
void clamp() {
if (this->pitch > 89.0f)
this->pitch = 89.0f;
if (this->pitch <= -89.0f)
this->pitch = -89.0f;
//TODO: Make this entirely seamless by getting the amount they rotated passed -180 and +180 by.
if (this->yaw <= -180.0f)
this->yaw = 180.0f;
if (this->yaw >= 180.01f)
this->yaw = -179.9f;
if (this->roll >= 360.0f)
this->roll = 0.0;
if (this->roll <= -360.0f)
this->roll = 0.0;
}
float GetPitch(float pitch_limit) const;
float GetYaw(float yaw_limit) const;
float GetRoll(float roll_limit) const;
bool operator==(const EulerAngle& a) const;
void clamp();
// TODO: Euler Angles do not represent a vector, length doesn't apply, nor is this information meaningful for this data type.
// If you need a meaningful representation of length in 3d space, use a vector!!
@@ -223,13 +254,11 @@ public:
// TODO: Implement
Vector3 unitVector() const;
Angle movementAngle() {
Angle a;
a.pitch = (cos(glm::radians(yaw)) * cos(glm::radians(pitch)));
a.yaw = -sin(glm::radians(pitch));
a.roll = (sin(glm::radians(yaw)) * cos(glm::radians(pitch)));
return a;
}
EulerAngle movementAngle() const;
public:
float pitch;
float yaw;
float roll;
};
// Transitional datatype, not useful for internal representation of rotation
@@ -249,8 +278,8 @@ class CoordinateFrame
Vector3 getRightVector();
Vector3 getUpVector();
AxisAngle GetAxisAngle();
Angle GetEulerAngleXYZ();
Angle GetWorldAngleYZX();
EulerAngle GetEulerAngleXYZ();
EulerAngle GetWorldAngleYZX();
};
class Matrix2x2 {
@@ -324,7 +353,7 @@ public:
};
struct Movement {
Angle angle;
EulerAngle angle;
Position position;
};
inline namespace VectorMath {
@@ -333,7 +362,7 @@ inline namespace VectorMath {
}
//Basically an aimbot.
inline Angle calcAngle(Position sP, Position eP) {
inline Vector3 calcAngle(Position sP, Position eP) {
const auto pi = glm::pi<float>();
//returned.x = -(asinf((eP.y - sP.y) / distance(sP, eP)) * 180.0f / M_PI);
//returned.y = (atan2f(eP.x - sP.x,eP.z - sP.z) / M_PI * 180.0f);

View File

@@ -1,6 +1,6 @@
#include <types/moby.h>
inline void Moby::move(Angle a, float speed)
inline void Moby::move(EulerAngle a, float speed)
{
this->position.z += (speed*engine->frameDelta) * a.pitch;
this->position.y += (speed*engine->frameDelta) * a.yaw;
@@ -8,7 +8,7 @@ inline void Moby::move(Angle a, float speed)
}
//Returns the position we'd be at *if* we did a movement.
Position Moby::simulateMove(Angle a, float speed) {
Position Moby::simulateMove(EulerAngle a, float speed) {
Position p;
p.z = this->position.z += (speed*engine->frameDelta) * a.pitch;
p.y = this->position.y += (speed*engine->frameDelta) * a.yaw;
@@ -16,38 +16,38 @@ Position Moby::simulateMove(Angle a, float speed) {
return p;
}
inline Angle Moby::fAngle()
inline EulerAngle Moby::fAngle()
{
Angle a;
EulerAngle a;
a.pitch = (cos(glm::radians(this->angle.yaw)) * cos(glm::radians(this->angle.pitch)));
a.yaw = -sin(glm::radians(this->angle.pitch));
a.roll = (sin(glm::radians(this->angle.yaw)) * cos(glm::radians(this->angle.pitch)));
return a;
}
Angle Moby::bAngle()
EulerAngle Moby::bAngle()
{
Angle a;
EulerAngle a;
a.pitch = (cos(glm::radians(this->angle.yaw)) * cos(glm::radians(this->angle.pitch)));
a.yaw = -sin(glm::radians(this->angle.pitch));
a.roll = (sin(glm::radians(this->angle.yaw)) * cos(glm::radians(this->angle.pitch)));
return a;
}
Angle Moby::lAngle()
EulerAngle Moby::lAngle()
{
Angle f = fAngle();
Angle a;
EulerAngle f = fAngle();
EulerAngle a;
a.pitch = f.pitch * upVector.z - f.roll * upVector.y;
a.yaw = f.roll * upVector.x - f.pitch * upVector.z;
a.roll = f.pitch * upVector.y - f.yaw * upVector.x;
return a;
}
Angle Moby::rAngle()
EulerAngle Moby::rAngle()
{
Angle f = fAngle();
Angle a;
EulerAngle f = fAngle();
EulerAngle a;
a.pitch = -(f.yaw * upVector.z - f.roll * upVector.y);
a.yaw = (f.roll * upVector.x - f.pitch * upVector.z);
a.roll = -(f.pitch * upVector.y - f.yaw * upVector.x);
@@ -76,7 +76,7 @@ void Moby::doScriptedMovement() {
scriptedMove.reset();
}
Angle a = VectorMath::calcAngle(this->position, scriptedMove.positions[scriptedMove.index]).movementAngle();
EulerAngle a = VectorMath::calcAngle(this->position, scriptedMove.positions[scriptedMove.index]).movementAngle();
move(a,scriptedMove.velocity);
//TODO: The angular velocity still isn't qccurate.
angle.pitch -= (angle.pitch - scriptedMove.angles[scriptedMove.index].pitch)*(scriptedMove.velocity)*engine->frameDelta;

View File

@@ -400,4 +400,53 @@ Vector4 Vector4::operator-(const Vector4& rhs) const
return {x-rhs.x, y-rhs.y, z-rhs.z, w-rhs.w};
}
#pragma endregion
#pragma region EulerAngle
float EulerAngle::GetPitch(float pitch_limit) const
{ return std::clamp( std::remainderf(pitch,360.f), -pitch_limit, pitch_limit); }
float EulerAngle::GetYaw(float yaw_limit) const
{ return std::clamp(std::remainderf(yaw, 360.f), -yaw_limit, yaw_limit); }
float EulerAngle::GetRoll(float pitch_limit) const
{ return std::clamp( std::remainderf(pitch,360.f), -pitch_limit, pitch_limit); }
bool EulerAngle::operator==(const EulerAngle& a) const
{
return (pitch == a.pitch) && (yaw == a.yaw) && (roll == a.roll);
}
void EulerAngle::clamp()
{
if (this->pitch > 89.0f)
this->pitch = 89.0f;
if (this->pitch <= -89.0f)
this->pitch = -89.0f;
//TODO: Make this entirely seamless by getting the amount they rotated passed -180 and +180 by.
if (this->yaw <= -180.0f)
this->yaw = 180.0f;
if (this->yaw >= 180.01f)
this->yaw = -179.9f;
if (this->roll >= 360.0f)
this->roll = 0.0;
if (this->roll <= -360.0f)
this->roll = 0.0;
}
EulerAngle EulerAngle::movementAngle() const
{
EulerAngle a;
a.pitch = (cos(glm::radians(yaw)) * cos(glm::radians(pitch)));
a.yaw = -sin(glm::radians(pitch));
a.roll = (sin(glm::radians(yaw)) * cos(glm::radians(pitch)));
return a;
}
#pragma endregion