Dqn/dqn_math.cpp

1573 lines
40 KiB
C++
Raw Normal View History

2024-04-18 22:59:11 +10:00
#pragma once
#include "dqn.h"
/*
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// $$\ $$\ $$$$$$\ $$$$$$$$\ $$\ $$\
// $$$\ $$$ |$$ __$$\\__$$ __|$$ | $$ |
// $$$$\ $$$$ |$$ / $$ | $$ | $$ | $$ |
// $$\$$\$$ $$ |$$$$$$$$ | $$ | $$$$$$$$ |
// $$ \$$$ $$ |$$ __$$ | $$ | $$ __$$ |
// $$ |\$ /$$ |$$ | $$ | $$ | $$ | $$ |
// $$ | \_/ $$ |$$ | $$ | $$ | $$ | $$ |
// \__| \__|\__| \__| \__| \__| \__|
//
// dqn_math.cpp
//
////////////////////////////////////////////////////////////////////////////////////////////////////
*/
2025-02-14 00:27:42 +11:00
#if !defined(DN_NO_V2)
// NOTE: [$VEC2] Vector2 ///////////////////////////////////////////////////////////////////////////
2025-02-14 00:27:42 +11:00
// NOTE: DN_V2I32
DN_API bool operator==(DN_V2I32 lhs, DN_V2I32 rhs)
{
2025-02-14 00:27:42 +11:00
bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator!=(DN_V2I32 lhs, DN_V2I32 rhs)
{
2025-02-14 00:27:42 +11:00
bool result = !(lhs == rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator>=(DN_V2I32 lhs, DN_V2I32 rhs)
{
bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator<=(DN_V2I32 lhs, DN_V2I32 rhs)
{
bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator<(DN_V2I32 lhs, DN_V2I32 rhs)
{
bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator>(DN_V2I32 lhs, DN_V2I32 rhs)
{
bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 operator-(DN_V2I32 lhs, DN_V2I32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2I32 result = DN_V2I32_Init2N(lhs.x - rhs.x, lhs.y - rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 operator-(DN_V2I32 lhs)
{
2025-02-14 00:27:42 +11:00
DN_V2I32 result = DN_V2I32_Init2N(-lhs.x, -lhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 operator+(DN_V2I32 lhs, DN_V2I32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2I32 result = DN_V2I32_Init2N(lhs.x + rhs.x, lhs.y + rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 operator*(DN_V2I32 lhs, DN_V2I32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2I32 result = DN_V2I32_Init2N(lhs.x * rhs.x, lhs.y * rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 operator*(DN_V2I32 lhs, DN_F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2I32 result = DN_V2I32_Init2N(lhs.x * rhs, lhs.y * rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 operator*(DN_V2I32 lhs, int32_t rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2I32 result = DN_V2I32_Init2N(lhs.x * rhs, lhs.y * rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 operator/(DN_V2I32 lhs, DN_V2I32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2I32 result = DN_V2I32_Init2N(lhs.x / rhs.x, lhs.y / rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 operator/(DN_V2I32 lhs, DN_F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2I32 result = DN_V2I32_Init2N(lhs.x / rhs, lhs.y / rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 operator/(DN_V2I32 lhs, int32_t rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2I32 result = DN_V2I32_Init2N(lhs.x / rhs, lhs.y / rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 &operator*=(DN_V2I32 &lhs, DN_V2I32 rhs)
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 &operator*=(DN_V2I32 &lhs, DN_F32 rhs)
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 &operator*=(DN_V2I32 &lhs, int32_t rhs)
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 &operator/=(DN_V2I32 &lhs, DN_V2I32 rhs)
{
lhs = lhs / rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 &operator/=(DN_V2I32 &lhs, DN_F32 rhs)
{
lhs = lhs / rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 &operator/=(DN_V2I32 &lhs, int32_t rhs)
{
lhs = lhs / rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 &operator-=(DN_V2I32 &lhs, DN_V2I32 rhs)
{
lhs = lhs - rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 &operator+=(DN_V2I32 &lhs, DN_V2I32 rhs)
{
lhs = lhs + rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 DN_V2I32_Min(DN_V2I32 a, DN_V2I32 b)
{
2025-02-14 00:27:42 +11:00
DN_V2I32 result = DN_V2I32_Init2N(DN_MIN(a.x, b.x), DN_MIN(a.y, b.y));
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 DN_V2I32_Max(DN_V2I32 a, DN_V2I32 b)
{
2025-02-14 00:27:42 +11:00
DN_V2I32 result = DN_V2I32_Init2N(DN_MAX(a.x, b.x), DN_MAX(a.y, b.y));
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2I32 DN_V2I32_Abs(DN_V2I32 a)
{
2025-02-14 00:27:42 +11:00
DN_V2I32 result = DN_V2I32_Init2N(DN_ABS(a.x), DN_ABS(a.y));
return result;
}
2025-02-14 00:27:42 +11:00
// NOTE: DN_V2U16
DN_API bool operator!=(DN_V2U16 lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
bool result = !(lhs == rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator==(DN_V2U16 lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator>=(DN_V2U16 lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator<=(DN_V2U16 lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator<(DN_V2U16 lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator>(DN_V2U16 lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 operator-(DN_V2U16 lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_V2U16 result = DN_V2U16_Init2N(lhs.x - rhs.x, lhs.y - rhs.y);
2023-08-16 21:59:38 +10:00
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 operator+(DN_V2U16 lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_V2U16 result = DN_V2U16_Init2N(lhs.x + rhs.x, lhs.y + rhs.y);
2023-08-16 21:59:38 +10:00
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 operator*(DN_V2U16 lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_V2U16 result = DN_V2U16_Init2N(lhs.x * rhs.x, lhs.y * rhs.y);
2023-08-16 21:59:38 +10:00
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 operator*(DN_V2U16 lhs, DN_F32 rhs)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_V2U16 result = DN_V2U16_Init2N(lhs.x * rhs, lhs.y * rhs);
2023-08-16 21:59:38 +10:00
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 operator*(DN_V2U16 lhs, int32_t rhs)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_V2U16 result = DN_V2U16_Init2N(lhs.x * rhs, lhs.y * rhs);
2023-08-16 21:59:38 +10:00
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 operator/(DN_V2U16 lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_V2U16 result = DN_V2U16_Init2N(lhs.x / rhs.x, lhs.y / rhs.y);
2023-08-16 21:59:38 +10:00
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 operator/(DN_V2U16 lhs, DN_F32 rhs)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_V2U16 result = DN_V2U16_Init2N(lhs.x / rhs, lhs.y / rhs);
2023-08-16 21:59:38 +10:00
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 operator/(DN_V2U16 lhs, int32_t rhs)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_V2U16 result = DN_V2U16_Init2N(lhs.x / rhs, lhs.y / rhs);
2023-08-16 21:59:38 +10:00
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 &operator*=(DN_V2U16 &lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 &operator*=(DN_V2U16 &lhs, DN_F32 rhs)
2023-08-16 21:59:38 +10:00
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 &operator*=(DN_V2U16 &lhs, int32_t rhs)
2023-08-16 21:59:38 +10:00
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 &operator/=(DN_V2U16 &lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
lhs = lhs / rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 &operator/=(DN_V2U16 &lhs, DN_F32 rhs)
2023-08-16 21:59:38 +10:00
{
lhs = lhs / rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 &operator/=(DN_V2U16 &lhs, int32_t rhs)
2023-08-16 21:59:38 +10:00
{
lhs = lhs / rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 &operator-=(DN_V2U16 &lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
lhs = lhs - rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2U16 &operator+=(DN_V2U16 &lhs, DN_V2U16 rhs)
2023-08-16 21:59:38 +10:00
{
lhs = lhs + rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
// NOTE: DN_V2
DN_API bool operator!=(DN_V2F32 lhs, DN_V2F32 rhs)
{
bool result = !(lhs == rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator==(DN_V2F32 lhs, DN_V2F32 rhs)
{
bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator>=(DN_V2F32 lhs, DN_V2F32 rhs)
{
bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator<=(DN_V2F32 lhs, DN_V2F32 rhs)
{
bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator<(DN_V2F32 lhs, DN_V2F32 rhs)
{
bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator>(DN_V2F32 lhs, DN_V2F32 rhs)
{
bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
// NOTE: DN_V2F32 operator- //////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 operator-(DN_V2F32 lhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(-lhs.x, -lhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 operator-(DN_V2F32 lhs, DN_V2F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x - rhs.x, lhs.y - rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 operator-(DN_V2F32 lhs, DN_V2I32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x - rhs.x, lhs.y - rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 operator-(DN_V2F32 lhs, DN_F32 rhs)
2023-08-25 20:35:04 +10:00
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x - rhs, lhs.y - rhs);
2023-08-25 20:35:04 +10:00
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 operator-(DN_V2F32 lhs, int32_t rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x - rhs, lhs.y - rhs);
return result;
}
2025-02-14 00:27:42 +11:00
// NOTE: DN_V2F32 operator+ //////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 operator+(DN_V2F32 lhs, DN_V2F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x + rhs.x, lhs.y + rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 operator+(DN_V2F32 lhs, DN_V2I32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x + rhs.x, lhs.y + rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 operator+(DN_V2F32 lhs, DN_F32 rhs)
2023-08-25 20:35:04 +10:00
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x + rhs, lhs.y + rhs);
2023-08-25 20:35:04 +10:00
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 operator+(DN_V2F32 lhs, int32_t rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x + rhs, lhs.y + rhs);
return result;
}
2025-02-14 00:27:42 +11:00
// NOTE: DN_V2F32 operator* //////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 operator*(DN_V2F32 lhs, DN_V2F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x * rhs.x, lhs.y * rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 operator*(DN_V2F32 lhs, DN_V2I32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x * rhs.x, lhs.y * rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 operator*(DN_V2F32 lhs, DN_F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x * rhs, lhs.y * rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 operator*(DN_V2F32 lhs, int32_t rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x * rhs, lhs.y * rhs);
return result;
}
2025-02-14 00:27:42 +11:00
// NOTE: DN_V2F32 operator/ //////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 operator/(DN_V2F32 lhs, DN_V2F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x / rhs.x, lhs.y / rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 operator/(DN_V2F32 lhs, DN_V2I32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x / rhs.x, lhs.y / rhs.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 operator/(DN_V2F32 lhs, DN_F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x / rhs, lhs.y / rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 operator/(DN_V2F32 lhs, int32_t rhs)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(lhs.x / rhs, lhs.y / rhs);
return result;
}
2025-02-14 00:27:42 +11:00
// NOTE: DN_V2F32 operator*/ /////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, DN_V2F32 rhs)
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, DN_V2I32 rhs)
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, DN_F32 rhs)
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, int32_t rhs)
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
// NOTE: DN_V2F32 operator// /////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, DN_V2F32 rhs)
{
lhs = lhs / rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, DN_V2I32 rhs)
{
lhs = lhs / rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, DN_F32 rhs)
{
lhs = lhs / rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, int32_t rhs)
{
lhs = lhs / rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
// NOTE: DN_V2F32 operator-/ /////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, DN_V2F32 rhs)
{
lhs = lhs - rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, DN_V2I32 rhs)
{
lhs = lhs - rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, DN_F32 rhs)
{
lhs = lhs - rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, int32_t rhs)
{
lhs = lhs - rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
// NOTE: DN_V2F32 operator+/ /////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, DN_V2F32 rhs)
{
lhs = lhs + rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, DN_V2I32 rhs)
{
lhs = lhs + rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, DN_F32 rhs)
{
lhs = lhs + rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, int32_t rhs)
{
lhs = lhs + rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_V2F32_Min(DN_V2F32 a, DN_V2F32 b)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(DN_MIN(a.x, b.x), DN_MIN(a.y, b.y));
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_V2F32_Max(DN_V2F32 a, DN_V2F32 b)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(DN_MAX(a.x, b.x), DN_MAX(a.y, b.y));
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_V2F32_Abs(DN_V2F32 a)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(DN_ABS(a.x), DN_ABS(a.y));
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_F32 DN_V2F32_Dot(DN_V2F32 a, DN_V2F32 b)
{
// NOTE: Scalar projection of B onto A /////////////////////////////////////////////////////////
//
// Scalar projection calculates the signed distance between `b` and `a`
// where `a` is a unit vector then, the dot product calculates the projection
// of `b` onto the infinite line that the direction of `a` represents. This
// calculation is the signed distance.
//
// signed_distance = dot_product(a, b) = (a.x * b.x) + (a.y * b.y)
//
// Y
// ^ b
// | /|
// | / |
// | / |
// | / | Projection
// | / |
// |/ V
// +--->--------> X
// . a .
// . .
// |------| <- Calculated signed distance
//
// The signed-ness of the result indicates the relationship:
//
// Distance <0 means `b` is behind `a`
// Distance >0 means `b` is in-front of `a`
// Distance ==0 means `b` is perpendicular to `a`
//
// If `a` is not normalized then the signed-ness of the result still holds
// however result no longer represents the actual distance between the
// 2 objects. One of the vectors must be normalised (e.g. turned into a unit
// vector).
//
// NOTE: Vector projection /////////////////////////////////////////////////////////////////////
//
// Vector projection calculates the exact X,Y coordinates of where `b` meets
// `a` when it was projected. This is calculated by multipying the
// 'scalar projection' result by the unit vector of `a`
//
// vector_projection = a * signed_distance = a * dot_product(a, b)
2025-02-14 00:27:42 +11:00
DN_F32 result = (a.x * b.x) + (a.y * b.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_F32 DN_V2F32_LengthSq_V2x2(DN_V2F32 lhs, DN_V2F32 rhs)
{
// NOTE: Pythagoras's theorem (a^2 + b^2 = c^2) without the square root
2025-02-14 00:27:42 +11:00
DN_F32 a = rhs.x - lhs.x;
DN_F32 b = rhs.y - lhs.y;
DN_F32 c_squared = DN_SQUARED(a) + DN_SQUARED(b);
DN_F32 result = c_squared;
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_F32 DN_V2F32_Length_V2x2(DN_V2F32 lhs, DN_V2F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_F32 result_squared = DN_V2F32_LengthSq_V2x2(lhs, rhs);
DN_F32 result = DN_SQRTF(result_squared);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_F32 DN_V2F32_LengthSq(DN_V2F32 lhs)
{
// NOTE: Pythagoras's theorem without the square root
2025-02-14 00:27:42 +11:00
DN_F32 c_squared = DN_SQUARED(lhs.x) + DN_SQUARED(lhs.y);
DN_F32 result = c_squared;
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_F32 DN_V2F32_Length(DN_V2F32 lhs)
{
2025-02-14 00:27:42 +11:00
DN_F32 c_squared = DN_V2F32_LengthSq(lhs);
DN_F32 result = DN_SQRTF(c_squared);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_V2F32_Normalise(DN_V2F32 a)
{
2025-02-14 00:27:42 +11:00
DN_F32 length = DN_V2F32_Length(a);
DN_V2F32 result = a / length;
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_V2F32_Perpendicular(DN_V2F32 a)
{
// NOTE: Matrix form of a 2D vector can be defined as
//
// x' = x cos(t) - y sin(t)
// y' = x sin(t) + y cos(t)
//
// Calculate a line perpendicular to a vector means rotating the vector by
// 90 degrees
//
// x' = x cos(90) - y sin(90)
// y' = x sin(90) + y cos(90)
//
// Where `cos(90) = 0` and `sin(90) = 1` then,
//
// x' = -y
// y' = +x
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(-a.y, a.x);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_V2F32_Reflect(DN_V2F32 in, DN_V2F32 surface)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 normal = DN_V2F32_Perpendicular(surface);
DN_V2F32 normal_norm = DN_V2F32_Normalise(normal);
DN_F32 signed_dist = DN_V2F32_Dot(in, normal_norm);
DN_V2F32 result = DN_V2F32_Init2N(in.x, in.y + (-signed_dist * 2.f));
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_F32 DN_V2F32_Area(DN_V2F32 a)
{
2025-02-14 00:27:42 +11:00
DN_F32 result = a.w * a.h;
return result;
}
2025-02-14 00:27:42 +11:00
#endif // !defined(DN_NO_V2)
2025-02-14 00:27:42 +11:00
#if !defined(DN_NO_V3)
// NOTE: [$VEC3] Vector3 ///////////////////////////////////////////////////////////////////////////
2025-02-14 00:27:42 +11:00
DN_API bool operator!=(DN_V3F32 lhs, DN_V3F32 rhs)
{
bool result = !(lhs == rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator==(DN_V3F32 lhs, DN_V3F32 rhs)
{
bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y) && (lhs.z == rhs.z);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator>=(DN_V3F32 lhs, DN_V3F32 rhs)
{
bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y) && (lhs.z >= rhs.z);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator<=(DN_V3F32 lhs, DN_V3F32 rhs)
{
bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y) && (lhs.z <= rhs.z);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator< (DN_V3F32 lhs, DN_V3F32 rhs)
{
bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y) && (lhs.z < rhs.z);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator>(DN_V3F32 lhs, DN_V3F32 rhs)
{
bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y) && (lhs.z > rhs.z);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 operator-(DN_V3F32 lhs, DN_V3F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V3F32 result = DN_V3F32_Init3F32(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 operator-(DN_V3F32 lhs)
{
2025-02-14 00:27:42 +11:00
DN_V3F32 result = DN_V3F32_Init3F32(-lhs.x, -lhs.y, -lhs.z);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 operator+(DN_V3F32 lhs, DN_V3F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V3F32 result = DN_V3F32_Init3F32(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 operator*(DN_V3F32 lhs, DN_V3F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V3F32 result = DN_V3F32_Init3F32(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 operator*(DN_V3F32 lhs, DN_F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V3F32 result = DN_V3F32_Init3F32(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 operator*(DN_V3F32 lhs, int32_t rhs)
{
2025-02-14 00:27:42 +11:00
DN_V3F32 result = DN_V3F32_Init3F32(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 operator/(DN_V3F32 lhs, DN_V3F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V3F32 result = DN_V3F32_Init3F32(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 operator/(DN_V3F32 lhs, DN_F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V3F32 result = DN_V3F32_Init3F32(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 operator/(DN_V3F32 lhs, int32_t rhs)
{
2025-02-14 00:27:42 +11:00
DN_V3F32 result = DN_V3F32_Init3F32(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 &operator*=(DN_V3F32 &lhs, DN_V3F32 rhs)
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 &operator*=(DN_V3F32 &lhs, DN_F32 rhs)
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 &operator*=(DN_V3F32 &lhs, int32_t rhs)
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 &operator/=(DN_V3F32 &lhs, DN_V3F32 rhs)
{
lhs = lhs / rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 &operator/=(DN_V3F32 &lhs, DN_F32 rhs)
{
lhs = lhs / rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 &operator/=(DN_V3F32 &lhs, int32_t rhs)
{
lhs = lhs / rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 &operator-=(DN_V3F32 &lhs, DN_V3F32 rhs)
{
lhs = lhs - rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 &operator+=(DN_V3F32 &lhs, DN_V3F32 rhs)
{
lhs = lhs + rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_F32 DN_V3_LengthSq(DN_V3F32 a)
{
2025-02-14 00:27:42 +11:00
DN_F32 result = DN_SQUARED(a.x) + DN_SQUARED(a.y) + DN_SQUARED(a.z);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_F32 DN_V3_Length(DN_V3F32 a)
{
2025-02-14 00:27:42 +11:00
DN_F32 length_sq = DN_SQUARED(a.x) + DN_SQUARED(a.y) + DN_SQUARED(a.z);
DN_F32 result = DN_SQRTF(length_sq);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V3F32 DN_V3_Normalise(DN_V3F32 a)
{
2025-02-14 00:27:42 +11:00
DN_F32 length = DN_V3_Length(a);
DN_V3F32 result = a / length;
return result;
}
2025-02-14 00:27:42 +11:00
#endif // !defined(DN_NO_V3)
2025-02-14 00:27:42 +11:00
#if !defined(DN_NO_V4)
// NOTE: [$VEC4] Vector4 ///////////////////////////////////////////////////////////////////////////
2025-02-14 00:27:42 +11:00
DN_API bool operator==(DN_V4F32 lhs, DN_V4F32 rhs)
{
2025-02-14 00:27:42 +11:00
bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y) && (lhs.z == rhs.z) && (lhs.w == rhs.w);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator!=(DN_V4F32 lhs, DN_V4F32 rhs)
{
2025-02-14 00:27:42 +11:00
bool result = !(lhs == rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator>=(DN_V4F32 lhs, DN_V4F32 rhs)
{
bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y) && (lhs.z >= rhs.z) && (lhs.w >= rhs.w);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator<=(DN_V4F32 lhs, DN_V4F32 rhs)
{
bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y) && (lhs.z <= rhs.z) && (lhs.w <= rhs.w);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator< (DN_V4F32 lhs, DN_V4F32 rhs)
{
bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y) && (lhs.z < rhs.z) && (lhs.w < rhs.w);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator>(DN_V4F32 lhs, DN_V4F32 rhs)
{
bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y) && (lhs.z > rhs.z) && (lhs.w > rhs.w);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V4F32 operator-(DN_V4F32 lhs, DN_V4F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V4F32 result = DN_V4F32_Init4N(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V4F32 operator-(DN_V4F32 lhs)
{
2025-02-14 00:27:42 +11:00
DN_V4F32 result = DN_V4F32_Init4N(-lhs.x, -lhs.y, -lhs.z, -lhs.w);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V4F32 operator+(DN_V4F32 lhs, DN_V4F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V4F32 result = DN_V4F32_Init4N(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V4F32 operator* (DN_V4F32 lhs, DN_V4F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V4F32 result = DN_V4F32_Init4N(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V4F32 operator*(DN_V4F32 lhs, DN_F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V4F32 result = DN_V4F32_Init4N(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V4F32 operator*(DN_V4F32 lhs, int32_t rhs)
{
2025-02-14 00:27:42 +11:00
DN_V4F32 result = DN_V4F32_Init4N(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V4F32 operator/(DN_V4F32 lhs, DN_F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_V4F32 result = DN_V4F32_Init4N(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V4F32 &operator*=(DN_V4F32 &lhs, DN_V4F32 rhs)
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V4F32 &operator*=(DN_V4F32 &lhs, DN_F32 rhs)
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V4F32 &operator*=(DN_V4F32 &lhs, int32_t rhs)
{
lhs = lhs * rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V4F32 &operator-=(DN_V4F32 &lhs, DN_V4F32 rhs)
{
lhs = lhs - rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V4F32 &operator+=(DN_V4F32 &lhs, DN_V4F32 rhs)
{
lhs = lhs + rhs;
return lhs;
}
2025-02-14 00:27:42 +11:00
DN_API DN_F32 DN_V4F32Dot(DN_V4F32 a, DN_V4F32 b)
{
2025-02-14 00:27:42 +11:00
DN_F32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w);
return result;
}
2025-02-14 00:27:42 +11:00
#endif // !defined(DN_NO_V4)
2025-02-14 00:27:42 +11:00
#if !defined(DN_NO_M4)
// NOTE: [$MAT4] DN_M4 ////////////////////////////////////////////////////////////////////////////
DN_API DN_M4 DN_M4_Identity()
{
2025-02-14 00:27:42 +11:00
DN_M4 result =
{{
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1},
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_ScaleF(DN_F32 x, DN_F32 y, DN_F32 z)
{
2025-02-14 00:27:42 +11:00
DN_M4 result =
{{
{x, 0, 0, 0},
{0, y, 0, 0},
{0, 0, z, 0},
{0, 0, 0, 1},
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_Scale(DN_V3F32 xyz)
{
2025-02-14 00:27:42 +11:00
DN_M4 result =
{{
{xyz.x, 0, 0, 0},
{0, xyz.y, 0, 0},
{0, 0, xyz.z, 0},
{0, 0, 0, 1},
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_TranslateF(DN_F32 x, DN_F32 y, DN_F32 z)
{
2025-02-14 00:27:42 +11:00
DN_M4 result =
{{
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{x, y, z, 1},
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_Translate(DN_V3F32 xyz)
{
2025-02-14 00:27:42 +11:00
DN_M4 result =
{{
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{xyz.x, xyz.y, xyz.z, 1},
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_Transpose(DN_M4 mat)
{
2025-02-14 00:27:42 +11:00
DN_M4 result = {};
for (int col = 0; col < 4; col++)
for (int row = 0; row < 4; row++)
result.columns[col][row] = mat.columns[row][col];
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_Rotate(DN_V3F32 axis01, DN_F32 radians)
{
2025-02-14 00:27:42 +11:00
DN_ASSERTF(DN_ABS(DN_V3_Length(axis01) - 1.f) <= 0.01f,
"Rotation axis must be normalised, length = %f",
2025-02-14 00:27:42 +11:00
DN_V3_Length(axis01));
2025-02-14 00:27:42 +11:00
DN_F32 sin = DN_SINF(radians);
DN_F32 cos = DN_COSF(radians);
DN_F32 one_minus_cos = 1.f - cos;
2025-02-14 00:27:42 +11:00
DN_F32 x = axis01.x;
DN_F32 y = axis01.y;
DN_F32 z = axis01.z;
DN_F32 x2 = DN_SQUARED(x);
DN_F32 y2 = DN_SQUARED(y);
DN_F32 z2 = DN_SQUARED(z);
2025-02-14 00:27:42 +11:00
DN_M4 result =
{{
{cos + x2*one_minus_cos, y*x*one_minus_cos + z*sin, z*x*one_minus_cos - y*sin, 0}, // Col 1
{x*y*one_minus_cos - z*sin, cos + y2*one_minus_cos, z*y*one_minus_cos + x*sin, 0}, // Col 2
{x*z*one_minus_cos + y*sin, y*z*one_minus_cos - x*sin, cos + z2*one_minus_cos, 0}, // Col 3
{0, 0, 0, 1}, // Col 4
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_Orthographic(DN_F32 left, DN_F32 right, DN_F32 bottom, DN_F32 top, DN_F32 z_near, DN_F32 z_far)
{
// NOTE: Here is the matrix in column major for readability. Below it's
// transposed due to how you have to declare column major matrices in C/C++.
//
// m = [2/r-l, 0, 0, -1*(r+l)/(r-l)]
// [0, 2/t-b, 0, 1*(t+b)/(t-b)]
// [0, 0, -2/f-n, -1*(f+n)/(f-n)]
// [0, 0, 0, 1 ]
2025-02-14 00:27:42 +11:00
DN_M4 result =
{{
{2.f / (right - left), 0.f, 0.f, 0.f},
{0.f, 2.f / (top - bottom), 0.f, 0.f},
{0.f, 0.f, -2.f / (z_far - z_near), 0.f},
{(-1.f * (right + left)) / (right - left), (-1.f * (top + bottom)) / (top - bottom), (-1.f * (z_far + z_near)) / (z_far - z_near), 1.f},
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_Perspective(DN_F32 fov /*radians*/, DN_F32 aspect, DN_F32 z_near, DN_F32 z_far)
{
2025-02-14 00:27:42 +11:00
DN_F32 tan_fov = DN_TANF(fov / 2.f);
DN_M4 result =
{{
{1.f / (aspect * tan_fov), 0.f, 0.f, 0.f},
{0, 1.f / tan_fov, 0.f, 0.f},
{0.f, 0.f, (z_near + z_far) / (z_near - z_far), -1.f},
{0.f, 0.f, (2.f * z_near * z_far)/(z_near - z_far), 0.f},
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_Add(DN_M4 lhs, DN_M4 rhs)
{
2025-02-14 00:27:42 +11:00
DN_M4 result;
for (int col = 0; col < 4; col++)
{
for (int it = 0; it < 4; it++)
result.columns[col][it] = lhs.columns[col][it] + rhs.columns[col][it];
}
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_Sub(DN_M4 lhs, DN_M4 rhs)
{
2025-02-14 00:27:42 +11:00
DN_M4 result;
for (int col = 0; col < 4; col++)
{
for (int it = 0; it < 4; it++)
result.columns[col][it] = lhs.columns[col][it] - rhs.columns[col][it];
}
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_Mul(DN_M4 lhs, DN_M4 rhs)
{
2025-02-14 00:27:42 +11:00
DN_M4 result;
for (int col = 0; col < 4; col++)
{
for (int row = 0; row < 4; row++)
{
2025-02-14 00:27:42 +11:00
DN_F32 sum = 0;
for (int f32_it = 0; f32_it < 4; f32_it++)
sum += lhs.columns[f32_it][row] * rhs.columns[col][f32_it];
result.columns[col][row] = sum;
}
}
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_Div(DN_M4 lhs, DN_M4 rhs)
{
2025-02-14 00:27:42 +11:00
DN_M4 result;
for (int col = 0; col < 4; col++)
{
for (int it = 0; it < 4; it++)
result.columns[col][it] = lhs.columns[col][it] / rhs.columns[col][it];
}
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_AddF(DN_M4 lhs, DN_F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_M4 result;
for (int col = 0; col < 4; col++)
{
for (int it = 0; it < 4; it++)
result.columns[col][it] = lhs.columns[col][it] + rhs;
}
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_SubF(DN_M4 lhs, DN_F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_M4 result;
for (int col = 0; col < 4; col++)
{
for (int it = 0; it < 4; it++)
result.columns[col][it] = lhs.columns[col][it] - rhs;
}
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_MulF(DN_M4 lhs, DN_F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_M4 result;
for (int col = 0; col < 4; col++)
{
for (int it = 0; it < 4; it++)
result.columns[col][it] = lhs.columns[col][it] * rhs;
}
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M4 DN_M4_DivF(DN_M4 lhs, DN_F32 rhs)
{
2025-02-14 00:27:42 +11:00
DN_M4 result;
for (int col = 0; col < 4; col++)
{
for (int it = 0; it < 4; it++)
result.columns[col][it] = lhs.columns[col][it] / rhs;
}
return result;
}
2025-02-14 00:27:42 +11:00
#if !defined(DN_NO_FSTR8)
DN_API DN_FStr8<256> DN_M4_ColumnMajorString(DN_M4 mat)
{
2025-02-14 00:27:42 +11:00
DN_FStr8<256> result = {};
for (int row = 0; row < 4; row++) {
for (int it = 0; it < 4; it++) {
2025-02-14 00:27:42 +11:00
if (it == 0) DN_FStr8_Add(&result, DN_STR8("|"));
DN_FStr8_AddF(&result, "%.5f", mat.columns[it][row]);
if (it != 3) DN_FStr8_Add(&result, DN_STR8(", "));
else DN_FStr8_Add(&result, DN_STR8("|\n"));
}
}
return result;
}
#endif
2025-02-14 00:27:42 +11:00
#endif // !defined(DN_M4)
2025-02-14 00:27:42 +11:00
// NOTE: [$M2x3] DN_M2x3 //////////////////////////////////////////////////////////////////////////
DN_API bool operator==(DN_M2x3 const &lhs, DN_M2x3 const &rhs)
{
2025-02-14 00:27:42 +11:00
bool result = DN_MEMCMP(lhs.e, rhs.e, sizeof(lhs.e[0]) * DN_ARRAY_UCOUNT(lhs.e)) == 0;
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool operator!=(DN_M2x3 const &lhs, DN_M2x3 const &rhs)
{
bool result = !(lhs == rhs);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M2x3 DN_M2x3_Identity()
{
2025-02-14 00:27:42 +11:00
DN_M2x3 result = {{
1, 0, 0,
0, 1, 0,
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M2x3 DN_M2x3_Translate(DN_V2F32 offset)
{
2025-02-14 00:27:42 +11:00
DN_M2x3 result = {{
1, 0, offset.x,
0, 1, offset.y,
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M2x3 DN_M2x3_Scale(DN_V2F32 scale)
{
2025-02-14 00:27:42 +11:00
DN_M2x3 result = {{
scale.x, 0, 0,
0, scale.y, 0,
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M2x3 DN_M2x3_Rotate(DN_F32 radians)
{
2025-02-14 00:27:42 +11:00
DN_M2x3 result = {{
DN_COSF(radians), DN_SINF(radians), 0,
-DN_SINF(radians), DN_COSF(radians), 0,
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_M2x3 DN_M2x3_Mul(DN_M2x3 m1, DN_M2x3 m2)
{
// NOTE: Ordinarily you can't multiply M2x3 with M2x3 because column count
// (3) != row count (2). We pretend we have two 3x3 matrices with the last
// row set to [0 0 1] and perform a 3x3 matrix multiply.
//
// | (0)a (1)b (2)c | | (0)g (1)h (2)i |
// | (3)d (4)e (5)f | x | (3)j (4)k (5)l |
// | (6)0 (7)0 (8)1 | | (6)0 (7)0 (8)1 |
2025-02-14 00:27:42 +11:00
DN_M2x3 result = {{
m1.e[0]*m2.e[0] + m1.e[1]*m2.e[3], // a*g + b*j + c*0[omitted],
m1.e[0]*m2.e[1] + m1.e[1]*m2.e[4], // a*h + b*k + c*0[omitted],
m1.e[0]*m2.e[2] + m1.e[1]*m2.e[5] + m1.e[2], // a*i + b*l + c*1,
m1.e[3]*m2.e[0] + m1.e[4]*m2.e[3], // d*g + e*j + f*0[omitted],
m1.e[3]*m2.e[1] + m1.e[4]*m2.e[4], // d*h + e*k + f*0[omitted],
m1.e[3]*m2.e[2] + m1.e[4]*m2.e[5] + m1.e[5], // d*i + e*l + f*1,
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_M2x3_Mul2F32(DN_M2x3 m1, DN_F32 x, DN_F32 y)
{
// NOTE: Ordinarily you can't multiply M2x3 with V2 because column count (3)
// != row count (2). We pretend we have a V3 with `z` set to `1`.
//
// | (0)a (1)b (2)c | | x |
// | (3)d (4)e (5)f | x | y |
// | 1 |
2025-02-14 00:27:42 +11:00
DN_V2F32 result = {{
m1.e[0]*x + m1.e[1]*y + m1.e[2], // a*x + b*y + c*1
m1.e[3]*x + m1.e[4]*y + m1.e[5], // d*x + e*y + f*1
}};
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_M2x3_MulV2(DN_M2x3 m1, DN_V2F32 v2)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_M2x3_Mul2F32(m1, v2.x, v2.y);
return result;
}
2025-02-14 00:27:42 +11:00
#if !defined(DN_NO_RECT)
// NOTE: [$RECT] DN_Rect //////////////////////////////////////////////////////////////////////////
DN_API bool operator==(const DN_Rect& lhs, const DN_Rect& rhs)
{
bool result = (lhs.pos == rhs.pos) && (lhs.size == rhs.size);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_Rect_Center(DN_Rect rect)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = rect.pos + (rect.size * .5f);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool DN_Rect_ContainsPoint(DN_Rect rect, DN_V2F32 p)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 min = rect.pos;
DN_V2F32 max = rect.pos + rect.size;
bool result = (p.x >= min.x && p.x <= max.x && p.y >= min.y && p.y <= max.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool DN_Rect_ContainsRect(DN_Rect a, DN_Rect b)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 a_min = a.pos;
DN_V2F32 a_max = a.pos + a.size;
DN_V2F32 b_min = b.pos;
DN_V2F32 b_max = b.pos + b.size;
bool result = (b_min >= a_min && b_max <= a_max);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_Rect DN_Rect_Expand(DN_Rect a, DN_F32 amount)
{
2025-02-14 00:27:42 +11:00
DN_Rect result = a;
result.pos -= amount;
result.size += (amount * 2.f);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_Rect DN_Rect_ExpandV2(DN_Rect a, DN_V2F32 amount)
{
2025-02-14 00:27:42 +11:00
DN_Rect result = a;
result.pos -= amount;
result.size += (amount * 2.f);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API bool DN_Rect_Intersects(DN_Rect a, DN_Rect b)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 a_min = a.pos;
DN_V2F32 a_max = a.pos + a.size;
DN_V2F32 b_min = b.pos;
DN_V2F32 b_max = b.pos + b.size;
bool result = (a_min.x <= b_max.x && a_max.x >= b_min.x) &&
(a_min.y <= b_max.y && a_max.y >= b_min.y);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_Rect DN_Rect_Intersection(DN_Rect a, DN_Rect b)
{
2025-02-14 00:27:42 +11:00
DN_Rect result = DN_Rect_Init2V2(a.pos, DN_V2F32_Init1N(0));
if (DN_Rect_Intersects(a, b)) {
DN_V2F32 a_min = a.pos;
DN_V2F32 a_max = a.pos + a.size;
DN_V2F32 b_min = b.pos;
DN_V2F32 b_max = b.pos + b.size;
2025-02-14 00:27:42 +11:00
DN_V2F32 min = {};
DN_V2F32 max = {};
min.x = DN_MAX(a_min.x, b_min.x);
min.y = DN_MAX(a_min.y, b_min.y);
max.x = DN_MIN(a_max.x, b_max.x);
max.y = DN_MIN(a_max.y, b_max.y);
result = DN_Rect_Init2V2(min, max - min);
}
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_Rect DN_Rect_Union(DN_Rect a, DN_Rect b)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 a_min = a.pos;
DN_V2F32 a_max = a.pos + a.size;
DN_V2F32 b_min = b.pos;
DN_V2F32 b_max = b.pos + b.size;
2025-02-14 00:27:42 +11:00
DN_V2F32 min, max;
min.x = DN_MIN(a_min.x, b_min.x);
min.y = DN_MIN(a_min.y, b_min.y);
max.x = DN_MAX(a_max.x, b_max.x);
max.y = DN_MAX(a_max.y, b_max.y);
DN_Rect result = DN_Rect_Init2V2(min, max - min);
return result;
}
2023-08-16 21:59:38 +10:00
2025-02-14 00:27:42 +11:00
DN_API DN_RectMinMax DN_Rect_MinMax(DN_Rect a)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_RectMinMax result = {};
2023-08-16 21:59:38 +10:00
result.min = a.pos;
result.max = a.pos + a.size;
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_F32 DN_Rect_Area(DN_Rect a)
{
2025-02-14 00:27:42 +11:00
DN_F32 result = a.size.w * a.size.h;
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_Rect DN_Rect_CutLeftClip(DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_F32 min_x = rect->pos.x;
DN_F32 max_x = rect->pos.x + rect->size.w;
DN_F32 result_max_x = min_x + amount;
2023-08-16 21:59:38 +10:00
if (clip)
2025-02-14 00:27:42 +11:00
result_max_x = DN_MIN(result_max_x, max_x);
DN_Rect result = DN_Rect_Init4N(min_x, rect->pos.y, result_max_x - min_x, rect->size.h);
2023-08-16 21:59:38 +10:00
rect->pos.x = result_max_x;
rect->size.w = max_x - result_max_x;
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_Rect DN_Rect_CutRightClip(DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_F32 min_x = rect->pos.x;
DN_F32 max_x = rect->pos.x + rect->size.w;
DN_F32 result_min_x = max_x - amount;
2023-08-16 21:59:38 +10:00
if (clip)
2025-02-14 00:27:42 +11:00
result_min_x = DN_MAX(result_min_x, 0);
DN_Rect result = DN_Rect_Init4N(result_min_x, rect->pos.y, max_x - result_min_x, rect->size.h);
2023-08-16 21:59:38 +10:00
rect->size.w = result_min_x - min_x;
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_Rect DN_Rect_CutTopClip(DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_F32 min_y = rect->pos.y;
DN_F32 max_y = rect->pos.y + rect->size.h;
DN_F32 result_max_y = min_y + amount;
2023-08-16 21:59:38 +10:00
if (clip)
2025-02-14 00:27:42 +11:00
result_max_y = DN_MIN(result_max_y, max_y);
DN_Rect result = DN_Rect_Init4N(rect->pos.x, min_y, rect->size.w, result_max_y - min_y);
2023-08-16 21:59:38 +10:00
rect->pos.y = result_max_y;
rect->size.h = max_y - result_max_y;
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_Rect DN_Rect_CutBottomClip(DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_F32 min_y = rect->pos.y;
DN_F32 max_y = rect->pos.y + rect->size.h;
DN_F32 result_min_y = max_y - amount;
2023-08-16 21:59:38 +10:00
if (clip)
2025-02-14 00:27:42 +11:00
result_min_y = DN_MAX(result_min_y, 0);
DN_Rect result = DN_Rect_Init4N(rect->pos.x, result_min_y, rect->size.w, max_y - result_min_y);
2023-08-16 21:59:38 +10:00
rect->size.h = result_min_y - min_y;
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_Rect DN_RectCut_Cut(DN_RectCut rect_cut, DN_V2F32 size, DN_RectCutClip clip)
2023-08-16 21:59:38 +10:00
{
2025-02-14 00:27:42 +11:00
DN_Rect result = {};
2023-08-16 21:59:38 +10:00
if (rect_cut.rect) {
switch (rect_cut.side) {
2025-02-14 00:27:42 +11:00
case DN_RectCutSide_Left: result = DN_Rect_CutLeftClip(rect_cut.rect, size.w, clip); break;
case DN_RectCutSide_Right: result = DN_Rect_CutRightClip(rect_cut.rect, size.w, clip); break;
case DN_RectCutSide_Top: result = DN_Rect_CutTopClip(rect_cut.rect, size.h, clip); break;
case DN_RectCutSide_Bottom: result = DN_Rect_CutBottomClip(rect_cut.rect, size.h, clip); break;
2023-08-16 21:59:38 +10:00
}
}
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_Rect_InterpolatedPoint(DN_Rect rect, DN_V2F32 t01)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_V2F32_Init2N(rect.pos.w + (rect.size.w * t01.x),
rect.pos.h + (rect.size.h * t01.y));
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_Rect_TopLeft(DN_Rect rect)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_Rect_InterpolatedPoint(rect, DN_V2F32_Init2N(0, 0));
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_Rect_TopRight(DN_Rect rect)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_Rect_InterpolatedPoint(rect, DN_V2F32_Init2N(1, 0));
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_Rect_BottomLeft(DN_Rect rect)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_Rect_InterpolatedPoint(rect, DN_V2F32_Init2N(0, 1));
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_Rect_BottomRight(DN_Rect rect)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = DN_Rect_InterpolatedPoint(rect, DN_V2F32_Init2N(1, 1));
return result;
}
2025-02-14 00:27:42 +11:00
#endif // !defined(DN_NO_RECT)
// NOTE: [$MATH] Raycast ///////////////////////////////////////////////////////////////////////////
2025-02-14 00:27:42 +11:00
DN_API DN_RaycastLineIntersectV2Result DN_Raycast_LineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a, DN_V2F32 origin_b, DN_V2F32 dir_b)
{
// NOTE: Parametric equation of a line
//
// p = o + (t*d)
//
// - o is the starting 2d point
// - d is the direction of the line
// - t is a scalar that scales along the direction of the point
//
// To determine if a ray intersections a ray, we want to solve
//
// (o_a + (t_a * d_a)) = (o_b + (t_b * d_b))
//
// Where '_a' and '_b' represent the 1st and 2nd point's origin, direction
// and 't' components respectively. This is 2 equations with 2 unknowns
// (`t_a` and `t_b`) which we can solve for by expressing the equation in
// terms of `t_a` and `t_b`.
//
// Working that math out produces the formula below for 't'.
2025-02-14 00:27:42 +11:00
DN_RaycastLineIntersectV2Result result = {};
DN_F32 denominator = ((dir_b.y * dir_a.x) - (dir_b.x * dir_a.y));
if (denominator != 0.0f) {
result.t_a = (((origin_a.y - origin_b.y) * dir_b.x) + ((origin_b.x - origin_a.x) * dir_b.y)) / denominator;
result.t_b = (((origin_a.y - origin_b.y) * dir_a.x) + ((origin_b.x - origin_a.x) * dir_a.y)) / denominator;
result.hit = true;
}
return result;
}
// NOTE: [$MATH] Other /////////////////////////////////////////////////////////////////////////////
2025-02-14 00:27:42 +11:00
DN_API DN_V2F32 DN_Lerp_V2F32(DN_V2F32 a, DN_F32 t, DN_V2F32 b)
{
2025-02-14 00:27:42 +11:00
DN_V2F32 result = {};
result.x = a.x + ((b.x - a.x) * t);
result.y = a.y + ((b.y - a.y) * t);
return result;
}
2025-02-14 00:27:42 +11:00
DN_API DN_F32 DN_Lerp_F32(DN_F32 a, DN_F32 t, DN_F32 b)
{
2025-02-14 00:27:42 +11:00
DN_F32 result = a + ((b - a) * t);
return result;
}