From c25125e55983c426f03c131ef01504725fbdaa07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romulo=20Leit=C3=A3o?= Date: Tue, 15 Oct 2024 22:40:51 -0300 Subject: [PATCH 1/4] new c++ support --- libyaul/build-files.mk | 1 + libyaul/gamemath/fix16/c++/fix16.cxx | 47 ++ libyaul/gamemath/fix16/c++/fix16_vec3.cxx | 26 +- libyaul/gamemath/gamemath/angle.h | 259 ++++++----- libyaul/gamemath/gamemath/fix16.h | 436 ++++++++++++------ libyaul/gamemath/gamemath/fix16/fix16_mat33.h | 240 +++++----- libyaul/gamemath/gamemath/fix16/fix16_mat43.h | 395 ++++++++-------- libyaul/gamemath/gamemath/fix16/fix16_quat.h | 167 ++++--- libyaul/gamemath/gamemath/fix16/fix16_trig.h | 12 - libyaul/gamemath/gamemath/fix16/fix16_vec2.h | 46 +- libyaul/gamemath/gamemath/fix16/fix16_vec3.h | 382 ++++++++------- 11 files changed, 1173 insertions(+), 838 deletions(-) create mode 100644 libyaul/gamemath/fix16/c++/fix16.cxx diff --git a/libyaul/build-files.mk b/libyaul/build-files.mk index 3e7b712d..b65fbb65 100644 --- a/libyaul/build-files.mk +++ b/libyaul/build-files.mk @@ -219,6 +219,7 @@ LIB_SRCS+= \ gamemath/fix16/fix16_vec2.c \ gamemath/fix16/fix16_vec3.c \ \ + gamemath/fix16/c++/fix16.cxx \ gamemath/fix16/c++/fix16_vec3.cxx \ \ gamemath/int16.c \ diff --git a/libyaul/gamemath/fix16/c++/fix16.cxx b/libyaul/gamemath/fix16/c++/fix16.cxx new file mode 100644 index 00000000..77662bfd --- /dev/null +++ b/libyaul/gamemath/fix16/c++/fix16.cxx @@ -0,0 +1,47 @@ +/*- + * Copyright (c) Authors of libfixmath + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +#include +#include +#include +#include + +namespace yaul { + +angle +fix16::rad_to_angle() const +{ + constexpr fix16 OneOver2Pi { FIX16(1.0 / (2.0 * M_PI)) }; + return angle { static_cast<::angle_t>((*this * OneOver2Pi).value) }; +} + +angle +fix16::deg_to_angle() const +{ + constexpr fix16 OneOver2Pi { FIX16(1.0 / (2.0 * M_PI)) }; + return angle { static_cast<::angle_t>((deg_to_rad() * OneOver2Pi).value) }; +} + +} // namespace yaul \ No newline at end of file diff --git a/libyaul/gamemath/fix16/c++/fix16_vec3.cxx b/libyaul/gamemath/fix16/c++/fix16_vec3.cxx index bbb824ee..ba85454d 100644 --- a/libyaul/gamemath/fix16/c++/fix16_vec3.cxx +++ b/libyaul/gamemath/fix16/c++/fix16_vec3.cxx @@ -1,22 +1,18 @@ #include +#include -bool fix16_vec3_t::is_near_zero(fix16_t epsilon) const { - // TODO: Implement this in C and use it here - return x.is_near_zero(epsilon) && y.is_near_zero(epsilon) && z.is_near_zero(epsilon); -} +#if defined(__cplusplus) + +namespace yaul { -void fix16_vec3_t::end_normalization() { - const fix16_t scale = fix16_t{cpu_divu_quotient_get()}; +const fix16_vec3 fix16_vec3::operator*(const fix16_quat &other) const +{ + fix16_vec3_t result; + fix16_quat_vec3_mul(other.as_fix16_quat_t(), as_fix16_vec3_t(), &result); - x = fix16_mul(scale, x); - y = fix16_mul(scale, y); - z = fix16_mul(scale, z); + return fix16_vec3 { result.x, result.y, result.z }; } -fix16_vec3_t fix16_vec3_t::reflect(const fix16_vec3_t& v, const fix16_vec3_t& normal) { - // TODO: Move this to a C function - const fix16_t factor = dot_product(v, normal) << 1; - const fix16_vec3_t proj = normal * factor; +} // namespace yaul - return (v - proj); -} +#endif /* __cplusplus */ diff --git a/libyaul/gamemath/gamemath/angle.h b/libyaul/gamemath/gamemath/angle.h index 42256786..0b1a09b9 100644 --- a/libyaul/gamemath/gamemath/angle.h +++ b/libyaul/gamemath/gamemath/angle.h @@ -22,7 +22,6 @@ /// @ingroup MATH /// @{ -#if !defined(__cplusplus) /// @brief Not yet documented. /// /// @param d Not yet documented. @@ -32,9 +31,7 @@ /// /// @param d Not yet documented. #define DEG2ANGLE(d) ((angle_t)((65536.0 * (d)) / 360.0)) -#endif /* !__cplusplus */ -#if !defined(__cplusplus) /// @brief Not yet documented. typedef int16_t angle_t; @@ -46,62 +43,8 @@ typedef struct euler { angle_t yaw; /// @brief Not yet documented. angle_t roll; -} euler_t; -#else -/// @brief Not yet documented. -struct angle_t { - /// @brief Not yet documented. - int16_t value; - - angle_t() = default; - - explicit constexpr angle_t(int32_t v); - - inline angle_t operator+(angle_t other) const; - inline angle_t operator-(angle_t other) const; - constexpr inline angle_t operator-() const; - inline angle_t operator>>(int32_t other) const; - inline angle_t operator<<(int32_t other) const; - - inline angle_t& operator+=(angle_t rhs); - inline angle_t& operator-=(angle_t rhs); - - inline bool operator<(angle_t other) const; - inline bool operator<(int32_t other) const; - inline bool operator>(angle_t other) const; - inline bool operator>(int32_t other) const; - inline bool operator<=(angle_t other) const; - inline bool operator<=(int32_t other) const; - inline bool operator>=(angle_t other) const; - inline bool operator>=(int32_t other) const; - inline bool operator==(angle_t other) const; - inline bool operator==(int32_t other) const; - - static constexpr inline angle_t from_rad_double(double rad); - - static constexpr inline angle_t from_deg_double(double value); - - inline angle_t from_deg(fix16_t degree); - - inline angle_t from_rad(fix16_t rad); - - inline size_t to_string(char* buffer, int32_t decimals = 7) const; -}; - -static_assert(sizeof(angle_t) == 2); +} __packed __aligned(2) euler_t; -/// @brief Not yet documented. -struct euler_t { - /// @brief Not yet documented. - angle_t pitch; - /// @brief Not yet documented. - angle_t yaw; - /// @brief Not yet documented. - angle_t roll; -}; -#endif /* !__cplusplus */ - -#if !defined(__cplusplus) /// @brief Not yet documented. /// /// @param angle Not yet documented. @@ -129,74 +72,172 @@ angle_int32_to(angle_t angle) { return (angle <= SHRT_MIN) ? (uint16_t)angle : angle; } -#else -constexpr angle_t operator"" _deg(long double v) { return angle_t::from_deg_double(v); } -constexpr angle_t operator"" _rad(long double v) { return angle_t::from_rad_double(v); } +#if defined(__cplusplus) -constexpr angle_t::angle_t(int32_t v) : value(v) {} +__BEGIN_DECLS -inline angle_t angle_t::operator+(angle_t other) const { return angle_t{value + other.value}; } -inline angle_t angle_t::operator-(angle_t other) const { return angle_t{value - other.value}; } +extern fix16_t fix16_cos(angle_t); -constexpr inline angle_t angle_t::operator-() const { - return angle_t{-value}; -} +extern fix16_t fix16_sin(angle_t); -inline angle_t angle_t::operator>>(int32_t other) const { - return angle_t{(value <= SHRT_MIN) ? (static_cast(value) >> other) : (value >> other)}; -} +extern fix16_t fix16_tan(angle_t); -inline angle_t angle_t::operator<<(int32_t other) const { - return angle_t{(value <= SHRT_MIN) ? (static_cast(value & 0xFFFF) << other) : (value << other)}; -} +extern void fix16_sincos(angle_t, fix16_t *, fix16_t *); -inline angle_t& angle_t::operator+=(angle_t rhs) { - *this += rhs; - return *this; -} +__END_DECLS -inline angle_t& angle_t::operator-=(angle_t rhs) { - *this -= rhs; - return *this; -} +namespace yaul { -inline bool angle_t::operator<(angle_t other) const { return value < other.value; } -inline bool angle_t::operator<(int32_t other) const { return value < other; } -inline bool angle_t::operator>(angle_t other) const { return value > other.value; } -inline bool angle_t::operator>(int32_t other) const { return value > other; } -inline bool angle_t::operator<=(angle_t other) const { return value <= other.value; } -inline bool angle_t::operator<=(int32_t other) const { return value <= other; } -inline bool angle_t::operator>=(angle_t other) const { return value >= other.value; } -inline bool angle_t::operator>=(int32_t other) const { return value >= other; } -inline bool angle_t::operator==(angle_t other) const { return value == other.value; } -inline bool angle_t::operator==(int32_t other) const { return value == other; } - -inline angle_t angle_t::from_deg(fix16_t degree) { - constexpr fix16_t scale{fix16_t::from_double(1.0 / 360.0)}; - - // Drop the fractional part of the fixed value - return angle_t{fix16_low_mul(scale, degree)}; -} +/// @brief Not yet documented. +struct __packed angle { + /// @brief Not yet documented. + angle_t value; + + angle() = default; + + constexpr explicit angle(angle_t v) : value(v) {} + + angle operator+(angle other) const + { + return angle{ static_cast(value + other.value) }; + } + + inline angle operator-(angle other) const + { + return angle { static_cast(value - other.value) }; + } + + constexpr angle operator-() const { return angle { static_cast(-value) }; } + + angle operator>>(int32_t other) const + { + return angle { static_cast((value <= SHRT_MIN) ? + (static_cast(value) >> other) : + (value >> other)) }; + } + + angle operator<<(int32_t other) const + { + return angle { static_cast((value <= SHRT_MIN) ? + (static_cast(value & 0xFFFF) << other) : + (value << other)) }; + } + + angle &operator+=(angle rhs) + { + value += rhs.value; + return *this; + } + + angle &operator-=(angle rhs) + { + value -= rhs.value; + return *this; + } + + bool operator<(angle other) const { return value < other.value; } + bool operator>(angle other) const { return value > other.value; } + bool operator<=(angle other) const { return value <= other.value; } + bool operator>=(angle other) const { return value >= other.value; } + bool operator==(angle other) const { return value == other.value; } + + bool operator<(int32_t other) const { return value < other; } + bool operator>(int32_t other) const { return value > other; } + bool operator<=(int32_t other) const { return value <= other; } + bool operator>=(int32_t other) const { return value >= other; } + bool operator==(int32_t other) const { return value == other; } + + angle from_deg(fix16 degree) + { + constexpr fix16 scale { fix16::from_double(1.0 / 360.0) }; + return angle { static_cast((scale * degree).value) }; + } + + angle from_rad(fix16 rad) + { + constexpr fix16 scale { fix16::from_double(1.0 / (2.0 * M_PI)) }; + return angle { static_cast((scale * rad).value) }; + } + + fix16 to_rad() const + { + constexpr fix16 toRadians = fix16::from_double(2.0 * M_PI); + return fix16(static_cast(value)) * toRadians; + } + + fix16 to_deg() const + { + constexpr fix16 toDeg = fix16::from_double(360.0); + return fix16(static_cast(value)) * toDeg; + } + + fix16 cos() const { return fix16{::fix16_cos(value)}; } + + fix16 sin() const { return fix16{::fix16_sin(value)}; } + + fix16 tan() const { return fix16{::fix16_tan(value)}; } + + void sincos(fix16_t &out_sin, fix16_t &out_cos) const + { + fix16_sincos(value, &out_sin, &out_cos); + } + + void sincos(fix16 &out_sin, fix16 &out_cos) const + { + fix16_sincos(value, &out_sin.value, &out_cos.value); + } + + static constexpr angle from_rad_double(double rad) + { + constexpr double _2pi = 2.0 * M_PI; + return angle { + fix16::from_double(fmod(rad + _2pi, _2pi) / _2pi).fractional() + }; + } + + static constexpr angle from_deg_double(double value) + { + return angle { + fix16::from_double(fmod(value + 360.0, 360.0) / 360.0).fractional() + }; + } + + size_t to_string(char *buffer, int32_t decimals) const + { + return fix16 { static_cast(value) }.to_string(buffer, + decimals); + } +}; -inline angle_t angle_t::from_rad(fix16_t rad) { - constexpr fix16_t scale{fix16_t::from_double(1.0 / M_PI)}; +static_assert(sizeof(angle) == sizeof(::angle_t)); - // Drop the fractional part of the fixed value - return angle_t{fix16_low_mul(scale, rad)}; -} +/// @brief Not yet documented. +struct __packed __aligned(2) euler { + /// @brief Not yet documented. + angle pitch; + /// @brief Not yet documented. + angle yaw; + /// @brief Not yet documented. + angle roll; +}; + +static_assert(sizeof(euler) == sizeof(::euler_t)); -constexpr inline angle_t angle_t::from_rad_double(double rad) { - constexpr double _2pi = 2.0 * M_PI; +} // namespace yaul - return angle_t{fix16_t::from_double(fmod(rad + _2pi, _2pi) / _2pi).fractional()}; +constexpr yaul::angle +operator"" _deg(long double v) +{ + return yaul::angle::from_deg_double(v); } -constexpr inline angle_t angle_t::from_deg_double(double value) { - return angle_t{fix16_t::from_double(fmod(value + 360.0, 360.0) / 360.0).fractional()}; +constexpr yaul::angle +operator"" _rad(long double v) +{ + return yaul::angle::from_rad_double(v); } -inline size_t angle_t::to_string(char* buffer, int32_t decimals) const { return fix16_t{(uint32_t)value}.to_string(buffer, decimals); } #endif /* !__cplusplus */ /// @} diff --git a/libyaul/gamemath/gamemath/fix16.h b/libyaul/gamemath/gamemath/fix16.h index 7b097537..7147ce6c 100644 --- a/libyaul/gamemath/gamemath/fix16.h +++ b/libyaul/gamemath/gamemath/fix16.h @@ -56,7 +56,6 @@ /// @addtogroup MATH_FIX16 /// @{ -#if !defined(__cplusplus) /// @brief Macro for defininge @p fix16_t constant values. /// /// @note The argument is evaluated multiple times, and also otherwise you @@ -67,75 +66,9 @@ #define FIX16(x) ((fix16_t)(((x) >= 0) \ ? ((double)(x) * 65536.0 + 0.5) \ : ((double)(x) * 65536.0 - 0.5))) -#endif /* !__cplusplus */ -#if !defined(__cplusplus) /// @brief Fixed point Q16.16. typedef int32_t fix16_t; -#else -/// @brief Fixed point Q16.16. -struct fix16_t { - int32_t value; - - fix16_t() = default; - - explicit constexpr fix16_t(int32_t v); - - explicit constexpr fix16_t(uint32_t v); - - // For dealing with C - explicit constexpr operator int32_t() const { return value; } - explicit constexpr operator uint32_t() const { return value; } - - inline fix16_t operator+(fix16_t other) const; - inline fix16_t operator-(fix16_t other) const; - constexpr inline fix16_t operator-() const; - inline fix16_t operator*(fix16_t other) const; - inline fix16_t operator*(int32_t other) const; - inline fix16_t operator*(uint32_t other) const; - inline fix16_t operator/(fix16_t other) const; - inline fix16_t operator>>(int32_t i) const; - inline fix16_t operator<<(int32_t i) const; - - inline fix16_t& operator+=(fix16_t rhs); - inline fix16_t& operator-=(fix16_t rhs); - inline fix16_t& operator*=(fix16_t rhs); - inline fix16_t& operator*=(int32_t rhs); - inline fix16_t& operator*=(uint32_t rhs); - inline fix16_t& operator/=(fix16_t rhs); - inline fix16_t& operator>>=(int32_t i); - inline fix16_t& operator<<=(int32_t i); - - inline bool operator<(fix16_t other) const; - inline bool operator<(int32_t other) const; - inline bool operator>(fix16_t other) const; - inline bool operator>(int32_t other) const; - inline bool operator<=(fix16_t other) const; - inline bool operator<=(int32_t other) const; - inline bool operator>=(fix16_t other) const; - inline bool operator>=(int32_t other) const; - inline bool operator==(fix16_t other) const; - inline bool operator==(int32_t other) const; - - constexpr inline int16_t fractional() const; - - inline bool is_near_zero(fix16_t epsilon = from_double(0.001)) const; - - inline bool is_near(fix16_t other, fix16_t epsilon = from_double(0.001)) const; - - inline bool is_negative() const; - - inline bool is_positive() const; - - constexpr inline int16_t to_int() const; - - inline size_t to_string(char* buffer, int32_t decimals = 7) const; - - constexpr static inline fix16_t from_double(double value); -}; - -static_assert(sizeof(fix16_t) == 4); -#endif /* !__cplusplus */ /// @brief Not yet documented. /// @@ -197,7 +130,7 @@ __BEGIN_ASM static inline fix16_t __always_inline fix16_mul(fix16_t a, fix16_t b) { - __register uint32_t mach; + __register int32_t mach; __register fix16_t out; __declare_asm("\tdmuls.l %[a], %[b]\n" @@ -216,7 +149,6 @@ fix16_mul(fix16_t a, fix16_t b) } __END_ASM -#if !defined(__cplusplus) /// @brief Not yet documented. /// /// @param value Operand. @@ -259,7 +191,7 @@ fix16_round_int32_to(fix16_t value) /// @param value Operand. /// /// @returns The value. -static inline uint32_t __always_inline +static inline int32_t __always_inline fix16_integral(fix16_t value) { return (value & 0xFFFF0000UL); @@ -270,7 +202,7 @@ fix16_integral(fix16_t value) /// @param value Operand. /// /// @returns The value. -static inline uint32_t __always_inline +static inline int32_t __always_inline fix16_fractional(fix16_t value) { return (value & 0x0000FFFFUL); @@ -299,7 +231,6 @@ fix16_ceil(fix16_t value) { return ((value & 0xFFFF0000UL) + ((value & 0x0000FFFFUL) ? FIX16(1.0) : 0)); } -#endif /* !__cplusplus */ __BEGIN_DECLS @@ -366,97 +297,320 @@ extern size_t fix16_str(fix16_t value, char *buffer, int32_t decimals); __END_DECLS #if defined(__cplusplus) -static inline fix16_t abs(fix16_t a) { - return fix16_t{::abs(a.value)}; -} -constexpr fix16_t operator"" _fp(long double v) { return fix16_t::from_double(v); } +__BEGIN_DECLS -constexpr fix16_t::fix16_t(int32_t v) : value(v) {} +static void cpu_divu_fix16_set(fix16_t, fix16_t); +static uint32_t cpu_divu_quotient_get(void); -constexpr fix16_t::fix16_t(uint32_t v) : value(v) {} +__END_DECLS -inline fix16_t fix16_t::operator+(fix16_t other) const { return fix16_t{value + other.value}; } -inline fix16_t fix16_t::operator-(fix16_t other) const { return fix16_t{value - other.value}; } -constexpr inline fix16_t fix16_t::operator-() const { return fix16_t{-value}; } -inline fix16_t fix16_t::operator*(fix16_t other) const { return fix16_mul(*this, other); } -inline fix16_t fix16_t::operator*(int32_t other) const { return fix16_mul(*this, fix16_t{other}); } -inline fix16_t fix16_t::operator*(uint32_t other) const { return fix16_mul(*this, fix16_t{other}); } -inline fix16_t fix16_t::operator/(fix16_t other) const { return fix16_div(*this, other); } +namespace yaul { -inline fix16_t fix16_t::operator>>(int32_t i) const { return fix16_t{value >> i}; } -inline fix16_t fix16_t::operator<<(int32_t i) const { return fix16_t{value << i}; } +struct angle; -inline fix16_t& fix16_t::operator+=(fix16_t rhs) { - value = value + rhs.value; - return *this; -} +/// @brief Fixed point Q16.16. +struct __packed __aligned(4) fix16 +{ + fix16_t value; -inline fix16_t& fix16_t::operator-=(fix16_t rhs) { - value = value - rhs.value; - return *this; -} + fix16() = default; -inline fix16_t& fix16_t::operator*=(fix16_t rhs) { - *this = fix16_mul(*this, rhs); - return *this; -} + explicit constexpr fix16(fix16_t v) + : value(v) + { + } -inline fix16_t& fix16_t::operator*=(int32_t rhs) { - *this = fix16_mul(*this, fix16_t{rhs}); - return *this; -} + // For dealing with C + explicit constexpr operator fix16_t() const + { + return value; + } -inline fix16_t& fix16_t::operator*=(uint32_t rhs) { - *this = fix16_mul(*this, fix16_t{rhs}); - return *this; -} + constexpr fix16 operator+(fix16 other) const + { + return fix16 { value + other.value }; + } + constexpr fix16 operator-(fix16 other) const + { + return fix16 { value - other.value }; + } + constexpr fix16 operator-() const + { + return fix16 { -value }; + } -inline fix16_t& fix16_t::operator/=(fix16_t rhs) { - *this = fix16_div(*this, rhs); - return *this; -} + fix16 operator*(fix16 other) const + { + return fix16 { fix16_mul(value, other.value) }; + } + fix16 operator/(fix16 other) const + { + return fix16 { fix16_div(value, other.value) }; + } -inline fix16_t& fix16_t::operator>>=(int32_t i) { - value = value >> i; - return *this; -} + fix16 operator*(fix16_t other) const + { + return fix16 { fix16_mul(value, other) }; + } + fix16 operator/(fix16_t other) const + { + return fix16 { fix16_div(value, other) }; + } -inline fix16_t& fix16_t::operator<<=(int32_t i) { - value = value >> i; - return *this; -} + constexpr fix16 operator>>(int32_t i) const + { + return fix16 { value >> i }; + } + constexpr fix16 operator<<(int32_t i) const + { + return fix16 { value << i }; + } -inline bool fix16_t::operator<(fix16_t other) const { return value < other.value; } -inline bool fix16_t::operator<(int32_t other) const { return value < other; } -inline bool fix16_t::operator>(fix16_t other) const { return value > other.value; } -inline bool fix16_t::operator>(int32_t other) const { return value > other; } -inline bool fix16_t::operator<=(fix16_t other) const { return value <= other.value; } -inline bool fix16_t::operator<=(int32_t other) const { return value <= other; } -inline bool fix16_t::operator>=(fix16_t other) const { return value >= other.value; } -inline bool fix16_t::operator>=(int32_t other) const { return value >= other; } -inline bool fix16_t::operator==(fix16_t other) const { return value == other.value; } -inline bool fix16_t::operator==(int32_t other) const { return value == other; } - -constexpr inline fix16_t fix16_t::from_double(double value) { - return fix16_t{static_cast((value >= 0) ? ((value * 65536.0) + 0.5) : ((value * 65536.0) - 0.5))}; -} + fix16 &operator+=(fix16 rhs) + { + value += rhs.value; + return *this; + } + fix16 &operator-=(fix16 rhs) + { + value -= rhs.value; + return *this; + } + fix16 &operator*=(fix16 rhs) + { + value = fix16_mul(value, rhs.value); + return *this; + } + fix16 &operator/=(fix16 rhs) + { + value = fix16_div(value, rhs.value); + return *this; + } -static inline fix16_t sqrt(fix16_t value) { return fix16_sqrt(value); } + fix16 &operator*=(fix16_t rhs) + { + value = fix16_mul(value, rhs); + return *this; + } + fix16 &operator/=(fix16_t rhs) + { + value = fix16_div(value, rhs); + return *this; + } -constexpr inline int16_t fix16_t::fractional() const { return (value & 0x0000FFFF); } + fix16 &operator>>=(int32_t i) + { + value >>= i; + return *this; + } + fix16 &operator<<=(int32_t i) + { + value <<= i; + return *this; + } -inline bool fix16_t::is_near_zero(fix16_t epsilon) const { return abs(*this) <= epsilon; } + bool operator<(fix16 other) const + { + return value < other.value; + } + bool operator>(fix16 other) const + { + return value > other.value; + } + bool operator<=(fix16 other) const + { + return value <= other.value; + } + bool operator>=(fix16 other) const + { + return value >= other.value; + } + bool operator==(fix16 other) const + { + return value == other.value; + } -inline bool fix16_t::is_near(fix16_t other, fix16_t epsilon) const { return abs(*this - other) <= epsilon; } + bool operator<(fix16_t other) const + { + return value < other; + } + bool operator>(fix16_t other) const + { + return value > other; + } + bool operator<=(fix16_t other) const + { + return value <= other; + } + bool operator>=(fix16_t other) const + { + return value >= other; + } + bool operator==(fix16_t other) const + { + return value == other; + } -inline bool fix16_t::is_negative() const { return (value < 0); } + void to_minimum_value() + { + value = INT32_MIN; + } -inline bool fix16_t::is_positive() const { return (value >= 0); } + void to_maximum_value() + { + value = INT32_MAX; + } -constexpr inline int16_t fix16_t::to_int() const { return (value / 65536); } + void negate() + { + value = -value; + } + + fix16 negated() const + { + return fix16 { -value }; + } + + fix16 abs() const + { + return fix16 { ::abs(value) }; + } + + fix16 sqrt() const + { + return fix16 { fix16_sqrt(value) }; + } + + fix16 deg_to_rad() const + { + constexpr fix16_t scale { FIX16(M_PI / 180.0) }; + return fix16 { fix16_mul(value, scale) }; + } + + fix16 rad_to_deg() const + { + constexpr fix16_t scale { FIX16(180.0 / M_PI) }; + return fix16 { fix16_mul(value, scale) }; + } + + angle rad_to_angle() const; + + angle deg_to_angle() const; + + fix16 approximate_distance(fix16 other) const + { + const fix16 dx { abs() }; + const fix16 dy { other.abs() }; + if (dx < dy) + return dx + dy - (dx >> 1); + else + return dx + dy - (dy >> 1); + } + + int32_t mul_to_int32(fix16 other) const + { + return static_cast( + (static_cast(value) * static_cast(other.value)) >> + 32); + } + + constexpr int16_t fractional() const + { + return (value & 0x0000FFFF); + } + + bool is_near_zero(fix16 epsilon) const + { + return ::abs(value) <= epsilon.value; + } + + bool is_near_zero(fix16_t epsilon) const + { + return ::abs(value) <= epsilon; + } + + bool is_near(fix16 other, fix16 epsilon) const + { + return ::abs(value - other.value) <= epsilon.value; + } + + bool is_near(fix16_t other, fix16_t epsilon) const + { + return ::abs(value - other) <= epsilon; + } + + constexpr bool is_negative() const + { + return (value < 0); + } + + constexpr bool is_positive() const + { + return (value >= 0); + } + + constexpr int32_t to_int() const + { + return (value >> 16); + } + + size_t to_string(char *buffer, int32_t decimals) const + { + return fix16_str(value, buffer, decimals); + } + + static constexpr fix16 from_int(int32_t i) + { + return fix16 { i * FIX16(1.0) }; + } + + static constexpr fix16 from_double(double value) + { + return fix16 { FIX16(value) }; + } + + static void start_divu_1_over_value(fix16 v) + { + ::cpu_divu_fix16_set(one().value, v.value); + } + + static void start_divu(fix16 num, fix16 denom) + { + ::cpu_divu_fix16_set(num.value, denom.value); + } + + static fix16 get_divu_quotient() + { + return fix16 { static_cast(::cpu_divu_quotient_get()) }; + } + + static constexpr fix16 zero() + { + return fix16 { FIX16(0.0) }; + } + + static constexpr fix16 one() + { + return fix16 { FIX16(1.0) }; + } + + static constexpr fix16 minus_one() + { + return fix16 { FIX16(-1.0) }; + } +}; + +static_assert(sizeof(fix16) == sizeof(::fix16_t)); + +} // namespace yaul + +constexpr yaul::fix16 +operator"" _fp(long double v) +{ + return yaul::fix16::from_double(v); +} -inline size_t fix16_t::to_string(char* buffer, int32_t decimals) const { return fix16_str(*this, buffer, decimals); } #endif /* __cplusplus */ /// @} diff --git a/libyaul/gamemath/gamemath/fix16/fix16_mat33.h b/libyaul/gamemath/gamemath/fix16/fix16_mat33.h index 6bc285c3..4b103b26 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_mat33.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_mat33.h @@ -28,68 +28,13 @@ /// @brief Not yet documented. #define FIX16_MAT33_ARR_COUNT (FIX16_MAT33_COLUMNS * FIX16_MAT33_ROWS) -#if !defined(__cplusplus) /// @brief Not yet documented. /// /// @note Row-major matrix. typedef struct fix16_mat33 { /// @brief Not yet documented. fix16_vec3_t row[FIX16_MAT33_ROWS]; -} fix16_mat33_t; -#else -struct fix16_mat33_t { - fix16_vec3_t row[FIX16_MAT33_ROWS]; - - fix16_mat33_t() = default; - fix16_mat33_t(fix16_mat33_t&&) = default; - fix16_mat33_t(const fix16_mat33_t&) = default; - - constexpr fix16_mat33_t( - // Row 0 - fix16_t m00, fix16_t m01, fix16_t m02, - // Row 1 - fix16_t m10, fix16_t m11, fix16_t m12, - // Row 2 - fix16_t m20, fix16_t m21, fix16_t m22); - - fix16_mat33_t(const fix16_vec3_t& row0, const fix16_vec3_t& row1, const fix16_vec3_t& row2); - - fix16_mat33_t& operator=(const fix16_mat33_t& other) = default; - fix16_mat33_t& operator=(fix16_mat33_t&& other) = default; - - inline fix16_mat33_t operator*(const fix16_mat33_t& other) const; - - static inline constexpr fix16_mat33_t from_double( - // Row 0 - double m00, double m01, double m02, - // Row 1 - double m10, double m11, double m12, - // Row 2 - double m20, double m21, double m22); - - inline void identity(); - - inline void zero(); - - inline void transpose(); - - inline void invert(); - - inline size_t to_string(char* buffer, int32_t decimals = 7) const; - - static inline void create_rotx(const fix16_mat33_t& m0, angle_t x, fix16_mat33_t& result); - - static inline void create_roty(const fix16_mat33_t& m0, angle_t y, fix16_mat33_t& result); - - static inline void create_rotz(const fix16_mat33_t& m0, angle_t z, fix16_mat33_t& result); - - static inline void create_rot(const euler_t& angles, fix16_mat33_t& result); - - static inline fix16_vec3_t transform_vector(const fix16_mat33_t& m0, const fix16_vec3_t& v); -}; - -static_assert(sizeof(fix16_mat33_t) == (sizeof(fix16_t) * FIX16_MAT33_ARR_COUNT)); -#endif /* !__cplusplus */ +} __packed __aligned(4) fix16_mat33_t; __BEGIN_DECLS @@ -210,78 +155,133 @@ extern size_t fix16_mat33_str(const fix16_mat33_t *m0, char *buffer, __END_DECLS #ifdef __cplusplus -constexpr fix16_mat33_t::fix16_mat33_t( - // Row 0 - fix16_t m00, fix16_t m01, fix16_t m02, - // Row 1 - fix16_t m10, fix16_t m11, fix16_t m12, - // Row 2 - fix16_t m20, fix16_t m21, fix16_t m22) - : row({// Row 0 - {m00, m01, m02}, - // Row 1 - {m10, m11, m12}, - // Row 2 - {m20, m21, m22}}) {} - -inline fix16_mat33_t fix16_mat33_t::operator*(const fix16_mat33_t& other) const { - fix16_mat33_t result; - fix16_mat33_mul(this, &other, &result); - - return result; -} - -inline constexpr fix16_mat33_t fix16_mat33_t::from_double( - // Row 0 - double m00, double m01, double m02, - // Row 1 - double m10, double m11, double m12, - // Row 2 - double m20, double m21, double m22) { - return fix16_mat33_t{ - // Row 0 - fix16_t::from_double(m00), fix16_t::from_double(m01), fix16_t::from_double(m02), - // Row 1 - fix16_t::from_double(m10), fix16_t::from_double(m11), fix16_t::from_double(m12), - // Row 2 - fix16_t::from_double(m20), fix16_t::from_double(m21), fix16_t::from_double(m22)}; -} - -inline void fix16_mat33_t::identity() { fix16_mat33_identity(this); } - -inline void fix16_mat33_t::zero() { fix16_mat33_zero(this); } - -inline void fix16_mat33_t::transpose() { fix16_mat33_inplace_transpose(this); } -inline void fix16_mat33_t::invert() { transpose(); } +namespace yaul { -inline size_t fix16_mat33_t::to_string(char* buffer, int32_t decimals) const { - return fix16_mat33_str(this, buffer, decimals); -} +struct __packed __aligned(4) fix16_mat33 { + fix16_vec3 row[FIX16_MAT33_ROWS]; -inline void fix16_mat33_t::create_rotx(const fix16_mat33_t& m0, angle_t x, fix16_mat33_t& result) { - fix16_mat33_x_rotate(&m0, x, &result); -} + fix16_mat33() = default; + fix16_mat33(fix16_mat33 &&) = default; + fix16_mat33(const fix16_mat33 &) = default; -inline void fix16_mat33_t::create_roty(const fix16_mat33_t& m0, angle_t y, fix16_mat33_t& result) { - fix16_mat33_y_rotate(&m0, y, &result); -} + constexpr explicit fix16_mat33(const fix16_mat33_t &other) + : row({ + fix16_vec3 { other.row[0] }, + fix16_vec3 { other.row[1] }, + fix16_vec3 { other.row[2] }, + }) + { + } -inline void fix16_mat33_t::create_rotz(const fix16_mat33_t& m0, angle_t z, fix16_mat33_t& result) { - fix16_mat33_z_rotate(&m0, z, &result); -} - -inline void fix16_mat33_t::create_rot(const euler_t& angles, fix16_mat33_t& result) { - fix16_mat33_rotation_create(angles.pitch, angles.yaw, angles.roll, &result); -} + constexpr explicit fix16_mat33( + // Row 0 + fix16 m00, fix16 m01, fix16 m02, + // Row 1 + fix16 m10, fix16 m11, fix16 m12, + // Row 2 + fix16 m20, fix16 m21, fix16 m22) + : row({ + // Row 0 + fix16_vec3{ m00, m01, m02 }, + // Row 1 + fix16_vec3{ m10, m11, m12 }, + // Row 2 + fix16_vec3{ m20, m21, m22 }, + }) + { + } + + fix16_mat33_t *as_fix16_mat33_t() + { + return reinterpret_cast(this); + } + + const fix16_mat33_t *as_fix16_mat33_t() const + { + return reinterpret_cast(this); + } + + fix16_mat33 operator*(const fix16_mat33 &other) const + { + fix16_mat33_t result; + fix16_mat33_mul(as_fix16_mat33_t(), other.as_fix16_mat33_t(), &result); + + return fix16_mat33 { result }; + } + + static constexpr fix16_mat33 from_double( + // Row 0 + double m00, double m01, double m02, + // Row 1 + double m10, double m11, double m12, + // Row 2 + double m20, double m21, double m22) + { + return fix16_mat33 { + // Row 0 + fix16::from_double(m00), + fix16::from_double(m01), + fix16::from_double(m02), + // Row 1 + fix16::from_double(m10), + fix16::from_double(m11), + fix16::from_double(m12), + // Row 2 + fix16::from_double(m20), + fix16::from_double(m21), + fix16::from_double(m22), + }; + } + + void identity() { fix16_mat33_identity(as_fix16_mat33_t()); } + + void zero() { fix16_mat33_zero(as_fix16_mat33_t()); } + + void transpose() { fix16_mat33_inplace_transpose(as_fix16_mat33_t()); } + + void invert() { transpose(); } + + size_t to_string(char *buffer, int32_t decimals) const + { + return fix16_mat33_str(as_fix16_mat33_t(), buffer, decimals); + } + + void create_rotx(const fix16_mat33 &m0, angle x, fix16_mat33 &result) + { + fix16_mat33_x_rotate(m0.as_fix16_mat33_t(), x.value, result.as_fix16_mat33_t()); + } + + void create_roty(const fix16_mat33 &m0, angle y, fix16_mat33 &result) + { + fix16_mat33_y_rotate(m0.as_fix16_mat33_t(), y.value, result.as_fix16_mat33_t()); + } + + void create_rotz(const fix16_mat33 &m0, angle z, fix16_mat33 &result) + { + fix16_mat33_z_rotate(m0.as_fix16_mat33_t(), z.value, result.as_fix16_mat33_t()); + } + + void create_rot(const euler &angles, fix16_mat33 &result) + { + fix16_mat33_rotation_create(angles.pitch.value, angles.yaw.value, + angles.roll.value, result.as_fix16_mat33_t()); + } + + fix16_vec3 transform_vector(const fix16_mat33 &m0, const fix16_vec3 &v) + { + fix16_vec3_t result; + fix16_mat33_vec3_mul(m0.as_fix16_mat33_t(), v.as_fix16_vec3_t(), + &result); + + return fix16_vec3 { result }; + } +}; -inline fix16_vec3_t fix16_mat33_t::transform_vector(const fix16_mat33_t& m0, const fix16_vec3_t& v) { - fix16_vec3_t result; +static_assert(sizeof(fix16_mat33) == sizeof(fix16_mat33_t)); - fix16_mat33_vec3_mul(&m0, &v, &result); +} // namespace yaul - return result; -} #endif /* __cplusplus */ /// @} diff --git a/libyaul/gamemath/gamemath/fix16/fix16_mat43.h b/libyaul/gamemath/gamemath/fix16/fix16_mat43.h index b8590127..750d8e80 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_mat43.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_mat43.h @@ -26,7 +26,6 @@ /// @brief Not yet documented. #define FIX16_MAT43_ARR_COUNT (FIX16_MAT43_COLUMNS * FIX16_MAT43_ROWS) -#if !defined(__cplusplus) /// @cond // TODO: Remove this struct fix16_vec3; @@ -46,80 +45,6 @@ typedef struct fix16_mat43 { /// @brief Not yet documented. fix16_vec3_t translation; } fix16_mat43_t; -#else -struct fix16_vec3_t; -struct fix16_mat33_t; - -struct fix16_mat43_t { - /// @brief Not yet documented. - fix16_mat33_t rotation; - /// @brief Not yet documented. - fix16_vec3_t translation; - - fix16_mat43_t() = default; - fix16_mat43_t(fix16_mat43_t&&) = default; - fix16_mat43_t(const fix16_mat43_t&) = default; - - constexpr fix16_mat43_t( - // Row 0 - fix16_t m00, fix16_t m01, fix16_t m02, - // Row 1 - fix16_t m10, fix16_t m11, fix16_t m12, - // Row 2 - fix16_t m20, fix16_t m21, fix16_t m22, - // Row 3 - fix16_t m30, fix16_t m31, fix16_t m32); - - fix16_mat43_t(const fix16_vec3_t& row0, const fix16_vec3_t& row1, const fix16_vec3_t& row2, const fix16_vec3_t& row3); - - fix16_mat43_t& operator=(const fix16_mat43_t& other) = default; - fix16_mat43_t& operator=(fix16_mat43_t&& other) = default; - - inline fix16_mat43_t operator*(const fix16_mat43_t& other) const; - - static inline constexpr fix16_mat43_t identity(); - - static inline constexpr fix16_mat43_t zero(); - - static inline constexpr fix16_mat43_t from_double( - // Row 0 - double m00, double m01, double m02, - // Row 1 - double m10, double m11, double m12, - // Row 2 - double m20, double m21, double m22, - // Row 3 - double m30, double m31, double m32); - - inline void set_identity(); - - inline void set_zero(); - - inline void invert(); - - inline void rotate_x(angle_t pitch); - - inline void rotate_y(angle_t yaw); - - inline void rotate_z(angle_t roll); - - inline size_t to_string(char* buffer, int32_t decimals = 7) const; - - static inline void create_rotx(angle_t pitch, fix16_mat43_t& result); - - static inline void create_roty(angle_t yaw, fix16_mat43_t& result); - - static inline void create_rotz(angle_t roll, fix16_mat43_t& result); - - static inline void create_rot(const euler_t& angles, fix16_mat43_t& result); - - static inline fix16_vec3_t transform_vector(const fix16_mat43_t& m0, const fix16_vec3_t& v); - - static inline fix16_vec3_t transform_position(const fix16_mat43_t& m0, const fix16_vec3_t& v); -}; - -static_assert(sizeof(fix16_mat43_t) == (sizeof(fix16_t) * FIX16_MAT43_ARR_COUNT)); -#endif /* !__cplusplus */ __BEGIN_DECLS @@ -257,120 +182,230 @@ extern size_t fix16_mat43_str(const fix16_mat43_t *m0, char *buffer, __END_DECLS #ifdef __cplusplus -constexpr fix16_mat43_t::fix16_mat43_t( - // Row 0 - fix16_t m00, fix16_t m01, fix16_t m02, - // Row 1 - fix16_t m10, fix16_t m11, fix16_t m12, - // Row 2 - fix16_t m20, fix16_t m21, fix16_t m22, - // Row 3 - fix16_t m30, fix16_t m31, fix16_t m32) - : rotation(// Row 0 - m00, m01, m02, - // Row 1 - m10, m11, m12, - // Row 2 - m20, m21, m22), - translation(m30, m31, m32) {} - -inline fix16_mat43_t fix16_mat43_t::operator*(const fix16_mat43_t& other) const { - fix16_mat43_t result; - - fix16_mat43_mul(this, &other, &result); - - return result; -} - -inline constexpr fix16_mat43_t fix16_mat43_t::identity() { - return fix16_mat43_t{// Row 0 - 1.0_fp, 0.0_fp, 0.0_fp, - // Row 1 - 0.0_fp, 1.0_fp, 0.0_fp, - // Row 2 - 0.0_fp, 0.0_fp, 1.0_fp, - // Row 3 - 0.0_fp, 0.0_fp, 0.0_fp}; -} - -inline constexpr fix16_mat43_t fix16_mat43_t::zero() { - return fix16_mat43_t{// Row 0 - 0.0_fp, 0.0_fp, 0.0_fp, - // Row 1 - 0.0_fp, 0.0_fp, 0.0_fp, - // Row 2 - 0.0_fp, 0.0_fp, 0.0_fp, - // Row 3 - 0.0_fp, 0.0_fp, 0.0_fp}; -} - -inline constexpr fix16_mat43_t fix16_mat43_t::from_double( - // Row 0 - double m00, double m01, double m02, - // Row 1 - double m10, double m11, double m12, - // Row 2 - double m20, double m21, double m22, - // Row 3 - double m30, double m31, double m32) { - return fix16_mat43_t{ - // Row 0 - fix16_t::from_double(m00), fix16_t::from_double(m01), fix16_t::from_double(m02), - // Row 1 - fix16_t::from_double(m10), fix16_t::from_double(m11), fix16_t::from_double(m12), - // Row 2 - fix16_t::from_double(m20), fix16_t::from_double(m21), fix16_t::from_double(m22), - // Row 3 - fix16_t::from_double(m30), fix16_t::from_double(m31), fix16_t::from_double(m32)}; -} - -inline void fix16_mat43_t::set_identity() { fix16_mat43_identity(this); } - -inline void fix16_mat43_t::set_zero() { fix16_mat43_zero(this); } - -inline void fix16_mat43_t::invert() { fix16_mat43_inplace_invert(this); } -inline void fix16_mat43_t::rotate_x(angle_t pitch) { fix16_mat43_x_rotate(this, pitch, this); } +namespace yaul { -inline void fix16_mat43_t::rotate_y(angle_t yaw) { fix16_mat43_y_rotate(this, yaw, this); } - -inline void fix16_mat43_t::rotate_z(angle_t roll) { fix16_mat43_z_rotate(this, roll, this); } - -inline size_t fix16_mat43_t::to_string(char* buffer, int32_t decimals) const { - return fix16_mat43_str(this, buffer, decimals); -} - -inline void fix16_mat43_t::create_rotx(angle_t pitch, fix16_mat43_t& result) { - fix16_mat43_x_rotation_set(pitch, &result); -} - -inline void fix16_mat43_t::create_roty(angle_t yaw, fix16_mat43_t& result) { - fix16_mat43_y_rotation_set(yaw, &result); -} - -inline void fix16_mat43_t::create_rotz(angle_t roll, fix16_mat43_t& result) { - fix16_mat43_z_rotation_set(roll, &result); -} +struct fix16_vec3; +struct fix16_mat33; -inline void fix16_mat43_t::create_rot(const euler_t& angles, fix16_mat43_t& result) { - fix16_mat43_rotation_set(angles.pitch, angles.yaw, angles.roll, &result); -} +struct __packed __aligned(4) fix16_mat43 { + /// @brief Not yet documented. + fix16_mat33 rotation; + /// @brief Not yet documented. + fix16_vec3 translation; -inline fix16_vec3_t fix16_mat43_t::transform_vector(const fix16_mat43_t& m0, const fix16_vec3_t& v) { - fix16_vec3_t result; + fix16_mat43() = default; + fix16_mat43(fix16_mat43 &&) = default; + fix16_mat43(const fix16_mat43 &) = default; - fix16_mat43_vec3_mul(&m0, &v, &result); + constexpr explicit fix16_mat43(const fix16_mat43_t &other) + : rotation(fix16_mat33 { other.rotation }) + , translation(fix16_vec3 { other.translation }) + { + } - return result; -} + constexpr explicit fix16_mat43( + // Row 0 + fix16_t m00, fix16_t m01, fix16_t m02, + // Row 1 + fix16_t m10, fix16_t m11, fix16_t m12, + // Row 2 + fix16_t m20, fix16_t m21, fix16_t m22, + // Row 3 + fix16_t m30, fix16_t m31, fix16_t m32) + : rotation( // Row 0 + fix16 { m00 }, fix16 { m01 }, fix16 { m02 }, + // Row 1 + fix16 { m10 }, fix16 { m11 }, fix16 { m12 }, + // Row 2 + fix16 { m20 }, fix16 { m21 }, fix16 { m22 }) + , translation(fix16 { m30 }, fix16 { m31 }, fix16 { m32 }) + { + } + + constexpr fix16_mat43( + // Row 0 + fix16 m00, fix16 m01, fix16 m02, + // Row 1 + fix16 m10, fix16 m11, fix16 m12, + // Row 2 + fix16 m20, fix16 m21, fix16 m22, + // Row 3 + fix16 m30, fix16 m31, fix16 m32) + : rotation( // Row 0 + m00, m01, m02, + // Row 1 + m10, m11, m12, + // Row 2 + m20, m21, m22) + , translation(m30, m31, m32) + { + } + + fix16_mat43_t *as_fix16_mat43_t() + { + return reinterpret_cast(this); + } + + const fix16_mat43_t *as_fix16_mat43_t() const + { + return reinterpret_cast(this); + } + + fix16_mat43 operator*(const fix16_mat43 &other) const + { + fix16_mat43_t result; + fix16_mat43_mul(as_fix16_mat43_t(), other.as_fix16_mat43_t(), &result); + + return fix16_mat43 { result }; + } + + static constexpr fix16_mat43 identity() + { + return fix16_mat43 { + // Row 0 + 1.0_fp, + 0.0_fp, + 0.0_fp, + // Row 1 + 0.0_fp, + 1.0_fp, + 0.0_fp, + // Row 2 + 0.0_fp, + 0.0_fp, + 1.0_fp, + // Row 3 + 0.0_fp, + 0.0_fp, + 0.0_fp, + }; + } + + static constexpr fix16_mat43 zero() + { + return fix16_mat43 { + // Row 0 + 0.0_fp, + 0.0_fp, + 0.0_fp, + // Row 1 + 0.0_fp, + 0.0_fp, + 0.0_fp, + // Row 2 + 0.0_fp, + 0.0_fp, + 0.0_fp, + // Row 3 + 0.0_fp, + 0.0_fp, + 0.0_fp, + }; + } + + static constexpr fix16_mat43 from_double( + // Row 0 + double m00, double m01, double m02, + // Row 1 + double m10, double m11, double m12, + // Row 2 + double m20, double m21, double m22, + // Row 3 + double m30, double m31, double m32) + { + return fix16_mat43 { + // Row 0 + fix16::from_double(m00), + fix16::from_double(m01), + fix16::from_double(m02), + // Row 1 + fix16::from_double(m10), + fix16::from_double(m11), + fix16::from_double(m12), + // Row 2 + fix16::from_double(m20), + fix16::from_double(m21), + fix16::from_double(m22), + // Row 3 + fix16::from_double(m30), + fix16::from_double(m31), + fix16::from_double(m32), + }; + } + + inline void set_identity() { fix16_mat43_identity(as_fix16_mat43_t()); } + + inline void set_zero() { fix16_mat43_zero(as_fix16_mat43_t()); } + + inline void invert() { fix16_mat43_inplace_invert(as_fix16_mat43_t()); } + + inline void rotate_x(angle pitch) + { + fix16_mat43_x_rotate(as_fix16_mat43_t(), pitch.value, as_fix16_mat43_t()); + } + + inline void rotate_y(angle yaw) + { + fix16_mat43_y_rotate(as_fix16_mat43_t(), yaw.value, as_fix16_mat43_t()); + } + + inline void rotate_z(angle roll) + { + fix16_mat43_z_rotate(as_fix16_mat43_t(), roll.value, + as_fix16_mat43_t()); + } + + inline size_t to_string(char *buffer, int32_t decimals) const + { + return fix16_mat43_str(as_fix16_mat43_t(), buffer, decimals); + } + + inline void create_rotx(angle pitch, fix16_mat43 & result) + { + fix16_mat43_x_rotation_set(pitch.value, result.as_fix16_mat43_t()); + } + + inline void create_roty(angle yaw, fix16_mat43 & result) + { + fix16_mat43_y_rotation_set(yaw.value, result.as_fix16_mat43_t()); + } + + inline void create_rotz(angle roll, fix16_mat43 & result) + { + fix16_mat43_z_rotation_set(roll.value, result.as_fix16_mat43_t()); + } + + inline void create_rot(const euler &angles, fix16_mat43 &result) + { + fix16_mat43_rotation_set(angles.pitch.value, angles.yaw.value, + angles.roll.value, result.as_fix16_mat43_t()); + } + + inline fix16_vec3 transform_vector(const fix16_mat43 &m0, + const fix16_vec3 &v) + { + fix16_vec3_t result; + fix16_mat43_vec3_mul(m0.as_fix16_mat43_t(), v.as_fix16_vec3_t(), + &result); + + return fix16_vec3 { result }; + } + + inline fix16_vec3 transform_position(const fix16_mat43 &m0, + const fix16_vec3 &v) + { + fix16_vec3_t result; + fix16_mat43_pos3_mul(m0.as_fix16_mat43_t(), v.as_fix16_vec3_t(), &result); + + return fix16_vec3{result}; + } +}; -inline fix16_vec3_t fix16_mat43_t::transform_position(const fix16_mat43_t& m0, const fix16_vec3_t& v) { - fix16_vec3_t result; +static_assert(sizeof(fix16_mat43) == (sizeof(fix16_t) * FIX16_MAT43_ARR_COUNT)); - fix16_mat43_pos3_mul(&m0, &v, &result); +} // namespace yaul - return result; -} #endif /* __cplusplus */ /// @} diff --git a/libyaul/gamemath/gamemath/fix16/fix16_quat.h b/libyaul/gamemath/gamemath/fix16/fix16_quat.h index 8d432155..a7bab248 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_quat.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_quat.h @@ -22,7 +22,6 @@ /// @ingroup MATH_FIX16_VECTOR /// @{ -#if !defined(__cplusplus) /// @brief Macro for defininge @p fix16_quat_t constant values. /// /// @note The argument is evaluated multiple times, and also otherwise you @@ -42,54 +41,13 @@ }, \ FIX16(w) \ } -#endif /* !__cplusplus */ -#if !defined(__cplusplus) /// @brief Fixed point Q16.16. typedef struct { fix16_vec3_t comp; /// @brief Not yet documented. fix16_t w; -} fix16_quat_t; -#else -/// @brief Fixed point Q16.16. -struct fix16_quat_t { - /// @brief Not yet documented. - fix16_vec3_t comp; - /// @brief Not yet documented. - fix16_t w; - - fix16_quat_t() = default; - fix16_quat_t(fix16_quat_t&&) = default; - fix16_quat_t(const fix16_quat_t&) = default; - - constexpr inline fix16_quat_t(fix16_t x_, fix16_t y_, fix16_t z_, fix16_t w_); - constexpr inline fix16_quat_t(const fix16_vec3_t& comp_, fix16_t w_); - - ~fix16_quat_t() = default; - - fix16_quat_t& operator=(const fix16_quat_t& other) = default; - fix16_quat_t& operator=(fix16_quat_t&& other) = default; - - inline const fix16_quat_t operator*(const fix16_quat_t& other) const; - - inline size_t to_string(char* buffer, int32_t decimals = 7) const; - - /// - static inline fix16_quat_t from_euler(const euler_t& angles); - - /// - static inline fix16_quat_t from_axis_angle(const fix16_vec3_t& axis, angle_t angle); - - /// - static inline constexpr fix16_quat_t from_double(double x, double y, double z, double w); - - /// - static inline fix16_quat_t conjugate(const fix16_quat_t& q); -}; - -static_assert(sizeof(fix16_quat_t) == 16); -#endif /* !__cplusplus */ +} __packed __aligned(4) fix16_quat_t; __BEGIN_DECLS @@ -145,43 +103,102 @@ extern size_t fix16_quat_str(const fix16_quat_t *q0, char *buffer, __END_DECLS #if defined(__cplusplus) -constexpr inline fix16_quat_t::fix16_quat_t(fix16_t x_, fix16_t y_, fix16_t z_, fix16_t w_) : comp({x_, y_, z_}), w(w_) { } - -constexpr inline fix16_quat_t::fix16_quat_t(const fix16_vec3_t& comp_, fix16_t w_) : comp(comp_), w(w_) { } - -inline const fix16_quat_t fix16_quat_t::operator*(const fix16_quat_t& other) const { - fix16_quat_t result; - fix16_quat_mul(this, &other, &result); - - return result; -} - -inline size_t fix16_quat_t::to_string(char* buffer, int32_t decimals) const { return fix16_quat_str(this, buffer, decimals); } - -inline fix16_quat_t fix16_quat_t::from_euler(const euler_t& angles) { - fix16_quat_t result; - fix16_quat_euler(angles.pitch, angles.yaw, angles.roll, &result); - - return result; -} -inline fix16_quat_t fix16_quat_t::from_axis_angle(const fix16_vec3_t& axis, angle_t angle) { - fix16_quat_t result; - fix16_quat_axis_angle(&axis, angle, &result); +namespace yaul { - return result; -} +/// @brief Fixed point Q16.16. +struct __packed __aligned(4) fix16_quat { + /// @brief Not yet documented. + fix16_vec3 comp; + /// @brief Not yet documented. + fix16 w; + + fix16_quat() = default; + fix16_quat(fix16_quat&&) = default; + fix16_quat(const fix16_quat&) = default; + + constexpr explicit fix16_quat(const fix16_quat_t& other) + : comp(other.comp) + , w(other.w) + { + } + + constexpr explicit fix16_quat(fix16 x_, fix16 y_, fix16 z_, fix16 w_) + : comp(x_, y_, z_) + , w(w_) + { + } + + constexpr explicit fix16_quat(const fix16_vec3 &comp_, fix16 w_) + : comp(comp_) + , w(w_) + { + } + + ~fix16_quat() = default; + + fix16_quat &operator=(const fix16_quat &other) = default; + fix16_quat &operator=(fix16_quat &&other) = default; + + fix16_quat_t* as_fix16_quat_t() + { + return reinterpret_cast(this); + } + + const fix16_quat_t* as_fix16_quat_t() const + { + return reinterpret_cast(this); + } + + const fix16_quat operator*(const fix16_quat &other) const + { + fix16_quat_t result; + fix16_quat_mul(as_fix16_quat_t(), other.as_fix16_quat_t(), &result); + + return fix16_quat { result }; + } + + size_t to_string(char *buffer, int32_t decimals) const + { + return fix16_quat_str(as_fix16_quat_t(), buffer, decimals); + } + + fix16_quat from_euler(const euler &angles) + { + fix16_quat_t result; + fix16_quat_euler(angles.pitch.value, angles.yaw.value, + angles.roll.value, &result); + + return fix16_quat{ result }; + } + + fix16_quat from_axis_angle(const fix16_vec3 &axis, angle angle) + { + fix16_quat_t result; + fix16_quat_axis_angle(axis.as_fix16_vec3_t(), angle.value, &result); + + return fix16_quat { result }; + } + + static constexpr fix16_quat from_double(double x, double y, double z, double w) + { + return fix16_quat { fix16::from_double(x), fix16::from_double(y), + fix16::from_double(z), fix16::from_double(w) }; + } + + static fix16_quat conjugate(const fix16_quat &q) + { + fix16_quat_t result; + fix16_quat_conjugate(q.as_fix16_quat_t(), &result); + + return fix16_quat { result }; + } +}; -constexpr inline fix16_quat_t fix16_quat_t::from_double(double x, double y, double z, double w) { - return fix16_quat_t{{fix16_t::from_double(x), fix16_t::from_double(y), fix16_t::from_double(z)}, fix16_t::from_double(w)}; -} +static_assert(sizeof(fix16_quat) == sizeof(::fix16_quat_t)); -inline fix16_quat_t fix16_quat_t::conjugate(const fix16_quat_t& q) { - fix16_quat_t result; - fix16_quat_conjugate(&q, &result); +} // namespace yaul - return result; -} #endif /* __cplusplus */ /// @} diff --git a/libyaul/gamemath/gamemath/fix16/fix16_trig.h b/libyaul/gamemath/gamemath/fix16/fix16_trig.h index 4971f896..59661361 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_trig.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_trig.h @@ -56,18 +56,6 @@ extern angle_t fix16_atan2(fix16_t y, fix16_t x); __END_DECLS -#if defined(__cplusplus) -static inline fix16_t cos(angle_t angle) { return fix16_cos(angle); } - -static inline fix16_t sin(angle_t angle) { return fix16_sin(angle); } - -static inline fix16_t tan(angle_t angle) { return fix16_tan(angle); } - -static inline void sincos(angle_t angle, fix16_t& out_sin, fix16_t& out_cos) { - fix16_sincos(angle, &out_sin, &out_cos); -} -#endif /* __cplusplus */ - /// @} #endif /* !_YAUL_GAMEMATH_FIX16_TRIG_H_ */ diff --git a/libyaul/gamemath/gamemath/fix16/fix16_vec2.h b/libyaul/gamemath/gamemath/fix16/fix16_vec2.h index 58088fa0..2474544b 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_vec2.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_vec2.h @@ -16,7 +16,6 @@ /// @ingroup MATH_FIX16_VECTOR /// @{ -#if !defined(__cplusplus) /// @brief Not yet documented. /// /// @param x Not yet documented. @@ -36,33 +35,15 @@ FIX16(x), \ FIX16(y) \ }) -#endif /* !__cplusplus */ -#if !defined(__cplusplus) /// @param x Not yet documented. typedef struct fix16_vec2 { /// @param x Not yet documented. fix16_t x; /// @param x Not yet documented. fix16_t y; -} fix16_vec2_t; -#else -/// @brief Not yet documented. -struct fix16_vec2_t { - /// @brief Not yet documented. - fix16_t x; - /// @brief Not yet documented. - fix16_t y; - - fix16_vec2_t() { } - fix16_vec2_t(fix16_vec2_t&&) = default; - fix16_vec2_t(const fix16_vec2_t&) = default; -}; - -static_assert(sizeof(fix16_vec2_t) == 8); -#endif /* !__cplusplus */ +} __packed __aligned(4) fix16_vec2_t; -#if !defined(__cplusplus) /// @brief Not yet documented. /// /// @param result Not yet documented. @@ -165,7 +146,6 @@ fix16_vec2_inline_dot(const fix16_vec2_t *a, const fix16_vec2_t *b) return aux1; } __END_ASM -#endif /* !__cplusplus */ __BEGIN_DECLS @@ -207,8 +187,30 @@ extern fix16_t fix16_vec2_dot(const fix16_vec2_t *v0, const fix16_vec2_t *v1); /// @returns The string length, not counting the `NUL` character. extern size_t fix16_vec2_str(const fix16_vec2_t *v0, char *buffer, int32_t decimals); +__END_DECLS + /// @} -__END_DECLS +#if defined(__cplusplus) + +namespace yaul { + +/// @brief Not yet documented. +struct fix16_vec2 { + /// @brief Not yet documented. + fix16_t x; + /// @brief Not yet documented. + fix16_t y; + + fix16_vec2() { } + fix16_vec2(fix16_vec2&&) = default; + fix16_vec2(const fix16_vec2&) = default; +}; + +static_assert(sizeof(fix16_vec2) == sizeof(::fix16_vec2_t)); + +} // namespace yaul + +#endif /* __cplusplus */ #endif /* !_YAUL_GAMEMATH_FIX16_VEC2_H_ */ diff --git a/libyaul/gamemath/gamemath/fix16/fix16_vec3.h b/libyaul/gamemath/gamemath/fix16/fix16_vec3.h index 99a460bb..6271b254 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_vec3.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_vec3.h @@ -18,7 +18,6 @@ /// @ingroup MATH_FIX16_VECTOR /// @{ -#if !defined(__cplusplus) /// @brief Not yet documented. /// /// @param x Not yet documented. @@ -42,9 +41,7 @@ FIX16(y), \ FIX16(z) \ }) -#endif /* !__cplusplus */ -#if !defined(__cplusplus) /// @brief Not yet documented. typedef struct fix16_vec3 { /// @brief Not yet documented. @@ -53,81 +50,8 @@ typedef struct fix16_vec3 { fix16_t y; /// @brief Not yet documented. fix16_t z; -} fix16_vec3_t; -#else -// XXX: Forwarding. Nasty, but in order to fix this, we need to restructure the header files -struct fix16_quat_t; +} __packed __aligned(4) fix16_vec3_t; -/// @brief Not yet documented. -struct fix16_vec3_t { - /// @brief Not yet documented. - fix16_t x; - /// @brief Not yet documented. - fix16_t y; - /// @brief Not yet documented. - fix16_t z; - - fix16_vec3_t() = default; - fix16_vec3_t(fix16_vec3_t&&) = default; - fix16_vec3_t(const fix16_vec3_t&) = default; - - constexpr inline fix16_vec3_t(fix16_t x_, fix16_t y_, fix16_t z_); - - ~fix16_vec3_t() = default; - - fix16_vec3_t& operator=(const fix16_vec3_t& other) = default; - fix16_vec3_t& operator=(fix16_vec3_t&& other) = default; - - inline const fix16_vec3_t operator+(const fix16_vec3_t& other) const; - inline const fix16_vec3_t operator-(const fix16_vec3_t& other) const; - inline const fix16_vec3_t operator-() const; - inline const fix16_vec3_t operator*(fix16_t scalar) const; - inline const fix16_vec3_t operator*(int32_t scalar) const; - inline const fix16_vec3_t operator*(uint32_t scalar) const; - inline const fix16_vec3_t operator*(const fix16_quat_t& other) const; - inline const fix16_vec3_t operator/(const fix16_t& other) const; - - inline fix16_vec3_t& operator+=(const fix16_vec3_t& rhs); - inline fix16_vec3_t& operator-=(const fix16_vec3_t& rhs); - inline fix16_vec3_t& operator*=(fix16_t rhs); - inline fix16_vec3_t& operator*=(int32_t rhs); - inline fix16_vec3_t& operator/=(fix16_t rhs); - - bool is_near_zero(fix16_t epsilon = 0.001_fp) const; - - inline fix16_t length() const; - - inline fix16_t length_sqrt() const; - - inline void normalize(); - - inline fix16_vec3_t normalized(); - - inline void start_normalization() const; - - void end_normalization(); - - inline size_t to_string(char* buffer, int32_t decimals = 7) const; - - static constexpr inline fix16_vec3_t zero(); - - static constexpr inline fix16_vec3_t unit_x(); - - static constexpr inline fix16_vec3_t unit_y(); - - static constexpr inline fix16_vec3_t unit_z(); - - static inline fix16_t dot_product(const fix16_vec3_t& a, const fix16_vec3_t& b); - - static inline fix16_vec3_t cross_product(const fix16_vec3_t& a, const fix16_vec3_t& b); - - static fix16_vec3_t reflect(const fix16_vec3_t& v, const fix16_vec3_t& normal); - - static inline constexpr fix16_vec3_t from_double(double x, double y, double z); -}; -#endif /* !__cplusplus */ - -#if !defined(__cplusplus) /// @brief Not yet documented. /// /// @param result Not yet documented. @@ -251,7 +175,6 @@ fix16_vec3_inline_dot(const fix16_vec3_t *a, const fix16_vec3_t *b) return aux1; } __END_ASM -#endif /* !__cplusplus */ __BEGIN_DECLS @@ -318,97 +241,228 @@ extern size_t fix16_vec3_str(const fix16_vec3_t *v0, char *buffer, int32_t decim __END_DECLS #if defined(__cplusplus) -constexpr inline fix16_vec3_t::fix16_vec3_t(fix16_t x_, fix16_t y_, fix16_t z_) : x(x_), y(y_), z(z_) {} - -inline const fix16_vec3_t fix16_vec3_t::operator+(const fix16_vec3_t& v) const { return fix16_vec3_t{x + v.x, y + v.y, z + v.z}; } -inline const fix16_vec3_t fix16_vec3_t::operator-(const fix16_vec3_t& v) const { return fix16_vec3_t{x - v.x, y - v.y, z - v.z}; } -inline const fix16_vec3_t fix16_vec3_t::operator-() const { return fix16_vec3_t{-x, -y, -z}; } -inline const fix16_vec3_t fix16_vec3_t::operator*(fix16_t scalar) const { return fix16_vec3_t{x * scalar, y * scalar, z * scalar}; } -inline const fix16_vec3_t fix16_vec3_t::operator*(int32_t scalar) const { return fix16_vec3_t{x * scalar, y * scalar, z * scalar}; } -inline const fix16_vec3_t fix16_vec3_t::operator*(uint32_t scalar) const { return fix16_vec3_t{x * scalar, y * scalar, z * scalar}; } -// XXX: Nasty, but in order to fix this, we need to restructure the header files -extern "C" void fix16_quat_vec3_mul(const fix16_quat_t *q0, const fix16_vec3_t *v0, fix16_vec3_t *result); +namespace yaul { -inline const fix16_vec3_t fix16_vec3_t::operator*(const fix16_quat_t& other) const { - fix16_vec3_t result; - fix16_quat_vec3_mul(&other, this, &result); - - return result; -} - -inline fix16_vec3_t& fix16_vec3_t::operator+=(const fix16_vec3_t& v) { - x += v.x; - y += v.y; - z += v.z; - - return *this; -} - -inline fix16_vec3_t& fix16_vec3_t::operator-=(const fix16_vec3_t& v) { - x -= v.x; - y -= v.y; - z -= v.z; - - return *this; -} - -inline fix16_vec3_t& fix16_vec3_t::operator*=(fix16_t value) { - x = x * value; - y = y * value; - z = z * value; - - return *this; -} - -inline fix16_vec3_t& fix16_vec3_t::operator/=(fix16_t value) { - const fix16_t inv_value = 1.0_fp / value; - x = x * inv_value; - y = y * inv_value; - z = z * inv_value; - - return *this; -} - -inline fix16_t fix16_vec3_t::length() const { return fix16_vec3_length(this); } - -inline fix16_t fix16_vec3_t::length_sqrt() const { return fix16_vec3_sqr_length(this); } - -inline void fix16_vec3_t::normalize() { fix16_vec3_normalize(this); } - -inline fix16_vec3_t fix16_vec3_t::normalized() { - fix16_vec3_t result; - fix16_vec3_normalized(this, &result); - - return result; -} - -inline void fix16_vec3_t::start_normalization() const { cpu_divu_fix16_set(1.0_fp, length()); } - -constexpr inline fix16_vec3_t fix16_vec3_t::zero() { return fix16_vec3_t{0.0_fp, 0.0_fp, 0.0_fp}; } - -constexpr inline fix16_vec3_t fix16_vec3_t::unit_x() { return fix16_vec3_t{1.0_fp, 0.0_fp, 0.0_fp}; } - -constexpr inline fix16_vec3_t fix16_vec3_t::unit_y() { return fix16_vec3_t{0.0_fp, 1.0_fp, 0.0_fp}; } - -constexpr inline fix16_vec3_t fix16_vec3_t::unit_z() { return fix16_vec3_t{0.0_fp, 0.0_fp, 1.0_fp}; } - -constexpr inline fix16_vec3_t fix16_vec3_t::from_double(double x, double y, double z) { - return fix16_vec3_t{fix16_t::from_double(x), fix16_t::from_double(y), fix16_t::from_double(z)}; -} - -inline fix16_t fix16_vec3_t::dot_product(const fix16_vec3_t& a, const fix16_vec3_t& b) { - return fix16_vec3_dot(&a, &b); -} +// XXX: Forwarding. Nasty, but in order to fix this, we need to restructure the header files +struct fix16_quat; -inline fix16_vec3_t fix16_vec3_t::cross_product(const fix16_vec3_t& a, const fix16_vec3_t& b) { - fix16_vec3_t result; - fix16_vec3_cross(&a, &b, &result); +/// @brief Not yet documented. +struct __packed __aligned(4) fix16_vec3 { + /// @brief Not yet documented. + fix16 x; + /// @brief Not yet documented. + fix16 y; + /// @brief Not yet documented. + fix16 z; + + fix16_vec3() = default; + fix16_vec3(fix16_vec3&&) = default; + fix16_vec3(const fix16_vec3&) = default; + + ~fix16_vec3() = default; + + constexpr explicit fix16_vec3(const fix16_vec3_t& other) + : x(fix16{other.x}) + , y(fix16{other.y}) + , z(fix16{other.z}) + { + } + + constexpr explicit fix16_vec3(fix16 x_, fix16 y_, fix16 z_) + : x(x_) + , y(y_) + , z(z_) + { + } + + constexpr explicit fix16_vec3(fix16_t x_, fix16_t y_, fix16_t z_) + : x(fix16 { x_ }) + , y(fix16 { y_ }) + , z(fix16 { z_ }) + { + } + + fix16_vec3& operator=(const fix16_vec3& other) = default; + fix16_vec3& operator=(fix16_vec3&& other) = default; + + const fix16_vec3 operator+(const fix16_vec3 &other) const + { + return fix16_vec3 { x + other.x, y + other.y, z + other.z }; + } + + const fix16_vec3 operator-(const fix16_vec3 &other) const + { + return fix16_vec3 { x - other.x, y - other.y, z - other.z }; + } + + const fix16_vec3 operator-() const { return fix16_vec3 { -x, -y, -z }; } + + const fix16_vec3 operator*(fix16 scalar) const + { + return fix16_vec3 { x * scalar, y * scalar, z * scalar }; + } + + const fix16_vec3 operator*(fix16_t scalar) const + { + return fix16_vec3 { x * scalar, y * scalar, z * scalar }; + } + + // Due to the forward declaration this can't be inline + const fix16_vec3 operator*(const fix16_quat &other) const; + + const fix16_vec3 operator/(const fix16 other) const + { + return fix16_vec3 { x / other, y / other, z / other }; + } + + const fix16_vec3 operator/(const fix16_t other) const + { + return fix16_vec3 { x / other, y / other, z / other }; + } + + fix16_vec3& operator+=(const fix16_vec3& rhs) + { + x += rhs.x; + y += rhs.y; + z += rhs.z; + return *this; + } + + fix16_vec3& operator-=(const fix16_vec3& rhs) + { + x -= rhs.x; + y -= rhs.y; + z -= rhs.z; + return *this; + } + + fix16_vec3& operator*=(fix16 rhs) + { + x *= rhs; + y *= rhs; + z *= rhs; + return *this; + } + + fix16_vec3& operator*=(fix16_t rhs) + { + x *= rhs; + y *= rhs; + z *= rhs; + return *this; + } + + fix16_vec3& operator/=(fix16 rhs) + { + const fix16 inv_value = 1.0_fp / rhs; + x *= inv_value; + y *= inv_value; + z *= inv_value; + return *this; + } + + fix16_vec3& operator/=(fix16_t rhs) + { + const fix16 inv_value = 1.0_fp / rhs; + x *= inv_value; + y *= inv_value; + z *= inv_value; + return *this; + } + + bool is_near_zero(fix16 epsilon = 0.001_fp) const + { + return x.is_near_zero(epsilon) && y.is_near_zero(epsilon) && + z.is_near_zero(epsilon); + } + + fix16_vec3_t *as_fix16_vec3_t() + { + return reinterpret_cast(this); + } + + const fix16_vec3_t *as_fix16_vec3_t() const + { + return reinterpret_cast(this); + } + + fix16 length() const + { + return fix16 { fix16_vec3_length(as_fix16_vec3_t()) }; + } + + fix16_t length_sqrt() const + { + return fix16_vec3_sqr_length(as_fix16_vec3_t()); + } + + void normalize() { fix16_vec3_normalize(as_fix16_vec3_t()); } + + fix16_vec3 normalized() + { + fix16_vec3_t result; + fix16_vec3_normalized(as_fix16_vec3_t(), &result); + + return fix16_vec3 { result.x, result.y, result.z }; + } + + void start_normalization() const + { + cpu_divu_fix16_set(FIX16(1.0), length().value); + } + + void end_normalization() + { + const fix16 scale = fix16 { static_cast(cpu_divu_quotient_get()) }; + x *= scale; + y *= scale; + z *= scale; + } + + static constexpr fix16_vec3 zero() { return fix16_vec3 { 0, 0, 0 }; } + + static constexpr fix16_vec3 unit_x() { return fix16_vec3 { FIX16(1.0), 0, 0 }; } + + static constexpr fix16_vec3 unit_y() { return fix16_vec3 { 0, FIX16(1.0), 0 }; } + + static constexpr fix16_vec3 unit_z() { return fix16_vec3 { 0, 0, FIX16(1.0) }; } + + static constexpr fix16_vec3 from_double(double x, double y, double z) + { + return fix16_vec3 { fix16::from_double(x), fix16::from_double(y), + fix16::from_double(z) }; + } + + static fix16 dot_product(const fix16_vec3 &a, const fix16_vec3 &b) + { + return fix16 { fix16_vec3_dot(a.as_fix16_vec3_t(), + b.as_fix16_vec3_t()) }; + } + + static fix16_vec3 cross_product(const fix16_vec3 &a, const fix16_vec3 &b) + { + fix16_vec3_t result; + fix16_vec3_cross(a.as_fix16_vec3_t(), b.as_fix16_vec3_t(), &result); + + return fix16_vec3 { result.x, result.y, result.z }; + } + + static fix16_vec3 reflect(const fix16_vec3& v, const fix16_vec3& normal) + { + const fix16 factor = dot_product(v, normal) << 1; + const fix16_vec3 proj = normal * factor; + return (v - proj); + } + + size_t to_string(char *buffer, int32_t decimals) const + { + return fix16_vec3_str(as_fix16_vec3_t(), buffer, decimals); + } +}; - return result; -} +} // namespace yaul -inline size_t fix16_vec3_t::to_string(char* buffer, int32_t decimals) const { return fix16_vec3_str(this, buffer, decimals); } #endif /* __cplusplus */ /// @} From 47107c205104300e5a71e7608bb4da73c65ca474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romulo=20Leit=C3=A3o?= Date: Tue, 15 Oct 2024 22:52:51 -0300 Subject: [PATCH 2/4] Fix Romulo's name in credits --- CONTRIBUTORS | 2 +- libyaul/gamemath/fix16/fix16_mat43.c | 2 +- libyaul/gamemath/gamemath/fix16/fix16_mat33.h | 2 +- libyaul/gamemath/gamemath/fix16/fix16_mat43.h | 2 +- libyaul/gamemath/gamemath/fix16/fix16_plane.h | 2 +- libyaul/gamemath/gamemath/fix16/fix16_trig.h | 2 +- libyaul/gamemath/gamemath/fix16/fix16_vec2.h | 2 +- libyaul/gamemath/gamemath/fix16/fix16_vec3.h | 2 +- libyaul/intellisense.h | 1 + libyaul/scu/bus/a/cs2/cd-block/cd-block-internal.h | 2 +- libyaul/scu/bus/a/cs2/cd-block/cd-block.h | 2 +- libyaul/scu/bus/a/cs2/cd-block/cd-block/cmd.h | 2 +- libyaul/scu/bus/a/cs2/cd-block/cd-block_cmds.c | 2 +- libyaul/scu/bus/a/cs2/cd-block/cd-block_execute.c | 2 +- libyaul/scu/bus/a/cs2/cd-block/cd-block_init.c | 2 +- 15 files changed, 15 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index e6e4c38b..0551030d 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,6 +1,6 @@ Joe Fenton Misty De Meo -Romulo Leitão +Romulo Leitao AJBats misscelan Tiago Rezende diff --git a/libyaul/gamemath/fix16/fix16_mat43.c b/libyaul/gamemath/fix16/fix16_mat43.c index 471e360d..83a17ee8 100644 --- a/libyaul/gamemath/fix16/fix16_mat43.c +++ b/libyaul/gamemath/fix16/fix16_mat43.c @@ -3,7 +3,7 @@ * See LICENSE for details. * * Israel Jacquez - * Romulo Fernandes + * Romulo Leitao */ #include diff --git a/libyaul/gamemath/gamemath/fix16/fix16_mat33.h b/libyaul/gamemath/gamemath/fix16/fix16_mat33.h index 4b103b26..eb8eed80 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_mat33.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_mat33.h @@ -3,7 +3,7 @@ * See LICENSE for details. * * Israel Jacquez - * Romulo Fernandes + * Romulo Leitao */ #ifndef _YAUL_GAMEMATH_FIX16_MAT33_H_ diff --git a/libyaul/gamemath/gamemath/fix16/fix16_mat43.h b/libyaul/gamemath/gamemath/fix16/fix16_mat43.h index 750d8e80..0624c110 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_mat43.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_mat43.h @@ -3,7 +3,7 @@ * See LICENSE for details. * * Israel Jacquez - * Romulo Fernandes + * Romulo Leitao */ #ifndef _YAUL_GAMEMATH_FIX16_MAT43_H_ diff --git a/libyaul/gamemath/gamemath/fix16/fix16_plane.h b/libyaul/gamemath/gamemath/fix16/fix16_plane.h index 6d46fdc5..c150d9e2 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_plane.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_plane.h @@ -3,7 +3,7 @@ * See LICENSE for details. * * Israel Jacquez - * Romulo Fernandes + * Romulo Leitao */ #ifndef _YAUL_GAMEMATH_FIX16_PLANE_H_ diff --git a/libyaul/gamemath/gamemath/fix16/fix16_trig.h b/libyaul/gamemath/gamemath/fix16/fix16_trig.h index 59661361..63f6059d 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_trig.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_trig.h @@ -3,7 +3,7 @@ * See LICENSE for details. * * Israel Jacquez - * Romulo Fernandes + * Romulo Leitao */ #ifndef _YAUL_GAMEMATH_FIX16_TRIG_H_ diff --git a/libyaul/gamemath/gamemath/fix16/fix16_vec2.h b/libyaul/gamemath/gamemath/fix16/fix16_vec2.h index 2474544b..20336d88 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_vec2.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_vec2.h @@ -3,7 +3,7 @@ * See LICENSE for details. * * Israel Jacquez - * Romulo Fernandes + * Romulo Leitao */ #ifndef _YAUL_GAMEMATH_FIX16_VEC2_H_ diff --git a/libyaul/gamemath/gamemath/fix16/fix16_vec3.h b/libyaul/gamemath/gamemath/fix16/fix16_vec3.h index 6271b254..68d14796 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_vec3.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_vec3.h @@ -3,7 +3,7 @@ * See LICENSE for details. * * Israel Jacquez - * Romulo Fernandes + * Romulo Leitao */ #ifndef _YAUL_GAMEMATH_FIX16_VEC3_H_ diff --git a/libyaul/intellisense.h b/libyaul/intellisense.h index 81f09f05..f520e872 100644 --- a/libyaul/intellisense.h +++ b/libyaul/intellisense.h @@ -3,6 +3,7 @@ * See LICENSE for details. * * Israel Jacquez + * Romulo Leitao */ #if defined(__INTELLISENSE__) || defined(__RESHARPER__) diff --git a/libyaul/scu/bus/a/cs2/cd-block/cd-block-internal.h b/libyaul/scu/bus/a/cs2/cd-block/cd-block-internal.h index 0007fa05..090b90d7 100644 --- a/libyaul/scu/bus/a/cs2/cd-block/cd-block-internal.h +++ b/libyaul/scu/bus/a/cs2/cd-block/cd-block-internal.h @@ -4,7 +4,7 @@ * * Theo Beraku * Israel Jacquez - * Romulo Fernandes Machado + * Romulo Leitao */ #ifndef _CD_BLOCK_INTERNAL_H_ diff --git a/libyaul/scu/bus/a/cs2/cd-block/cd-block.h b/libyaul/scu/bus/a/cs2/cd-block/cd-block.h index d634c071..98e51623 100644 --- a/libyaul/scu/bus/a/cs2/cd-block/cd-block.h +++ b/libyaul/scu/bus/a/cs2/cd-block/cd-block.h @@ -3,7 +3,7 @@ * See LICENSE for details. * * Israel Jacquez - * Romulo Fernandes Machado + * Romulo Leitao */ #ifndef _YAUL_CD_BLOCK_H_ diff --git a/libyaul/scu/bus/a/cs2/cd-block/cd-block/cmd.h b/libyaul/scu/bus/a/cs2/cd-block/cd-block/cmd.h index 096a1333..080bfc71 100644 --- a/libyaul/scu/bus/a/cs2/cd-block/cd-block/cmd.h +++ b/libyaul/scu/bus/a/cs2/cd-block/cd-block/cmd.h @@ -3,7 +3,7 @@ * See LICENSE for details. * * Israel Jacquez - * Romulo Fernandes Machado + * Romulo Leitao */ #ifndef _YAUL_CD_BLOCK_CMD_H_ diff --git a/libyaul/scu/bus/a/cs2/cd-block/cd-block_cmds.c b/libyaul/scu/bus/a/cs2/cd-block/cd-block_cmds.c index da286895..fedb28c4 100644 --- a/libyaul/scu/bus/a/cs2/cd-block/cd-block_cmds.c +++ b/libyaul/scu/bus/a/cs2/cd-block/cd-block_cmds.c @@ -3,7 +3,7 @@ * See LICENSE for details. * * Israel Jacquez - * Romulo Fernandes Machado + * Romulo Leitao */ #include diff --git a/libyaul/scu/bus/a/cs2/cd-block/cd-block_execute.c b/libyaul/scu/bus/a/cs2/cd-block/cd-block_execute.c index c52d4ba4..0ed241c9 100644 --- a/libyaul/scu/bus/a/cs2/cd-block/cd-block_execute.c +++ b/libyaul/scu/bus/a/cs2/cd-block/cd-block_execute.c @@ -3,7 +3,7 @@ * See LICENSE for details. * * Theo Beraku - * Romulo Fernandes Machado + * Romulo Leitao */ #include diff --git a/libyaul/scu/bus/a/cs2/cd-block/cd-block_init.c b/libyaul/scu/bus/a/cs2/cd-block/cd-block_init.c index 6a77dae7..b81cf16e 100644 --- a/libyaul/scu/bus/a/cs2/cd-block/cd-block_init.c +++ b/libyaul/scu/bus/a/cs2/cd-block/cd-block_init.c @@ -3,7 +3,7 @@ * See LICENSE for details. * * Israel Jacquez - * Romulo Fernandes Machado + * Romulo Leitao */ #include From 7878631f6537202b09c9196f4bf66c844e626148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romulo=20Leit=C3=A3o?= Date: Thu, 17 Oct 2024 20:30:32 -0300 Subject: [PATCH 3/4] Improved vec2 and vec3 --- libyaul/gamemath/gamemath/fix16/fix16_vec2.h | 240 ++++++++++++++++++- libyaul/gamemath/gamemath/fix16/fix16_vec3.h | 137 ++++++++--- 2 files changed, 334 insertions(+), 43 deletions(-) diff --git a/libyaul/gamemath/gamemath/fix16/fix16_vec2.h b/libyaul/gamemath/gamemath/fix16/fix16_vec2.h index 20336d88..9d385ca7 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_vec2.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_vec2.h @@ -9,6 +9,7 @@ #ifndef _YAUL_GAMEMATH_FIX16_VEC2_H_ #define _YAUL_GAMEMATH_FIX16_VEC2_H_ +#include #include /// @addtogroup MATH_FIX16_VECTOR @@ -196,17 +197,242 @@ __END_DECLS namespace yaul { /// @brief Not yet documented. -struct fix16_vec2 { +struct __packed __aligned(4) fix16_vec2 +{ /// @brief Not yet documented. - fix16_t x; + fix16 x; /// @brief Not yet documented. - fix16_t y; - - fix16_vec2() { } - fix16_vec2(fix16_vec2&&) = default; - fix16_vec2(const fix16_vec2&) = default; + fix16 y; + + fix16_vec2() + { + } + fix16_vec2(fix16_vec2 &&) = default; + fix16_vec2(const fix16_vec2 &) = default; + + constexpr explicit fix16_vec2(fix16_t x, fix16_t y) + : x { x } + , y { y } + { + } + + constexpr explicit fix16_vec2(fix16 x, fix16 y) + : x { x } + , y { y } + { + } + + fix16_vec2 operator>>(int i) const + { + return fix16_vec2 { x >> i, y >> i }; + } + + fix16_vec2 operator<<(int i) const + { + return fix16_vec2 { x << i, y << i }; + } + + fix16_vec2 &operator=(const fix16_vec2 &other) = default; + + fix16_vec2 &operator=(fix16_vec2 &&other) = default; + + const fix16_vec2 operator+(const fix16_vec2 &other) const + { + return fix16_vec2 { x + other.x, y + other.y }; + } + + const fix16_vec2 operator-(const fix16_vec2 &other) const + { + return fix16_vec2 { x - other.x, y - other.y }; + } + + const fix16_vec2 operator-() const + { + return fix16_vec2 { -x, -y }; + } + + const fix16_vec2 operator*(fix16 scalar) const + { + return fix16_vec2 { x * scalar, y * scalar }; + } + + const fix16_vec2 operator*(fix16_t scalar) const + { + return fix16_vec2 { x * scalar, y * scalar }; + } + + const fix16_vec2 operator/(const fix16 other) const + { + return fix16_vec2 { x / other, y / other }; + } + + const fix16_vec2 operator/(const fix16_t other) const + { + return fix16_vec2 { x / other, y / other }; + } + + fix16_vec2 &operator+=(const fix16_vec2 &v) + { + x += v.x; + y += v.y; + return *this; + } + + fix16_vec2 &operator-=(const fix16_vec2 &v) + { + x -= v.x; + y -= v.y; + return *this; + } + + fix16_vec2 &operator*=(fix16 value) + { + x *= value; + y *= value; + return *this; + } + + fix16_vec2 &operator/=(fix16 value) + { + x /= value; + y /= value; + return *this; + } + + fix16 operator[](int32_t index) const + { + switch (index) { + case 0: + return x; + case 1: + return y; + default: + assert(false); + return fix16::zero(); + } + } + + bool is_zero() const + { + return x == 0 && y == 0; + } + + bool is_near_zero(const fix16 epsilon = 0.001_fp) const + { + return x.is_near_zero(epsilon) && y.is_near_zero(epsilon); + } + + fix16_vec2_t *as_fix16_vec2_t() + { + return reinterpret_cast(this); + } + + const fix16_vec2_t *as_fix16_vec2_t() const + { + return reinterpret_cast(this); + } + + fix16 dot(const fix16_vec2 &other) const + { + return dot(*this, other); + } + + fix16 cross(const fix16_vec2 &other) const + { + return cross(*this, other); + } + + fix16 length_squared() const + { + return dot(*this, *this); + } + + fix16 length() const + { + return dot(*this, *this).sqrt(); + } + + void start_normalization() const + { + fix16::start_divu_1_over_value(length()); + } + + static void finish_normalization(fix16_vec2 & result) + { + const fix16 denom { fix16::get_divu_quotient() }; + result.x *= denom; + result.y *= denom; + } + + void normalize() + { + start_normalization(); + finish_normalization(*this); + } + + fix16 approximate_distance(const fix16_vec2 &other) const + { + const fix16 first { x - other.x }; + const fix16 second { y - other.y }; + return first.approximate_distance(second); + } + + static fix16 dot(const fix16_vec2 &a, const fix16_vec2 &b) + { + return fix16 { fix16_vec2_dot(a.as_fix16_vec2_t(), + b.as_fix16_vec2_t()) }; + } + + static fix16 cross(const fix16_vec2 &a, const fix16_vec2 &b) + { + return fix16 { (a.x * b.y) - (a.y * b.x) }; + } + + fix16_vec2 reflect(const fix16_vec2 &normal) const + { + // this - 2 * proj(this, normal) + const fix16 factor { dot(*this, normal).value << 1 }; + const fix16_vec2 proj { + factor * normal.x, + factor * normal.y, + }; + + return fix16_vec2 { + x - proj.x, + y - proj.y, + }; + } + + static constexpr fix16_vec2 from_double(double x, double y) + { + return fix16_vec2 { + fix16::from_double(x), + fix16::from_double(y), + }; + } + + static constexpr fix16_vec2 zero() + { + return fix16_vec2 { 0, 0 }; + } + + static constexpr fix16_vec2 unit_x() + { + return fix16_vec2 { FIX16(1.0), 0 }; + } + + static constexpr fix16_vec2 unit_y() + { + return fix16_vec2 { 0, FIX16(1.0) }; + } }; +inline fix16_vec2 +operator*(fix16 scalar, const fix16_vec2 &v) +{ + return fix16_vec2 { v.x * scalar, v.y * scalar }; +} + static_assert(sizeof(fix16_vec2) == sizeof(::fix16_vec2_t)); } // namespace yaul diff --git a/libyaul/gamemath/gamemath/fix16/fix16_vec3.h b/libyaul/gamemath/gamemath/fix16/fix16_vec3.h index 68d14796..88ce64ca 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_vec3.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_vec3.h @@ -9,6 +9,7 @@ #ifndef _YAUL_GAMEMATH_FIX16_VEC3_H_ #define _YAUL_GAMEMATH_FIX16_VEC3_H_ +#include #include #include @@ -248,7 +249,8 @@ namespace yaul { struct fix16_quat; /// @brief Not yet documented. -struct __packed __aligned(4) fix16_vec3 { +struct __packed __aligned(4) fix16_vec3 +{ /// @brief Not yet documented. fix16 x; /// @brief Not yet documented. @@ -257,34 +259,34 @@ struct __packed __aligned(4) fix16_vec3 { fix16 z; fix16_vec3() = default; - fix16_vec3(fix16_vec3&&) = default; - fix16_vec3(const fix16_vec3&) = default; + fix16_vec3(fix16_vec3 &&) = default; + fix16_vec3(const fix16_vec3 &) = default; ~fix16_vec3() = default; - constexpr explicit fix16_vec3(const fix16_vec3_t& other) - : x(fix16{other.x}) - , y(fix16{other.y}) - , z(fix16{other.z}) + constexpr explicit fix16_vec3(const fix16_vec3_t &other) + : x { fix16 { other.x } } + , y { fix16 { other.y } } + , z { fix16 { other.z } } { } constexpr explicit fix16_vec3(fix16 x_, fix16 y_, fix16 z_) - : x(x_) - , y(y_) - , z(z_) + : x { x_ } + , y { y_ } + , z { z_ } { } constexpr explicit fix16_vec3(fix16_t x_, fix16_t y_, fix16_t z_) - : x(fix16 { x_ }) - , y(fix16 { y_ }) - , z(fix16 { z_ }) + : x { fix16 { x_ } } + , y { fix16 { y_ } } + , z { fix16 { z_ } } { } - fix16_vec3& operator=(const fix16_vec3& other) = default; - fix16_vec3& operator=(fix16_vec3&& other) = default; + fix16_vec3 &operator=(const fix16_vec3 &other) = default; + fix16_vec3 &operator=(fix16_vec3 &&other) = default; const fix16_vec3 operator+(const fix16_vec3 &other) const { @@ -296,7 +298,10 @@ struct __packed __aligned(4) fix16_vec3 { return fix16_vec3 { x - other.x, y - other.y, z - other.z }; } - const fix16_vec3 operator-() const { return fix16_vec3 { -x, -y, -z }; } + const fix16_vec3 operator-() const + { + return fix16_vec3 { -x, -y, -z }; + } const fix16_vec3 operator*(fix16 scalar) const { @@ -321,7 +326,7 @@ struct __packed __aligned(4) fix16_vec3 { return fix16_vec3 { x / other, y / other, z / other }; } - fix16_vec3& operator+=(const fix16_vec3& rhs) + fix16_vec3 &operator+=(const fix16_vec3 &rhs) { x += rhs.x; y += rhs.y; @@ -329,7 +334,7 @@ struct __packed __aligned(4) fix16_vec3 { return *this; } - fix16_vec3& operator-=(const fix16_vec3& rhs) + fix16_vec3 &operator-=(const fix16_vec3 &rhs) { x -= rhs.x; y -= rhs.y; @@ -337,7 +342,7 @@ struct __packed __aligned(4) fix16_vec3 { return *this; } - fix16_vec3& operator*=(fix16 rhs) + fix16_vec3 &operator*=(fix16 rhs) { x *= rhs; y *= rhs; @@ -345,7 +350,7 @@ struct __packed __aligned(4) fix16_vec3 { return *this; } - fix16_vec3& operator*=(fix16_t rhs) + fix16_vec3 &operator*=(fix16_t rhs) { x *= rhs; y *= rhs; @@ -353,7 +358,7 @@ struct __packed __aligned(4) fix16_vec3 { return *this; } - fix16_vec3& operator/=(fix16 rhs) + fix16_vec3 &operator/=(fix16 rhs) { const fix16 inv_value = 1.0_fp / rhs; x *= inv_value; @@ -362,7 +367,7 @@ struct __packed __aligned(4) fix16_vec3 { return *this; } - fix16_vec3& operator/=(fix16_t rhs) + fix16_vec3 &operator/=(fix16_t rhs) { const fix16 inv_value = 1.0_fp / rhs; x *= inv_value; @@ -387,17 +392,55 @@ struct __packed __aligned(4) fix16_vec3 { return reinterpret_cast(this); } + fix16 min() const + { + return ::min(::min(x, y), z); + } + + fix16 max() const + { + return ::max(::max(x, y), z); + } + + fix16 dot(const fix16_vec3 &other) const + { + return dot(*this, other); + } + + fix16_vec3 cross(const fix16_vec3 &other) const + { + return cross(*this, other); + } + fix16 length() const { return fix16 { fix16_vec3_length(as_fix16_vec3_t()) }; } - fix16_t length_sqrt() const + fix16 length_squared() const { - return fix16_vec3_sqr_length(as_fix16_vec3_t()); + return fix16 { fix16_vec3_sqr_length(as_fix16_vec3_t()) }; } - void normalize() { fix16_vec3_normalize(as_fix16_vec3_t()); } + fix16 operator[](int32_t index) const + { + switch (index) { + case 0: + return x; + case 1: + return y; + case 2: + return z; + default: + assert(false); + return fix16::zero(); + } + } + + void normalize() + { + fix16_vec3_normalize(as_fix16_vec3_t()); + } fix16_vec3 normalized() { @@ -414,33 +457,49 @@ struct __packed __aligned(4) fix16_vec3 { void end_normalization() { - const fix16 scale = fix16 { static_cast(cpu_divu_quotient_get()) }; + const fix16 scale = fix16 { static_cast( + cpu_divu_quotient_get()) }; x *= scale; y *= scale; z *= scale; } - static constexpr fix16_vec3 zero() { return fix16_vec3 { 0, 0, 0 }; } + static constexpr fix16_vec3 zero() + { + return fix16_vec3 { 0, 0, 0 }; + } - static constexpr fix16_vec3 unit_x() { return fix16_vec3 { FIX16(1.0), 0, 0 }; } + static constexpr fix16_vec3 unit_x() + { + return fix16_vec3 { FIX16(1.0), 0, 0 }; + } - static constexpr fix16_vec3 unit_y() { return fix16_vec3 { 0, FIX16(1.0), 0 }; } + static constexpr fix16_vec3 unit_y() + { + return fix16_vec3 { 0, FIX16(1.0), 0 }; + } - static constexpr fix16_vec3 unit_z() { return fix16_vec3 { 0, 0, FIX16(1.0) }; } + static constexpr fix16_vec3 unit_z() + { + return fix16_vec3 { 0, 0, FIX16(1.0) }; + } static constexpr fix16_vec3 from_double(double x, double y, double z) { - return fix16_vec3 { fix16::from_double(x), fix16::from_double(y), - fix16::from_double(z) }; + return fix16_vec3 { + fix16::from_double(x), + fix16::from_double(y), + fix16::from_double(z), + }; } - static fix16 dot_product(const fix16_vec3 &a, const fix16_vec3 &b) + static fix16 dot(const fix16_vec3 &a, const fix16_vec3 &b) { return fix16 { fix16_vec3_dot(a.as_fix16_vec3_t(), b.as_fix16_vec3_t()) }; } - static fix16_vec3 cross_product(const fix16_vec3 &a, const fix16_vec3 &b) + static fix16_vec3 cross(const fix16_vec3 &a, const fix16_vec3 &b) { fix16_vec3_t result; fix16_vec3_cross(a.as_fix16_vec3_t(), b.as_fix16_vec3_t(), &result); @@ -448,9 +507,9 @@ struct __packed __aligned(4) fix16_vec3 { return fix16_vec3 { result.x, result.y, result.z }; } - static fix16_vec3 reflect(const fix16_vec3& v, const fix16_vec3& normal) + static fix16_vec3 reflect(const fix16_vec3 &v, const fix16_vec3 &normal) { - const fix16 factor = dot_product(v, normal) << 1; + const fix16 factor = dot(v, normal) << 1; const fix16_vec3 proj = normal * factor; return (v - proj); } @@ -461,6 +520,12 @@ struct __packed __aligned(4) fix16_vec3 { } }; +inline fix16_vec3 +operator*(fix16 scalar, const fix16_vec3 &v) +{ + return fix16_vec3 { v.x * scalar, v.y * scalar, v.z * scalar }; +} + } // namespace yaul #endif /* __cplusplus */ From 36a741cbef9797c552ef53a4a0b331c87a9ee749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romulo=20Leit=C3=A3o?= Date: Thu, 17 Oct 2024 22:08:19 -0300 Subject: [PATCH 4/4] Declare static constants, add cxx files to check problems during yaul compilation, more improvements (specially fix16_mat33) --- libyaul/build-files.mk | 5 + libyaul/gamemath/c++/angle.cxx | 8 + libyaul/gamemath/fix16/c++/fix16.cxx | 18 ++ libyaul/gamemath/fix16/c++/fix16_mat33.cxx | 35 +++ libyaul/gamemath/fix16/c++/fix16_mat43.cxx | 8 + libyaul/gamemath/fix16/c++/fix16_plane.cxx | 8 + libyaul/gamemath/fix16/c++/fix16_quat.cxx | 8 + libyaul/gamemath/fix16/c++/fix16_vec2.cxx | 8 + libyaul/gamemath/gamemath/fix16.h | 70 ++--- libyaul/gamemath/gamemath/fix16/fix16_mat33.h | 279 +++++++++++++++++- libyaul/gamemath/gamemath/fix16/fix16_quat.h | 8 +- libyaul/gamemath/gamemath/fix16/fix16_vec2.h | 113 ++++--- libyaul/gamemath/gamemath/fix16/fix16_vec3.h | 58 ++-- 13 files changed, 511 insertions(+), 115 deletions(-) create mode 100644 libyaul/gamemath/c++/angle.cxx create mode 100644 libyaul/gamemath/fix16/c++/fix16_mat33.cxx create mode 100644 libyaul/gamemath/fix16/c++/fix16_mat43.cxx create mode 100644 libyaul/gamemath/fix16/c++/fix16_plane.cxx create mode 100644 libyaul/gamemath/fix16/c++/fix16_quat.cxx create mode 100644 libyaul/gamemath/fix16/c++/fix16_vec2.cxx diff --git a/libyaul/build-files.mk b/libyaul/build-files.mk index b65fbb65..d476b03b 100644 --- a/libyaul/build-files.mk +++ b/libyaul/build-files.mk @@ -219,8 +219,13 @@ LIB_SRCS+= \ gamemath/fix16/fix16_vec2.c \ gamemath/fix16/fix16_vec3.c \ \ + gamemath/c++/angle.cxx \ gamemath/fix16/c++/fix16.cxx \ + gamemath/fix16/c++/fix16_vec2.cxx \ gamemath/fix16/c++/fix16_vec3.cxx \ + gamemath/fix16/c++/fix16_mat33.cxx \ + gamemath/fix16/c++/fix16_mat43.cxx \ + gamemath/fix16/c++/fix16_quat.cxx \ \ gamemath/int16.c \ gamemath/int32.c \ diff --git a/libyaul/gamemath/c++/angle.cxx b/libyaul/gamemath/c++/angle.cxx new file mode 100644 index 00000000..066c42c0 --- /dev/null +++ b/libyaul/gamemath/c++/angle.cxx @@ -0,0 +1,8 @@ +#include + +#if defined(__cplusplus) + +namespace yaul { +} // namespace yaul + +#endif /* __cplusplus */ diff --git a/libyaul/gamemath/fix16/c++/fix16.cxx b/libyaul/gamemath/fix16/c++/fix16.cxx index 77662bfd..727a8341 100644 --- a/libyaul/gamemath/fix16/c++/fix16.cxx +++ b/libyaul/gamemath/fix16/c++/fix16.cxx @@ -44,4 +44,22 @@ fix16::deg_to_angle() const return angle { static_cast<::angle_t>((deg_to_rad() * OneOver2Pi).value) }; } +void +fix16::start_divu_1_over_value(fix16 v) +{ + ::cpu_divu_fix16_set(One.value, v.value); +} + +void +fix16::start_divu(fix16 num, fix16 denom) +{ + ::cpu_divu_fix16_set(num.value, denom.value); +} + +fix16 +fix16::get_divu_quotient() +{ + return fix16 { static_cast(::cpu_divu_quotient_get()) }; +} + } // namespace yaul \ No newline at end of file diff --git a/libyaul/gamemath/fix16/c++/fix16_mat33.cxx b/libyaul/gamemath/fix16/c++/fix16_mat33.cxx new file mode 100644 index 00000000..dd26b5fb --- /dev/null +++ b/libyaul/gamemath/fix16/c++/fix16_mat33.cxx @@ -0,0 +1,35 @@ +/* + * Copyright (c) + * See LICENSE for details. + * + * Mattias Jansson + * Israel Jacquez + * Romulo Leitao + */ + +#include + +#include +#include + +namespace yaul { + +fix16_mat33 +fix16_mat33::look_at(const fix16_vec3 &from, const fix16_vec3 &to, + const fix16_vec3 &up) +{ + fix16_mat33 result; + + lookat_t lookat; + lookat.from = from.as_fix16_vec3_t(); + lookat.to = to.as_fix16_vec3_t(); + lookat.up = up.as_fix16_vec3_t(); + lookat.basis_right = result.row[0].as_fix16_vec3_t(); + lookat.basis_up = result.row[1].as_fix16_vec3_t(); + lookat.basis_forward = result.row[2].as_fix16_vec3_t(); + + math3d_lookat(&lookat); + return result; +} + +} // namespace yaul diff --git a/libyaul/gamemath/fix16/c++/fix16_mat43.cxx b/libyaul/gamemath/fix16/c++/fix16_mat43.cxx new file mode 100644 index 00000000..1c49c1db --- /dev/null +++ b/libyaul/gamemath/fix16/c++/fix16_mat43.cxx @@ -0,0 +1,8 @@ +#include + +#if defined(__cplusplus) + +namespace yaul { +} // namespace yaul + +#endif /* __cplusplus */ diff --git a/libyaul/gamemath/fix16/c++/fix16_plane.cxx b/libyaul/gamemath/fix16/c++/fix16_plane.cxx new file mode 100644 index 00000000..c104c3f2 --- /dev/null +++ b/libyaul/gamemath/fix16/c++/fix16_plane.cxx @@ -0,0 +1,8 @@ +#include + +#if defined(__cplusplus) + +namespace yaul { +} // namespace yaul + +#endif /* __cplusplus */ diff --git a/libyaul/gamemath/fix16/c++/fix16_quat.cxx b/libyaul/gamemath/fix16/c++/fix16_quat.cxx new file mode 100644 index 00000000..174e731a --- /dev/null +++ b/libyaul/gamemath/fix16/c++/fix16_quat.cxx @@ -0,0 +1,8 @@ +#include + +#if defined(__cplusplus) + +namespace yaul { +} // namespace yaul + +#endif /* __cplusplus */ diff --git a/libyaul/gamemath/fix16/c++/fix16_vec2.cxx b/libyaul/gamemath/fix16/c++/fix16_vec2.cxx new file mode 100644 index 00000000..16e4f894 --- /dev/null +++ b/libyaul/gamemath/fix16/c++/fix16_vec2.cxx @@ -0,0 +1,8 @@ +#include + +#if defined(__cplusplus) + +namespace yaul { +} // namespace yaul + +#endif /* __cplusplus */ diff --git a/libyaul/gamemath/gamemath/fix16.h b/libyaul/gamemath/gamemath/fix16.h index 7147ce6c..5bcb6f77 100644 --- a/libyaul/gamemath/gamemath/fix16.h +++ b/libyaul/gamemath/gamemath/fix16.h @@ -298,13 +298,6 @@ __END_DECLS #if defined(__cplusplus) -__BEGIN_DECLS - -static void cpu_divu_fix16_set(fix16_t, fix16_t); -static uint32_t cpu_divu_quotient_get(void); - -__END_DECLS - namespace yaul { struct angle; @@ -315,14 +308,19 @@ struct __packed __aligned(4) fix16 fix16_t value; fix16() = default; + fix16(const fix16&) = default; + fix16(fix16&&) = default; - explicit constexpr fix16(fix16_t v) + constexpr explicit fix16(fix16_t v) : value(v) { } + fix16 &operator=(const fix16 &) = default; + fix16 &operator=(fix16 &&) = default; + // For dealing with C - explicit constexpr operator fix16_t() const + constexpr explicit operator fix16_t() const { return value; } @@ -331,10 +329,12 @@ struct __packed __aligned(4) fix16 { return fix16 { value + other.value }; } + constexpr fix16 operator-(fix16 other) const { return fix16 { value - other.value }; } + constexpr fix16 operator-() const { return fix16 { -value }; @@ -344,6 +344,7 @@ struct __packed __aligned(4) fix16 { return fix16 { fix16_mul(value, other.value) }; } + fix16 operator/(fix16 other) const { return fix16 { fix16_div(value, other.value) }; @@ -353,6 +354,7 @@ struct __packed __aligned(4) fix16 { return fix16 { fix16_mul(value, other) }; } + fix16 operator/(fix16_t other) const { return fix16 { fix16_div(value, other) }; @@ -362,6 +364,7 @@ struct __packed __aligned(4) fix16 { return fix16 { value >> i }; } + constexpr fix16 operator<<(int32_t i) const { return fix16 { value << i }; @@ -372,16 +375,19 @@ struct __packed __aligned(4) fix16 value += rhs.value; return *this; } + fix16 &operator-=(fix16 rhs) { value -= rhs.value; return *this; } + fix16 &operator*=(fix16 rhs) { value = fix16_mul(value, rhs.value); return *this; } + fix16 &operator/=(fix16 rhs) { value = fix16_div(value, rhs.value); @@ -393,6 +399,7 @@ struct __packed __aligned(4) fix16 value = fix16_mul(value, rhs); return *this; } + fix16 &operator/=(fix16_t rhs) { value = fix16_div(value, rhs); @@ -404,6 +411,7 @@ struct __packed __aligned(4) fix16 value >>= i; return *this; } + fix16 &operator<<=(int32_t i) { value <<= i; @@ -414,18 +422,22 @@ struct __packed __aligned(4) fix16 { return value < other.value; } + bool operator>(fix16 other) const { return value > other.value; } + bool operator<=(fix16 other) const { return value <= other.value; } + bool operator>=(fix16 other) const { return value >= other.value; } + bool operator==(fix16 other) const { return value == other.value; @@ -435,18 +447,22 @@ struct __packed __aligned(4) fix16 { return value < other; } + bool operator>(fix16_t other) const { return value > other; } + bool operator<=(fix16_t other) const { return value <= other; } + bool operator>=(fix16_t other) const { return value >= other; } + bool operator==(fix16_t other) const { return value == other; @@ -570,36 +586,24 @@ struct __packed __aligned(4) fix16 return fix16 { FIX16(value) }; } - static void start_divu_1_over_value(fix16 v) - { - ::cpu_divu_fix16_set(one().value, v.value); - } + static void start_divu_1_over_value(fix16 v); - static void start_divu(fix16 num, fix16 denom) - { - ::cpu_divu_fix16_set(num.value, denom.value); - } + static void start_divu(fix16 num, fix16 denom); - static fix16 get_divu_quotient() - { - return fix16 { static_cast(::cpu_divu_quotient_get()) }; - } + static fix16 get_divu_quotient(); - static constexpr fix16 zero() - { - return fix16 { FIX16(0.0) }; - } + static const fix16 Zero; - static constexpr fix16 one() - { - return fix16 { FIX16(1.0) }; - } + static const fix16 One; - static constexpr fix16 minus_one() - { - return fix16 { FIX16(-1.0) }; - } + static const fix16 Minus_one; }; + +inline const fix16 fix16::Zero{ fix16::from_double(0.0) }; + +inline const fix16 fix16::One{ fix16::from_double(1.0) }; + +inline const fix16 fix16::Minus_one{ fix16::from_double(-1.0) }; static_assert(sizeof(fix16) == sizeof(::fix16_t)); diff --git a/libyaul/gamemath/gamemath/fix16/fix16_mat33.h b/libyaul/gamemath/gamemath/fix16/fix16_mat33.h index eb8eed80..11f398b1 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_mat33.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_mat33.h @@ -9,6 +9,7 @@ #ifndef _YAUL_GAMEMATH_FIX16_MAT33_H_ #define _YAUL_GAMEMATH_FIX16_MAT33_H_ +#include #include #include @@ -166,11 +167,11 @@ struct __packed __aligned(4) fix16_mat33 { fix16_mat33(const fix16_mat33 &) = default; constexpr explicit fix16_mat33(const fix16_mat33_t &other) - : row({ + : row{ fix16_vec3 { other.row[0] }, fix16_vec3 { other.row[1] }, fix16_vec3 { other.row[2] }, - }) + } { } @@ -181,17 +182,20 @@ struct __packed __aligned(4) fix16_mat33 { fix16 m10, fix16 m11, fix16 m12, // Row 2 fix16 m20, fix16 m21, fix16 m22) - : row({ + : row{ // Row 0 fix16_vec3{ m00, m01, m02 }, // Row 1 fix16_vec3{ m10, m11, m12 }, // Row 2 fix16_vec3{ m20, m21, m22 }, - }) + } { } + fix16_mat33 &operator=(const fix16_mat33 &) = default; + fix16_mat33 &operator=(fix16_mat33 &&) = default; + fix16_mat33_t *as_fix16_mat33_t() { return reinterpret_cast(this); @@ -210,6 +214,11 @@ struct __packed __aligned(4) fix16_mat33 { return fix16_mat33 { result }; } + fix16_vec3 operator*(const fix16_vec3 &v) const + { + return transform_vector(*this, v); + } + static constexpr fix16_mat33 from_double( // Row 0 double m00, double m01, double m02, @@ -240,42 +249,284 @@ struct __packed __aligned(4) fix16_mat33 { void transpose() { fix16_mat33_inplace_transpose(as_fix16_mat33_t()); } - void invert() { transpose(); } + fix16_mat33 transposed() const + { + fix16_mat33 copy { *this }; + fix16_mat33_inplace_transpose(copy.as_fix16_mat33_t()); + + return copy; + } + + // Warning: Matrix must be orthonormal + void invert() + { + transpose(); + } + + // Warning: Matrix must be orthonormal + fix16_mat33 inverted() const + { + fix16_mat33 copy { *this }; + copy.transpose(); + + return copy; + } size_t to_string(char *buffer, int32_t decimals) const { return fix16_mat33_str(as_fix16_mat33_t(), buffer, decimals); } - void create_rotx(const fix16_mat33 &m0, angle x, fix16_mat33 &result) + void transform_xy(const fix16_vec3 &v, const fix16_vec3 &translation, + fix16_vec3 &result) const + { + transform_xy(*this, v, translation, result); + } + + void transform_z(const fix16_vec3 &v, const fix16_vec3 &translation, + fix16_vec3 &result) const + { + transform_z(*this, v, translation, result); + } + + fix16_vec3 transform_vector(const fix16_vec3 &v) const + { + return transform_vector(*this, v); + } + + fix16& operator[](int32_t index) + { + switch (index) { + case 0: + return row[0].x; + case 1: + return row[0].y; + case 2: + return row[0].z; + case 3: + return row[1].x; + case 4: + return row[1].y; + case 5: + return row[1].z; + case 6: + return row[2].x; + case 7: + return row[2].y; + case 8: + return row[2].z; + default: + assert(false); + return row[0].x; + } + } + + fix16 operator[](int32_t index) const + { + switch (index) { + case 0: + return row[0].x; + case 1: + return row[0].y; + case 2: + return row[0].z; + case 3: + return row[1].x; + case 4: + return row[1].y; + case 5: + return row[1].z; + case 6: + return row[2].x; + case 7: + return row[2].y; + case 8: + return row[2].z; + default: + assert(false); + return row[0].x; + } + } + + static fix16_mat33 look_at(const fix16_vec3 &from, const fix16_vec3 &to, + const fix16_vec3 &up); + + static fix16_mat33 rotation_on_x(angle x) { - fix16_mat33_x_rotate(m0.as_fix16_mat33_t(), x.value, result.as_fix16_mat33_t()); + fix16_mat33 result; + fix16_mat33_x_rotate(fix16_mat33::Identity.as_fix16_mat33_t(), x.value, + result.as_fix16_mat33_t()); + + return result; } - void create_roty(const fix16_mat33 &m0, angle y, fix16_mat33 &result) + static fix16_mat33 rotation_on_y(angle y) { - fix16_mat33_y_rotate(m0.as_fix16_mat33_t(), y.value, result.as_fix16_mat33_t()); + fix16_mat33 result; + fix16_mat33_y_rotate(fix16_mat33::Identity.as_fix16_mat33_t(), y.value, + result.as_fix16_mat33_t()); + + return result; } - void create_rotz(const fix16_mat33 &m0, angle z, fix16_mat33 &result) + static fix16_mat33 rotation_on_z(angle z) { - fix16_mat33_z_rotate(m0.as_fix16_mat33_t(), z.value, result.as_fix16_mat33_t()); + fix16_mat33 result; + fix16_mat33_z_rotate(fix16_mat33::Identity.as_fix16_mat33_t(), z.value, + result.as_fix16_mat33_t()); + + return result; } - void create_rot(const euler &angles, fix16_mat33 &result) + static fix16_mat33 rotation_on_x(const fix16_mat33 &m, angle x) { + fix16_mat33 result; + fix16_mat33_x_rotate(m.as_fix16_mat33_t(), x.value, + result.as_fix16_mat33_t()); + return result; + } + + static fix16_mat33 rotation_on_y(const fix16_mat33 &m, angle y) + { + fix16_mat33 result; + fix16_mat33_y_rotate(m.as_fix16_mat33_t(), y.value, + result.as_fix16_mat33_t()); + return result; + } + + static fix16_mat33 rotation_on_z(const fix16_mat33 &m, angle z) + { + fix16_mat33 result; + fix16_mat33_z_rotate(m.as_fix16_mat33_t(), z.value, + result.as_fix16_mat33_t()); + return result; + } + + static fix16_mat33 create_rotation_radians(fix16 pitch, fix16 yaw, + fix16 roll) + { + fix16_mat33 result; + fix16_mat33_rotation_create(pitch.rad_to_angle().value, + yaw.rad_to_angle().value, roll.rad_to_angle().value, + result.as_fix16_mat33_t()); + + return result; + } + + static fix16_mat33 create_rotation_degrees(fix16 pitch, fix16 yaw, + fix16 roll) + { + fix16_mat33 result; + fix16_mat33_rotation_create(pitch.deg_to_angle().value, + yaw.deg_to_angle().value, roll.deg_to_angle().value, + result.as_fix16_mat33_t()); + + return result; + } + + static fix16_mat33 create_rotation_degrees(int32_t pitch, int32_t yaw, + int32_t roll) + { + fix16_mat33 result; + fix16_mat33_rotation_create(fix16::from_int(pitch).deg_to_angle().value, + fix16::from_int(yaw).deg_to_angle().value, + fix16::from_int(roll).deg_to_angle().value, + result.as_fix16_mat33_t()); + + return result; + } + + static fix16_mat33 create_rotation(const euler &angles) + { + fix16_mat33 result; fix16_mat33_rotation_create(angles.pitch.value, angles.yaw.value, angles.roll.value, result.as_fix16_mat33_t()); + + return result; } - fix16_vec3 transform_vector(const fix16_mat33 &m0, const fix16_vec3 &v) + // + // If the matrix represent a rotation vector that is part of a + // transformation matrix, this function transforms the input vector by the + // matrix but only calculating the result x and y components. This is very + // useful to break the transformation in separate stages. + // + static void transform_xy(const fix16_mat33 &m, const fix16_vec3 &v, + const fix16_vec3 &translation, fix16_vec3 &result) + { + const fix16_t *pMat = reinterpret_cast(m.row); + const fix16_t *pVec = reinterpret_cast(&v); + + fix16_t mach, macl; + + cpu_instr_clrmac(); + cpu_instr_macl(&pMat, &pVec); + cpu_instr_macl(&pMat, &pVec); + cpu_instr_macl(&pMat, &pVec); + mach = cpu_instr_sts_mach(); + macl = cpu_instr_sts_macl(); + result.x = fix16 { static_cast(cpu_instr_xtrct(mach, macl)) } + + translation.x; + + pVec = reinterpret_cast(&v); + cpu_instr_clrmac(); + cpu_instr_macl(&pMat, &pVec); + cpu_instr_macl(&pMat, &pVec); + cpu_instr_macl(&pMat, &pVec); + mach = cpu_instr_sts_mach(); + macl = cpu_instr_sts_macl(); + result.y = fix16 { static_cast(cpu_instr_xtrct(mach, macl)) } + + translation.y; + } + + // + // If the matrix represent a rotation vector that is part of a + // transformation matrix, this function transforms the input vector by the + // matrix but only calculating the result z component. This is very + // useful to break the transformation in separate stages. + // + static void transform_z(const fix16_mat33 &m, const fix16_vec3 &v, + const fix16_vec3 &translation, fix16_vec3 &result) + { + const fix16_t *pMat = reinterpret_cast(&m.row[2]); + const fix16_t *pVec = reinterpret_cast(&v); + + cpu_instr_clrmac(); + cpu_instr_macl(&pMat, &pVec); + cpu_instr_macl(&pMat, &pVec); + cpu_instr_macl(&pMat, &pVec); + const fix16_t mach = cpu_instr_sts_mach(); + const fix16_t macl = cpu_instr_sts_macl(); + result.z = fix16 { static_cast(cpu_instr_xtrct(mach, macl)) } + + translation.z; + } + + static fix16_vec3 transform_vector(const fix16_mat33 &m, + const fix16_vec3 &v) { fix16_vec3_t result; - fix16_mat33_vec3_mul(m0.as_fix16_mat33_t(), v.as_fix16_vec3_t(), + fix16_mat33_vec3_mul(m.as_fix16_mat33_t(), v.as_fix16_vec3_t(), &result); return fix16_vec3 { result }; } + + static const fix16_mat33 Identity; +}; + +inline const fix16_mat33 fix16_mat33::Identity { + // Row 0 + 1.0_fp, + 0.0_fp, + 0.0_fp, + // Row 1 + 0.0_fp, + 1.0_fp, + 0.0_fp, + // Row 2 + 0.0_fp, + 0.0_fp, + 1.0_fp, }; static_assert(sizeof(fix16_mat33) == sizeof(fix16_mat33_t)); diff --git a/libyaul/gamemath/gamemath/fix16/fix16_quat.h b/libyaul/gamemath/gamemath/fix16/fix16_quat.h index a7bab248..b7def1e8 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_quat.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_quat.h @@ -135,8 +135,6 @@ struct __packed __aligned(4) fix16_quat { { } - ~fix16_quat() = default; - fix16_quat &operator=(const fix16_quat &other) = default; fix16_quat &operator=(fix16_quat &&other) = default; @@ -150,6 +148,12 @@ struct __packed __aligned(4) fix16_quat { return reinterpret_cast(this); } + void identity() + { + comp.zero(); + w = fix16::One; + } + const fix16_quat operator*(const fix16_quat &other) const { fix16_quat_t result; diff --git a/libyaul/gamemath/gamemath/fix16/fix16_vec2.h b/libyaul/gamemath/gamemath/fix16/fix16_vec2.h index 9d385ca7..144dfc0b 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_vec2.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_vec2.h @@ -204,21 +204,19 @@ struct __packed __aligned(4) fix16_vec2 /// @brief Not yet documented. fix16 y; - fix16_vec2() - { - } + fix16_vec2() = default; fix16_vec2(fix16_vec2 &&) = default; fix16_vec2(const fix16_vec2 &) = default; - constexpr explicit fix16_vec2(fix16_t x, fix16_t y) - : x { x } - , y { y } + constexpr explicit fix16_vec2(fix16_t x_, fix16_t y_) + : x { x_ } + , y { y_ } { } - constexpr explicit fix16_vec2(fix16 x, fix16 y) - : x { x } - , y { y } + constexpr explicit fix16_vec2(fix16 x_, fix16 y_) + : x { x_ } + , y { y_ } { } @@ -299,19 +297,6 @@ struct __packed __aligned(4) fix16_vec2 return *this; } - fix16 operator[](int32_t index) const - { - switch (index) { - case 0: - return x; - case 1: - return y; - default: - assert(false); - return fix16::zero(); - } - } - bool is_zero() const { return x == 0 && y == 0; @@ -332,6 +317,12 @@ struct __packed __aligned(4) fix16_vec2 return reinterpret_cast(this); } + void zero() + { + x = 0.0_fp; + y = 0.0_fp; + } + fix16 dot(const fix16_vec2 &other) const { return dot(*this, other); @@ -357,13 +348,6 @@ struct __packed __aligned(4) fix16_vec2 fix16::start_divu_1_over_value(length()); } - static void finish_normalization(fix16_vec2 & result) - { - const fix16 denom { fix16::get_divu_quotient() }; - result.x *= denom; - result.y *= denom; - } - void normalize() { start_normalization(); @@ -377,6 +361,44 @@ struct __packed __aligned(4) fix16_vec2 return first.approximate_distance(second); } + fix16_vec2 reflect(const fix16_vec2 &normal) const + { + return reflect(*this, normal); + } + + fix16 &operator[](int32_t index) + { + switch (index) { + case 0: + return x; + case 1: + return y; + default: + assert(false); + return x; + } + } + + fix16 operator[](int32_t index) const + { + switch (index) { + case 0: + return x; + case 1: + return y; + default: + assert(false); + return x; + } + } + + static void finish_normalization(fix16_vec2 & result) + { + const fix16 denom { fix16::get_divu_quotient() }; + result.x *= denom; + result.y *= denom; + } + static fix16 dot(const fix16_vec2 &a, const fix16_vec2 &b) { return fix16 { fix16_vec2_dot(a.as_fix16_vec2_t(), @@ -388,18 +410,18 @@ struct __packed __aligned(4) fix16_vec2 return fix16 { (a.x * b.y) - (a.y * b.x) }; } - fix16_vec2 reflect(const fix16_vec2 &normal) const + static fix16_vec2 reflect(const fix16_vec2 &v, const fix16_vec2 &normal) { - // this - 2 * proj(this, normal) - const fix16 factor { dot(*this, normal).value << 1 }; + // v - 2 * proj(v, normal) + const fix16 factor { dot(v, normal).value << 1 }; const fix16_vec2 proj { factor * normal.x, factor * normal.y, }; return fix16_vec2 { - x - proj.x, - y - proj.y, + v.x - proj.x, + v.y - proj.y, }; } @@ -411,22 +433,21 @@ struct __packed __aligned(4) fix16_vec2 }; } - static constexpr fix16_vec2 zero() - { - return fix16_vec2 { 0, 0 }; - } + static const fix16_vec2 Zero; - static constexpr fix16_vec2 unit_x() - { - return fix16_vec2 { FIX16(1.0), 0 }; - } + static const fix16_vec2 Unit_x; - static constexpr fix16_vec2 unit_y() - { - return fix16_vec2 { 0, FIX16(1.0) }; - } + static const fix16_vec2 Unit_y; }; +inline const fix16_vec2 fix16_vec2::Zero { fix16_vec2::from_double(0.0, 0.0) }; + +inline const fix16_vec2 fix16_vec2::Unit_x { fix16_vec2::from_double(1.0, + 0.0) }; + +inline const fix16_vec2 fix16_vec2::Unit_y { fix16_vec2::from_double(0.0, + 1.0) }; + inline fix16_vec2 operator*(fix16 scalar, const fix16_vec2 &v) { diff --git a/libyaul/gamemath/gamemath/fix16/fix16_vec3.h b/libyaul/gamemath/gamemath/fix16/fix16_vec3.h index 88ce64ca..c5374f77 100644 --- a/libyaul/gamemath/gamemath/fix16/fix16_vec3.h +++ b/libyaul/gamemath/gamemath/fix16/fix16_vec3.h @@ -392,6 +392,13 @@ struct __packed __aligned(4) fix16_vec3 return reinterpret_cast(this); } + void zero() + { + x = 0.0_fp; + y = 0.0_fp; + z = 0.0_fp; + } + fix16 min() const { return ::min(::min(x, y), z); @@ -421,6 +428,21 @@ struct __packed __aligned(4) fix16_vec3 { return fix16 { fix16_vec3_sqr_length(as_fix16_vec3_t()) }; } + + fix16& operator[](int32_t index) + { + switch (index) { + case 0: + return x; + case 1: + return y; + case 2: + return z; + default: + assert(false); + return x; + } + } fix16 operator[](int32_t index) const { @@ -433,7 +455,7 @@ struct __packed __aligned(4) fix16_vec3 return z; default: assert(false); - return fix16::zero(); + return x; } } @@ -464,25 +486,13 @@ struct __packed __aligned(4) fix16_vec3 z *= scale; } - static constexpr fix16_vec3 zero() - { - return fix16_vec3 { 0, 0, 0 }; - } - - static constexpr fix16_vec3 unit_x() - { - return fix16_vec3 { FIX16(1.0), 0, 0 }; - } - - static constexpr fix16_vec3 unit_y() - { - return fix16_vec3 { 0, FIX16(1.0), 0 }; - } - - static constexpr fix16_vec3 unit_z() - { - return fix16_vec3 { 0, 0, FIX16(1.0) }; - } + static const fix16_vec3 Zero; + + static const fix16_vec3 Unit_x; + + static const fix16_vec3 Unit_y; + + static const fix16_vec3 Unit_z; static constexpr fix16_vec3 from_double(double x, double y, double z) { @@ -520,6 +530,14 @@ struct __packed __aligned(4) fix16_vec3 } }; +inline const fix16_vec3 fix16_vec3::Zero { fix16_vec3::from_double(0.0, 0.0, 0.0) }; + +inline const fix16_vec3 fix16_vec3::Unit_x { fix16_vec3::from_double(1.0, 0.0, 0.0) }; + +inline const fix16_vec3 fix16_vec3::Unit_y { fix16_vec3::from_double(0.0, 1.0, 0.0) }; + +inline const fix16_vec3 fix16_vec3::Unit_z { fix16_vec3::from_double(0.0, 0.0, 1.0) }; + inline fix16_vec3 operator*(fix16 scalar, const fix16_vec3 &v) {