Remove built in angle class

This commit is contained in:
2024-01-03 18:55:32 -05:00
parent 89a21ebb5c
commit c83d364493
11 changed files with 83 additions and 579 deletions

View File

@@ -45,7 +45,7 @@ CPMAddPackage(
CPMAddPackage(
NAME J3ML
URL https://git.redacted.cc/josh/j3ml/archive/pre-1.zip
URL https://git.redacted.cc/josh/j3ml/archive/Prerelease-2.zip
)

View File

@@ -18,7 +18,7 @@ void pre_render() {
storeEntity(camera);
// TODO:
getCamera()->position = {0.0f,-2.0f,-5.0f};
getCamera()->angle.yaw = 0.0f;
getCamera()->angle.y = 0.0f;
getCamera()->scriptedMove.load("assets/scriptedMove/default.smov");
auto* skybox = new Skybox();
skybox->draw = true;

View File

@@ -12,11 +12,11 @@
class ScriptedMove {
public:
std::vector<Position> positions;
std::vector<Angle> angles;
std::vector<LinearAlgebra::Vector3> positions;
std::vector<LinearAlgebra::Vector3> angles;
//We won't even need that many positions anyways.
int16_t index = -1;
Position start = {NULL, NULL, NULL};
LinearAlgebra::Vector3 start = {NULL, NULL, NULL};
float velocity;
float lastDistance;
bool loop = false;

View File

@@ -63,12 +63,12 @@ public:
if (cameraMode == CameraMode::THIRD_PERSON) {
if (engine->debug)
std::cout << "Calculated Pitch: " << VectorMath::calcAngle(position,getPlayer()->position).pitch << " Calculated Yaw: " << VectorMath::calcAngle(position,getPlayer()->position).yaw << std::endl;
std::cout << "Calculated Pitch: " << VectorMath::calcAngle(position,getPlayer()->position).x << " Calculated Yaw: " << VectorMath::calcAngle(position,getPlayer()->position).y << std::endl;
this->position = getPlayer()->cameraPoint(2);
//Make the camera pitch down a little bit.
this->position.y += 0.5;
this->angle.pitch = VectorMath::calcAngle(position,getPlayer()->position).pitch;
this->angle.yaw = VectorMath::calcAngle(position,getPlayer()->position).yaw;
this->angle.x = VectorMath::calcAngle(position,getPlayer()->position).x;
this->angle.y = VectorMath::calcAngle(position,getPlayer()->position).y;
}
//if (engine->frameCount == 5000)
@@ -97,16 +97,16 @@ public:
}
if (engine->window->keyDown(SCANCODE::LEFT)) {
this->angle.yaw +=75.0f*engine->frameDelta;
this->angle.y +=75.0f*engine->frameDelta;
}
if (engine->window->keyDown(SCANCODE::RIGHT)) {
this->angle.yaw -=75.0f*engine->frameDelta;
this->angle.y -=75.0f*engine->frameDelta;
}
if (engine->window->keyDown(SCANCODE::UP)) {
this->angle.pitch -=75.0f*engine->frameDelta;
this->angle.x -=75.0f*engine->frameDelta;
}
if (engine->window->keyDown(SCANCODE::DOWN)) {
this->angle.pitch +=75.0f*engine->frameDelta;
this->angle.x +=75.0f*engine->frameDelta;
}
}
}
@@ -114,9 +114,10 @@ public:
void render() {
// Preferrably: Camera would return a coordinate system that GameEngine
// would set gluLookAt() with, this helps keep objects self contained
this->angle.clamp();
glRotatef(angle.pitch,1.0f, 0.0f, 0.0f);
glRotatef(-angle.yaw,0.0f, 1.0f, 0.0f);
//TODO
//this->angle.clamp();
glRotatef(angle.x,1.0f, 0.0f, 0.0f);
glRotatef(-angle.y,0.0f, 1.0f, 0.0f);
glTranslatef(0.0f, 0.0f, 0.0f);
gluLookAt(position.x, position.y, position.z, // camera position

View File

@@ -9,7 +9,7 @@ class Entity {
protected:
LinearAlgebra::Matrix4x4 coordinates;
public:
Position position; //X Y Z
LinearAlgebra::Vector3 position; //X Y Z
uint32_t ticksAlive; //At 64tps it'd take 776 days to overflow.
LinearAlgebra::Vector3 GetPos() const;

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.
LinearAlgebra::Vector3 angle = {0,0,0}; //Pitch Yaw Roll, The orientation of the entity in the world,
LinearAlgebra::Vector3 velAngle = {0,0,0}; //The angle of an entities velocity.
LinearAlgebra::Vector3 Velocity;
LinearAlgebra::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(LinearAlgebra::Vector3 a, float speed);
LinearAlgebra::Vector3 fAngle(); // forward angle
LinearAlgebra::Vector3 bAngle(); // back angle
LinearAlgebra::Vector3 lAngle(); // left angle
LinearAlgebra::Vector3 rAngle(); // right angle
void doScriptedMovement();
Position simulateMove(Angle a, float speed);
LinearAlgebra::Vector3 simulateMove(LinearAlgebra::Vector3 a, float speed);
};

View File

@@ -11,7 +11,7 @@ public:
bool alive;
uint8_t health;
uint8_t state;
Position cameraTarget;//The point where the 3rd-person camera will want to look at.
LinearAlgebra::Vector3 cameraTarget;//The point where the 3rd-person camera will want to look at.
VertexArray geometry;
//Each type of entity will have an "update" function and a "render" function.
//These will be declared in each type of entity and not in the base entity because
@@ -19,12 +19,12 @@ public:
//The "camera point" is the position the camera will want to be while following the player.
//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();
behindPosition.x -= reverseDirection.pitch * distance;
behindPosition.y -= reverseDirection.yaw * distance;
behindPosition.z -= reverseDirection.roll * distance;
LinearAlgebra::Vector3 cameraPoint (float distance) {
LinearAlgebra::Vector3 behindPosition = this->position;
LinearAlgebra::Vector3 reverseDirection = this->bAngle();
behindPosition.x -= reverseDirection.x * distance;
behindPosition.y -= reverseDirection.y * distance;
behindPosition.z -= reverseDirection.z * distance;
return behindPosition;
}
@@ -41,13 +41,13 @@ public:
position = {0,-2,0};
}
//Rotate
this->angle.yaw += 200.0*engine->frameDelta;
this->angle.y += 200.0*engine->frameDelta;
}
void render() override {
glColor3f(0.75,0.75,0.75);
glPushMatrix();
glRotatef(-angle.pitch,1.0f, 0.0f, 0.0f);
glRotatef(-angle.yaw,0.0f, 1.0f, 0.0f);
glRotatef(-angle.x,1.0f, 0.0f, 0.0f);
glRotatef(-angle.y,0.0f, 1.0f, 0.0f);
glTranslatef(position.x ,position.y,position.z);
geometry.draw();
glPopMatrix();

View File

@@ -6,220 +6,20 @@
#include <functional>
#include <J3ML/LinearAlgebra.h>
#include <J3ML/LinearAlgebra/Matrix4x4.h>
#include <J3ML/LinearAlgebra/Vector3.h>
#include <cassert>
inline float lerp(float a, float b, float t) {
}
// A stab at a vector<length> implementation suitable for game engineering
template <std::size_t length>
class numeric_vector {
public:
virtual float operator[](std::size_t index) = 0;
};
class vector2 : public numeric_vector<2> {
public:
vector2() : x(0), y(0) {}
vector2(float X, float Y) : x(X), y(Y) {}
vector2(const vector2& rhs): x(rhs.x), y(rhs.y)
{}
vector2(vector2&&) = default; // Move Constructor
float operator[](std::size_t index) override
{
assert(index < 2);
if (index == 0) return x;
if (index == 1) return y;
return 0;
}
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;
vector2 max(const vector2& max) const;
vector2 clamp(const vector2& min, const vector2& max) const;
float distance(const vector2& to) const;
float length() const;
float lengthSquared() const;
float magnitude() const;
float dot(const vector2& rhs) const;
vector2 project(const vector2& rhs) const;
vector2 normalize() const;
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;
public:
float x = 0;
float y = 0;
};
class vector3 : public numeric_vector<3>
{
public:
vector3() : x(0), y(0), z(0) {}
vector3(float X, float Y, float Z): x(X), y(Y), z(Z) {}
vector3(const vector3& rhs);
vector3(vector3&&) = default;
vector3& operator=(const vector3& rhs);
float operator[](std::size_t index) override;
bool IsWithinMarginOfError(const vector3& rhs, float margin=0.001f) const;
bool operator == (const vector3& rhs) const;
bool operator != (const vector3& rhs) const;
vector3 min(const vector3& min) const;
vector3 max(const vector3& max) const;
vector3 clamp(const vector3& min, const vector3& max) const;
float distance(const vector3& to) const;
float length() const;
float lengthSquared() const;
float magnitude() const;
float dot(const vector3& rhs) const;
vector3 project(const vector3& rhs) const;
vector3 cross(const vector3& rhs) const;
vector3 normalize() const;
vector3 lerp(const vector3& goal, float alpha) const;
vector3 operator+(const vector3& rhs) const;
vector3 operator-(const vector3& rhs) const;
vector3 operator*(float rhs) const;
vector3 operator/(float rhs) const;
vector3 operator+() const; // TODO: Implement
vector3 operator-() const;
public:
float x = 0;
float y = 0;
float z = 0;
};
class vector4 : public numeric_vector<4> {};
// Essential Reading:
// http://www.essentialmath.com/GDC2012/GDC2012_JMV_Rotations.pdf
class Angle {
public:
// 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;
}
// 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!!
[[nodiscard]] float length() const {
return 0;
}
// TODO: Implement
vector3 unitVector() const;
Angle movementAngle() {
Angle a;
a.pitch = (cos(Math::Radians(yaw)) * cos(Math::Radians(pitch)));
a.yaw = -sin(Math::Radians(pitch));
a.roll = (sin(Math::Radians(yaw)) * cos(Math::Radians(pitch)));
return a;
}
};
// Transitional datatype, not useful for internal representation of rotation
// But has uses for conversion and manipulation.
class AxisAngle {
vector3 axis;
float angle;
};
using Position = vector3;
/*class Position : public vector3 {
public:
bool operator==(const Position& p) const {
return (x == p.x) && (y == p.y) && (z == p.z);
}
void set(Position p) {
this->x = p.x;
this->y = p.y;
this->z = p.z;
}
void set(Position* p) {
this->x = p->x;
this->y = p->y;
this->z = p->z;
}
void set(vector3 v) {
this->x = v.x;
this->y = v.y;
this->z = v.z;
}
void set(vector3* v) {
this->x = v->x;
this->y = v->y;
this->z = v->z;
}
void set(float x, float y, float z) {
this->x = x;
this->y = y;
this->z = z;
}
float distanceFrom(Position p) {
return sqrt(pow(this->x - p.x, 2) + pow(this->y - p.y, 2) + pow(this->z - p.z, 2));
}
};*/
// The CFrame is fundamentally 4 vectors (position, forward, right, up vector)
class CoordinateFrame
{
LinearAlgebra::Matrix4x4 matrix;
vector3 getPosition();
vector3 getLookVector();
vector3 getRightVector();
vector3 getUpVector();
AxisAngle GetAxisAngle();
Angle GetEulerAngleXYZ();
Angle GetWorldAngleYZX();
};
struct Movement {
Angle angle;
Position position;
LinearAlgebra::Vector3 angle;
LinearAlgebra::Vector3 position;
};
inline namespace VectorMath {
inline float distance(Position sP, Position eP) {
inline float distance(LinearAlgebra::Vector3 sP, LinearAlgebra::Vector3 eP) {
return sqrt(pow(eP.x - sP.x, 2) + pow(eP.y - sP.y, 2) + pow(eP.z - sP.z, 2));
}
//Basically an aimbot.
inline Angle calcAngle(Position sP, Position eP) {
inline LinearAlgebra::Vector3 calcAngle(LinearAlgebra::Vector3 sP, LinearAlgebra::Vector3 eP) {
const auto pi = Math::Pi;
//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

@@ -9,6 +9,6 @@ void Camera::update()
if (engine->debug && engine->tickCount %64 == 0) {
std::cout << "Camera:" << std::endl;
std::cout << "X: " << position.x << " Y: " << position.y << " Z: " << position.z << std::endl;
std::cout << "Pitch: " << angle.pitch << " Yaw: " << angle.yaw << " Roll: " << angle.roll << std::endl;
std::cout << "Pitch: " << angle.x << " Yaw: " << angle.y << " Roll: " << angle.z << std::endl;
}
}

View File

@@ -1,59 +1,60 @@
#include <types/moby.h>
inline void Moby::move(Angle a, float speed)
void Moby::move(LinearAlgebra::Vector3 a, float speed)
{
this->position.z += (speed*engine->frameDelta) * a.pitch;
this->position.y += (speed*engine->frameDelta) * a.yaw;
this->position.x += (speed*engine->frameDelta) * a.roll;
this->position.z += (speed*engine->frameDelta) * a.x;
this->position.y += (speed*engine->frameDelta) * a.y;
this->position.x += (speed*engine->frameDelta) * a.z;
}
//Returns the position we'd be at *if* we did a movement.
Position Moby::simulateMove(Angle 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;
p.x = this->position.x += (speed*engine->frameDelta) * a.roll;
LinearAlgebra::Vector3 Moby::simulateMove(LinearAlgebra::Vector3 a, float speed) {
LinearAlgebra::Vector3 p;
p.z = this->position.z += (speed*engine->frameDelta) * a.x;
p.y = this->position.y += (speed*engine->frameDelta) * a.y;
p.x = this->position.x += (speed*engine->frameDelta) * a.z;
return p;
}
inline Angle Moby::fAngle()
inline LinearAlgebra::Vector3 Moby::fAngle()
{
Angle a;
a.pitch = (cos(Math::Radians(this->angle.yaw)) * cos(Math::Radians(this->angle.pitch)));
a.yaw = -sin(Math::Radians(this->angle.pitch));
a.roll = (sin(Math::Radians(this->angle.yaw)) * cos(Math::Radians(this->angle.pitch)));
LinearAlgebra::Vector3 a;
a.x = (cos(Math::Radians(this->angle.y)) * cos(Math::Radians(this->angle.x)));
a.y = -sin(Math::Radians(this->angle.x));
a.z = (sin(Math::Radians(this->angle.y)) * cos(Math::Radians(this->angle.x)));
return a;
}
Angle Moby::bAngle()
LinearAlgebra::Vector3 Moby::bAngle()
{
Angle a;
a.pitch = -(cos(Math::Radians(this->angle.yaw)) * cos(Math::Radians(this->angle.pitch)));
a.yaw = sin(Math::Radians(this->angle.pitch));
a.roll = -(sin(Math::Radians(this->angle.yaw)) * cos(Math::Radians(this->angle.pitch)));
LinearAlgebra::Vector3 a;
a.x = -(cos(Math::Radians(this->angle.y)) * cos(Math::Radians(this->angle.x)));
a.y = sin(Math::Radians(this->angle.x));
a.z = -(sin(Math::Radians(this->angle.y)) * cos(Math::Radians(this->angle.x)));
return a;
}
Angle Moby::lAngle()
LinearAlgebra::Vector3 Moby::lAngle()
{
Angle f = fAngle();
Angle 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;
LinearAlgebra::Vector3 f = fAngle();
LinearAlgebra::Vector3 a;
a.x = f.x * upVector.z - f.z * upVector.y;
a.y = f.z * upVector.x - f.x * upVector.z;
a.z = f.x * upVector.y - f.y * upVector.x;
return a;
}
Angle Moby::rAngle()
LinearAlgebra::Vector3 Moby::rAngle()
{
Angle f = fAngle();
Angle 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);
LinearAlgebra::Vector3 f = fAngle();
LinearAlgebra::Vector3 a;
a.x = -(f.y * upVector.z - f.z * upVector.y);
a.y = (f.z * upVector.x - f.x * upVector.z);
a.z = -(f.x * upVector.y - f.y * upVector.x);
return a;
}
//broken
void Moby::doScriptedMovement() {
//If the movement has a set starting position, Then teleport there.
if (scriptedMove.positions.empty())
@@ -76,20 +77,20 @@ void Moby::doScriptedMovement() {
scriptedMove.reset();
}
Angle a = VectorMath::calcAngle(this->position, scriptedMove.positions[scriptedMove.index]).movementAngle();
move(a,scriptedMove.velocity);
//LinearAlgebra::Vector3 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;
angle.yaw -= (angle.yaw -scriptedMove.angles[scriptedMove.index].yaw)*(scriptedMove.velocity)*engine->frameDelta;
angle.roll -= (angle.roll - scriptedMove.angles[scriptedMove.index].roll)*engine->frameDelta;
angle.x -= (angle.x - scriptedMove.angles[scriptedMove.index].x)*(scriptedMove.velocity)*engine->frameDelta;
angle.y -= (angle.y -scriptedMove.angles[scriptedMove.index].y)*(scriptedMove.velocity)*engine->frameDelta;
angle.z -= (angle.z - scriptedMove.angles[scriptedMove.index].z)*engine->frameDelta;
//If the next movement would make us go passed it.
if (scriptedMove.lastDistance < VectorMath::distance(simulateMove(a,scriptedMove.velocity),scriptedMove.positions[scriptedMove.index])) {
position = scriptedMove.positions[scriptedMove.index];
//if (scriptedMove.lastDistance < VectorMath::distance(simulateMove(a,scriptedMove.velocity),scriptedMove.positions[scriptedMove.index])) {
//position = scriptedMove.positions[scriptedMove.index];
//this->angle = scriptedMove.angles[scriptedMove.index];
scriptedMove.index++;
return;
}
//scriptedMove.index++;
//return;
//}
}

View File

@@ -1,298 +0,0 @@
#include <types/vector.h>
#pragma region vector2
bool vector2::IsWithinMarginOfError(const vector2& rhs, float margin) const
{
return this->distance(rhs) <= margin;
}
bool vector2::operator==(const vector2& rhs) const
{
return this->IsWithinMarginOfError(rhs);
}
bool vector2::operator!=(const vector2& rhs) const
{
return this->IsWithinMarginOfError(rhs) == false;
}
vector2 vector2::min(const vector2& min) const
{
return {
std::min(this->x, min.x),
std::min(this->y, min.y)
};
}
vector2 vector2::max(const vector2& max) const
{
return {
std::max(this->x, max.x),
std::max(this->y, max.y)
};
}
vector2 vector2::clamp(const vector2& min, const vector2& max) const
{
return {
std::clamp(this->x, min.x, max.x),
std::clamp(this->y, min.y, max.y)
};
}
float vector2::distance(const vector2& to) const
{
return ((*this)-to).magnitude();
}
float vector2::length() const
{
return std::sqrt(lengthSquared());
}
float vector2::lengthSquared() const
{
return (x*x + y*y);
}
float vector2::magnitude() const
{
return std::sqrt(lengthSquared());
}
float vector2::dot(const vector2& rhs) const
{
auto a = this->normalize();
auto b = rhs.normalize();
return a.x * b.x + a.y * b.y;
}
vector2 vector2::project(const vector2& rhs) const
{
float scalar = this->dot(rhs) / (rhs.magnitude()*rhs.magnitude());
return rhs * scalar;
}
vector2 vector2::normalize() const
{
if (length() > 0)
return {
x / length(),
y / length()
};
else
return {0,0};
}
vector2 vector2::lerp(const vector2& rhs, float alpha) const
{
return this->operator*(1.0f - alpha) + (rhs * alpha);
}
vector2 vector2::operator+(const vector2& rhs) const
{
return {this->x + rhs.x, this->y + rhs.y};
}
vector2 vector2::operator-(const vector2& rhs) const
{
return {this->x - rhs.x, this->y - rhs.y};
}
vector2 vector2::operator*(float rhs) const
{
return {
this->x * rhs,
this->y * rhs
};
}
vector2 vector2::operator/(float rhs) const
{
return {
this->x / rhs,
this->y / rhs
};
}
vector2 vector2::operator-() const
{
return {-x, -y};
}
#pragma endregion
#pragma region vector3
vector3 vector3::operator+(const vector3& rhs) const
{
return {this->x + rhs.x, this->y + rhs.y, this->z + rhs.z};
}
vector3 vector3::operator-(const vector3& rhs) const
{
return {
this->x- rhs.x,
this->y-rhs.y,
this->z-rhs.z
};
}
vector3 vector3::operator*(float rhs) const
{
return {
this->x * rhs,
this->y * rhs,
this->z * rhs
};
}
vector3 vector3::operator/(float rhs) const
{
return {
this->x / rhs,
this->y / rhs,
this->z / rhs
};
}
vector3 vector3::operator-() const
{
return {-x, -y, -z};
}
vector3::vector3(const vector3& rhs)
{
this->x = rhs.x;
this->y = rhs.y;
this->z = rhs.z;
}
vector3& vector3::operator=(const vector3& rhs)
{
this->x = rhs.x;
this->y = rhs.y;
this->z = rhs.z;
return *this;
}
float vector3::operator[](std::size_t index)
{
assert(index < 3);
if (index==0) return x;
if (index==1) return y;
if (index==2) return z;
return 0;
}
bool vector3::IsWithinMarginOfError(const vector3& rhs, float margin) const
{
return this->distance(rhs) <= margin;
}
bool vector3::operator==(const vector3& rhs) const
{
return this->IsWithinMarginOfError(rhs);
}
bool vector3::operator!=(const vector3& rhs) const
{
return this->IsWithinMarginOfError(rhs) == false;
}
vector3 vector3::min(const vector3& min) const
{
return {
std::min(this->x, min.x),
std::min(this->y, min.y),
std::min(this->z, min.z)
};
}
vector3 vector3::max(const vector3& max) const
{
return {
std::max(this->x, max.x),
std::max(this->y, max.y),
std::max(this->z, max.z)
};
}
vector3 vector3::clamp(const vector3& min, const vector3& max) const
{
return {
std::clamp(this->x, min.x, max.x),
std::clamp(this->y, min.y, max.y),
std::clamp(this->z, min.z, max.z)
};
}
float vector3::distance(const vector3& to) const
{
return ((*this)-to).magnitude();
}
float vector3::length() const
{
return std::sqrt(lengthSquared());
}
float vector3::lengthSquared() const
{
return (x*x + y*y + z*z);
}
float vector3::magnitude() const
{
return std::sqrt(x*x + y*y + z*z);
}
float vector3::dot(const vector3& rhs) const
{
auto a = this->normalize();
auto b = rhs.normalize();
return a.x * b.x +
a.y * b.y +
a.z * b.z;
}
vector3 vector3::project(const vector3& rhs) const
{
float scalar = this->dot(rhs) / (rhs.magnitude()*rhs.magnitude());
return rhs * scalar;
}
vector3 vector3::cross(const vector3& rhs) const
{
return {
this->y * rhs.z - this->z * rhs.y,
this->z * rhs.x - this->x * rhs.z,
this->x * rhs.y - this->y * rhs.x
};
}
vector3 vector3::normalize() const
{
if (length() > 0)
return {
x / length(),
y / length(),
z / length()
};
else
return {0,0,0};
}
vector3 vector3::lerp(const vector3& goal, float alpha) const
{
return this->operator*(1.0f - alpha) + (goal * alpha);
}
#pragma endregion