diff --git a/include/CAABox.hpp b/include/CAABox.hpp index de5ba35..36974d7 100644 --- a/include/CAABox.hpp +++ b/include/CAABox.hpp @@ -7,7 +7,9 @@ #include "CPlane.hpp" #include "CLine.hpp" #include "Math.hpp" +#if ZE_ATHENA_TYPES #include +#endif namespace Zeus { @@ -58,8 +60,9 @@ public: m_max(maxX, maxY, maxZ) { } - +#if ZE_ATHENA_TYPES CAABox(Athena::io::IStreamReader& in) {readBoundingBox(in);} +#endif inline void readBoundingBox(Athena::io::IStreamReader& in) { diff --git a/include/CColor.hpp b/include/CColor.hpp index 25b168d..4c387f6 100644 --- a/include/CColor.hpp +++ b/include/CColor.hpp @@ -1,26 +1,23 @@ #ifndef CCOLOR_HPP #define CCOLOR_HPP -#include "MathLib.hpp" -#include +#include "Global.hpp" +#include "Math.hpp" +#if ZE_ATHENA_TYPES +#include +#endif #if BYTE_ORDER == __ORDER_LITTLE_ENDIAN__ -#define COLOR(rgba) ( ( (rgba) & 0x000000FF ) << 24 | ( (rgba) & 0x0000FF00 ) << 8 \ +#define COLOR(rgba) (unsigned long)( ( (rgba) & 0x000000FF ) << 24 | ( (rgba) & 0x0000FF00 ) << 8 \ | ( (rgba) & 0x00FF0000 ) >> 8 | ( (rgba) & 0xFF000000 ) >> 24 ) #else -#define COLOR(rgba) rgba +#define COLOR(rgba) (unsigned long)rgba #endif namespace Zeus { -typedef union -{ - struct - { - unsigned char r, g, b, a; - }; - unsigned int rgba; -} RGBA32; +typedef unsigned char Comp8; +typedef unsigned long Comp32; class alignas(16) CColor { @@ -37,170 +34,126 @@ public: static const CColor skYellow; static const CColor skWhite; -#if __SSE__ - CColor(const __m128& mVec128) : mVec128(mVec128) {} -#endif - CColor() : r(1.0f), g(1.0f), b(1.0f), a(1.0f) {} + CColor() : rgba(~0u) {} CColor(float rgb, float a = 1.0) { splat(rgb, a); } - CColor(float r, float g, float b, float a = 1.0f) {v[0] = r; v[1] = g; v[2] = b; v[3] = a; } - CColor(Athena::io::IStreamReader& reader) {readRGBA(reader);} - CColor(atUint32 rgba) { fromRGBA32(rgba); } - CColor(const unsigned char* rgba) { fromRGBA8(rgba[0], rgba[1], rgba[2], rgba[3]); } + CColor(float r, float g, float b, float a = 1.0f) + : r(Comp8(255*r)), + g(Comp8(255*g)), + b(Comp8(255*b)), + a(Comp8(255*a)) + {} +#if ZE_ATHENA_TYPES + CColor(Athena::io::IStreamReader& reader) {readRGBA(reader);} +#endif + CColor(Comp32 rgba) { fromRGBA32(rgba); } + CColor(const Comp8 rgba[4]) : r(rgba[0]), g(rgba[1]), b(rgba[2]), a(rgba[3]) {} + CColor(Comp8 r, Comp8 g, Comp8 b, Comp8 a = 255) + : r(r), g(g), b(b), a(a) {} + +#if ZE_ATHENA_TYPES inline void readRGBA(Athena::io::IStreamReader& reader) { - r = reader.readFloat(); - g = reader.readFloat(); - b = reader.readFloat(); - a = reader.readFloat(); + r = Comp8(255 * reader.readFloat()); + g = Comp8(255 * reader.readFloat()); + b = Comp8(255 * reader.readFloat()); + a = Comp8(255 * reader.readFloat()); } inline void readBGRA(Athena::io::IStreamReader& reader) { - b = reader.readFloat(); - g = reader.readFloat(); - r = reader.readFloat(); - a = reader.readFloat(); + b = Comp8(255 * reader.readFloat()); + g = Comp8(255 * reader.readFloat()); + r = Comp8(255 * reader.readFloat()); + a = Comp8(255 * reader.readFloat()); } +#endif + inline bool operator==(const CColor& rhs) const - { return (r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a); } + { return (rgba == rhs.rgba); } inline bool operator!=(const CColor& rhs) const { return !(*this == rhs); } inline CColor operator+(const CColor& rhs) const { -#if __SSE__ - return CColor(_mm_add_ps(mVec128, rhs.mVec128)); -#else - return CColor(r + rhs.r, g + rhs.g, b + rhs.b, a + rhs.a); -#endif + CColor ret; ret.r = r + rhs.r; ret.g = g + rhs.g; ret.b = b + rhs.b; ret.a = a + rhs.a; + return ret; } inline CColor operator-(const CColor& rhs) const { -#if __SSE__ - return CColor(_mm_sub_ps(mVec128, rhs.mVec128)); -#else - return CColor(r - rhs.r, g - rhs.g, b - rhs.b, a - rhs.a); -#endif + CColor ret; ret.r = r - rhs.r; ret.g = g - rhs.g; ret.b = b - rhs.b; ret.a = a - rhs.a; + return ret; } + inline CColor operator*(const CColor& rhs) const { -#if __SSE__ - return CColor(_mm_mul_ps(mVec128, rhs.mVec128)); -#else - return CColor(r * rhs.r, g * rhs.g, b * rhs.b, a * rhs.a); -#endif + CColor ret; ret.r = r * rhs.r; ret.g = g * rhs.g; ret.b = b * rhs.b; ret.a = a * rhs.a; + return ret; } inline CColor operator/(const CColor& rhs) const { -#if __SSE__ - return CColor(_mm_div_ps(mVec128, rhs.mVec128)); -#else - return CColor(r / rhs.r, g / rhs.g, b / rhs.b, a / rhs.a); -#endif + CColor ret; ret.r = r / rhs.r; ret.g = g / rhs.g; ret.b = b / rhs.b; ret.a = a / rhs.a; + return ret; } inline CColor operator+(float val) const { -#if __SSE__ - TVectorUnion splat = {{val, val, val, val}}; - return CColor(_mm_add_ps(mVec128, splat.mVec128)); -#else - return CColor(r + val, g + val, b + val, a + val); -#endif + CColor ret; + ret.r = r + Comp8(255 * val); ret.g = g + Comp8(255 * val); ret.b = b + Comp8(255 * val); ret.a = a + Comp8(255 * val); + return ret; } inline CColor operator-(float val) const { -#if __SSE__ - TVectorUnion splat = {{val, val, val, val}}; - return CColor(_mm_sub_ps(mVec128, splat.mVec128)); -#else - return CColor(r - val, g - val, b - val, a - val); -#endif + CColor ret; + ret.r = r - Comp8(255 * val); ret.g = g - Comp8(255 * val); ret.b = b - Comp8(255 * val); ret.a = a - Comp8(255 * val); + return ret; } inline CColor operator*(float val) const { -#if __SSE__ - TVectorUnion splat = {{val, val, val, val}}; - return CColor(_mm_mul_ps(mVec128, splat.mVec128)); -#else - return CColor(r * val, g * val, b * val, a * val); -#endif + CColor ret; + ret.r = r * Comp8(255 * val); ret.g = g * Comp8(255 * val); ret.b = b * Comp8(255 * val); ret.a = a * Comp8(255 * val); + return ret; } inline CColor operator/(float val) const { -#if __SSE__ - TVectorUnion splat = {{val, val, val, val}}; - return CColor(_mm_div_ps(mVec128, splat.mVec128)); -#else - return CColor(r / val, g / val, b / val, a / val); -#endif + CColor ret; + ret.r = r / Comp8(255 * val); ret.g = g / Comp8(255 * val); ret.b = b / Comp8(255 * val); ret.a = a / Comp8(255 * val); + return ret; } inline const CColor& operator+=(const CColor& rhs) { -#if __SSE__ - mVec128 = _mm_add_ps(mVec128, rhs.mVec128); -#else - r += rhs.r; g += rhs.g; b += rhs.b; a += rhs.a; -#endif - return *this; + r += rhs.r; g += rhs.g; b += rhs.b; + a += rhs.a; return *this; } inline const CColor& operator-=(const CColor& rhs) { -#if __SSE__ - mVec128 = _mm_sub_ps(mVec128, rhs.mVec128); -#else r -= rhs.r; g -= rhs.g; b -= rhs.b; a -= rhs.a; -#endif return *this; } inline const CColor& operator *=(const CColor& rhs) { -#if __SSE__ - mVec128 = _mm_mul_ps(mVec128, rhs.mVec128); -#else r *= rhs.r; g *= rhs.g; b *= rhs.b; a *= rhs.a; -#endif return *this; } inline const CColor& operator /=(const CColor& rhs) { -#if __SSE__ - mVec128 = _mm_div_ps(mVec128, rhs.mVec128); -#else r /= rhs.r; g /= rhs.g; b /= rhs.b; a /= rhs.a; -#endif return *this; } inline void normalize() { float mag = magnitude(); - assert(mag != 0.0); - mag = 1.0 / mag; *this *= mag; } inline CColor normalized() { float mag = magnitude(); - assert(mag != 0.0); - mag = 1.0 / mag; return *this * mag; } inline float magSquared() const - { -#if __SSE4_1__ - TVectorUnion result; - result.mVec128 = _mm_dp_ps(mVec128, mVec128, 0xF1); - return result.v[0]; -#elif __SSE__ - TVectorUnion result; - result.mVec128 = _mm_mul_ps(mVec128, mVec128); - return result.v[0] + result.v[1] + result.v[2] + result.v[3]; -#else - return r * r + g * g + b * b + a * a; -#endif - } + { return ((r * r + g * g + b * b + a * a) / 255.f); } + inline float magnitude() const { - return sqrtf(magSquared()); + return Math::sqrtF(magSquared()); } static inline CColor lerp(const CColor& a, const CColor& b, float t) { @@ -210,84 +163,139 @@ public: { return lerp(a, b, t).normalized(); } - inline float& operator[](const size_t& idx) {return (&r)[idx];} - inline const float& operator[](const size_t& idx) const { return (&r)[idx]; } + + inline Comp8& operator[](size_t idx) {return (&r)[idx];} + inline const Comp8& operator[](size_t idx) const { return (&r)[idx]; } inline void splat(float rgb, float a) { -#if __SSE__ - TVectorUnion splat = {{rgb, rgb, rgb, a}}; - mVec128 = splat.mVec128; -#else - v[0] = rgb; v[1] = rgb; v[2] = rgb; v[3] = a; -#endif + r = Comp8(255 * rgb); + g = Comp8(255 * rgb); + b = Comp8(255 * rgb); + this->a = Comp8(255 * a); } union { - struct - { - float r, g, b, a; - }; - float v[4]; -#if __SSE__ - __m128 mVec128; -#endif + struct { Comp8 r, g, b, a; }; + Comp32 rgba; }; void fromRGBA8(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { - this->r = r / 255.f; - this->g = g / 255.f; - this->b = b / 255.f; - this->a = a / 255.f; + this->r = r; + this->g = g; + this->b = b; + this->a = a; + } + + /** + * @brief Assigns rgba from hsv + * @param h[0-1] The hue percentagee of the color. + * @param s[0-1] The saturation percentage of the color. + * @param v[0-1] The value percentage of the color. + * @param a[0-1] The alpha percentage of the color. + */ + void fromHSV(float h, float s, float v, float _a = 1.0) + { + int i = int(h * 6); + float f = h * 6 - i; + float p = v * (1 - s); + float q = v * (1 - f * s); + float t = v * (1 - (1 - f) * s); + float _r, _g, _b; + + switch(i % 6) + { + case 0: _r = v, _g = t, _b = p; break; + case 1: _r = q, _g = v, _b = p; break; + case 2: _r = p, _g = v, _b = t; break; + case 3: _r = p, _g = q, _b = v; break; + case 4: _r = t, _g = p, _b = v; break; + case 5: _r = v, _g = p, _b = q; break; + } + + r = _r * 255; + g = _g * 255; + b = _b * 255; + a = _a * 255; + } + + /** + * @brief Converts rgba to hsv + * @param h[0-1] The hue percentagee of the color. + * @param s[0-1] The saturation percentage of the color. + * @param v[0-1] The value percentage of the color. + * @param a[0-1] The alpha percentage of the color. + */ + void toHSV(float& h, float& s, float& v) const + { + float rf = r/255.f; + float gf = g/255.f; + float bf = b/255.f; + + float min = Math::min(rf, Math::min(gf, bf)); + float max = Math::max(rf, Math::max(gf, bf)); + v = max; + + float delta = max - min; + s = max == 0 ? 0 : delta / max; + + if (max == min) + h = 0; + else + { + if (max == rf) + h = (gf - bf) / delta + (gf < bf ? 6 : 0); + else if (max == gf) + h = (bf - rf) / delta + 2; + else if (max == bf) + h = (rf - gf) / delta + 4; + h /= 6; + } } void fromRGBA32(unsigned int rgba) - { - static RGBA32 tmp; - tmp.rgba = rgba; - fromRGBA8(tmp.r, tmp.g, tmp.b, tmp.a); - } + { this->rgba = COLOR(rgba); } }; static inline CColor operator+(float lhs, const CColor& rhs) { -#if __SSE__ - TVectorUnion splat = {{lhs, lhs, lhs, lhs}}; - return CColor(_mm_add_ps(splat.mVec128, rhs.mVec128)); -#else - return CColor(lhs + rhs.r, lhs + rhs.g, lhs + rhs.b, lhs + rhs.a); -#endif + CColor ret; + ret.r = Comp8(255 * lhs) + rhs.r; + ret.g = Comp8(255 * lhs) + rhs.g; + ret.b = Comp8(255 * lhs) + rhs.b; + ret.a = Comp8(255 * lhs) + rhs.a; + return ret; } static inline CColor operator-(float lhs, const CColor& rhs) { -#if __SSE__ - TVectorUnion splat = {{lhs, lhs, lhs, lhs}}; - return CColor(_mm_sub_ps(splat.mVec128, rhs.mVec128)); -#else - return CColor(lhs - rhs.r, lhs - rhs.g, lhs - rhs.b, lhs - rhs.a); -#endif + CColor ret; + ret.r = Comp8(255 * lhs) - rhs.r; + ret.g = Comp8(255 * lhs) - rhs.g; + ret.b = Comp8(255 * lhs) - rhs.b; + ret.a = Comp8(255 * lhs) - rhs.a; + return ret; } static inline CColor operator*(float lhs, const CColor& rhs) { -#if __SSE__ - TVectorUnion splat = {{lhs, lhs, lhs, lhs}}; - return CColor(_mm_mul_ps(splat.mVec128, rhs.mVec128)); -#else - return CColor(lhs * rhs.r, lhs * rhs.g, lhs * rhs.b, lhs * rhs.a); -#endif + CColor ret; + ret.r = Comp8(255 * lhs) * rhs.r; + ret.g = Comp8(255 * lhs) * rhs.g; + ret.b = Comp8(255 * lhs) * rhs.b; + ret.a = Comp8(255 * lhs) * rhs.a; + return ret; } static inline CColor operator/(float lhs, const CColor& rhs) { -#if __SSE__ - TVectorUnion splat = {{lhs, lhs, lhs, lhs}}; - return CColor(_mm_div_ps(splat.mVec128, rhs.mVec128)); -#else - return CColor(lhs / rhs.r, lhs / rhs.g, lhs / rhs.b, lhs / rhs.a); -#endif + CColor ret; + ret.r = Comp8(255 * lhs) / rhs.r; + ret.g = Comp8(255 * lhs) / rhs.g; + ret.b = Comp8(255 * lhs) / rhs.b; + ret.a = Comp8(255 * lhs) / rhs.a; + return ret; } } diff --git a/include/CQuaternion.hpp b/include/CQuaternion.hpp index 397bc00..1a2bb68 100644 --- a/include/CQuaternion.hpp +++ b/include/CQuaternion.hpp @@ -6,7 +6,9 @@ #include "CVector3f.hpp" #include "CVector4f.hpp" #include +#if ZE_ATHENA_TYPES #include +#endif namespace Zeus { @@ -19,7 +21,9 @@ public: CQuaternion(float r, float x, float y, float z) : r(r), v(x, y, z){} CQuaternion(float x, float y, float z) { fromVector3f(CVector3f(x, y, z)); } CQuaternion(float r, const CVector3f& vec) : r(r), v(vec){} +#if ZE_ATHENA_TYPES CQuaternion(Athena::io::IStreamReader& input) { r = input.readFloat(); v = CVector3f(input);} +#endif CQuaternion(const CVector3f& vec) { fromVector3f(vec); } CQuaternion(const CVector4f& vec) : r(vec.w) diff --git a/include/CVector2f.hpp b/include/CVector2f.hpp index 975b56c..9a9fcad 100644 --- a/include/CVector2f.hpp +++ b/include/CVector2f.hpp @@ -5,7 +5,10 @@ #include "Math.hpp" #include "TVectorUnion.hpp" +#if ZE_ATHENA_TYPES #include +#endif + #include #include @@ -32,6 +35,7 @@ class alignas(16) CVector2f #endif CVector2f(float xy) {splat(xy);} CVector2f(float x, float y) {v[0] = x; v[1] = y; v[2] = 0; v[3] = 0.0;} +#if ZE_ATHENA_TYPES CVector2f(Athena::io::IStreamReader& input) { x = input.readFloat(); @@ -39,6 +43,7 @@ class alignas(16) CVector2f v[2] = 0.0f; v[3] = 0.0f; } +#endif inline bool operator ==(const CVector2f& rhs) const {return (x == rhs.x && y == rhs.y);} diff --git a/include/CVector3f.hpp b/include/CVector3f.hpp index ecf7e7b..81aba23 100644 --- a/include/CVector3f.hpp +++ b/include/CVector3f.hpp @@ -5,7 +5,10 @@ #include "Math.hpp" #include "CVector2f.hpp" #include "TVectorUnion.hpp" +#if ZE_ATHENA_TYPES #include +#endif + #include #include @@ -32,6 +35,7 @@ public: #endif CVector3f(float xyz) {splat(xyz);} CVector3f(float x, float y, float z) {v[0] = x; v[1] = y; v[2] = z; v[3] = 0.0;} +#if ZE_ATHENA_TYPES CVector3f(Athena::io::IStreamReader& input) { x = input.readFloat(); @@ -39,6 +43,7 @@ public: z = input.readFloat(); v[3] = 0.0f; } +#endif CVector3f(const CVector2f& other) { x = other.x; diff --git a/include/CVector4f.hpp b/include/CVector4f.hpp index 21adfea..1dfee45 100644 --- a/include/CVector4f.hpp +++ b/include/CVector4f.hpp @@ -4,7 +4,9 @@ #include "Global.hpp" #include "TVectorUnion.hpp" #include "CVector3f.hpp" +#if ZE_ATHENA_TYPES #include +#endif #include #include #include @@ -33,6 +35,7 @@ class alignas(16) CVector4f CVector4f(float xyzw) {splat(xyzw);} CVector4f(float x, float y, float z, float w) {v[0] = x; v[1] = y; v[2] = z; v[3] = w;} +#if ZE_ATHENA_TYPES CVector4f(Athena::io::IStreamReader& input) { x = input.readFloat(); @@ -40,6 +43,7 @@ class alignas(16) CVector4f z = input.readFloat(); w = input.readFloat(); } +#endif CVector4f(const CVector3f& other) { diff --git a/test/main.cpp b/test/main.cpp index c5a88ff..939c60c 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -5,6 +5,12 @@ // This is only for testing, do NOT do this normally using namespace Zeus; +union Color +{ + struct { Zeus::Comp8 r, g, b, a; }; + Zeus::Comp32 rgba; +}; + int main() { assert(!CAABox({100, 100, 100}, {100, 100, 100}).invalid()); @@ -42,5 +48,11 @@ int main() std::cout << Math::floorPowerOfTwo(256) << std::endl; CLine line({-89.120926, 59.328712, 3.265882}, CUnitVector3f({-90.120926, 59.328712, 3.265882})); + CColor ctest1; + ctest1.fromHSV(0, 255/255.f, .5); + float h, s, v; + ctest1.toHSV(h, s, v); + std::cout << (int)ctest1.r << " " << (int)ctest1.g << " " << (int)ctest1.b << " " << (int)ctest1.a << std::endl; + std::cout << h << " " << s << " " << v << " " << (float)(ctest1.a / 255.f) << std::endl; return 0; }