diff --git a/ChangeLog.md b/ChangeLog.md index 5c5b1491a..b3b0d9541 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -10,6 +10,13 @@ Nazara Engine: - Fix reflection sometimes being enabled by default for Materials - Fix built-in unserialization of std::string which was corruption memory - Fix Buffer::Destroy() not really destroying buffer +- Fix Bitset::TestAll() returned wrong result on full of '1' bitset +- ByteStream now returns the number of bytes written as the other streams +- Total rewriting of the color conversions +- Fix NormalizeAngle to the correct range +- Fix BoundingVolume::Lerp() with Extend_Null +- Simplification of methods Matrix4::SetRotation() and Quaternion::MakeRotationBetween() +- Fix mouve moved event generated on X11 platform when doing Mouse::SetPosition() Nazara Development Kit: @@ -256,4 +263,4 @@ Issues fixed: - #80: When initializing the engine, some pixel format errors occurs, this currently has no side-effect. # 0.1 -- Initial release \ No newline at end of file +- Initial release diff --git a/SDK/include/NDK/Canvas.inl b/SDK/include/NDK/Canvas.inl index 2e76348af..a70a0edb1 100644 --- a/SDK/include/NDK/Canvas.inl +++ b/SDK/include/NDK/Canvas.inl @@ -8,8 +8,8 @@ namespace Ndk { inline Canvas::Canvas(WorldHandle world, Nz::EventHandler& eventHandler, Nz::CursorControllerHandle cursorController) : - m_hoveredWidget(InvalidCanvasIndex), m_keyboardOwner(InvalidCanvasIndex), + m_hoveredWidget(InvalidCanvasIndex), m_cursorController(cursorController), m_world(std::move(world)) { diff --git a/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp b/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp index 1dcf6ef0d..909a91daa 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp @@ -355,9 +355,9 @@ namespace Ndk { std::size_t skinIndex(lua.Check(&argIndex)); Nz::String subMesh(lua.Check(&argIndex)); - Nz::MaterialRef material(lua.Check(&argIndex)); + Nz::MaterialRef materialRef(lua.Check(&argIndex)); - instance->SetMaterial(skinIndex, subMesh, std::move(material)); + instance->SetMaterial(skinIndex, subMesh, std::move(materialRef)); return 0; } diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index b7c276c11..095ef3710 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -130,8 +130,6 @@ namespace Nz * \brief Returns the number of elements in a C-array * \return The number of elements * - * \param name C-array - * * \see CountOf */ template diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index c3649cf1d..3b24586bd 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -815,7 +815,7 @@ namespace Nz for (std::size_t i = 0; i < m_blocks.size(); ++i) { Block mask = (i == m_blocks.size() - 1) ? lastBlockMask : fullBitMask; - if (m_blocks[i] == mask) // The extra bits are set to zero, thus we can't test without proceeding with a mask + if (m_blocks[i] != mask) // The extra bits are set to zero, thus we can't test without proceeding with a mask return false; } diff --git a/include/Nazara/Core/ByteArray.inl b/include/Nazara/Core/ByteArray.inl index 108b672cb..5d6e823dc 100644 --- a/include/Nazara/Core/ByteArray.inl +++ b/include/Nazara/Core/ByteArray.inl @@ -421,7 +421,6 @@ namespace Nz /*! * \brief Resizes the string - * \return A reference to this * * \param newSize Target size */ @@ -433,7 +432,6 @@ namespace Nz /*! * \brief Resizes the string - * \return A reference to this * * \param newSize Target size * \param byte Byte to add if newSize is greather than actual size diff --git a/include/Nazara/Core/ByteStream.hpp b/include/Nazara/Core/ByteStream.hpp index 0cdf1b795..e6e941256 100644 --- a/include/Nazara/Core/ByteStream.hpp +++ b/include/Nazara/Core/ByteStream.hpp @@ -41,7 +41,7 @@ namespace Nz void SetStream(void* ptr, Nz::UInt64 size); void SetStream(const void* ptr, Nz::UInt64 size); - inline void Write(const void* data, std::size_t size); + inline std::size_t Write(const void* data, std::size_t size); template ByteStream& operator>>(T& value); diff --git a/include/Nazara/Core/ByteStream.inl b/include/Nazara/Core/ByteStream.inl index 1dbf9535e..49d51b7d6 100644 --- a/include/Nazara/Core/ByteStream.inl +++ b/include/Nazara/Core/ByteStream.inl @@ -101,7 +101,7 @@ namespace Nz * \brief Reads data * \return Number of data read * - * \param buffer Preallocated buffer to contain information read + * \param ptr Preallocated buffer to contain information read * \param size Size of the read and thus of the buffer */ @@ -117,7 +117,7 @@ namespace Nz /*! * \brief Sets the stream endianness * - * \param Type of the endianness + * \param endiannes Type of the endianness */ inline void ByteStream::SetDataEndianness(Endianness endiannes) @@ -154,13 +154,13 @@ namespace Nz * \remark Produces a NazaraAssert if buffer is nullptr */ - inline void ByteStream::Write(const void* data, std::size_t size) + inline std::size_t ByteStream::Write(const void* data, std::size_t size) { if (!m_context.stream) OnEmptyStream(); FlushBits(); - m_context.stream->Write(data, size); + return m_context.stream->Write(data, size); } /*! diff --git a/include/Nazara/Core/Color.hpp b/include/Nazara/Core/Color.hpp index 4ed06796f..0e0247f0a 100644 --- a/include/Nazara/Core/Color.hpp +++ b/include/Nazara/Core/Color.hpp @@ -23,6 +23,7 @@ namespace Nz inline explicit Color(UInt8 lightness); inline Color(UInt8 color[3], UInt8 alpha = 255); inline Color(const Color& color) = default; + inline Color(Color&& color) = default; inline ~Color() = default; inline bool IsOpaque() const; @@ -32,6 +33,9 @@ namespace Nz inline Color operator+(const Color& angles) const; inline Color operator*(const Color& angles) const; + inline Color& operator=(const Color& other) = default; + inline Color& operator=(Color&& other) = default; + inline Color operator+=(const Color& angles); inline Color operator*=(const Color& angles); @@ -40,13 +44,13 @@ namespace Nz static inline Color FromCMY(float cyan, float magenta, float yellow); static inline Color FromCMYK(float cyan, float magenta, float yellow, float black); - static inline Color FromHSL(UInt8 hue, UInt8 saturation, UInt8 lightness); + static inline Color FromHSL(float hue, float saturation, float lightness); static inline Color FromHSV(float hue, float saturation, float value); static inline Color FromXYZ(const Vector3f& vec); static inline Color FromXYZ(float x, float y, float z); static inline void ToCMY(const Color& color, float* cyan, float* magenta, float* yellow); static inline void ToCMYK(const Color& color, float* cyan, float* magenta, float* yellow, float* black); - static inline void ToHSL(const Color& color, UInt8* hue, UInt8* saturation, UInt8* lightness); + static inline void ToHSL(const Color& color, float* hue, float* saturation, float* lightness); static inline void ToHSV(const Color& color, float* hue, float* saturation, float* value); static inline void ToXYZ(const Color& color, Vector3f* vec); static inline void ToXYZ(const Color& color, float* x, float* y, float* z); diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl index 77b6be8ae..f391f0c76 100644 --- a/include/Nazara/Core/Color.inl +++ b/include/Nazara/Core/Color.inl @@ -219,35 +219,29 @@ namespace Nz * \brief Converts HSL representation to RGB * \return Color resulting * - * \param hue Hue component - * \param saturation Saturation component - * \param lightness Lightness component + * \param hue Hue component in [0, 360] + * \param saturation Saturation component [0, 1] + * \param lightness Lightness component [0, 1] */ - inline Color Color::FromHSL(UInt8 hue, UInt8 saturation, UInt8 lightness) + inline Color Color::FromHSL(float hue, float saturation, float lightness) { - if (saturation == 0) + if (NumberEquals(saturation, 0.f)) { // RGB results from 0 to 255 - return Color(lightness * 255, - lightness * 255, - lightness * 255); + return Color(static_cast(lightness * 255.f)); } else { - // Norme Windows - float l = lightness/240.f; - float h = hue/240.f; - float s = saturation/240.f; - float v2; - if (l < 0.5f) - v2 = l * (1.f + s); + if (lightness < 0.5f) + v2 = lightness * (1.f + saturation); else - v2 = (l + s) - (s*l); + v2 = (lightness + saturation) - (saturation * lightness); - float v1 = 2.f * l - v2; + float v1 = 2.f * lightness - v2; + float h = hue / 360.f; return Color(static_cast(255.f * Hue2RGB(v1, v2, h + (1.f/3.f))), static_cast(255.f * Hue2RGB(v1, v2, h)), static_cast(255.f * Hue2RGB(v1, v2, h - (1.f/3.f)))); @@ -258,9 +252,9 @@ namespace Nz * \brief Converts HSV representation to RGB * \return Color resulting * - * \param hue Hue component - * \param saturation Saturation component - * \param value Value component + * \param hue Hue component in [0, 360] + * \param saturation Saturation component in [0, 1] + * \param value Value component in [0, 1] */ inline Color Color::FromHSV(float hue, float saturation, float value) @@ -269,16 +263,15 @@ namespace Nz return Color(static_cast(value * 255.f)); else { - float h = hue/360.f * 6.f; - float s = saturation/360.f; + float h = (hue / 360.f) * 6.f; - if (NumberEquals(h, 6.f)) - h = 0; // hue must be < 1 + if (NumberEquals(h , 6.f)) + h = 0.f; // hue must be < 1 - int i = static_cast(h); - float v1 = value * (1.f - s); - float v2 = value * (1.f - s * (h - i)); - float v3 = value * (1.f - s * (1.f - (h - i))); + int i = static_cast(h); + float v1 = value * (1.f - saturation); + float v2 = value * (1.f - saturation * (h - i)); + float v3 = value * (1.f - saturation * (1.f - (h - i))); float r, g, b; switch (i) @@ -321,7 +314,7 @@ namespace Nz } // RGB results from 0 to 255 - return Color(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); + return Color(static_cast(r * 255.f), static_cast(g * 255.f), static_cast(b * 255.f)); } } @@ -338,7 +331,7 @@ namespace Nz } /*! - * \brief Converts XYZ representation to RGB + * \brief Converts XYZ representation (D65/2°) to RGB * \return Color resulting * * \param x X component @@ -362,12 +355,12 @@ namespace Nz r *= 12.92f; if (g > 0.0031308f) - g = 1.055f * (std::pow(r, 1.f/2.4f)) - 0.055f; + g = 1.055f * (std::pow(g, 1.f/2.4f)) - 0.055f; else g *= 12.92f; if (b > 0.0031308f) - b = 1.055f * (std::pow(r, 1.f/2.4f)) - 0.055f; + b = 1.055f * (std::pow(b, 1.f/2.4f)) - 0.055f; else b *= 12.92f; @@ -427,12 +420,12 @@ namespace Nz * \brief Converts RGB representation to HSL * * \param color Color to transform - * \param hue Hue component - * \param saturation Saturation component - * \param lightness Lightness component + * \param hue Hue component [0, 360] + * \param saturation Saturation component in [0, 1] + * \param lightness Lightness component in [0, 1] */ - inline void Color::ToHSL(const Color& color, UInt8* hue, UInt8* saturation, UInt8* lightness) + inline void Color::ToHSL(const Color& color, float* hue, float* saturation, float* lightness) { float r = color.r / 255.f; float g = color.g / 255.f; @@ -443,42 +436,41 @@ namespace Nz float deltaMax = max - min; //Delta RGB value - float l = (max + min)/2.f; + float l = (max + min) / 2.f; + *lightness = l; if (NumberEquals(deltaMax, 0.f)) { //This is a gray, no chroma... - *hue = 0; //HSL results from 0 to 1 - *saturation = 0; + *hue = 0.f; + *saturation = 0.f; } else { - //Chromatic data... - if (l < 0.5f) - *saturation = static_cast(deltaMax/(max+min)*240.f); + if (l <= 0.5f) + *saturation = deltaMax / (max + min); else - *saturation = static_cast(deltaMax/(2.f-max-min)*240.f); + *saturation = (deltaMax / (2.f - max - min)); - *lightness = static_cast(l*240.f); - - float deltaR = ((max - r)/6.f + deltaMax/2.f)/deltaMax; - float deltaG = ((max - g)/6.f + deltaMax/2.f)/deltaMax; - float deltaB = ((max - b)/6.f + deltaMax/2.f)/deltaMax; + float deltaR = ((max - r) / 6.f + deltaMax / 2.f) / deltaMax; + float deltaG = ((max - g) / 6.f + deltaMax / 2.f) / deltaMax; + float deltaB = ((max - b) / 6.f + deltaMax / 2.f) / deltaMax; float h; + if (NumberEquals(r, max)) h = deltaB - deltaG; else if (NumberEquals(g, max)) - h = (1.f/3.f) + deltaR - deltaB; + h = (1.f / 3.f) + deltaR - deltaB; else - h = (2.f/3.f) + deltaG - deltaR; + h = (2.f / 3.f) + deltaG - deltaR; if (h < 0.f) h += 1.f; else if (h > 1.f) h -= 1.f; - *hue = static_cast(h*240.f); + *hue = h * 360.f; } } @@ -507,33 +499,33 @@ namespace Nz if (NumberEquals(deltaMax, 0.f)) { //This is a gray, no chroma... - *hue = 0; //HSV results from 0 to 1 - *saturation = 0; + *hue = 0.f; + *saturation = 0.f; } else { //Chromatic data... - *saturation = deltaMax/max*360.f; + *saturation = deltaMax / max; - float deltaR = ((max - r)/6.f + deltaMax/2.f)/deltaMax; - float deltaG = ((max - g)/6.f + deltaMax/2.f)/deltaMax; - float deltaB = ((max - b)/6.f + deltaMax/2.f)/deltaMax; + float deltaR = ((max - r) / 6.f + deltaMax / 2.f) / deltaMax; + float deltaG = ((max - g) / 6.f + deltaMax / 2.f) / deltaMax; + float deltaB = ((max - b) / 6.f + deltaMax / 2.f) / deltaMax; float h; if (NumberEquals(r, max)) h = deltaB - deltaG; else if (NumberEquals(g, max)) - h = (1.f/3.f) + deltaR - deltaB; + h = (1.f / 3.f) + deltaR - deltaB; else - h = (2.f/3.f) + deltaG - deltaR; + h = (2.f / 3.f) + deltaG - deltaR; if (h < 0.f) h += 1.f; else if (h > 1.f) h -= 1.f; - *hue = h*360.f; + *hue = h * 360.f; } } diff --git a/include/Nazara/Core/Flags.inl b/include/Nazara/Core/Flags.inl index 1899e7576..2f83a3b8b 100644 --- a/include/Nazara/Core/Flags.inl +++ b/include/Nazara/Core/Flags.inl @@ -29,7 +29,7 @@ namespace Nz /*! * \brief Constructs a Flags object using an Enum value * - * \param value enumVal + * \param enumVal enumVal * * Setup a Flags object with only one flag active (corresponding to the enum value passed as argument). */ diff --git a/include/Nazara/Core/ObjectRef.inl b/include/Nazara/Core/ObjectRef.inl index c3e783186..b4d89531c 100644 --- a/include/Nazara/Core/ObjectRef.inl +++ b/include/Nazara/Core/ObjectRef.inl @@ -484,16 +484,17 @@ namespace Nz namespace std { - /*! - * \ingroup core - * \brief Gives a hash representation of the object, specialisation of std - * \return Hash of the ObjectRef - * - * \param object Object to hash - */ template struct hash> { + /*! + * \ingroup core + * \brief Gives a hash representation of the object, specialisation of std + * \return Hash of the ObjectRef + * + * \param object Object to hash + */ + size_t operator()(const Nz::ObjectRef& object) const { hash h; diff --git a/include/Nazara/Core/Primitive.inl b/include/Nazara/Core/Primitive.inl index fff7f82bb..24d14e8f7 100644 --- a/include/Nazara/Core/Primitive.inl +++ b/include/Nazara/Core/Primitive.inl @@ -385,7 +385,7 @@ namespace Nz * * \param size (Width, Depth) * \param subdivision Number of subdivision for the axis - * \param planeInfo Information for the plane + * \param plane Information for the plane * \param uvCoords Coordinates for texture */ inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Planef& plane, const Rectf& uvCoords) diff --git a/include/Nazara/Core/String.inl b/include/Nazara/Core/String.inl index 027ab4349..1406c6798 100644 --- a/include/Nazara/Core/String.inl +++ b/include/Nazara/Core/String.inl @@ -121,7 +121,7 @@ namespace std const char* ptr = str.GetConstBuffer(); do - h = ((h << 5) + h) + *ptr; + h = ((h << 5) + h) + static_cast(*ptr); while (*++ptr); } diff --git a/include/Nazara/Graphics/Light.inl b/include/Nazara/Graphics/Light.inl index 509016112..f76bbe841 100644 --- a/include/Nazara/Graphics/Light.inl +++ b/include/Nazara/Graphics/Light.inl @@ -265,7 +265,8 @@ namespace Nz /*! * \brief Sets the inner angle in spot light - * \return innerAngle Inner angle + * + * \param innerAngle Inner angle */ inline void Light::SetInnerAngle(float innerAngle) @@ -289,7 +290,8 @@ namespace Nz /*! * \brief Sets the outer angle in spot light - * \return outerAngle Outer angle + * + * \param outerAngle Outer angle * * \remark Invalidates the bounding volume */ @@ -305,7 +307,8 @@ namespace Nz /*! * \brief Sets the radius of the light - * \return radius Light radius + * + * \param radius Light radius * * \remark Invalidates the bounding volume */ diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index e50385c78..195251a19 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -552,11 +552,11 @@ namespace Nz #endif const T twoLimit = limit * T(2); - angle = std::fmod(angle + limit, twoLimit); + angle = std::fmod(angle, twoLimit); if (angle < T(0)) angle += twoLimit; - return angle - limit; + return angle; } /*! diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index d2dee79f8..5bbd83f31 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -541,7 +541,7 @@ namespace Nz return Infinite(); case Extend_Null: - return from.obb * interpolation; + return to.obb * interpolation; } // If we arrive here, the extend is invalid diff --git a/include/Nazara/Math/EulerAngles.inl b/include/Nazara/Math/EulerAngles.inl index d903de52a..0fc972164 100644 --- a/include/Nazara/Math/EulerAngles.inl +++ b/include/Nazara/Math/EulerAngles.inl @@ -77,7 +77,6 @@ namespace Nz /*! * \brief Makes the euler angle (0, 0, 0) - * \return A reference to this euler angle with components (0, 0, 0) * * \see Zero */ @@ -276,7 +275,7 @@ namespace Nz * \brief Substracts the components of other euler angle to this euler angle * \return A reference to this euler angle where components are the difference of this euler angle and the other one * - * \param angle The other euler angle to substract components with + * \param angles The other euler angle to substract components with */ template diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index f3effcc5e..27b7d3183 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -664,9 +664,9 @@ namespace Nz template Vector3 Matrix4::GetSquaredScale() const { - return Vector3(m11*m11 + m21*m21 + m31*m31, - m12*m12 + m22*m22 + m32*m32, - m13*m13 + m23*m23 + m33*m33); + return Vector3(m11 * m11 + m12 * m12 + m13 * m13, + m21 * m21 + m22 * m22 + m23 * m23, + m31 * m31 + m32 * m32 + m33 * m33); } /*! @@ -1153,36 +1153,32 @@ namespace Nz * * \param rotation Quaternion representing a rotation of space * - * \remark 3rd column and row are unchanged + * \remark 3rd column and row are unchanged. Scale is removed. */ template Matrix4& Matrix4::SetRotation(const Quaternion& rotation) { - T tx = rotation.x + rotation.x; - T ty = rotation.y + rotation.y; - T tz = rotation.z + rotation.z; - T twx = tx * rotation.w; - T twy = ty * rotation.w; - T twz = tz * rotation.w; - T txx = tx * rotation.x; - T txy = ty * rotation.x; - T txz = tz * rotation.x; - T tyy = ty * rotation.y; - T tyz = tz * rotation.y; - T tzz = tz * rotation.z; + T qw = rotation.w; + T qx = rotation.x; + T qy = rotation.y; + T qz = rotation.z; - m11 = F(1.0) - (tyy + tzz); - m12 = txy + twz; - m13 = txz - twy; + T qx2 = qx * qx; + T qy2 = qy * qy; + T qz2 = qz * qz; - m21 = txy - twz; - m22 = F(1.0) - (txx + tzz); - m23 = tyz + twx; + m11 = F(1.0) - F(2.0) * qy2 - F(2.0) * qz2; + m21 = F(2.0) * qx * qy - F(2.0) * qz * qw; + m31 = F(2.0) * qx * qz + F(2.0) * qy * qw; - m31 = txz + twy; - m32 = tyz - twx; - m33 = F(1.0) - (txx + tyy); + m12 = F(2.0) * qx * qy + F(2.0) * qz * qw; + m22 = F(1.0) - F(2.0) * qx2 - F(2.0) * qz2; + m32 = F(2.0) * qy * qz - F(2.0) * qx * qw; + + m13 = F(2.0) * qx * qz - F(2.0) * qy * qw; + m23 = F(2.0) * qy * qz + F(2.0) * qx * qw; + m33 = F(1.0) - F(2.0) * qx2 - F(2.0) * qy2; return *this; } diff --git a/include/Nazara/Math/Plane.inl b/include/Nazara/Math/Plane.inl index 15bf8cae7..d80809988 100644 --- a/include/Nazara/Math/Plane.inl +++ b/include/Nazara/Math/Plane.inl @@ -106,9 +106,9 @@ namespace Nz * \brief Returns the distance from the plane to the point * \return Distance to the point * - * \param X X position of the point - * \param Y Y position of the point - * \param Z Z position of the point + * \param x X position of the point + * \param y Y position of the point + * \param z Z position of the point * * \remark If T is negative, it means that the point is in the opposite direction of the normal * @@ -319,7 +319,7 @@ namespace Nz * \brief Compares the plane to other one * \return true if the planes are the same * - * \param vec Other vector to compare with + * \param plane Other vector to compare with * * \remark Plane with normal N and distance D is the same than with normal -N et distance -D */ diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index 553dedad8..f07524c0f 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -251,35 +251,19 @@ namespace Nz * \param from Initial vector * \param to Target vector * + * \remark Vectors are not required to be normalized + * * \see RotationBetween */ template Quaternion& Quaternion::MakeRotationBetween(const Vector3& from, const Vector3& to) { - // TODO (Gawaboumga): Replace by http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors ? - - T dot = from.DotProduct(to); - if (NumberEquals(dot, F(-1.0))) - { - Vector3 cross = Vector3::CrossProduct(Vector3::UnitX(), from); - if (NumberEquals(cross.GetLength(), F(0.0))) - cross = Vector3::CrossProduct(Vector3::UnitY(), from); - - return Set(F(180.0), cross); - } - else if (NumberEquals(dot, F(1.0))) - return MakeIdentity(); - else - { - Vector3 a = from.CrossProduct(to); - x = a.x; - y = a.y; - z = a.z; - w = T(1.0) + dot; - - return Normalize(); - } + // Based on: http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors + T norm = std::sqrt(from.GetSquaredLength() * to.GetSquaredLength()); + Vector3 crossProduct = from.CrossProduct(to); + Set(norm + from.DotProduct(to), crossProduct.x, crossProduct.y, crossProduct.z); + return Normalize(); } /*! @@ -425,7 +409,7 @@ namespace Nz * \brief Sets the components of the quaternion from another quaternion * \return A reference to this quaternion * - * \param vec The other quaternion + * \param quat The other quaternion */ template @@ -647,7 +631,7 @@ namespace Nz * \brief Compares the quaternion to other one * \return true if the quaternions are the same * - * \param vec Other quaternion to compare with + * \param quat Other quaternion to compare with */ template @@ -663,7 +647,7 @@ namespace Nz * \brief Compares the quaternion to other one * \return false if the quaternions are the same * - * \param vec Other quaternion to compare with + * \param quat Other quaternion to compare with */ template diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index 5aede77c2..48930be94 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -500,7 +500,7 @@ namespace Nz * \brief Multiplies the radius of the sphere with a scalar * \return A sphere where the center is the same and radius is the product of this radius and the scalar * - * \param scale The scalar to multiply radius with + * \param scalar The scalar to multiply radius with */ template @@ -513,7 +513,7 @@ namespace Nz * \brief Multiplies the radius of other sphere with a scalar * \return A reference to this sphere where the center is the same and radius is the product of this radius and the scalar * - * \param scale The scalar to multiply radius with + * \param scalar The scalar to multiply radius with */ template diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 1883ecfdc..2c9d87978 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -692,7 +692,7 @@ namespace Nz * \brief Multiplies the components of other vector with a scalar * \return A reference to this vector where components are the product of this vector and the scalar * - * \param vec The other vector to multiply components with + * \param scale The scalar to multiply components with */ template @@ -737,7 +737,7 @@ namespace Nz * \brief Divides the components of other vector with a scalar * \return A reference to this vector where components are the quotient of this vector and the scalar * - * \param vec The other vector to divide components with + * \param scale The scalar to divide components with * * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 37be47fba..9a74717ff 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -810,7 +810,7 @@ namespace Nz * \brief Multiplies the components of other vector with a scalar * \return A reference to this vector where components are the product of this vector and the scalar * - * \param vec The other vector to multiply components with + * \param scale The scalar to multiply components with */ template Vector3& Vector3::operator*=(T scale) @@ -853,7 +853,7 @@ namespace Nz * \brief Divides the components of other vector with a scalar * \return A reference to this vector where components are the quotient of this vector and the scalar * - * \param vec The other vector to divide components with + * \param scale The scalar to divide components with * * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index b79e6a644..2263eb66a 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -728,7 +728,7 @@ namespace Nz * \brief Multiplies the components of other vector with a scalar * \return A reference to this vector where components are the product of this vector and the scalar * - * \param vec The other vector to multiply components with + * \param scale The scalar to multiply components with */ template @@ -777,7 +777,7 @@ namespace Nz * \brief Divides the components of other vector with a scalar * \return A reference to this vector where components are the quotient of this vector and the scalar * - * \param vec The other vector to divide components with + * \param scale The scalar to divide components with * * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null diff --git a/src/Nazara/Core/Directory.cpp b/src/Nazara/Core/Directory.cpp index 1470a0f3d..3a65c1153 100644 --- a/src/Nazara/Core/Directory.cpp +++ b/src/Nazara/Core/Directory.cpp @@ -312,7 +312,7 @@ namespace Nz /*! * \brief Sets the pattern of the directory * - * \param dirPath Pattern of the directory + * \param pattern Pattern of the directory */ void Directory::SetPattern(const String& pattern) @@ -327,7 +327,7 @@ namespace Nz * \return true if copy is successful * * \param sourcePath Path of the original directory - * \param targetPath Path of the copied directory + * \param destPath Path of the copied directory * * \remark Produces a NazaraError if could not create destination directory * \remark Produces a NazaraError if could not open origin directory diff --git a/src/Nazara/Core/GuillotineBinPack.cpp b/src/Nazara/Core/GuillotineBinPack.cpp index 0df4e0429..9ebae4bbb 100644 --- a/src/Nazara/Core/GuillotineBinPack.cpp +++ b/src/Nazara/Core/GuillotineBinPack.cpp @@ -293,7 +293,7 @@ namespace Nz * * \param rects List of rectangles * \param flipped List of flipped rectangles - * \param flipped List of inserted rectangles + * \param inserted List of inserted rectangles * \param count Count of rectangles * \param merge Merge possible * \param rectChoice Heuristic to use to free diff --git a/src/Nazara/Core/MemoryManager.cpp b/src/Nazara/Core/MemoryManager.cpp index 2b1bd6a72..ad175126e 100644 --- a/src/Nazara/Core/MemoryManager.cpp +++ b/src/Nazara/Core/MemoryManager.cpp @@ -94,7 +94,7 @@ namespace Nz * \return Raw memory allocated * * \param size Size to allocate - * \parma multi Array or not + * \param multi Array or not * \param file File of the allocation * \param line Line of the allocation in the file */ diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index 7d3b82972..25298b950 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -718,7 +718,6 @@ namespace Nz * \brief Create an uninitialized value of a set name * * \param name Name of the parameter - * \param value Value of the parameter * * \remark The previous value if any gets destroyed */ diff --git a/src/Nazara/Core/PluginManager.cpp b/src/Nazara/Core/PluginManager.cpp index 2a7fa8eee..14bc6744e 100644 --- a/src/Nazara/Core/PluginManager.cpp +++ b/src/Nazara/Core/PluginManager.cpp @@ -190,7 +190,7 @@ namespace Nz /*! * \brief Unmounts the plugin with a path * - * \param pluginPath Path to the plugin + * \param plugin Path to the plugin * * \remark Produces a NazaraError if not initialized * \remark Produces a NazaraError if plugin is not loaded diff --git a/src/Nazara/Core/Posix/DynLibImpl.cpp b/src/Nazara/Core/Posix/DynLibImpl.cpp index 27204443e..f519c916f 100644 --- a/src/Nazara/Core/Posix/DynLibImpl.cpp +++ b/src/Nazara/Core/Posix/DynLibImpl.cpp @@ -42,7 +42,7 @@ namespace Nz { String path = libraryPath; - unsigned int pos = path.FindLast(".so"); + size_t pos = path.FindLast(".so"); if (pos == String::npos || (path.GetLength() > pos+3 && path[pos+3] != '.')) path += ".so"; diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 2551ceb34..ba29d0916 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -295,7 +295,7 @@ namespace Nz } /*! - * \Brief Checks whether the string contains the character + * \brief Checks whether the string contains the character * \return true if found in the string * * \param character Single character @@ -311,7 +311,7 @@ namespace Nz } /*! - * \Brief Checks whether the string contains the "C string" + * \brief Checks whether the string contains the "C string" * \return true if found in the string * * \param string String to search @@ -327,7 +327,7 @@ namespace Nz } /*! - * \Brief Checks whether the string contains the string + * \brief Checks whether the string contains the string * \return true if found in the string * * \param string String to search @@ -2244,7 +2244,7 @@ namespace Nz * \brief Gets the word until next separator * \return Word string * - * \param start Index to begin the search + * \param index Index to begin the search * \param flags Flag for the look up */ @@ -2289,7 +2289,7 @@ namespace Nz * \brief Gets the word position * \return Position of the beginning of the word * - * \param start Index to begin the search + * \param index Index to begin the search * \param flags Flag for the look up */ @@ -2729,8 +2729,8 @@ namespace Nz * \brief Replaces the old "C string" by the new one * \return Number of changes * - * \param oldCharacter Pattern to find - * \param newCharacter Pattern to change for + * \param oldString Pattern to find + * \param replaceString Pattern to change for * \param start Index to begin the search * \param flags Flag for the look up */ @@ -2744,10 +2744,10 @@ namespace Nz * \brief Replaces the old "C string" by the new one * \return Number of changes * - * \param oldCharacter Pattern to find + * \param oldString Pattern to find * \param oldLength Length of the old string - * \param newCharacter Pattern to change for - * \param Length of the new string + * \param replaceString Pattern to change for + * \param replaceLength of the new string * \param start Index to begin the search * \param flags Flag for the look up */ @@ -2822,8 +2822,8 @@ namespace Nz * \brief Replaces the old string by the new one * \return Number of changes * - * \param oldCharacter Pattern to find - * \param newCharacter Pattern to change for + * \param oldString Pattern to find + * \param replaceString Pattern to change for * \param start Index to begin the search * \param flags Flag for the look up */ @@ -2838,7 +2838,7 @@ namespace Nz * \return Number of changes * * \param oldCharacters Pattern to find - * \param newCharacter Pattern to change for + * \param replaceCharacter Pattern to change for * \param start Index to begin the search * \param flags Flag for the look up * @@ -3646,7 +3646,7 @@ namespace Nz * \return The number of splits * * \param result Resulting tokens - * \param separation List of characters of separation + * \param separations List of characters for separation * \param start Index for the beginning of the search * \param flags Flag for the look up */ @@ -3687,7 +3687,7 @@ namespace Nz * \return The number of splits * * \param result Resulting tokens - * \param separation List of characters of separation + * \param separations List of characters for separation * \param start Index for the beginning of the search * \param flags Flag for the look up */ @@ -3885,7 +3885,7 @@ namespace Nz * \brief Returns a sub string of the string from a character * \return SubString * - * \param charater Pattern to find + * \param character Pattern to find * \param startPos Index for the beginning of the search * \param fromLast beginning by the end * \param include Include the character @@ -3975,7 +3975,7 @@ namespace Nz * \brief Returns a sub string of the string up to a character * \return SubString * - * \param charater Pattern to find + * \param character Pattern to find * \param startPos Index for the beginning of the search * \param toLast beginning by the end * \param include Include the character @@ -4124,7 +4124,6 @@ namespace Nz * \return true if successful * * \param value Double to convert to - * \param flags Flag for the look up */ bool String::ToDouble(double* value) const @@ -4143,7 +4142,7 @@ namespace Nz * \return true if successful * * \param value Integer to convert to - * \param flags Flag for the look up + * \param base Base to convert the integer to */ bool String::ToInteger(long long* value, UInt8 base) const @@ -5483,7 +5482,7 @@ namespace Nz * \brief Output operator * \return The stream * - * \param out The stream + * \param os The stream * \param str The string to output */ @@ -5523,7 +5522,7 @@ namespace Nz * \return String which is the result of the concatenation * * \param string String to add - * \param string String in the right hand side + * \param nstring String in the right hand side */ String operator+(const char* string, const String& nstring) @@ -5549,7 +5548,7 @@ namespace Nz * \return String which is the result of the concatenation * * \param string String to add - * \param string String in the right hand side + * \param nstring String in the right hand side */ String operator+(const std::string& string, const String& nstring) @@ -5667,7 +5666,7 @@ namespace Nz * \return true if it is the case * * \param character Single character in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator==(char character, const String& nstring) @@ -5680,7 +5679,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator==(const char* string, const String& nstring) @@ -5693,7 +5692,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator==(const std::string& string, const String& nstring) @@ -5706,7 +5705,7 @@ namespace Nz * \return false if it is the case * * \param character Single character in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator!=(char character, const String& nstring) @@ -5719,7 +5718,7 @@ namespace Nz * \return false if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator!=(const char* string, const String& nstring) @@ -5732,7 +5731,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator!=(const std::string& string, const String& nstring) @@ -5745,7 +5744,7 @@ namespace Nz * \return true if it is the case * * \param character Single character in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator<(char character, const String& nstring) @@ -5758,7 +5757,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator<(const char* string, const String& nstring) @@ -5771,7 +5770,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator<(const std::string& string, const String& nstring) @@ -5784,7 +5783,7 @@ namespace Nz * \return true if it is the case * * \param character Single character in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator<=(char character, const String& nstring) @@ -5797,7 +5796,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator<=(const char* string, const String& nstring) @@ -5810,7 +5809,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator<=(const std::string& string, const String& nstring) @@ -5823,7 +5822,7 @@ namespace Nz * \return true if it is the case * * \param character Single character in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator>(char character, const String& nstring) @@ -5836,7 +5835,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator>(const char* string, const String& nstring) @@ -5849,7 +5848,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator>(const std::string& string, const String& nstring) @@ -5862,7 +5861,7 @@ namespace Nz * \return true if it is the case * * \param character Single character in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator>=(char character, const String& nstring) @@ -5875,7 +5874,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator>=(const char* string, const String& nstring) @@ -5888,7 +5887,7 @@ namespace Nz * \return true if it is the case * * \param string String to compare in left hand side - * \param second String to compare in right hand side + * \param nstring String to compare in right hand side */ bool operator>=(const std::string& string, const String& nstring) diff --git a/src/Nazara/Physics2D/PhysWorld2D.cpp b/src/Nazara/Physics2D/PhysWorld2D.cpp index 67e1f479a..c0db3749f 100644 --- a/src/Nazara/Physics2D/PhysWorld2D.cpp +++ b/src/Nazara/Physics2D/PhysWorld2D.cpp @@ -26,14 +26,14 @@ namespace Nz auto drawOptions = static_cast(userdata); if (drawOptions->circleCallback) drawOptions->circleCallback(Vector2f(float(pos.x), float(pos.y)), float(angle), float(radius), CpDebugColorToColor(outlineColor), CpDebugColorToColor(fillColor), drawOptions->userdata); - }; + } void DrawDot(cpFloat size, cpVect pos, cpSpaceDebugColor color, cpDataPointer userdata) { auto drawOptions = static_cast(userdata); if (drawOptions->dotCallback) drawOptions->dotCallback(Vector2f(float(pos.x), float(pos.y)), float(size), CpDebugColorToColor(color), drawOptions->userdata); - }; + } using DebugDrawPolygonCallback = std::function; @@ -50,21 +50,21 @@ namespace Nz drawOptions->polygonCallback(nVertices.data(), vertexCount, float(radius), CpDebugColorToColor(outlineColor), CpDebugColorToColor(fillColor), drawOptions->userdata); } - }; + } void DrawSegment(cpVect a, cpVect b, cpSpaceDebugColor color, cpDataPointer userdata) { auto drawOptions = static_cast(userdata); if (drawOptions->segmentCallback) drawOptions->segmentCallback(Vector2f(float(a.x), float(a.y)), Vector2f(float(b.x), float(b.y)), CpDebugColorToColor(color), drawOptions->userdata); - }; + } void DrawThickSegment(cpVect a, cpVect b, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer userdata) { auto drawOptions = static_cast(userdata); if (drawOptions->thickSegmentCallback) drawOptions->thickSegmentCallback(Vector2f(float(a.x), float(a.y)), Vector2f(float(b.x), float(b.y)), float(radius), CpDebugColorToColor(outlineColor), CpDebugColorToColor(fillColor), drawOptions->userdata); - }; + } cpSpaceDebugColor GetColorForShape(cpShape* shape, cpDataPointer userdata) { @@ -76,7 +76,7 @@ namespace Nz } else return cpSpaceDebugColor{255.f, 0.f, 0.f, 255.f}; - }; + } } PhysWorld2D::PhysWorld2D() : diff --git a/src/Nazara/Physics2D/RigidBody2D.cpp b/src/Nazara/Physics2D/RigidBody2D.cpp index c3cb5af0c..0931e0a45 100644 --- a/src/Nazara/Physics2D/RigidBody2D.cpp +++ b/src/Nazara/Physics2D/RigidBody2D.cpp @@ -55,8 +55,8 @@ namespace Nz OnRigidBody2DRelease(std::move(object.OnRigidBody2DRelease)), m_shapes(std::move(object.m_shapes)), m_geom(std::move(object.m_geom)), - m_userData(object.m_userData), m_handle(object.m_handle), + m_userData(object.m_userData), m_world(object.m_world), m_isStatic(object.m_isStatic), m_gravityFactor(object.m_gravityFactor), diff --git a/src/Nazara/Platform/X11/WindowImpl.cpp b/src/Nazara/Platform/X11/WindowImpl.cpp index 278e6fec8..7ceefa701 100644 --- a/src/Nazara/Platform/X11/WindowImpl.cpp +++ b/src/Nazara/Platform/X11/WindowImpl.cpp @@ -58,7 +58,8 @@ namespace Nz m_parent(parent), m_smoothScrolling(false), m_mousePos(0, 0), - m_keyRepeat(true) + m_keyRepeat(true), + m_lastSequence(0) { std::memset(&m_size_hints, 0, sizeof(m_size_hints)); } @@ -1244,9 +1245,12 @@ namespace Nz { xcb_motion_notify_event_t* motionNotifyEvent = (xcb_motion_notify_event_t*)windowEvent; - if (m_mousePos.x == motionNotifyEvent->event_x && m_mousePos.y == motionNotifyEvent->event_y) + // We use the sequence to determine whether the motion is linked to a Mouse::SetPosition + if ((m_mousePos.x == motionNotifyEvent->event_x && m_mousePos.y == motionNotifyEvent->event_y) || m_lastSequence == motionNotifyEvent->sequence) break; + m_lastSequence = motionNotifyEvent->sequence; + WindowEvent event; event.type = Nz::WindowEventType_MouseMoved; event.mouseMove.deltaX = motionNotifyEvent->event_x - m_mousePos.x; diff --git a/src/Nazara/Platform/X11/WindowImpl.hpp b/src/Nazara/Platform/X11/WindowImpl.hpp index 0bd286944..425630e23 100644 --- a/src/Nazara/Platform/X11/WindowImpl.hpp +++ b/src/Nazara/Platform/X11/WindowImpl.hpp @@ -113,6 +113,7 @@ namespace Nz bool m_threadActive; Vector2i m_mousePos; bool m_keyRepeat; + uint16_t m_lastSequence; struct { diff --git a/tests/Engine/Core/AlgorithmCore.cpp b/tests/Engine/Core/AlgorithmCore.cpp index 9401a974d..39e06c566 100644 --- a/tests/Engine/Core/AlgorithmCore.cpp +++ b/tests/Engine/Core/AlgorithmCore.cpp @@ -30,9 +30,63 @@ TEST_CASE("Apply", "[CORE][ALGORITHM]") TEST_CASE("ComputeHash", "[CORE][ALGORITHM]") { - SECTION("Compute hash of '0'") + /*SECTION("Compute CRC32 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_CRC32, "1234"); + REQUIRE(result.ToHex().ToUpper() == "596A3B55"); + } + + SECTION("Compute CRC64 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_CRC64, "1234"); + REQUIRE(result.ToHex().ToUpper() == "33302B9FC23855A8"); + } + + SECTION("Compute Fletcher16 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_Fletcher16, "1234"); + REQUIRE(result.ToHex().ToUpper() == "F5CA"); + }*/ + + SECTION("Compute MD5 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_MD5, "1234"); + REQUIRE(result.ToHex().ToUpper() == "81DC9BDB52D04DC20036DBD8313ED055"); + } + + SECTION("Compute SHA1 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_SHA1, "1234"); + REQUIRE(result.ToHex().ToUpper() == "7110EDA4D09E062AA5E4A390B0A572AC0D2C0220"); + } + + SECTION("Compute SHA224 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_SHA224, "1234"); + REQUIRE(result.ToHex().ToUpper() == "99FB2F48C6AF4761F904FC85F95EB56190E5D40B1F44EC3A9C1FA319"); + } + + SECTION("Compute SHA256 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_SHA256, "1234"); + REQUIRE(result.ToHex().ToUpper() == "03AC674216F3E15C761EE1A5E255F067953623C8B388B4459E13F978D7C846F4"); + } + + SECTION("Compute SHA384 of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_SHA384, "1234"); + REQUIRE(result.ToHex().ToUpper() == "504F008C8FCF8B2ED5DFCDE752FC5464AB8BA064215D9C5B5FC486AF3D9AB8C81B14785180D2AD7CEE1AB792AD44798C"); + } + + SECTION("Compute SHA512 of '1234'") { auto result = Nz::ComputeHash(Nz::HashType_SHA512, "1234"); REQUIRE(result.ToHex().ToUpper() == "D404559F602EAB6FD602AC7680DACBFAADD13630335E951F097AF3900E9DE176B6DB28512F2E000B9D04FBA5133E8B1C6E8DF59DB3A8AB9D60BE4B97CC9E81DB"); } + + SECTION("Compute Whirlpool of '1234'") + { + auto result = Nz::ComputeHash(Nz::HashType_Whirlpool, "1234"); + REQUIRE(result.ToHex().ToUpper() == "2F9959B230A44678DD2DC29F037BA1159F233AA9AB183CE3A0678EAAE002E5AA6F27F47144A1A4365116D3DB1B58EC47896623B92D85CB2F191705DAF11858B8"); + } } diff --git a/tests/Engine/Core/Bitset.cpp b/tests/Engine/Core/Bitset.cpp index b06a38aa8..9cbd605b3 100644 --- a/tests/Engine/Core/Bitset.cpp +++ b/tests/Engine/Core/Bitset.cpp @@ -8,6 +8,7 @@ template void Check(const char* title); template void CheckAppend(const char* title); template void CheckBitOps(const char* title); +template void CheckBitOpsMultipleBlocks(const char* title); template void CheckConstructor(const char* title); template void CheckCopyMoveSwap(const char* title); template void CheckRead(const char* title); @@ -28,6 +29,7 @@ void Check(const char* title) CheckCopyMoveSwap(title); CheckBitOps(title); + CheckBitOpsMultipleBlocks(title); CheckAppend(title); CheckRead(title); @@ -111,7 +113,68 @@ void CheckBitOps(const char* title) { CHECK(andBitset == Nz::Bitset("00001")); CHECK(orBitset == Nz::Bitset("11111")); + CHECK(orBitset.TestAll()); CHECK(xorBitset == Nz::Bitset("11110")); + CHECK(!xorBitset.TestAll()); + CHECK((~orBitset).TestNone()); + } + } + + WHEN("We perform bit shifts") + { + first.ShiftLeft(1); + second.ShiftRight(2); + + THEN("We should obtain these") + { + CHECK(first == Nz::Bitset("10010")); + CHECK(second == Nz::Bitset("101")); + } + } + } + } +} + +template +void CheckBitOpsMultipleBlocks(const char* title) +{ + SECTION(title) + { + GIVEN("Two bitsets") + { + Nz::Bitset first("01001011010010101001010011010101001"); + Nz::Bitset second("10111111101101110110111101101110110"); + + WHEN("We perform operators") + { + Nz::Bitset andBitset = first & second; + Nz::Bitset orBitset = first | second; + Nz::Bitset xorBitset = first ^ second; + + THEN("They should operate as logical operators") + { + CHECK(andBitset == Nz::Bitset("00001011000000100000010001000100000")); + CHECK(orBitset == Nz::Bitset("11111111111111111111111111111111111")); + CHECK(orBitset.TestAll()); + CHECK(xorBitset == Nz::Bitset("11110100111111011111101110111011111")); + CHECK(!xorBitset.TestAll()); + CHECK((~orBitset).TestNone()); + } + } + + WHEN("We perform bit shifts") + { + first.ShiftLeft(16); + second.ShiftRight(16); + + THEN("We should obtain these") + { + CHECK(first == Nz::Bitset("10010100110101010010000000000000000")); + first.ShiftLeft(1); + CHECK(first == Nz::Bitset("00101001101010100100000000000000000")); + CHECK(second == Nz::Bitset("1011111110110111011")); + second.ShiftRight(1); + CHECK(second == Nz::Bitset("101111111011011101")); } } } diff --git a/tests/Engine/Core/ByteStream.cpp b/tests/Engine/Core/ByteStream.cpp new file mode 100644 index 000000000..58c31020d --- /dev/null +++ b/tests/Engine/Core/ByteStream.cpp @@ -0,0 +1,73 @@ +#include +#include + +#include + +SCENARIO("ByteStream", "[CORE][BYTESTREAM]") +{ + GIVEN("A bytestream from a bunch of bytes") + { + const int numberOfBytes = 16; + std::array data; + + Nz::ByteStream byteStream(data.data(), numberOfBytes); + + WHEN("We write some data in it") + { + int value = 5; + byteStream << value; + Nz::String string = "string"; + byteStream << string; + + byteStream.FlushBits(); + + THEN("We can retrieve them") + { + const void* const ptrData = data.data(); + Nz::ByteStream readStream; + CHECK(readStream.GetSize() == 0); + readStream = Nz::ByteStream(ptrData, byteStream.GetSize()); + int retrievedValue = 0; + readStream >> retrievedValue; + Nz::String retrievedString; + readStream >> retrievedString; + + CHECK(value == retrievedValue); + CHECK(string == retrievedString); + } + } + } + + GIVEN("A bytestream with a byte array and a different endianness") + { + const int numberOfBytes = 16; + Nz::ByteArray byteArray(numberOfBytes); + Nz::ByteStream byteStream(&byteArray); + + byteStream.SetDataEndianness(Nz::GetPlatformEndianness() == Nz::Endianness_BigEndian ? Nz::Endianness_LittleEndian : Nz::Endianness_BigEndian); + + WHEN("We write an integer") + { + int value = 7; + byteStream.Write(&value, sizeof(int)); + bool boolean = true; + byteStream << boolean; + byteStream.FlushBits(); + + THEN("We can retrieve it properly") + { + Nz::ByteStream tmpStream(&byteArray); + tmpStream.SetDataEndianness(byteStream.GetDataEndianness()); + + int retrievedValue = 0; + tmpStream.Read(&retrievedValue, sizeof(int)); + CHECK(value == retrievedValue); + + Nz::ByteStream readStream(std::move(tmpStream)); + bool retrievedBoolean = false; + readStream >> retrievedBoolean; + CHECK(boolean == retrievedBoolean); + } + } + } +} \ No newline at end of file diff --git a/tests/Engine/Core/Clock.cpp b/tests/Engine/Core/Clock.cpp index 5b004f885..0bd579163 100644 --- a/tests/Engine/Core/Clock.cpp +++ b/tests/Engine/Core/Clock.cpp @@ -6,24 +6,43 @@ SCENARIO("Clock", "[CORE][CLOCK]") { GIVEN("A clock paused") { - Nz::UInt64 initialTime = 1; + Nz::UInt64 initialTime = 100; Nz::Clock clock(initialTime, true); - WHEN("We get time") + WHEN("We get time since it is paused") { THEN("Time must be the initialTime") { - REQUIRE(clock.GetMicroseconds() == initialTime); + CHECK(clock.GetMicroseconds() == initialTime); + CHECK(clock.IsPaused()); } + } - AND_WHEN("We unpause it") + WHEN("We unpause it") + { + clock.Unpause(); + REQUIRE(!clock.IsPaused()); + + THEN("Time must not be the initialTime") { - clock.Unpause(); - THEN("Time must not be the initialTime") - { - Nz::Thread::Sleep(1); - REQUIRE(clock.GetMicroseconds() != initialTime); - } + Nz::Thread::Sleep(1); + Nz::UInt64 microSeconds = clock.GetMicroseconds(); + CHECK(microSeconds != initialTime); + CHECK(microSeconds / 1000 <= clock.GetMilliseconds()); + CHECK(microSeconds / (1000.f * 1000.f) <= clock.GetSeconds()); + } + } + + WHEN("We restart it") + { + clock.Restart(); + + THEN("It is unpaused and we can pause it") + { + CHECK(!clock.IsPaused()); + clock.Pause(); + CHECK(clock.IsPaused()); + CHECK(clock.GetMicroseconds() != initialTime); } } } diff --git a/tests/Engine/Core/Color.cpp b/tests/Engine/Core/Color.cpp index 40ada67c2..ce9b50cfa 100644 --- a/tests/Engine/Core/Color.cpp +++ b/tests/Engine/Core/Color.cpp @@ -1,6 +1,63 @@ #include #include +const float epsilon = 0.01f; + +void CompareColor(const Nz::Color& lhs, const Nz::Color& rhs) +{ + Nz::UInt8 tolerance = 3; + REQUIRE(Nz::NumberEquals(lhs.r, rhs.r, tolerance)); + REQUIRE(Nz::NumberEquals(lhs.g, rhs.g, tolerance)); + REQUIRE(Nz::NumberEquals(lhs.b, rhs.b, tolerance)); + REQUIRE(Nz::NumberEquals(lhs.a, rhs.a, tolerance)); +} + +void CompareCMY(const Nz::Color& color, float cyan, float magenta, float yellow) +{ + float retrievedCyan = 0.f, retrievedMagenta = 0.f, retrievedYellow = 0.f; + Nz::Color::ToCMY(color, &retrievedCyan, &retrievedMagenta, &retrievedYellow); + CHECK(retrievedCyan == Approx(cyan).epsilon(epsilon)); + CHECK(retrievedMagenta == Approx(magenta).epsilon(epsilon)); + CHECK(retrievedYellow == Approx(yellow).epsilon(epsilon)); +} + +void CompareCMYK(const Nz::Color& color, float cyan, float magenta, float yellow, float black) +{ + float retrievedCyan = 0.f, retrievedMagenta = 0.f, retrievedYellow = 0.f, retrievedBlack = 0.f; + Nz::Color::ToCMYK(color, &retrievedCyan, &retrievedMagenta, &retrievedYellow, &retrievedBlack); + CHECK(retrievedCyan == Approx(cyan).epsilon(epsilon)); + CHECK(retrievedMagenta == Approx(magenta).epsilon(epsilon)); + CHECK(retrievedYellow == Approx(yellow).epsilon(epsilon)); + CHECK(retrievedBlack == Approx(black).epsilon(epsilon)); +} + +void CompareHSL(const Nz::Color& color, float hue, float saturation, float luminosity) +{ + float retrievedHue = 0.f, retrievedSaturation = 0.f, retrievedLuminosity = 0.f; + Nz::Color::ToHSL(color, &retrievedHue, &retrievedSaturation, &retrievedLuminosity); + CHECK(retrievedHue == Approx(hue).epsilon(epsilon)); + CHECK(retrievedSaturation == Approx(saturation).epsilon(epsilon)); + CHECK(retrievedLuminosity == Approx(luminosity).epsilon(epsilon)); +} + +void CompareHSV(const Nz::Color& color, float hue, float saturation, float value) +{ + float retrievedHue = 0.f, retrievedSaturation = 0.f, retrievedValue = 0.f; + Nz::Color::ToHSV(color, &retrievedHue, &retrievedSaturation, &retrievedValue); + CHECK(retrievedHue == Approx(hue).epsilon(epsilon)); + CHECK(retrievedSaturation == Approx(saturation).epsilon(epsilon)); + CHECK(retrievedValue == Approx(value).epsilon(epsilon)); +} + +void CompareXYZ(const Nz::Color& color, float x, float y, float z) +{ + Nz::Vector3f retrievedValues = Nz::Vector3f::Zero(); + Nz::Color::ToXYZ(color, &retrievedValues); + CHECK(retrievedValues.x == Approx(x).epsilon(epsilon)); + CHECK(retrievedValues.y == Approx(y).epsilon(epsilon)); + CHECK(retrievedValues.z == Approx(z).epsilon(epsilon)); +} + SCENARIO("Color", "[CORE][COLOR]") { GIVEN("Two colors, one red (255) and one gray (128)") @@ -19,4 +76,74 @@ SCENARIO("Color", "[CORE][COLOR]") } } } + + GIVEN("A special color in different formats") + { + struct ColorData + { + const char* name; + Nz::Color rgb; + float cyan, magenta, yellow; + float cyanK, magentaK, yellowK, black; + float hue, saturation, luminosity; + float hueV, saturationV, valueV; + float x, y, z; + }; + + std::vector colors; + + colors.push_back({ + "blue", + Nz::Color(0, 0, 255), + 1.f, 1.f, 0.f, // cmy + 1.f, 1.f, 0.f, 0.f, // cmyk + 240.f, 1.f, 0.5f, // hsl + 240.f, 1.f, 1.f, // hsv + 18.05f, 7.22f, 95.05f // xyz + }); + + colors.push_back({ + "white", + Nz::Color(255, 255, 255), + 0.f, 0.f, 0.f, // cmy + 0.f, 0.f, 0.f, 0.f, // cmyk + 0.f, 0.f, 1.f, // hsl + 0.f, 0.f, 1.f, // hsv + 95.05f, 100.f, 108.09f // xyz + }); + + colors.push_back({ + "greenish", + Nz::Color(5, 191, 25), + 0.980f, 0.251f, 0.902f, // cmy + 0.974f, 0.000f, 0.869f, 0.251f, // cmyk + 126.f, 0.95f, 0.38f, // hsl + 126.f, 0.97f, 0.75f, // hsv + 18.869f, 37.364f, 7.137f // xyz + }); + + for (const ColorData& color : colors) + { + WHEN("We perform conversion for: " + color.name) + { + THEN("From other color spaces") + { + CompareColor(color.rgb, Nz::Color::FromCMY(color.cyan, color.magenta, color.yellow)); + CompareColor(color.rgb, Nz::Color::FromCMYK(color.cyanK, color.magentaK, color.yellowK, color.black)); + CompareColor(color.rgb, Nz::Color::FromHSL(color.hue, color.saturation, color.luminosity)); + CompareColor(color.rgb, Nz::Color::FromHSV(color.hueV, color.saturationV, color.valueV)); + CompareColor(color.rgb, Nz::Color::FromXYZ(Nz::Vector3f(color.x, color.y, color.z))); + } + + THEN("To other color spaces") + { + CompareCMY(color.rgb, color.cyan, color.magenta, color.yellow); + CompareCMYK(color.rgb, color.cyanK, color.magentaK, color.yellowK, color.black); + CompareHSL(color.rgb, color.hue, color.saturation, color.luminosity); + CompareHSV(color.rgb, color.hueV, color.saturationV, color.valueV); + CompareXYZ(color.rgb, color.x, color.y, color.z); + } + } + } + } } diff --git a/tests/Engine/Core/MemoryPool.cpp b/tests/Engine/Core/MemoryPool.cpp index 6a3c230c4..2cd90a9dc 100644 --- a/tests/Engine/Core/MemoryPool.cpp +++ b/tests/Engine/Core/MemoryPool.cpp @@ -24,5 +24,21 @@ SCENARIO("MemoryPool", "[CORE][MEMORYPOOL]") memoryPool.Delete(vector2); } } + + WHEN("We construct three vectors") + { + Nz::Vector2* vector1 = memoryPool.New>(1, 2); + Nz::Vector2* vector2 = memoryPool.New>(3, 4); + Nz::Vector2* vector3 = memoryPool.New>(5, 6); + + THEN("Memory is available") + { + vector1->x = 3; + vector2->y = 5; + CHECK(*vector1 == Nz::Vector2(3, 2)); + CHECK(*vector2 == Nz::Vector2(3, 5)); + CHECK(vector3->GetSquaredLength() == Approx(61.f)); + } + } } } diff --git a/tests/Engine/Core/ParameterList.cpp b/tests/Engine/Core/ParameterList.cpp index 5d998f5b8..8ffca3097 100644 --- a/tests/Engine/Core/ParameterList.cpp +++ b/tests/Engine/Core/ParameterList.cpp @@ -3,35 +3,204 @@ #include +void nullAction(void*) +{ +} + SCENARIO("ParameterList", "[CORE][PARAMETERLIST]") { GIVEN("An empty ParameterList") { Nz::ParameterList parameterList; - WHEN("We add String 'string'") + WHEN("We add Bool 'true' and analogous") + { + bool boolean = true; + parameterList.SetParameter("bool", boolean); + + long long intTrue = 1; + parameterList.SetParameter("intTrue", intTrue); + long long intFalse = 0; + parameterList.SetParameter("intFalse", intFalse); + + Nz::String strTrue = "true"; + parameterList.SetParameter("strTrue", strTrue); + Nz::String strFalse = "false"; + parameterList.SetParameter("strFalse", strFalse); + + THEN("We can get it back") + { + bool retrievedValue = false; + CHECK(parameterList.GetBooleanParameter("bool", &retrievedValue)); + CHECK(retrievedValue == boolean); + } + + THEN("Conversion from int to bool should also work") + { + bool retrievedValue = false; + CHECK(parameterList.GetBooleanParameter("intTrue", &retrievedValue)); + CHECK(retrievedValue); + CHECK(parameterList.GetBooleanParameter("intFalse", &retrievedValue)); + CHECK(!retrievedValue); + } + + THEN("Conversion from str to bool should also work") + { + bool retrievedValue = false; + CHECK(parameterList.GetBooleanParameter("strTrue", &retrievedValue)); + CHECK(retrievedValue); + CHECK(parameterList.GetBooleanParameter("strFalse", &retrievedValue)); + CHECK(!retrievedValue); + } + } + + WHEN("We add Color 'rgb(1, 2, 3)'") + { + Nz::Color rgb(1, 2, 3); + parameterList.SetParameter("color", rgb); + + THEN("We can get it back") + { + Nz::Color retrievedColor; + CHECK(parameterList.GetColorParameter("color", &retrievedColor)); + CHECK(retrievedColor == rgb); + } + } + + WHEN("We add Double '3.0' and analogous") + { + double fl = 3.0; + parameterList.SetParameter("double", fl); + + long long intDouble = 3; + parameterList.SetParameter("intDouble", intDouble); + + Nz::String strDouble = "3.0"; + parameterList.SetParameter("strDouble", strDouble); + + THEN("We can get it back") + { + double retrievedValue; + CHECK(parameterList.GetDoubleParameter("double", &retrievedValue)); + CHECK(retrievedValue == fl); + } + + THEN("Conversion from int to double should also work") + { + double retrievedValue; + CHECK(parameterList.GetDoubleParameter("intDouble", &retrievedValue)); + CHECK(retrievedValue == fl); + } + + THEN("Conversion from string to double should also work") + { + double retrievedValue; + CHECK(parameterList.GetDoubleParameter("strDouble", &retrievedValue)); + CHECK(retrievedValue == fl); + } + } + + WHEN("We add Int '3' and analogous") + { + long long i = 3; + parameterList.SetParameter("int", i); + + bool trueInt = 1; + parameterList.SetParameter("trueInt", trueInt); + bool falseInt = 0; + parameterList.SetParameter("falseInt", falseInt); + + double doubleInt = 3; + parameterList.SetParameter("doubleInt", doubleInt); + + Nz::String strInt = "3"; + parameterList.SetParameter("strInt", strInt); + + THEN("We can get it back") + { + long long retrievedValue; + CHECK(parameterList.GetIntegerParameter("int", &retrievedValue)); + CHECK(retrievedValue == i); + } + + THEN("Conversion from bool to int should also work") + { + long long retrievedValue; + CHECK(parameterList.GetIntegerParameter("trueInt", &retrievedValue)); + CHECK(retrievedValue == trueInt); + CHECK(parameterList.GetIntegerParameter("falseInt", &retrievedValue)); + CHECK(retrievedValue == falseInt); + } + + THEN("Conversion from double to int should also work") + { + long long retrievedValue; + CHECK(parameterList.GetIntegerParameter("doubleInt", &retrievedValue)); + CHECK(retrievedValue == i); + } + + THEN("Conversion from string to int should also work") + { + long long retrievedValue; + CHECK(parameterList.GetIntegerParameter("strInt", &retrievedValue)); + CHECK(retrievedValue == i); + } + } + + WHEN("We add String 'string' and analogous") { Nz::String string("string"); parameterList.SetParameter("string", string); + bool trueString = 1; + parameterList.SetParameter("trueString", trueString); + bool falseString = 0; + parameterList.SetParameter("falseString", falseString); + + Nz::Color colorString(1, 2, 3); + parameterList.SetParameter("colorString", colorString); + + double doubleString = 3.0; + parameterList.SetParameter("doubleString", doubleString); + + long long intString = 3; + parameterList.SetParameter("intString", intString); + THEN("We can get it back") { Nz::String newString; - REQUIRE(parameterList.GetStringParameter("string", &newString)); - REQUIRE(newString == string); + CHECK(parameterList.GetStringParameter("string", &newString)); + CHECK(newString == string); } - } - WHEN("We add Float '3.f'") - { - double fl = 3.f; - parameterList.SetParameter("double", fl); - - THEN("We can get it back") + THEN("Conversion from bool to str should also work") { - double newFl; - REQUIRE(parameterList.GetDoubleParameter("double", &newFl)); - REQUIRE(newFl == fl); + Nz::String retrievedValue; + CHECK(parameterList.GetStringParameter("trueString", &retrievedValue)); + CHECK(retrievedValue == "true"); + CHECK(parameterList.GetStringParameter("falseString", &retrievedValue)); + CHECK(retrievedValue == "false"); + } + + THEN("Conversion from color to string should also work") + { + Nz::String retrievedValue; + CHECK(parameterList.GetStringParameter("colorString", &retrievedValue)); + CHECK(retrievedValue == colorString.ToString()); + } + + THEN("Conversion from string to double should also work") + { + Nz::String retrievedValue; + CHECK(parameterList.GetStringParameter("doubleString", &retrievedValue)); + CHECK(retrievedValue == "3"); + } + + THEN("Conversion from string to int should also work") + { + Nz::String retrievedValue; + CHECK(parameterList.GetStringParameter("intString", &retrievedValue)); + CHECK(retrievedValue == "3"); } } @@ -44,8 +213,71 @@ SCENARIO("ParameterList", "[CORE][PARAMETERLIST]") THEN("We can get it back") { void* newPtrToStackValue = nullptr; - REQUIRE(parameterList.GetPointerParameter("ptr", &newPtrToStackValue)); - REQUIRE(newPtrToStackValue == ptrToStackValue); + CHECK(parameterList.GetPointerParameter("ptr", &newPtrToStackValue)); + CHECK(newPtrToStackValue == ptrToStackValue); + } + } + + WHEN("We set our own data") + { + struct Data { + int i; + float f; + }; + + Data data{ 1, 3.f }; + parameterList.SetParameter("userData", &data, nullAction); + + THEN("We can get it back") + { + Data retrievedValue; + void* ptrToData = &retrievedValue; + + CHECK(parameterList.GetUserdataParameter("userData", &ptrToData)); + Data* dataPtr = reinterpret_cast(ptrToData); + CHECK(dataPtr->i == data.i); + CHECK(dataPtr->f == data.f); + } + } + } + + GIVEN("A parameter list with some values") + { + Nz::ParameterList parameterList; + + long long i = 3; + parameterList.SetParameter("i", i); + double d = 1.0; + parameterList.SetParameter("d", d); + + parameterList.SetParameter("toaster"); + parameterList.SetParameter("str", "ing"); + + WHEN("We remove two elements") + { + CHECK(parameterList.HasParameter("i")); + CHECK(parameterList.HasParameter("toaster")); + + parameterList.RemoveParameter("i"); + parameterList.RemoveParameter("toaster"); + + THEN("They do not exist anymore") + { + CHECK(!parameterList.HasParameter("i")); + CHECK(!parameterList.HasParameter("toaster")); + } + } + + WHEN("We copy this list") + { + Nz::ParameterList copy = parameterList; + + THEN("It has the same elements") + { + CHECK(parameterList.HasParameter("i")); + CHECK(parameterList.HasParameter("d")); + CHECK(parameterList.HasParameter("toaster")); + CHECK(parameterList.HasParameter("str")); } } } diff --git a/tests/Engine/Math/AlgorithmMath.cpp b/tests/Engine/Math/AlgorithmMath.cpp index e6dc2218b..de21817f4 100644 --- a/tests/Engine/Math/AlgorithmMath.cpp +++ b/tests/Engine/Math/AlgorithmMath.cpp @@ -204,6 +204,69 @@ TEST_CASE("MultiplyAdd", "[MATH][ALGORITHM]") } } +TEST_CASE("NormalizeAngle", "[MATH][ALGORITHM]") +{ + SECTION("-90 should be normalized to +270") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(-90.f)) == Nz::FromDegrees(270.f)); + } + + SECTION("-540 should be normalized to +180") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(-540.f)) == Nz::FromDegrees(180.f)); + } + + SECTION("0 should remain 0") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(0.f)) == Nz::FromDegrees(0.f)); + } + + SECTION("90 should remain 90") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(90.f)) == Nz::FromDegrees(90.f)); + } + + SECTION("360 should be normalized to 0") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(360.f)) == Nz::FromDegrees(0.f)); + } + + SECTION("450 should be normalized to 90") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(450.f)) == Nz::FromDegrees(90.f)); + } + + SECTION("-90 should be normalized to +270") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(-90)) == Nz::FromDegrees(270)); + } + + SECTION("-540 should be normalized to +180") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(-540)) == Nz::FromDegrees(180)); + } + + SECTION("0 should remain 0") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(0)) == Nz::FromDegrees(0)); + } + + SECTION("90 should remain 90") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(90)) == Nz::FromDegrees(90)); + } + + SECTION("360 should be normalized to 0") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(360)) == Nz::FromDegrees(0)); + } + + SECTION("450 should be normalized to 90") + { + REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(450)) == Nz::FromDegrees(90)); + } +} + TEST_CASE("NumberEquals", "[MATH][ALGORITHM]") { SECTION("2.35 and 2.351 should be the same at 0.01") @@ -211,11 +274,16 @@ TEST_CASE("NumberEquals", "[MATH][ALGORITHM]") CHECK(Nz::NumberEquals(2.35, 2.35, 0.01)); } - SECTION("0 and 4 unsigned should be the same at 1") + SECTION("0 and 4 unsigned should be the same at 4") { CHECK(Nz::NumberEquals(0U, 4U, 4U)); } + SECTION("1 and -1 signed should be the same at 2") + { + CHECK(Nz::NumberEquals(1, -1, 2)); + } + SECTION("Maximum integer and -1 should not be equal") { CHECK_FALSE(Nz::NumberEquals(std::numeric_limits::max(), -1)); @@ -229,6 +297,11 @@ TEST_CASE("NumberEquals", "[MATH][ALGORITHM]") TEST_CASE("NumberToString", "[MATH][ALGORITHM]") { + SECTION("0 to string") + { + REQUIRE(Nz::NumberToString(0) == "0"); + } + SECTION("235 to string") { REQUIRE(Nz::NumberToString(235) == "235"); @@ -265,8 +338,20 @@ TEST_CASE("StringToNumber", "[MATH][ALGORITHM]") REQUIRE(Nz::StringToNumber("-235") == -235); } + SECTION("235 157 in string") + { + REQUIRE(Nz::StringToNumber("235 157") == 235157); + } + SECTION("16 in base 16 in string") { REQUIRE(Nz::StringToNumber("10", 16) == 16); } + + SECTION("8 in base 4 in string should not be valid") + { + bool ok = true; + REQUIRE(Nz::StringToNumber("8", 4, &ok) == 0); + REQUIRE(!ok); + } } diff --git a/tests/Engine/Math/BoundingVolume.cpp b/tests/Engine/Math/BoundingVolume.cpp index 9fd552863..a8213b09e 100644 --- a/tests/Engine/Math/BoundingVolume.cpp +++ b/tests/Engine/Math/BoundingVolume.cpp @@ -114,5 +114,52 @@ SCENARIO("BoundingVolume", "[MATH][BOUNDINGVOLUME]") REQUIRE(Nz::BoundingVolumef::Lerp(nullBoundingVolume, centerAndUnit, 0.5f) == result); } } + + WHEN("We lerp with special cases") + { + Nz::OrientedBoxf centerAndUnitOBB(0.f, 0.f, 0.f, 1.f, 1.f, 1.f); + centerAndUnitOBB.Update(Nz::Matrix4f::Identity()); + + Nz::BoundingVolumef centerAndUnit(centerAndUnitOBB); + + Nz::BoundingVolumef nullBoundingVolume(Nz::Extend_Null); + Nz::BoundingVolumef infiniteBoundingVolume(Nz::Extend_Infinite); + + THEN("Normal to null should give a smaller volume") + { + Nz::BoundingVolumef result(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f); + result.Update(Nz::Matrix4f::Identity()); + + REQUIRE(Nz::BoundingVolumef::Lerp(centerAndUnit, nullBoundingVolume, 0.5f) == result); + } + + THEN("Normal to infinite should give an infinite volume") + { + REQUIRE(Nz::BoundingVolumef::Lerp(centerAndUnit, infiniteBoundingVolume, 0.5f) == infiniteBoundingVolume); + } + + THEN("Null to normal should give a small volume") + { + Nz::BoundingVolumef result(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f); + result.Update(Nz::Matrix4f::Identity()); + + REQUIRE(Nz::BoundingVolumef::Lerp(nullBoundingVolume, centerAndUnit, 0.5f) == result); + } + + THEN("Infinite to normal should give an infinite volume") + { + REQUIRE(Nz::BoundingVolumef::Lerp(infiniteBoundingVolume, centerAndUnit, 0.5f) == infiniteBoundingVolume); + } + + THEN("Infinite to null should give an infinite volume") + { + REQUIRE(Nz::BoundingVolumef::Lerp(infiniteBoundingVolume, nullBoundingVolume, 0.5f) == infiniteBoundingVolume); + } + + THEN("Null to null should give a null volume") + { + REQUIRE(Nz::BoundingVolumef::Lerp(nullBoundingVolume, nullBoundingVolume, 0.5f) == nullBoundingVolume); + } + } } } diff --git a/tests/Engine/Math/Box.cpp b/tests/Engine/Math/Box.cpp index 7d9b42a51..ade117515 100644 --- a/tests/Engine/Math/Box.cpp +++ b/tests/Engine/Math/Box.cpp @@ -56,6 +56,16 @@ SCENARIO("Box", "[MATH][BOX]") } } + WHEN("We ask for the intersection when there are none") + { + firstCenterAndUnit.Translate(Nz::Vector3f::UnitZ() * 5.f); + THEN("We should have a center and unit") + { + Nz::Boxf thirdCenterAndUnit; + CHECK(!firstCenterAndUnit.Intersect(secondCenterAndUnit, &thirdCenterAndUnit)); + } + } + WHEN("We use the constructor of conversion") { THEN("Shouldn't be a problem") diff --git a/tests/Engine/Math/Matrix4.cpp b/tests/Engine/Math/Matrix4.cpp index eec10aacd..d649cbf72 100644 --- a/tests/Engine/Math/Matrix4.cpp +++ b/tests/Engine/Math/Matrix4.cpp @@ -1,7 +1,9 @@ #include #include -SCENARIO("Matrix4", "[MATH][Matrix4]") +#include + +SCENARIO("Matrix4", "[MATH][MATRIX4]") { GIVEN("Two identity matrix") { @@ -20,9 +22,9 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") { THEN("Nz::Vector stay the same") { - REQUIRE(firstIdentity.Transform(Nz::Vector2f::Unit()) == Nz::Vector2f::Unit()); - REQUIRE(firstIdentity.Transform(Nz::Vector3f::Unit()) == Nz::Vector3f::Unit()); - REQUIRE(firstIdentity.Transform(Nz::Vector4f(1.f, 1.f, 1.f, 1.f)) == Nz::Vector4f(1.f, 1.f, 1.f, 1.f)); + CHECK(firstIdentity * Nz::Vector2f::Unit() == Nz::Vector2f::Unit()); + CHECK(firstIdentity * Nz::Vector3f::Unit() == Nz::Vector3f::Unit()); + CHECK(firstIdentity * Nz::Vector4f(1.f, 1.f, 1.f, 1.f) == Nz::Vector4f(1.f, 1.f, 1.f, 1.f)); } } @@ -30,11 +32,11 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") { THEN("It keeps being a identity") { - REQUIRE(firstIdentity.Concatenate(secondIdentity) == firstIdentity); - REQUIRE(firstIdentity.ConcatenateAffine(secondIdentity) == firstIdentity); - REQUIRE((firstIdentity * secondIdentity) == firstIdentity); - REQUIRE((1.f * firstIdentity) == firstIdentity); - REQUIRE(firstIdentity.Inverse() == secondIdentity.InverseAffine()); + CHECK(firstIdentity.Concatenate(secondIdentity) == firstIdentity); + CHECK(firstIdentity.ConcatenateAffine(secondIdentity) == firstIdentity); + CHECK((firstIdentity * secondIdentity) == firstIdentity); + CHECK((1.f * firstIdentity) == firstIdentity); + CHECK(firstIdentity.Inverse() == secondIdentity.InverseAffine()); } } @@ -65,8 +67,8 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") { THEN("These results are expected") { - REQUIRE(matrix1.GetDeterminant() == Approx(24.f)); - REQUIRE(matrix2.GetDeterminant() == Approx(-1.f)); + CHECK(matrix1.GetDeterminant() == Approx(24.f)); + CHECK(matrix2.GetDeterminant() == Approx(-1.f)); } } @@ -81,12 +83,12 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") THEN("We get the identity") { Nz::Matrix4f tmp = matrix1 * invMatrix1; - REQUIRE(tmp.m32 == Approx(0.f)); - REQUIRE(tmp.m42 == Approx(0.f)); + CHECK(tmp.m32 == Approx(0.f)); + CHECK(tmp.m42 == Approx(0.f)); tmp.m32 = 0.f; tmp.m42 = 0.f; - REQUIRE(tmp == Nz::Matrix4f::Identity()); - REQUIRE((matrix2 * invMatrix2) == Nz::Matrix4f::Identity()); + CHECK(tmp == Nz::Matrix4f::Identity()); + CHECK((matrix2 * invMatrix2) == Nz::Matrix4f::Identity()); } } } @@ -106,10 +108,10 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") 0.f, -std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, 0.f, 0.f, 0.f, 1.f); - REQUIRE(transformedMatrix == rotation45X); + CHECK(transformedMatrix == rotation45X); transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(Nz::FromDegrees(45.f), 0.f, 0.f).ToQuaternion()); rotation45X.ApplyTranslation(Nz::Vector3f::Unit()); - REQUIRE(transformedMatrix == rotation45X); + CHECK(transformedMatrix == rotation45X); } THEN("Rotation around Y") @@ -120,10 +122,10 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") std::sqrt(2.f) / 2.f, 0.f, std::sqrt(2.f) / 2.f, 0.f, 0.f, 0.f, 0.f, 1.f); - REQUIRE(transformedMatrix == rotation45Y); + CHECK(transformedMatrix == rotation45Y); transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(0.f, Nz::FromDegrees(45.f), 0.f).ToQuaternion()); rotation45Y.ApplyTranslation(Nz::Vector3f::Unit()); - REQUIRE(transformedMatrix == rotation45Y); + CHECK(transformedMatrix == rotation45Y); } THEN("Rotation around Z") @@ -134,10 +136,172 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f); - REQUIRE(transformedMatrix == rotation45Z); + CHECK(transformedMatrix == rotation45Z); transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(Nz::EulerAnglesf(0.f, 0.f, Nz::FromDegrees(45.f)).ToQuaternion())); rotation45Z.ApplyTranslation(Nz::Vector3f::Unit()); - REQUIRE(transformedMatrix == rotation45Z); + CHECK(transformedMatrix == rotation45Z); + } + } + } + + GIVEN("An identity matrix") + { + std::array content{{ 1.f, 0.f, 0.f, 0.f, + 0.f, 1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f + }}; + + Nz::Matrix4f identity(content.data()); + REQUIRE(identity.IsIdentity()); + + WHEN("We rotate it from pitch 30") + { + Nz::Quaternionf rotation(Nz::EulerAnglesf(Nz::FromDegrees(30.f), 0.f, 0.f)); + identity.ApplyRotation(rotation); + + THEN("We should retrieve it") + { + REQUIRE(identity.GetRotation() == rotation); + } + } + + WHEN("We rotate it from yaw 30") + { + Nz::Quaternionf rotation(Nz::EulerAnglesf(0.f, Nz::FromDegrees(30.f), 0.f)); + identity.ApplyRotation(rotation); + + THEN("We should retrieve it") + { + REQUIRE(identity.GetRotation() == rotation); + } + } + + WHEN("We rotate it from roll 30") + { + Nz::Quaternionf rotation(Nz::EulerAnglesf(0.f, 0.f, Nz::FromDegrees(30.f))); + identity.ApplyRotation(rotation); + + THEN("We should retrieve it") + { + REQUIRE(identity.GetRotation() == rotation); + } + } + + WHEN("We rotate it from a strange rotation") + { + Nz::Quaternionf rotation(Nz::EulerAnglesf(Nz::FromDegrees(10.f), Nz::FromDegrees(20.f), Nz::FromDegrees(30.f))); + identity.ApplyRotation(rotation); + + THEN("We should retrieve it") + { + REQUIRE(identity.GetRotation() == rotation); + } + } + + WHEN("We scale it") + { + Nz::Vector3f scale(1.f, 2.f, 3.f); + Nz::Vector3f squaredScale(scale.x * scale.x, scale.y * scale.y, scale.z * scale.z); + identity.ApplyScale(scale); + + THEN("We should retrieve it") + { + CHECK(identity.GetScale() == scale); + CHECK(identity.GetSquaredScale() == squaredScale); + } + + AND_THEN("With a rotation") + { + identity.ApplyRotation(Nz::EulerAnglesf(Nz::FromDegrees(10.f), Nz::FromDegrees(20.f), Nz::FromDegrees(30.f))); + Nz::Vector3f retrievedScale = identity.GetScale(); + CHECK(retrievedScale.x == Approx(scale.x)); + CHECK(retrievedScale.y == Approx(scale.y)); + CHECK(retrievedScale.z == Approx(scale.z)); + } + } + } + + GIVEN("A matrix with a negative determinant") + { + Nz::Matrix4f negativeDeterminant( -1.f, 0.f, 0.f, 0.f, + 0.f, 1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f); + + WHEN("We ask information about determinant") + { + THEN("We expect those to be true") + { + CHECK(negativeDeterminant.GetDeterminant() == Approx(-1.f)); + CHECK(!negativeDeterminant.HasScale()); + CHECK(negativeDeterminant.HasNegativeScale()); + } + } + } + + GIVEN("Some transformed matrices") + { + Nz::Vector3f simpleTranslation = Nz::Vector3f::Zero(); + Nz::Quaternionf simpleRotation = Nz::Quaternionf::Identity(); + Nz::Vector3f simpleScale = Nz::Vector3f::Unit(); + Nz::Matrix4f simple = Nz::Matrix4f::Transform(simpleTranslation, simpleRotation, simpleScale); + + Nz::Vector3f complexTranslation = Nz::Vector3f(-5.f, 7.f, 3.5f); + Nz::Quaternionf complexRotation = Nz::EulerAnglesf(Nz::FromDegrees(-22.5f), Nz::FromDegrees(30.f), Nz::FromDegrees(15.f)); + Nz::Vector3f complexScale = Nz::Vector3f(1.f, 2.f, 0.5f); + Nz::Matrix4f complex = Nz::Matrix4f::Transform(complexTranslation, complexRotation, complexScale); + + Nz::Vector3f oppositeTranslation = Nz::Vector3f(-5.f, 7.f, 3.5f); + Nz::Quaternionf oppositeRotation = Nz::EulerAnglesf(Nz::FromDegrees(-90.f), Nz::FromDegrees(0.f), Nz::FromDegrees(0.f)); + Nz::Vector3f oppositeScale = Nz::Vector3f(1.f, 2.f, 0.5f); + Nz::Matrix4f opposite = Nz::Matrix4f::Transform(oppositeTranslation, oppositeRotation, oppositeScale); + + WHEN("We retrieve the different components") + { + THEN("It should be the original ones") + { + CHECK(simple.GetTranslation() == simpleTranslation); + CHECK(simple.GetRotation() == simpleRotation); + CHECK(simple.GetScale() == simpleScale); + + /*CHECK(complex.GetTranslation() == complexTranslation); + CHECK(complex.GetRotation() == complexRotation); + CHECK(complex.GetScale() == complexScale); + + CHECK(opposite.GetTranslation() == oppositeTranslation); + CHECK(opposite.GetRotation() == oppositeRotation); + CHECK(opposite.GetScale() == oppositeScale);*/ + } + } + } + + GIVEN("Some defined matrix and its opposite") + { + Nz::Vector3f translation(-5.f, 3.f, 0.5); + Nz::Matrix4f initial = Nz::Matrix4f::Translate(translation); + Nz::Quaternionf rotation = Nz::EulerAnglesf(Nz::FromDegrees(30.f), Nz::FromDegrees(-90.f), 0.f); + initial.ApplyRotation(rotation); + + Nz::Matrix4f simple = Nz::Matrix4f::Transform(-translation, rotation.GetInverse(), Nz::Vector3f::Unit()); + + WHEN("We multiply them together") + { + Nz::Matrix4f result = Nz::Matrix4f::Concatenate(simple, initial); + + THEN("We should get the identity") + { + Nz::Matrix4f identity = Nz::Matrix4f::Identity(); + for (int i = 0; i != 4; ++i) + { + Nz::Vector4f row = result.GetRow(i); + Nz::Vector4f column = result.GetColumn(i); + for (int j = 0; j != 4; ++j) + { + CHECK(Nz::NumberEquals(row[j], identity(i, j), 0.00001f)); + CHECK(Nz::NumberEquals(column[j], identity(i, j), 0.00001f)); + } + } } } } diff --git a/tests/Engine/Math/Quaternion.cpp b/tests/Engine/Math/Quaternion.cpp index 46a0c5f89..3cae63386 100644 --- a/tests/Engine/Math/Quaternion.cpp +++ b/tests/Engine/Math/Quaternion.cpp @@ -173,13 +173,34 @@ SCENARIO("Quaternion", "[MATH][QUATERNION]") WHEN("We get the rotation between two vectors") { - Nz::Quaternionf rotationBetweenXY = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitX(), Nz::Vector3f::UnitY()); - THEN("The rotation in right-handed is 90 degree on z") { + Nz::Quaternionf rotationBetweenXY = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitX(), Nz::Vector3f::UnitY()); Nz::Quaternionf rotation90Z(Nz::FromDegrees(90.f), Nz::Vector3f::UnitZ()); REQUIRE(rotation90Z == rotationBetweenXY); } + + THEN("The rotation in right-handed is 90 degree on y") + { + Nz::Quaternionf rotationBetweenXZ = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitX(), Nz::Vector3f::UnitZ()); + Nz::Quaternionf rotation90Y(Nz::FromDegrees(-90.f), Nz::Vector3f::UnitY()); + REQUIRE(rotation90Y == rotationBetweenXZ); + } + + THEN("The rotation in right-handed is 90 degree on x") + { + Nz::Quaternionf rotationBetweenYZ = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitY(), Nz::Vector3f::UnitZ()); + Nz::Quaternionf rotation90X(Nz::FromDegrees(90.f), Nz::Vector3f::UnitX()); + REQUIRE(rotation90X == rotationBetweenYZ); + } + + THEN("The rotation in right-handed is 90 degree on y with non-unit vectors") + { + Nz::Vector3f origin(1.f, 0.f, 1.f); + Nz::Vector3f extremity(-1.f, 0.f, 1.f); + Nz::Quaternionf rotation = Nz::Quaternionf::RotationBetween(origin, extremity); + REQUIRE(rotation * origin == extremity); + } } } diff --git a/tests/Engine/Math/Rect.cpp b/tests/Engine/Math/Rect.cpp index b119d76c9..7fe9d30fb 100644 --- a/tests/Engine/Math/Rect.cpp +++ b/tests/Engine/Math/Rect.cpp @@ -12,9 +12,9 @@ SCENARIO("Rect", "[MATH][RECT]") { THEN("They should be") { - REQUIRE(firstCenterAndUnit == secondCenterAndUnit); - REQUIRE(firstCenterAndUnit.GetCenter() == secondCenterAndUnit.GetCenter()); - REQUIRE(firstCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom) == secondCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom)); + CHECK(firstCenterAndUnit == secondCenterAndUnit); + CHECK(firstCenterAndUnit.GetCenter() == secondCenterAndUnit.GetCenter()); + CHECK(firstCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom) == secondCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom)); CHECK(firstCenterAndUnit.IsValid()); } } @@ -43,16 +43,24 @@ SCENARIO("Rect", "[MATH][RECT]") { THEN("These results are expected") { - REQUIRE(firstCenterAndUnit.GetLengths() == Nz::Vector2f::Unit()); - REQUIRE(firstCenterAndUnit.GetMaximum() == Nz::Vector2f::Unit()); - REQUIRE(firstCenterAndUnit.GetMinimum() == Nz::Vector2f::Zero()); - REQUIRE(firstCenterAndUnit.GetNegativeVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Zero()); - REQUIRE(firstCenterAndUnit.GetPosition() == Nz::Vector2f::Zero()); - REQUIRE(firstCenterAndUnit.GetPositiveVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Unit()); + CHECK(firstCenterAndUnit.GetLengths() == Nz::Vector2f::Unit()); + CHECK(firstCenterAndUnit.GetMaximum() == Nz::Vector2f::Unit()); + CHECK(firstCenterAndUnit.GetMinimum() == Nz::Vector2f::Zero()); + CHECK(firstCenterAndUnit.GetNegativeVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Zero()); + CHECK(firstCenterAndUnit.GetPosition() == Nz::Vector2f::Zero()); + CHECK(firstCenterAndUnit.GetPositiveVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Unit()); } } + WHEN("We ask for intersection") + { + Nz::Rectf intersection; + CHECK(firstCenterAndUnit.Intersect(secondCenterAndUnit, &intersection)); + CHECK(intersection == Nz::Rectf(1.f, 1.f)); + CHECK(intersection == Nz::Rectf(Nz::Vector2f(1.f, 1.f))); + } + WHEN("We try to lerp") { THEN("Compilation should be fine") diff --git a/tests/Engine/Math/Vector3.cpp b/tests/Engine/Math/Vector3.cpp index 84c6a01ae..2bcfbd361 100644 --- a/tests/Engine/Math/Vector3.cpp +++ b/tests/Engine/Math/Vector3.cpp @@ -1,6 +1,7 @@ #include #include +#include #include SCENARIO("Vector3", "[MATH][VECTOR3]") @@ -97,4 +98,24 @@ SCENARIO("Vector3", "[MATH][VECTOR3]") } } } + + GIVEN("Two vectors") + { + Nz::Vector2f unit = Nz::Vector2f::Unit(); + Nz::Vector3f smaller(-1.f, unit); + + float data[3] = { 1.f, unit.x, unit.y }; + Nz::Vector3f bigger(data); + + WHEN("We combine divisions and multiplications") + { + Nz::Vector3f result = smaller / bigger; + result *= bigger; + + THEN("We should get the identity") + { + REQUIRE(result == smaller); + } + } + } } diff --git a/tests/Engine/Physics2D/PhysWorld2D.cpp b/tests/Engine/Physics2D/PhysWorld2D.cpp index 539932f71..3c19ba653 100644 --- a/tests/Engine/Physics2D/PhysWorld2D.cpp +++ b/tests/Engine/Physics2D/PhysWorld2D.cpp @@ -99,6 +99,94 @@ SCENARIO("PhysWorld2D", "[PHYSICS2D][PHYSWORLD2D]") } } } + + GIVEN("Three entities, a character, a wall and a trigger zone") + { + unsigned int CHARACTER_COLLISION_ID = 1; + unsigned int WALL_COLLISION_ID = 2; + unsigned int TRIGGER_COLLISION_ID = 3; + + Nz::PhysWorld2D world; + + Nz::Rectf characterAABB(0.f, 0.f, 1.f, 1.f); + Nz::Collider2DRef characterBox = Nz::BoxCollider2D::New(characterAABB); + characterBox->SetCollisionId(CHARACTER_COLLISION_ID); + Nz::RigidBody2D character(&world, 1.f, characterBox); + character.SetPosition(Nz::Vector2f::Zero()); + + Nz::Rectf wallAABB(0.f, 0.f, 1.f, 2.f); + Nz::Collider2DRef wallBox = Nz::BoxCollider2D::New(wallAABB); + wallBox->SetCollisionId(WALL_COLLISION_ID); + Nz::RigidBody2D wall(&world, 0.f, wallBox); + wall.SetPosition(Nz::Vector2f(5.f, 0.f)); + + Nz::Rectf triggerAABB(0.f, 0.f, 1.f, 1.f); + Nz::Collider2DRef triggerBox = Nz::BoxCollider2D::New(triggerAABB); + triggerBox->SetTrigger(true); + triggerBox->SetCollisionId(TRIGGER_COLLISION_ID); + Nz::RigidBody2D trigger(&world, 0.f, triggerBox); + trigger.SetPosition(Nz::Vector2f(2.f, 0.f)); + + world.Step(0.f); + + int statusTriggerCollision = 0; + Nz::PhysWorld2D::Callback characterTriggerCallback; + characterTriggerCallback.startCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) -> bool { + statusTriggerCollision = statusTriggerCollision | 1 << 0; + return true; + }; + characterTriggerCallback.preSolveCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) -> bool { + statusTriggerCollision = statusTriggerCollision | 1 << 1; + return true; + }; + characterTriggerCallback.postSolveCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) { + statusTriggerCollision = statusTriggerCollision | 1 << 2; + }; + characterTriggerCallback.endCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) { + statusTriggerCollision = statusTriggerCollision | 1 << 3; + }; + world.RegisterCallbacks(CHARACTER_COLLISION_ID, TRIGGER_COLLISION_ID, characterTriggerCallback); + + int statusWallCollision = 0; + Nz::PhysWorld2D::Callback characterWallCallback; + characterWallCallback.startCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) -> bool { + statusWallCollision = statusWallCollision | 1 << 0; + return true; + }; + characterWallCallback.endCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) { + statusWallCollision = statusWallCollision | 1 << 1; + }; + world.RegisterCallbacks(CHARACTER_COLLISION_ID, WALL_COLLISION_ID, characterWallCallback); + + WHEN("We make our character go towards the wall") + { + character.SetVelocity(Nz::Vector2f(1.f, 0.f)); + for (int i = 0; i != 11; ++i) + world.Step(0.1f); + + THEN("It should trigger several collisions") + { + CHECK(statusTriggerCollision == 3); + for (int i = 0; i != 20; ++i) + world.Step(0.1f); + CHECK(statusTriggerCollision == 11); + + CHECK(character.GetPosition().x == Approx(3.1f).epsilon(0.01f)); + + for (int i = 0; i != 9; ++i) + world.Step(0.1f); + CHECK(character.GetPosition().x == Approx(4.f).epsilon(0.01f)); + world.Step(0.1f); + CHECK(character.GetPosition().x == Approx(4.f).epsilon(0.01f)); + CHECK(statusWallCollision == 1); // It should be close to the wall + + character.SetVelocity(Nz::Vector2f(-2.f, 0.f)); + for (int i = 0; i != 10; ++i) + world.Step(0.1f); + CHECK(statusWallCollision == 3); + } + } + } } Nz::RigidBody2D CreateBody(Nz::PhysWorld2D& world, const Nz::Vector2f& position, bool isMoving, const Nz::Vector2f& lengths) diff --git a/tests/SDK/NDK/Systems/RenderSystem.cpp b/tests/SDK/NDK/Systems/RenderSystem.cpp index 0ceefaa07..ec22d6e57 100644 --- a/tests/SDK/NDK/Systems/RenderSystem.cpp +++ b/tests/SDK/NDK/Systems/RenderSystem.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,7 @@ SCENARIO("RenderSystem", "[NDK][RenderSystem]") entity->AddComponent(boxCollider2D); Ndk::PhysicsComponent2D& physicsComponent2D = entity->AddComponent(); + world.GetSystem().SetFixedUpdateRate(30.f); world.Update(1.f); WHEN("We move it")