From 639e1b76083f9064ac4dbaccf5f2d37820ff2a6d Mon Sep 17 00:00:00 2001 From: MrDev023 Date: Sun, 31 Jul 2016 00:41:57 +0200 Subject: [PATCH] Add Math Library --- clean.sh | 1 + src/main.cpp | 20 +--- src/math.cpp | 63 ++++++++++ src/math.h | 243 +++++++++++++++++++++++++++++++++++++++ src/matrix4f.cpp | 222 ++++++++++++++++++++++++++++++++++++ src/quaternion.cpp | 278 +++++++++++++++++++++++++++++++++++++++++++++ src/transform.cpp | 142 +++++++++++++++++++++++ src/vector2f.cpp | 131 +++++++++++++++++++++ src/vector3f.cpp | 227 ++++++++++++++++++++++++++++++++++++ src/vector4f.cpp | 124 ++++++++++++++++++++ 10 files changed, 1437 insertions(+), 14 deletions(-) create mode 100644 src/matrix4f.cpp create mode 100644 src/quaternion.cpp create mode 100644 src/transform.cpp create mode 100644 src/vector2f.cpp create mode 100644 src/vector3f.cpp create mode 100644 src/vector4f.cpp diff --git a/clean.sh b/clean.sh index 43d5a69..741ee46 100644 --- a/clean.sh +++ b/clean.sh @@ -1,4 +1,5 @@ #!/bin/bash +rm -rf bin rm -rf CMakeFiles rm -f CMakeCache.txt rm -f cmake_install.cmake diff --git a/src/main.cpp b/src/main.cpp index fa2e299..bc27acb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,8 @@ #include #include +//43,2ko + void event(SDL_Event e){ } @@ -11,33 +13,23 @@ void event(SDL_Event e){ int main(int argc, char** argv){ Window::initWindow(800,600,"Test"); Audio::initOpenAL(); - float i = 0; - ALuint s = Audio::createSource("a.wav"); - Audio::set3DSource(&s,true); - Audio::playSource(&s); - float x,y,dis = 10.0f; while(!Window::closeRequested){//main loop - x = cosf(i) * dis; - y = sinf(i) * dis; Window::pollEvent(&event); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); - glPointSize(12); glBegin(GL_POINTS); - glColor3f(1,0,0); - glVertex2f(x/dis,y/dis); + glVertex2f(-1,-1); + glVertex2f(-1,1); + glVertex2f(1,-1); + glVertex2f(1,-1); glEnd(); Window::displayUpdate(); - - i+=1.0f/5000.0f; - Audio::setSourcePosition(&s,-x,0.0f,-y); } - Audio::destroySource(&s); Audio::destroyOpenAL(); Window::destroyWindow(); return 0; diff --git a/src/math.cpp b/src/math.cpp index e69de29..bac9bb9 100644 --- a/src/math.cpp +++ b/src/math.cpp @@ -0,0 +1,63 @@ +#include "math.h" + +const float PI = 3.14159265358979323846264338327950288419716939937510582f; + +float lerp(float s,float e,float t){ + return s + (e - s) * t; +} + +float cLerp(float s, float e, float t){ + float t2 = (1 - (float) cos(t * PI)) / 2; + return (s * (1 - t2) + e * t2); +} + +float sLerp(float s, float e, float t){ + float t2 = (1 - (float) sin(t * PI)) / 2; + return (s * (1 - t2) + e * t2); +} + +float bLerp(float c00, float c10, float c01, float c11, float tx, float ty){ + return cLerp(cLerp(c00, c10, tx), cLerp(c01, c11, tx), ty); +} + +float clamp(float min, float max, float value){ + if (value < min)value = min; + if (value > max)value = max; + return value; +} + +float min(float a, float b){ + if(a==b)return a; + return (a < b)?a:b; +} + +float max(float a, float b){ + if(a==b)return a; + return (a > b)?a:b; +} + +int norm(float v){ + return (v>=0)?1:-1; +} + +float abs(float a){ + return (a<0)?-a:a; +} + +float nearest(float a, float b, float v){ + float absA = abs(a); + float absB = abs(b); + float absV = abs(v); + float tempA = abs(absV - absA); + float tempB = abs(absV - absB); + if (tempA < tempB)return a; + return b; +} + +float toRadians(float d){ + return d * 2.0f * PI /360.0f; +} + +float toDegrees(float r){ + return r * 360.0f / (2.0f * PI); +} diff --git a/src/math.h b/src/math.h index 624e12d..c3c55ad 100644 --- a/src/math.h +++ b/src/math.h @@ -1,5 +1,248 @@ #ifndef MATH_H #define MATH_H +#include +#include + +extern const float PI; +float lerp(float,float,float); +float cLerp(float,float,float); +float sLerp(float,float,float); +float bLerp(float,float,float,float,float,float); +float clamp(float,float,float); +float min(float,float); +float max(float,float); +float toRadians(float); +float toDegrees(float); +int norm(float); +float abs(float); +float nearest(float,float,float); + +class Vector4f; +class Vector3f; +class Vector2f; +class Matrix4f; +class Quaternion; +class Transform; + +class Vector4f{ + public: + float x; + float y; + float z; + float w; + + ~Vector4f(); + Vector4f(float,float,float,float); + Vector4f(const Vector4f&); + Vector4f(); + float Sqrt(); + float Magnitude(); + Vector4f Normalize(); + float Max(); + float Min(); + float SquaredDistance(Vector4f v); + float Distance(Vector4f v); + static Vector4f Lerp(Vector4f,Vector4f,float); + static Vector4f CLerp(Vector4f,Vector4f,float); + static Vector4f SLerp(Vector4f,Vector4f,float); + Vector4f Negate(); + Vector4f Add(Vector4f); + Vector4f Sub(Vector4f); + Vector4f Div(Vector4f); + Vector4f Mul(Vector4f); + Vector4f Add(float,float,float,float); + Vector4f Sub(float,float,float,float); + Vector4f Div(float,float,float,float); + Vector4f Mul(float,float,float,float); + Vector4f Add(float); + Vector4f Sub(float); + Vector4f Div(float); + Vector4f Mul(float); + Vector4f Copy(); + bool Equals(Vector4f); +}; + +class Vector3f{ + public: + static Vector3f UP,FRONT,RIGHT; + float x; + float y; + float z; + + ~Vector3f(); + Vector3f(float,float,float); + Vector3f(const Vector3f&); + Vector3f(); + float Sqrt(); + float Magnitude(); + Vector3f Normalize(); + Vector3f GtNorm(Vector3f); + Vector3f CheckNormals(); + Vector3f Cross(Vector3f); + float Dot(Vector3f); + float Max(); + float Min(); + Vector3f Reflect(Vector3f); + Vector3f Refract(Vector3f,float); + static Vector3f Lerp(Vector3f,Vector3f,float); + static Vector3f CLerp(Vector3f,Vector3f,float); + static Vector3f CLerp(Vector3f,Vector3f,float,float,float); + static Vector3f SLerp(Vector3f,Vector3f,float); + Vector3f Negate(); + Vector3f Add(Vector3f); + Vector3f Sub(Vector3f); + Vector3f Div(Vector3f); + Vector3f Mul(Vector3f); + Vector3f Add(float,float,float); + Vector3f Sub(float,float,float); + Vector3f Div(float,float,float); + Vector3f Mul(float,float,float); + Vector3f Add(float); + Vector3f Sub(float); + Vector3f Div(float); + Vector3f Mul(float); + Vector3f Reo(); + Vector3f Abs(); + Vector3f Rotate(Quaternion); + Vector3f Copy(); + bool Equals(Vector3f); +}; + +class Vector2f{ + public: + static Vector2f UP,RIGHT; + float x; + float y; + + ~Vector2f(); + Vector2f(float,float); + Vector2f(const Vector2f&); + Vector2f(); + float Sqrt(); + float Magnitude(); + Vector2f Normalize(); + Vector2f Cross(Vector2f); + float Dot(Vector2f); + float Max(); + float Min(); + Vector2f Reflect(Vector2f); + Vector2f Refract(Vector2f,float); + static Vector2f Lerp(Vector3f,Vector3f,float); + static Vector2f CLerp(Vector3f,Vector3f,float); + static Vector2f SLerp(Vector3f,Vector3f,float); + Vector2f Negate(); + Vector2f Add(Vector2f); + Vector2f Sub(Vector2f); + Vector2f Div(Vector2f); + Vector2f Mul(Vector2f); + Vector2f Add(float,float); + Vector2f Sub(float,float); + Vector2f Div(float,float); + Vector2f Mul(float,float); + Vector2f Add(float); + Vector2f Sub(float); + Vector2f Div(float); + Vector2f Mul(float); + Vector2f Copy(); + bool Equals(Vector2f); +}; + +class Matrix4f{ + public: + float m[4][4]; + + ~Matrix4f(); + Matrix4f(); + Matrix4f(const Matrix4f&); + Matrix4f(float*); + static Matrix4f Identity(); + void SetIdentity(); + Matrix4f Mul(Matrix4f); + static Matrix4f Translate(Vector3f); + static Matrix4f Translate(float,float,float); + static Matrix4f Rotate(float,float,float); + static Matrix4f Rotate(Vector3f,Vector3f,Vector3f); + static Matrix4f Rotate(Vector3f,Vector3f); + static Matrix4f Scale(float,float,float); + static Matrix4f Scale(Vector3f); + static Matrix4f Perspective(float,float,float,float); + static Matrix4f Orthographic(float,float,float,float,float,float); + static Vector3f Transform(Matrix4f,Vector3f); + float* GetComponents(); +}; + +class Quaternion{ + public: + float x,y,z,w; + + ~Quaternion(); + Quaternion(); + Quaternion(const Quaternion&); + Quaternion(float,float,float,float); + Quaternion(Vector3f,float); + Quaternion(const Quaternion&,Vector3f,float); + Quaternion(Vector3f); + Quaternion(Matrix4f); + static Quaternion Euler(float,float,float); + static Quaternion Euler(Vector3f); + static Quaternion LookAt(Vector3f,Vector3f); + static Quaternion CreateFromAxisAngle(Vector3f,float); + float Magnitude(); + Quaternion Normalize(); + Quaternion Conjugate(); + Quaternion Sub(Quaternion); + Quaternion Add(Quaternion); + Quaternion Add(float); + Quaternion Mul(float); + Quaternion Mul(Quaternion); + Quaternion Mul(Vector3f); + float Dot(Quaternion); + Matrix4f ToMatrix(); + Quaternion NLerp(Quaternion,float,bool); + Quaternion SLerp(Quaternion,float,bool); + Vector3f GetForward(); + Vector3f GetBackward(); + Vector3f GetRight(); + Vector3f GetLeft(); + Vector3f GetUp(); + Vector3f GetDown(); +}; + +class Transform{ + public: + Vector3f pos; + Quaternion rot; + Vector3f scale; + Transform *parent; + + ~Transform(); + Transform(); + Transform(Vector3f); + Transform(const Transform&); + Transform(Vector3f,Vector3f); + Transform(Vector3f,Quaternion); + Transform(Vector3f,Quaternion,Vector3f); + Matrix4f ToMatrix(); + void Rotate(Vector3f,float); + void SetParent(Transform*); + void Add(Transform); + Vector3f GetPosition(); + Quaternion GetRotation(); + void LookAt(Vector3f,Vector3f); + Vector3f GetLocalPosition(); + void SetLocalPosition(Vector3f); + Quaternion GetLocalRotation(); + void SetLocalRotation(Quaternion); + Vector3f GetLocalScale(); + void SetLocalScale(Vector3f); + void Translate(Vector3f,float); + Vector3f GetForward(); + Vector3f GetBackward(); + Vector3f GetLeft(); + Vector3f GetRight(); + Vector3f GetUp(); + Vector3f GetDown(); +}; #endif \ No newline at end of file diff --git a/src/matrix4f.cpp b/src/matrix4f.cpp new file mode 100644 index 0000000..c6595bd --- /dev/null +++ b/src/matrix4f.cpp @@ -0,0 +1,222 @@ +#include "math.h" + +Matrix4f::~Matrix4f(){} + +Matrix4f::Matrix4f(){ + for(int i = 0;i < 4;i++){ + for(int j = 0;j < 4;j++){ + if(i == j)m[i][j] = 1; + else m[i][j] = 0; + } + } +} + +Matrix4f::Matrix4f(const Matrix4f& ma){ + for(int i = 0;i < 4;i++){ + for(int j = 0;j < 4;j++){ + m[i][j] = ma.m[i][j]; + } + } +} + +Matrix4f::Matrix4f(float* matrix){ + for(int i = 0;i < 4;i++){ + for(int j = 0;j < 4;j++){ + m[i][j] = matrix[i*4+j]; + } + } +} + +Matrix4f Matrix4f::Identity(){ + return Matrix4f(); +} + +void Matrix4f::SetIdentity(){ + for(int i = 0;i < 4;i++){ + for(int j = 0;j < 4;j++){ + if(i == j)m[i][j] = 1; + else m[i][j] = 0; + } + } +} + +Matrix4f Matrix4f::Mul(Matrix4f ma){ + Matrix4f result = Matrix4f(); + + for (int x = 0; x < 4; x++) { + for (int y = 0; y < 4; y++) { + result.m[x][y] = (m[x][0] * ma.m[0][y]) + + (m[x][1] * ma.m[1][y]) + + (m[x][2] * ma.m[2][y]) + + (m[x][3] * ma.m[3][y]); + } + } + + return result; +} + +Matrix4f Matrix4f::Translate(Vector3f pos){ + Matrix4f result = Identity(); + + result.m[0][3] = pos.x; + result.m[1][3] = pos.y; + result.m[2][3] = pos.z; + + return result; +} + +Matrix4f Matrix4f::Translate(float x,float y,float z){ + Matrix4f result = Identity(); + + result.m[0][3] = x; + result.m[1][3] = y; + result.m[2][3] = z; + + return result; +} + +Matrix4f Matrix4f::Rotate(float x,float y,float z){ + Matrix4f rx = Identity(); + Matrix4f ry = Identity(); + Matrix4f rz = Identity(); + + x = toRadians(x); + y = toRadians(y); + z = toRadians(z); + + float xcos = cos(x); + float xsin = sin(x); + + float ycos = cos(y); + float ysin = sin(y); + + float zcos = cos(z); + float zsin = sin(z); + + rx.m[1][1] = xcos; + rx.m[1][2] = -xsin; + rx.m[2][1] = xsin; + rx.m[2][2] = xcos; + + ry.m[0][0] = ycos; + ry.m[0][2] = -ysin; + ry.m[2][0] = ysin; + ry.m[2][2] = ycos; + + rz.m[0][0] = zcos; + rz.m[0][1] = -zsin; + rz.m[1][0] = zsin; + rz.m[1][1] = zcos; + + return rz.Mul(ry.Mul(rx)); +} + +Matrix4f Matrix4f::Rotate(Vector3f forward,Vector3f up,Vector3f right){ + Matrix4f result = Identity(); + + Vector3f f = Vector3f(forward).Normalize(); + Vector3f r = Vector3f(right).Normalize(); + Vector3f u = Vector3f(up).Normalize(); + + result.m[0][0] = r.x; + result.m[0][1] = r.y; + result.m[0][2] = r.z; + + result.m[1][0] = u.x; + result.m[1][1] = u.y; + result.m[1][2] = u.z; + + result.m[2][0] = f.x; + result.m[2][1] = f.y; + result.m[2][2] = f.z; + + return result; +} + +Matrix4f Matrix4f::Rotate(Vector3f forward,Vector3f up){ + Matrix4f ma = Identity(); + + Vector3f f = Vector3f(forward).Normalize(); + Vector3f r = Vector3f(up).Normalize(); + r = r.Cross(f); + Vector3f u = f.Cross(r); + + ma.m[0][0] = r.x; + ma.m[0][1] = r.y; + ma.m[0][2] = r.z; + + ma.m[1][0] = u.x; + ma.m[1][1] = u.y; + ma.m[1][2] = u.z; + + ma.m[2][0] = f.x; + ma.m[2][1] = f.y; + ma.m[2][2] = f.z; + + return ma; +} + +Matrix4f Matrix4f::Scale(float x,float y,float z){ + Matrix4f result = Identity(); + + result.m[0][0] = x; + result.m[1][1] = y; + result.m[2][2] = z; + + return result; +} + +Matrix4f Matrix4f::Scale(Vector3f vec){ + return Scale(vec.x, vec.y, vec.z); +} + +Matrix4f Matrix4f::Perspective(float fov, float aspect, float zNear, float zFar){ + Matrix4f result = Identity(); + + float FOV = (float) tan(toRadians(fov / 2)); + float dist = zNear - zFar; + + result.m[0][0] = 1.0f / (FOV * aspect); + result.m[1][1] = 1.0f / FOV; + + result.m[2][2] = (-zNear - zFar) / dist; + result.m[2][3] = 2 * zFar * zNear / dist; + + result.m[3][2] = 1; + result.m[3][3] = 0; + + return result; +} + +Matrix4f Matrix4f::Orthographic(float right, float left, float top, float bottom, float zNear, float zFar){ + Matrix4f ma = Identity(); + + ma.m[0][0] = 2/(right - left); + ma.m[0][3] = -(right + left) / (right - left); + + ma.m[1][1] = 2/(top - bottom); + ma.m[1][3] = -(top + bottom) / (top - bottom); + + ma.m[2][2] = -2/(zFar - zNear); + ma.m[2][3] = -(zFar + zNear) / (zFar - zNear); + + return ma; +} + +Vector3f Matrix4f::Transform(Matrix4f ma,Vector3f v){ + return Vector3f( + ma.m[0][0] * v.x + ma.m[0][1] * v.y + ma.m[0][2] * v.z + ma.m[0][3], + ma.m[1][0] * v.x + ma.m[1][1] * v.y + ma.m[1][2] * v.z + ma.m[1][3], + ma.m[2][0] * v.x + ma.m[2][1] * v.y + ma.m[2][2] * v.z + ma.m[2][3] + ); +} + +float* Matrix4f::GetComponents(){ + float* result = new float[16]; + for (int x = 0; x < 4; x++){ + for (int y = 0; y < 4; y++){ + result[x + y * 4] = m[x][y]; + } + } + return result; +} diff --git a/src/quaternion.cpp b/src/quaternion.cpp new file mode 100644 index 0000000..4bf4aa8 --- /dev/null +++ b/src/quaternion.cpp @@ -0,0 +1,278 @@ +#include "math.h" + +Quaternion::~Quaternion(){} + +Quaternion::Quaternion(){ + this->x = 0; + this->y = 0; + this->z = 0; + this->w = 1; +} + +Quaternion::Quaternion(const Quaternion& v){ + this->x = v.x; + this->y = v.y; + this->z = v.z; + this->w = v.w; +} + +Quaternion::Quaternion(float x, float y, float z, float w){ + this->x = x; + this->y = y; + this->z = z; + this->w = w; +} + +Quaternion::Quaternion(Vector3f axis,float angle){ + float s = (float) sin(angle / 2); + float c = (float) cos(angle / 2); + + this->x = axis.x * s; + this->y = axis.y * s; + this->z = axis.z * s; + this->w = c; +} + +Quaternion::Quaternion(const Quaternion& q,Vector3f axis,float angle){ + float s = (float) sin(angle / 2); + float c = (float) cos(angle / 2); + + this->x = q.x + (axis.x * s); + this->y = q.y + (axis.y * s); + this->z = q.z + (axis.z * s); + this->w = q.w + (c); +} + +Quaternion::Quaternion(Vector3f euler){ + float c1 = (float) cos(euler.x / 2); + float s1 = (float) sin(euler.x / 2); + + float c2 = (float) cos(euler.y / 2); + float s2 = (float) sin(euler.y / 2); + + float c3 = (float) cos(euler.z / 2); + float s3 = (float) sin(euler.z / 2); + + float c1c2 = c1 * c2; + float s1s2 = s1 * s2; + + x = c1c2 * s3 + s1s2 * c3; + y = s1 * c2 * c3 + c1 * s2 * s3; + z = c1 * s2 * c3 - s1 * c2 * s3; + w = c1c2 * c3 - s1s2 * s3; +} + +Quaternion::Quaternion(Matrix4f rot){ + float trace = rot.m[0][0] + rot.m[1][1] + rot.m[2][2]; + if (trace > 0) { + float s = 0.5f / (float) sqrt(trace + 1.0f); + w = 0.25f / s; + x = (rot.m[1][2] - rot.m[2][1]) * s; + y = (rot.m[2][0] - rot.m[0][2]) * s; + z = (rot.m[0][1] - rot.m[1][0]) * s; + } else { + if (rot.m[0][0] > rot.m[1][1] && rot.m[0][0] > rot.m[2][2]) { + float s = 2.0f * (float) sqrt(1.0f + rot.m[0][0] - rot.m[1][1] - rot.m[2][2]); + w = (rot.m[1][2] - rot.m[2][1]) / s; + x = 0.25f * s; + y = (rot.m[1][0] + rot.m[0][1]) / s; + z = (rot.m[2][0] + rot.m[0][2]) / s; + } else if (rot.m[1][1] > rot.m[2][2]) { + float s = 2.0f * (float) sqrt(1.0f + rot.m[1][1] - rot.m[0][0] - rot.m[2][2]); + w = (rot.m[2][0] - rot.m[0][2]) / s; + x = (rot.m[1][0] + rot.m[0][1]) / s; + y = 0.25f * s; + z = (rot.m[2][1] + rot.m[1][2]) / s; + } else { + float s = 2.0f * (float) sqrt(1.0f + rot.m[2][2] - rot.m[0][0] - rot.m[1][1]); + w = (rot.m[0][1] - rot.m[1][0]) / s; + x = (rot.m[2][0] + rot.m[0][2]) / s; + y = (rot.m[1][2] + rot.m[2][1]) / s; + z = 0.25f * s; + } + } + float length = (float) sqrt(x * x + y * y + z * z + w * w); + x /= length; + y /= length; + z /= length; + w /= length; +} + +Quaternion Quaternion::Euler(float yaw, float pitch, float roll){ + float angle; + float sinRoll, sinPitch, sinYaw, cosRoll, cosPitch, cosYaw; + + angle = pitch * 0.5f; + sinPitch = sin(angle); + cosPitch = cos(angle); + + angle = roll * 0.5f; + sinRoll = sin(angle); + cosRoll = cos(angle); + + angle = yaw * 0.5f; + sinYaw = sin(angle); + cosYaw = cos(angle); + + float cosRollXcosPitch = cosRoll * cosPitch; + float sinRollXsinPitch = sinRoll * sinPitch; + float cosRollXsinPitch = cosRoll * sinPitch; + float sinRollXcosPitch = sinRoll * cosPitch; + + Quaternion r = Quaternion(); + + r.w = (cosRollXcosPitch * cosYaw - sinRollXsinPitch * sinYaw); + r.x = (cosRollXcosPitch * sinYaw + sinRollXsinPitch * cosYaw); + r.y = (sinRollXcosPitch * cosYaw + cosRollXsinPitch * sinYaw); + r.z = (cosRollXsinPitch * cosYaw - sinRollXcosPitch * sinYaw); + + return r.Normalize(); +} + +Quaternion Quaternion::Euler(Vector3f euler){ + return Quaternion::Euler(euler.x, euler.z, euler.y); +} + +Quaternion Quaternion::LookAt(Vector3f sourcePoint, Vector3f destPoint){ + Vector3f forwardVector = Vector3f(destPoint).Sub(sourcePoint).Normalize(); + + float dot = Vector3f(0, 0, 1).Dot(forwardVector); + + if (abs(dot - (-1.0f)) < 0.000001f){ + return Quaternion(Vector3f::UP.x, Vector3f::UP.y, Vector3f::UP.z, PI); + } + if (abs(dot - (1.0f)) < 0.000001f){ + return Quaternion(); + } + + float rotAngle = acos(dot); + Vector3f rotAxis = Vector3f(0, 0, 1).Cross(forwardVector).Normalize(); + return CreateFromAxisAngle(rotAxis, rotAngle); +} + +Quaternion Quaternion::CreateFromAxisAngle(Vector3f axis, float angle){ + float halfAngle = angle * 0.5f; + float s = sin(halfAngle); + Quaternion q = Quaternion(); + q.x = axis.x * s; + q.y = axis.y * s; + q.z = axis.z * s; + q.w = cos(halfAngle); + return q; +} + +float Quaternion::Magnitude(){ + return (float)sqrt(x * x + y * y + z * z + w * w); +} + +Quaternion Quaternion::Normalize(){ + float mag = Magnitude(); + return Quaternion(x / mag, y / mag, z / mag, w / mag); +} + +Quaternion Quaternion::Conjugate(){ + return Quaternion(-x, -y, -z, w); +} + +Quaternion Quaternion::Sub(Quaternion value){ + return Quaternion(x - value.x, y - value.y, z - value.z, w - value.w); +} + +Quaternion Quaternion::Add(Quaternion value){ + return Quaternion(x + value.x, y + value.y, z + value.z, w + value.w); +} + +Quaternion Quaternion::Add(float value){ + return Quaternion(x + value, y + value, z + value, w + value); +} + +Quaternion Quaternion::Mul(float value){ + return Quaternion(x * value, y * value, z * value, w * value); +} + +Quaternion Quaternion::Mul(Quaternion r){ + float nw = w * r.w - x * r.x - y * r.y - z * r.z; + float nx = x * r.w + w * r.x + y * r.z - z * r.y; + float ny = y * r.w + w * r.y + z * r.x - x * r.z; + float nz = z * r.w + w * r.z + x * r.y - y * r.x; + + return Quaternion(nx, ny, nz, nw); +} + +Quaternion Quaternion::Mul(Vector3f r){ + float nw = -x * r.x - y * r.y - z * r.z; + float nx = w * r.x + y * r.z - z * r.y; + float ny = w * r.y + z * r.x - x * r.z; + float nz = w * r.z + x * r.y - y * r.x; + + return Quaternion(nx, ny, nz, nw); +} + +float Quaternion::Dot(Quaternion r){ + return x * r.x + y * r.y + z * r.z + w * r.w; +} + +Matrix4f Quaternion::ToMatrix(){ + Vector3f forward = Vector3f(2.0f * (x * z - w * y), 2.0f * (y * z + w * x), 1.0f - 2.0f * (x * x + y * y)); + Vector3f up = Vector3f(2.0f * (x * y + w * z), 1.0f - 2.0f * (x * x + z * z), 2.0f * (y * z - w * x)); + Vector3f right = Vector3f(1.0f - 2.0f * (y * y + z * z), 2.0f * (x * y - w * z), 2.0f * (x * z + w * y)); + + return Matrix4f::Rotate(forward, up, right); +} + +Quaternion Quaternion::NLerp(Quaternion dest, float lerpFactor, bool shortest){ + Quaternion correctedDest = dest; + + if(shortest && this->Dot(dest) < 0) + correctedDest = Quaternion(-dest.x, -dest.y, -dest.z, -dest.w); + + return correctedDest.Sub(*this).Mul(lerpFactor).Add(*this).Normalize(); +} + +Quaternion Quaternion::SLerp(Quaternion dest, float lerpFactor, bool shortest){ + const float EPSILON = 1e3f; + + float c = this->Dot(dest); + Quaternion correctedDest = dest; + + if(shortest && c < 0){ + c = -c; + correctedDest = Quaternion(-dest.x, -dest.y, -dest.z, -dest.w); + } + + if(abs(c) >= 1 - EPSILON) + return NLerp(correctedDest, lerpFactor, false); + + float s = (float)sqrt(1.0f - c * c); + float angle = (float)atan2(s, c); + float invs = 1.0f/s; + + float srcFactor = (float)sin((1.0f - lerpFactor) * angle) * invs; + float destFactor = (float)sin((lerpFactor) * angle) * invs; + + return this->Mul(srcFactor).Add(correctedDest.Mul(destFactor)); +} + +Vector3f Quaternion::GetForward(){ + return Vector3f(0, 0, 1).Rotate(*this); +} + +Vector3f Quaternion::GetBackward(){ + return Vector3f(0, 0, -1).Rotate(*this); +} + +Vector3f Quaternion::GetRight(){ + return Vector3f(1, 0, 0).Rotate(*this); +} + +Vector3f Quaternion::GetLeft(){ + return Vector3f(-1, 0, 0).Rotate(*this); +} + +Vector3f Quaternion::GetUp(){ + return Vector3f(0, 1, 0).Rotate(*this); +} + +Vector3f Quaternion::GetDown(){ + return Vector3f(0, -1, 0).Rotate(*this); +} diff --git a/src/transform.cpp b/src/transform.cpp new file mode 100644 index 0000000..0254c99 --- /dev/null +++ b/src/transform.cpp @@ -0,0 +1,142 @@ +#include "math.h" + +Transform::~Transform(){ + +} + +Transform::Transform(){ + this->pos = Vector3f(0,0,0); + this->rot = Quaternion(); + this->scale = Vector3f(1,1,1); +} + +Transform::Transform(Vector3f pos){ + this->pos = pos; + this->rot = Quaternion(); + this->scale = Vector3f(1,1,1); +} + +Transform::Transform(const Transform& transform){ + this->pos = Vector3f(transform.pos); + this->rot = Quaternion(transform.rot); + this->scale = Vector3f(1,1,1); +} + +Transform::Transform(Vector3f pos,Vector3f scale){ + this->pos = pos; + this->rot = Quaternion(); + this->scale = scale; +} + +Transform::Transform(Vector3f pos,Quaternion rot){ + this->pos = pos; + this->rot = rot; + this->scale = Vector3f(1,1,1); +} + +Transform::Transform(Vector3f pos,Quaternion rot,Vector3f size){ + this->pos = pos; + this->rot = rot; + this->scale = size; +} + +Matrix4f Transform::ToMatrix(){ + Matrix4f translationMatrix = Matrix4f::Translate(pos.x, pos.y, pos.z); + Matrix4f rotationMatrix = rot.ToMatrix(); + Matrix4f scaleMatrix = Matrix4f::Scale(scale.x, scale.y, scale.z); + Matrix4f parentMatrix = Matrix4f::Identity(); + if (parent != NULL) { + parentMatrix = parent->ToMatrix(); + } + + Matrix4f transformationMatrix = parentMatrix.Mul(translationMatrix.Mul(rotationMatrix.Mul(scaleMatrix))); + + return transformationMatrix; +} + +void Transform::Rotate(Vector3f axis,float angle){ + rot = Quaternion(axis, (float) toRadians(angle)).Mul(rot).Normalize(); +} + +void Transform::SetParent(Transform* parent){ + this->parent = parent; +} + +void Transform::Add(Transform transform){ + pos.Add(transform.pos); + rot.Add(transform.rot); + scale.Add(transform.scale); +} + +Vector3f Transform::GetPosition(){ + if (parent == NULL) { + return pos; + } + return Matrix4f::Transform(parent->ToMatrix(), pos); +} + +Quaternion Transform::GetRotation(){ + Quaternion parentRotation = Quaternion(); + + if (parent != NULL) { + parentRotation = parent->GetRotation(); + } + + return parentRotation.Mul(rot); +} + +void Transform::LookAt(Vector3f source,Vector3f look){ + rot = Quaternion::LookAt(source, look); +} + +Vector3f Transform::GetLocalPosition(){ + return this->pos; +} + +void Transform::SetLocalPosition(Vector3f pos){ + this->pos = pos; +} + +Quaternion Transform::GetLocalRotation(){ + return this->rot; +} + +void Transform::SetLocalRotation(Quaternion r){ + this->rot = r; +} + +Vector3f Transform::GetLocalScale(){ + return this->scale; +} + +void Transform::SetLocalScale(Vector3f scale){ + this->scale = scale; +} + +void Transform::Translate(Vector3f axis,float speed){ + pos.Add(axis.Mul(speed)); +} + +Vector3f Transform::GetForward(){ + return rot.GetForward(); +} + +Vector3f Transform::GetBackward(){ + return rot.GetBackward(); +} + +Vector3f Transform::GetLeft(){ + return rot.GetLeft(); +} + +Vector3f Transform::GetRight(){ + return rot.GetRight(); +} + +Vector3f Transform::GetUp(){ + return rot.GetUp(); +} + +Vector3f Transform::GetDown(){ + return rot.GetDown(); +} diff --git a/src/vector2f.cpp b/src/vector2f.cpp new file mode 100644 index 0000000..033c98d --- /dev/null +++ b/src/vector2f.cpp @@ -0,0 +1,131 @@ +#include "math.h" + +Vector2f Vector2f::UP(0,1); +Vector2f Vector2f::RIGHT(1,0); + +Vector2f::~Vector2f(){} + +Vector2f::Vector2f(float vx,float vy) : x(vx),y(vy){} + +Vector2f::Vector2f(const Vector2f& vec) : x(vec.x),y(vec.y){} + +Vector2f::Vector2f() : x(0),y(0){} + +float Vector2f::Sqrt(){ + return x * x + y * y; +} + +float Vector2f::Magnitude(){ + return sqrt(Sqrt()); +} + +Vector2f Vector2f::Normalize(){ + return Vector2f(x/Magnitude(),y/Magnitude()); +} + +Vector2f Vector2f::Cross(Vector2f v){ + return Vector2f(v.x,-v.y); +} + +float Vector2f::Dot(Vector2f v){ + return x * v.x + y * v.y; +} + +float Vector2f::Max(){ + if(x==y)return x; + return (x > y)?x:y; +} + +float Vector2f::Min(){ + if(x==y)return x; + return (x < y)?x:y; +} + +Vector2f Vector2f::Reflect(Vector2f v){ + return this->Sub(v.Mul(this->Dot(v) * 2.0f)); +} + +Vector2f Vector2f::Refract(Vector2f v,float a){ + float dot = v.Dot(*this); + float k = 1.f - a * a * (1.f - dot * dot); + Vector2f res = v.Mul(this->Mul(a).Sub((float)(a * dot + sqrt(k)))); + return (k < 0.f)?Vector2f():res; +} + +Vector2f Vector2f::Lerp(Vector3f v,Vector3f v2,float t){ + float x = lerp(v.x,v2.x,t); + float y = lerp(v.y,v2.y,t); + return Vector2f(x,y); +} + +Vector2f Vector2f::CLerp(Vector3f v,Vector3f v2,float t){ + float x = cLerp(v.x,v2.x,t); + float y = cLerp(v.y,v2.y,t); + return Vector2f(x,y); +} + +Vector2f Vector2f::SLerp(Vector3f v,Vector3f v2,float t){ + float x = sLerp(v.x,v2.x,t); + float y = sLerp(v.y,v2.y,t); + return Vector2f(x,y); +} + +Vector2f Vector2f::Negate(){ + return Vector2f(-x,-y); +} + +Vector2f Vector2f::Add(Vector2f v){ + return Vector2f(x + v.x,y + v.y); +} + +Vector2f Vector2f::Sub(Vector2f v){ + return Vector2f(x - v.x,y - v.y); +} + +Vector2f Vector2f::Div(Vector2f v){ + return Vector2f(x / v.x,y / v.y); +} + +Vector2f Vector2f::Mul(Vector2f v){ + return Vector2f(x * v.x,y * v.y); +} + +Vector2f Vector2f::Add(float a,float b){ + return Vector2f(x+a,y+b); +} + +Vector2f Vector2f::Sub(float a,float b){ + return Vector2f(x-a,y-b); +} + +Vector2f Vector2f::Div(float a,float b){ + return Vector2f(x/a,y/b); +} + +Vector2f Vector2f::Mul(float a,float b){ + return Vector2f(x*a,y*b); +} + +Vector2f Vector2f::Add(float a){ + return Vector2f(x+a,y+a); +} + +Vector2f Vector2f::Sub(float a){ + return Vector2f(x-a,y-a); +} + +Vector2f Vector2f::Div(float a){ + return Vector2f(x/a,y/a); +} + +Vector2f Vector2f::Mul(float a){ + return Vector2f(x*a,y*a); +} + +Vector2f Vector2f::Copy(){ + return Vector2f(x,y); +} + +bool Vector2f::Equals(Vector2f v){ + return x == v.x && y == v.y; +} diff --git a/src/vector3f.cpp b/src/vector3f.cpp new file mode 100644 index 0000000..a832d09 --- /dev/null +++ b/src/vector3f.cpp @@ -0,0 +1,227 @@ +#include "math.h" + +Vector3f Vector3f::UP(0,1,0); +Vector3f Vector3f::FRONT(0,0,1); +Vector3f Vector3f::RIGHT(1,0,0); + +Vector3f::~Vector3f(){} + +Vector3f::Vector3f(float vx,float vy,float vz) : x(vx),y(vy),z(vz){} + +Vector3f::Vector3f(const Vector3f& vec) : x(vec.x),y(vec.y),z(vec.z){} + +Vector3f::Vector3f() : x(0),y(0),z(0){} + +float Vector3f::Sqrt(){ + return x * x + y * y + z * z; +} + +float Vector3f::Magnitude(){ + return sqrt(Sqrt()); +} + +Vector3f Vector3f::Normalize(){ + return Vector3f(x/Magnitude(),y/Magnitude(),z/Magnitude()); +} + +Vector3f Vector3f::GtNorm(Vector3f ref){ + Vector3f result = Vector3f(); + Vector3f d = Vector3f(x - ref.x, y - ref.y, z - ref.z); + float abx = abs(d.x); + float aby = abs(d.y); + float abz = abs(d.z); + float good = max(max(abx, aby), abz); + if (abx == good) + { + result.Add(1.0f, 0.0f, 0.0f); + if (d.x < 0) + result.x *= -1; + } + if (aby == good) + { + result.Add(0.0f, 1.0f, 0.0f); + if (d.y < 0) + result.y *= -1; + } + if (abz == good) + { + result.Add(0.0f, 0.0f, 1.0f); + if (d.z < 0) + result.z *= -1; + } + + return result; +} + +Vector3f Vector3f::CheckNormals(){ + float m = max(max(x, y), z); + float mi = min(min(x, y), z); + + float absMax = abs(m - 1); + float absMin = abs(mi); + + float v = 0; + if (absMax > absMin) v = mi; + else v = m; + int rv = 1; + + if (v < 0.5f) rv = -1; + + return Vector3f(v == x ? rv : 0, v == y ? rv : 0, v == z ? rv : 0); +} + +Vector3f Vector3f::Cross(Vector3f r){ + float nx = y * r.z - z * r.y; + float ny = z * r.x - x * r.z; + float nz = x * r.y - y * r.x; + return Vector3f(nx, ny, nz); +} + +float Vector3f::Dot(Vector3f r){ + return x * r.x + y * r.y + z * r.z; +} + +float Vector3f::Max(){ + if(x==y && y==z)return x; + return (x > y)?((x>z)?x:z):y; +} + +float Vector3f::Min(){ + if(x==y && y==z)return x; + return (x < y)?((xMul(a).Sub((float)(a * dot + sqrt(k)))); + return (k < 0.f)?Vector3f():res; +} + +Vector3f Vector3f::Lerp(Vector3f a,Vector3f b,float t){ + float x = lerp(a.x, b.x, t); + float y = lerp(a.y, b.y, t); + float z = lerp(a.z, b.z, t); + return Vector3f(x,y,z); +} + +Vector3f Vector3f::CLerp(Vector3f a,Vector3f b,float t){ + float x = cLerp(a.x, b.x, t); + float y = cLerp(a.y, b.y, t); + float z = cLerp(a.z, b.z, t); + return Vector3f(x,y,z); +} + +Vector3f Vector3f::CLerp(Vector3f a, Vector3f b, float t1, float t2, float t3) { + float ft1 = (float) (t1 * PI); + float f1 = (float) ((1.f - cos(ft1)) * 0.5f); + float ft2 = (float) (t2 * PI); + float f2 = (float) ((1.f - cos(ft2)) * 0.5f); + float ft3 = (float) (t3 * PI); + float f3 = (float) ((1.f - cos(ft3)) * 0.5f); + + float x = a.x * (1.f - f1) + b.x * f1; + float y = a.y * (1.f - f2) + b.y * f2; + float z = a.z * (1.f - f3) + b.z * f3; + + return Vector3f(x, y, z); +} + +Vector3f Vector3f::SLerp(Vector3f a,Vector3f b,float t){ + float x = sLerp(a.x, b.x, t); + float y = sLerp(a.y, b.y, t); + float z = sLerp(a.z, b.z, t); + return Vector3f(x,y,z); +} + +Vector3f Vector3f::Negate(){ + return Vector3f(-x,-y,-z); +} + +Vector3f Vector3f::Add(Vector3f v){ + return Vector3f(x + v.x,y + v.y,z + v.z); +} + +Vector3f Vector3f::Sub(Vector3f v){ + return Vector3f(x - v.x,y - v.y,z - v.z); +} + +Vector3f Vector3f::Div(Vector3f v){ + return Vector3f(x / v.x,y / v.y,z / v.z); +} + +Vector3f Vector3f::Mul(Vector3f v){ + return Vector3f(x * v.x,y * v.y,z * v.z); +} + +Vector3f Vector3f::Add(float a,float b,float c){ + return Vector3f(x+a,y+b,z+c); +} + +Vector3f Vector3f::Sub(float a,float b,float c){ + return Vector3f(x-a,y-b,z-c); +} + +Vector3f Vector3f::Div(float a,float b,float c){ + return Vector3f(x/a,y/b,z/c); +} + +Vector3f Vector3f::Mul(float a,float b,float c){ + return Vector3f(x*a,y*b,z*c); +} + +Vector3f Vector3f::Add(float a){ + return Vector3f(x+a,y+a,z+a); +} + +Vector3f Vector3f::Sub(float a){ + return Vector3f(x-a,y-a,y-a); +} + +Vector3f Vector3f::Div(float a){ + return Vector3f(x/a,y/a,z/a); +} + +Vector3f Vector3f::Mul(float a){ + return Vector3f(x*a,y*a,z*a); +} + +Vector3f Vector3f::Reo(){ + Vector3f result = Vector3f(); + + result.x = 1 - x; + result.y = 1 - y; + result.z = 1 - z; + + return result; +} + +Vector3f Vector3f::Abs(){ + float lx = x; + float ly = y; + float lz = z; + if (lx < 0) + lx = -lx; + if (ly < 0) + ly = -ly; + if (lz < 0) + lz = -lz; + return Vector3f(lx,ly,lz); +} + +Vector3f Vector3f::Rotate(Quaternion rot){ + Quaternion w = rot.Mul(*this).Mul(rot.Conjugate()); + return Vector3f(w.x, w.y, w.z); +} + +Vector3f Vector3f::Copy(){ + return Vector3f(x,y,z); +} + +bool Vector3f::Equals(Vector3f v){ + return x == v.x && y == v.y && z == v.z; +} \ No newline at end of file diff --git a/src/vector4f.cpp b/src/vector4f.cpp new file mode 100644 index 0000000..23af77c --- /dev/null +++ b/src/vector4f.cpp @@ -0,0 +1,124 @@ +#include "math.h" + +Vector4f::~Vector4f(){} + +Vector4f::Vector4f(float vx,float vy,float vz,float vw) : x(vx),y(vy),z(vz),w(vw){} + +Vector4f::Vector4f(const Vector4f& vec) : x(vec.x),y(vec.y),z(vec.z),w(vec.w){} + +Vector4f::Vector4f() : x(0),y(0),z(0),w(0){} + +float Vector4f::Sqrt(){ + return x * x + y * y + z * z + w * w; +} + +float Vector4f::Magnitude(){ + return sqrt(Sqrt()); +} + +Vector4f Vector4f::Normalize(){ + return Vector4f(x/Magnitude(),y/Magnitude(),z/Magnitude(),w/Magnitude()); +} + + +float Vector4f::Max(){ + if(x==y && y==z && z==w)return x; + return (x > y)?((x>z)?((x>w)?x:w):z):y; +} + +float Vector4f::Min(){ + if(x==y && y==z && z==w)return x; + return (x < y)?((x