This commit is contained in:
Jérôme Leclercq 2017-11-21 12:26:45 +01:00
commit f84ac9c52b
55 changed files with 1323 additions and 275 deletions

View File

@ -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()
- ⚠️ Reworked Flags class, replaced EnumAsFlags<E>::value by IsEnumFlag<E>::value, EnumAsFlags<E> no longer need to contains a `value` field. The `max` field can also be of the same type as the enum.
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
- Initial release

View File

@ -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))
{

View File

@ -22,9 +22,11 @@ namespace Ndk
PhysicsComponent2D() = default;
PhysicsComponent2D(const PhysicsComponent2D& physics);
~PhysicsComponent2D() = default;
void AddForce(const Nz::Vector2f& force, Nz::CoordSys coordSys = Nz::CoordSys_Global);
void AddForce(const Nz::Vector2f& force, const Nz::Vector2f& point, Nz::CoordSys coordSys = Nz::CoordSys_Global);
void AddImpulse(const Nz::Vector2f& impulse, Nz::CoordSys coordSys = Nz::CoordSys_Global);
void AddImpulse(const Nz::Vector2f& impulse, const Nz::Vector2f& point, Nz::CoordSys coordSys = Nz::CoordSys_Global);
void AddTorque(float torque);
Nz::Rectf GetAABB() const;

View File

@ -50,7 +50,38 @@ namespace Ndk
m_object->AddForce(force, point, coordSys);
}
/*!
* \brief Applies a impulse to the entity
*
* \param impulse Impulse to apply on the entity
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent2D::AddImpulse(const Nz::Vector2f& impulse, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->AddImpulse(impulse, coordSys);
}
/*!
* \brief Applies a impulse to the entity
*
* \param impulse Impulse to apply on the entity
* \param point Point where the impulse is applied
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent2D::AddImpulse(const Nz::Vector2f& impulse, const Nz::Vector2f& point, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->AddImpulse(impulse, point, coordSys);
}
/*!
* \brief Applies a torque to the entity
*

View File

@ -355,9 +355,9 @@ namespace Ndk
{
std::size_t skinIndex(lua.Check<std::size_t>(&argIndex));
Nz::String subMesh(lua.Check<Nz::String>(&argIndex));
Nz::MaterialRef material(lua.Check<Nz::MaterialRef>(&argIndex));
Nz::MaterialRef materialRef(lua.Check<Nz::MaterialRef>(&argIndex));
instance->SetMaterial(skinIndex, subMesh, std::move(material));
instance->SetMaterial(skinIndex, subMesh, std::move(materialRef));
return 0;
}

View File

@ -1,4 +1,4 @@
// Copyright (C) 2017 Jérôme Leclercq, Arnaud Cadot
// Copyright (C) 2017 Jérôme Leclercq, Arnaud Cadot
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp

View File

@ -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<typename T, std::size_t N>

View File

@ -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;
}

View File

@ -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

View File

@ -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<typename T>
ByteStream& operator>>(T& value);

View File

@ -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);
}
/*!

View File

@ -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);

View File

@ -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<UInt8>(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<UInt8>(255.f * Hue2RGB(v1, v2, h + (1.f/3.f))),
static_cast<UInt8>(255.f * Hue2RGB(v1, v2, h)),
static_cast<UInt8>(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<UInt8>(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<unsigned int>(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<int>(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<UInt8>(r*255.f), static_cast<UInt8>(g*255.f), static_cast<UInt8>(b*255.f));
return Color(static_cast<UInt8>(r * 255.f), static_cast<UInt8>(g * 255.f), static_cast<UInt8>(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<UInt8>(deltaMax/(max+min)*240.f);
if (l <= 0.5f)
*saturation = deltaMax / (max + min);
else
*saturation = static_cast<UInt8>(deltaMax/(2.f-max-min)*240.f);
*saturation = (deltaMax / (2.f - max - min));
*lightness = static_cast<UInt8>(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<UInt8>(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;
}
}

View File

@ -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).
*/

View File

@ -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<typename T>
struct hash<Nz::ObjectRef<T>>
{
/*!
* \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<T>& object) const
{
hash<T*> h;

View File

@ -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)

View File

@ -121,7 +121,7 @@ namespace std
const char* ptr = str.GetConstBuffer();
do
h = ((h << 5) + h) + *ptr;
h = ((h << 5) + h) + static_cast<size_t>(*ptr);
while (*++ptr);
}

View File

@ -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
*/

View File

@ -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;
}
/*!

View File

@ -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

View File

@ -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<typename T>

View File

@ -664,9 +664,9 @@ namespace Nz
template<typename T>
Vector3<T> Matrix4<T>::GetSquaredScale() const
{
return Vector3<T>(m11*m11 + m21*m21 + m31*m31,
m12*m12 + m22*m22 + m32*m32,
m13*m13 + m23*m23 + m33*m33);
return Vector3<T>(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<typename T>
Matrix4<T>& Matrix4<T>::SetRotation(const Quaternion<T>& 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;
}

View File

@ -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
*/

View File

@ -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<typename T>
Quaternion<T>& Quaternion<T>::MakeRotationBetween(const Vector3<T>& from, const Vector3<T>& 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<T> cross = Vector3<T>::CrossProduct(Vector3<T>::UnitX(), from);
if (NumberEquals(cross.GetLength(), F(0.0)))
cross = Vector3<T>::CrossProduct(Vector3<T>::UnitY(), from);
return Set(F(180.0), cross);
}
else if (NumberEquals(dot, F(1.0)))
return MakeIdentity();
else
{
Vector3<T> 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<T> 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<typename T>
@ -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<typename T>
@ -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<typename T>

View File

@ -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<typename T>
@ -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<typename T>

View File

@ -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<typename T>
@ -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

View File

@ -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<typename T>
Vector3<T>& Vector3<T>::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

View File

@ -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<typename T>
@ -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

View File

@ -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

View File

@ -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

View File

@ -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
*/

View File

@ -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
*/

View File

@ -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

View File

@ -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";

View File

@ -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)

View File

@ -26,14 +26,14 @@ namespace Nz
auto drawOptions = static_cast<PhysWorld2D::DebugDrawOptions*>(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<PhysWorld2D::DebugDrawOptions*>(userdata);
if (drawOptions->dotCallback)
drawOptions->dotCallback(Vector2f(float(pos.x), float(pos.y)), float(size), CpDebugColorToColor(color), drawOptions->userdata);
};
}
using DebugDrawPolygonCallback = std::function<void(const Vector2f* vertices, std::size_t vertexCount, float radius, Color outlineColor, Color fillColor, void* userdata)>;
@ -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<PhysWorld2D::DebugDrawOptions*>(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<PhysWorld2D::DebugDrawOptions*>(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() :

View File

@ -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),

View File

@ -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;

View File

@ -113,6 +113,7 @@ namespace Nz
bool m_threadActive;
Vector2i m_mousePos;
bool m_keyRepeat;
uint16_t m_lastSequence;
struct
{

View File

@ -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");
}
}

View File

@ -8,6 +8,7 @@
template<typename Block> void Check(const char* title);
template<typename Block> void CheckAppend(const char* title);
template<typename Block> void CheckBitOps(const char* title);
template<typename Block> void CheckBitOpsMultipleBlocks(const char* title);
template<typename Block> void CheckConstructor(const char* title);
template<typename Block> void CheckCopyMoveSwap(const char* title);
template<typename Block> void CheckRead(const char* title);
@ -28,6 +29,7 @@ void Check(const char* title)
CheckCopyMoveSwap<Block>(title);
CheckBitOps<Block>(title);
CheckBitOpsMultipleBlocks<Block>(title);
CheckAppend<Block>(title);
CheckRead<Block>(title);
@ -111,7 +113,68 @@ void CheckBitOps(const char* title)
{
CHECK(andBitset == Nz::Bitset<Block>("00001"));
CHECK(orBitset == Nz::Bitset<Block>("11111"));
CHECK(orBitset.TestAll());
CHECK(xorBitset == Nz::Bitset<Block>("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<Block>("10010"));
CHECK(second == Nz::Bitset<Block>("101"));
}
}
}
}
}
template<typename Block>
void CheckBitOpsMultipleBlocks(const char* title)
{
SECTION(title)
{
GIVEN("Two bitsets")
{
Nz::Bitset<Block> first("01001011010010101001010011010101001");
Nz::Bitset<Block> second("10111111101101110110111101101110110");
WHEN("We perform operators")
{
Nz::Bitset<Block> andBitset = first & second;
Nz::Bitset<Block> orBitset = first | second;
Nz::Bitset<Block> xorBitset = first ^ second;
THEN("They should operate as logical operators")
{
CHECK(andBitset == Nz::Bitset<Block>("00001011000000100000010001000100000"));
CHECK(orBitset == Nz::Bitset<Block>("11111111111111111111111111111111111"));
CHECK(orBitset.TestAll());
CHECK(xorBitset == Nz::Bitset<Block>("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<Block>("10010100110101010010000000000000000"));
first.ShiftLeft(1);
CHECK(first == Nz::Bitset<Block>("00101001101010100100000000000000000"));
CHECK(second == Nz::Bitset<Block>("1011111110110111011"));
second.ShiftRight(1);
CHECK(second == Nz::Bitset<Block>("101111111011011101"));
}
}
}

View File

@ -0,0 +1,73 @@
#include <Nazara/Core/ByteStream.hpp>
#include <Catch/catch.hpp>
#include <array>
SCENARIO("ByteStream", "[CORE][BYTESTREAM]")
{
GIVEN("A bytestream from a bunch of bytes")
{
const int numberOfBytes = 16;
std::array<Nz::Int8, numberOfBytes> 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);
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -1,6 +1,63 @@
#include <Nazara/Core/Color.hpp>
#include <Catch/catch.hpp>
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<ColorData> 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);
}
}
}
}
}

View File

@ -24,5 +24,21 @@ SCENARIO("MemoryPool", "[CORE][MEMORYPOOL]")
memoryPool.Delete(vector2);
}
}
WHEN("We construct three vectors")
{
Nz::Vector2<int>* vector1 = memoryPool.New<Nz::Vector2<int>>(1, 2);
Nz::Vector2<int>* vector2 = memoryPool.New<Nz::Vector2<int>>(3, 4);
Nz::Vector2<int>* vector3 = memoryPool.New<Nz::Vector2<int>>(5, 6);
THEN("Memory is available")
{
vector1->x = 3;
vector2->y = 5;
CHECK(*vector1 == Nz::Vector2<int>(3, 2));
CHECK(*vector2 == Nz::Vector2<int>(3, 5));
CHECK(vector3->GetSquaredLength() == Approx(61.f));
}
}
}
}

View File

@ -3,35 +3,204 @@
#include <Nazara/Core/String.hpp>
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<Data*>(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"));
}
}
}

View File

@ -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<int>::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);
}
}

View File

@ -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);
}
}
}
}

View File

@ -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")

View File

@ -1,7 +1,9 @@
#include <Nazara/Math/Matrix4.hpp>
#include <Catch/catch.hpp>
SCENARIO("Matrix4", "[MATH][Matrix4]")
#include <array>
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<float, 16> 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));
}
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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")

View File

@ -1,6 +1,7 @@
#include <Nazara/Math/Vector3.hpp>
#include <Catch/catch.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Math/Vector4.hpp>
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);
}
}
}
}

View File

@ -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)

View File

@ -1,6 +1,7 @@
#include <NDK/Systems/RenderSystem.hpp>
#include <NDK/World.hpp>
#include <NDK/Components.hpp>
#include <NDK/Systems/PhysicsSystem2D.hpp>
#include <Nazara/Graphics/ForwardRenderTechnique.hpp>
#include <Nazara/Graphics/Sprite.hpp>
#include <Catch/catch.hpp>
@ -62,6 +63,7 @@ SCENARIO("RenderSystem", "[NDK][RenderSystem]")
entity->AddComponent<Ndk::CollisionComponent2D>(boxCollider2D);
Ndk::PhysicsComponent2D& physicsComponent2D = entity->AddComponent<Ndk::PhysicsComponent2D>();
world.GetSystem<Ndk::PhysicsSystem2D>().SetFixedUpdateRate(30.f);
world.Update(1.f);
WHEN("We move it")