Merge branch 'master' into SDL2

This commit is contained in:
Jérôme Leclercq
2020-05-27 11:11:21 +02:00
committed by GitHub
211 changed files with 7628 additions and 2883 deletions

View File

@@ -43,6 +43,7 @@
#include <Nazara/Core/Core.hpp>
#include <Nazara/Core/Directory.hpp>
#include <Nazara/Core/DynLib.hpp>
#include <Nazara/Core/EmptyStream.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Core/Error.hpp>

View File

@@ -0,0 +1,43 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_BYTEARRAYPOOL_HPP
#define NAZARA_BYTEARRAYPOOL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/String.hpp>
#include <vector>
namespace Nz
{
class AbstractHash;
class NAZARA_CORE_API ByteArrayPool
{
public:
ByteArrayPool() = default;
ByteArrayPool(const ByteArrayPool&) = delete;
ByteArrayPool(ByteArrayPool&&) = default;
~ByteArrayPool() = default;
inline void Clear();
inline ByteArray GetByteArray(std::size_t capacity = 0);
inline void ReturnByteArray(ByteArray byteArray);
ByteArrayPool& operator=(const ByteArrayPool&) = delete;
ByteArrayPool& operator=(ByteArrayPool&&) = default;
private:
std::vector<ByteArray> m_byteArrays;
};
}
#include <Nazara/Core/ByteArrayPool.inl>
#endif // NAZARA_BYTEARRAYPOOL_HPP

View File

@@ -0,0 +1,44 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/ByteArrayPool.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
namespace Detail
{
bool SortByteArrayByCapacity(const ByteArray& byteArray, std::size_t refCapacity)
{
return refCapacity > byteArray.GetCapacity();
}
}
inline void ByteArrayPool::Clear()
{
m_byteArrays.clear();
}
inline ByteArray ByteArrayPool::GetByteArray(std::size_t capacity)
{
ByteArray ret;
auto it = std::lower_bound(m_byteArrays.begin(), m_byteArrays.end(), capacity, Detail::SortByteArrayByCapacity);
if (it != m_byteArrays.end())
{
ret = std::move(*it);
m_byteArrays.erase(it);
}
return ret;
}
inline void ByteArrayPool::ReturnByteArray(ByteArray byteArray)
{
auto it = std::lower_bound(m_byteArrays.begin(), m_byteArrays.end(), byteArray.GetCapacity(), Detail::SortByteArrayByCapacity);
m_byteArrays.emplace(it, std::move(byteArray));
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -0,0 +1,46 @@
// Copyright (C) 2019 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_EMPTYSTREAM_HPP
#define NAZARA_EMPTYSTREAM_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Stream.hpp>
namespace Nz
{
class NAZARA_CORE_API EmptyStream : public Stream
{
public:
inline EmptyStream();
EmptyStream(const EmptyStream&) = default;
EmptyStream(EmptyStream&&) noexcept = default;
~EmptyStream() = default;
void Clear();
bool EndOfStream() const override;
UInt64 GetCursorPos() const override;
UInt64 GetSize() const override;
bool SetCursorPos(UInt64 offset) override;
EmptyStream& operator=(const EmptyStream&) = default;
EmptyStream& operator=(EmptyStream&&) noexcept = default;
private:
void FlushStream() override;
std::size_t ReadBlock(void* buffer, std::size_t size) override;
std::size_t WriteBlock(const void* buffer, std::size_t size) override;
UInt64 m_size;
};
}
#include <Nazara/Core/EmptyStream.inl>
#endif // NAZARA_EMPTYSTREAM_HPP

View File

@@ -0,0 +1,22 @@
// Copyright (C) 2019 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/EmptyStream.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::EmptyStream
* \brief Constructs an EmptyStream object by default
*/
inline EmptyStream::EmptyStream() :
m_size(0)
{
m_openMode = Nz::OpenMode_ReadWrite;
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -39,15 +39,20 @@ namespace Nz
static constexpr std::size_t MaxValue = static_cast<std::size_t>(EnumAsFlags<E>::max);
using BitField16 = std::conditional_t<(MaxValue > 8), UInt16, UInt8>;
using BitField32 = std::conditional_t<(MaxValue > 16), UInt32, BitField16>;
using BitField16 = std::conditional_t<(MaxValue >= 8), UInt16, UInt8>;
using BitField32 = std::conditional_t<(MaxValue >= 16), UInt32, BitField16>;
public:
using BitField = std::conditional_t<(MaxValue > 32), UInt64, BitField32>;
using BitField = std::conditional_t<(MaxValue >= 32), UInt64, BitField32>;
constexpr Flags(BitField value = 0);
constexpr Flags(E enumVal);
void Clear();
void Clear(const Flags& flags);
void Set(const Flags& flags);
constexpr bool Test(const Flags& flags) const;
explicit constexpr operator bool() const;

View File

@@ -39,9 +39,49 @@ namespace Nz
{
}
/*!
* \brief Clear all flags
*
* \see Test
*/
template<typename E>
void Flags<E>::Clear()
{
m_value = 0;
}
/*!
* \brief Clear some flags
*
* \param flags Flags to be cleared
*
* \see Test
*/
template<typename E>
void Flags<E>::Clear(const Flags& flags)
{
m_value &= ~flags.m_value;
}
/*!
* \brief Enable some flags
*
* \param flags Flags to be enabled
*
* \see Clear
* \see Test
*/
template<typename E>
void Flags<E>::Set(const Flags& flags)
{
m_value |= flags.m_value;
}
/*!
* \brief Tests if all flags from a Flags object are enabled
* \return True if all tested flags are enabled.
*
* \see Clear
*/
template<typename E>
constexpr bool Flags<E>::Test(const Flags& flags) const

View File

@@ -8,6 +8,7 @@
#define NAZARA_OBJECTHANDLER_HPP
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Core/Signal.hpp>
#include <memory>
#include <vector>
@@ -41,6 +42,8 @@ namespace Nz
HandledObject& operator=(const HandledObject& object);
HandledObject& operator=(HandledObject&& object) noexcept;
NazaraSignal(OnHandledObjectDestruction, HandledObject* /*emitter*/);
protected:
void UnregisterAllHandles() noexcept;

View File

@@ -105,6 +105,8 @@ namespace Nz
{
if (m_handleData)
{
OnHandledObjectDestruction(this);
m_handleData->object = nullptr;
m_handleData.reset();
}

View File

@@ -335,7 +335,7 @@ namespace Nz
template<typename T>
bool operator<(const ObjectRef<T>& lhs, const ObjectRef<T>& rhs)
{
return lhs.m_object < rhs.m_object;
return lhs.Get() < rhs.Get();
}
/*!
@@ -348,7 +348,7 @@ namespace Nz
template<typename T>
bool operator<(const T& lhs, const ObjectRef<T>& rhs)
{
return &lhs < rhs.m_object;
return &lhs < rhs.Get();
}
/*!
@@ -361,7 +361,7 @@ namespace Nz
template<typename T>
bool operator<(const ObjectRef<T>& lhs, const T& rhs)
{
return lhs.m_object < &rhs;
return lhs.Get() < &rhs;
}
/*!

View File

@@ -0,0 +1,46 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_POOLBYTESTREAM_HPP
#define NAZARA_POOLBYTESTREAM_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/ByteStream.hpp>
#include <Nazara/Core/Config.hpp>
namespace Nz
{
class ByteArrayPool;
class NAZARA_CORE_API PoolByteStream : public ByteStream
{
friend class Network;
public:
inline PoolByteStream(ByteArrayPool& pool);
inline PoolByteStream(ByteArrayPool& pool, std::size_t capacity);
PoolByteStream(const PoolByteStream&) = delete;
PoolByteStream(PoolByteStream&& packet) = default;
inline ~PoolByteStream();
void Reset();
void Reset(std::size_t capacity);
PoolByteStream& operator=(const PoolByteStream&) = delete;
PoolByteStream& operator=(PoolByteStream&&) = delete;
private:
void OnEmptyStream() override;
ByteArrayPool& m_pool;
ByteArray m_buffer;
};
}
#include <Nazara/Core/PoolByteStream.inl>
#endif // NAZARA_POOLBYTESTREAM_HPP

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/PoolByteStream.hpp>
#include <Nazara/Core/Error.hpp>
#include <cstring>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
inline PoolByteStream::PoolByteStream(ByteArrayPool& pool) :
m_pool(pool)
{
}
inline PoolByteStream::PoolByteStream(ByteArrayPool& pool, std::size_t capacity) :
PoolByteStream(pool)
{
Reset(capacity);
}
inline PoolByteStream::~PoolByteStream()
{
FlushBits(); //< Needs to be done here as the stream will be freed before ByteStream calls it
Reset(); //< Returns the byte array (if any) to the pool
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -8,6 +8,7 @@
#define NAZARA_STACKARRAY_HPP
#include <Nazara/Core/MemoryHelper.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#ifdef NAZARA_ALLOCA_SUPPORT
#define NazaraStackArray(T, size) Nz::StackArray<T>(static_cast<T*>(NAZARA_ALLOCA((size) * sizeof(T))), size)
@@ -40,8 +41,11 @@ namespace Nz
using reverse_iterator = std::reverse_iterator<iterator>;
using size_type = std::size_t;
StackArray();
StackArray(T* stackMemory, std::size_t size);
StackArray(T* stackMemory, std::size_t size, NoInitTag);
StackArray(const StackArray&) = delete;
StackArray(StackArray&&) = default;
~StackArray();
reference back();
@@ -81,9 +85,12 @@ namespace Nz
reference operator[](size_type pos);
const_reference operator[](size_type pos) const;
StackArray& operator=(const StackArray&) = delete;
StackArray& operator=(StackArray&&) = default;
private:
std::size_t m_size;
T* m_ptr;
MovablePtr<T> m_ptr;
};
}

View File

@@ -24,6 +24,14 @@ namespace Nz
* \class Nz::StackArray
* \brief Core class that represents a stack-allocated (if alloca is present) array
*/
template<typename T>
StackArray<T>::StackArray() :
m_size(0),
m_ptr(nullptr)
{
}
template<typename T>
StackArray<T>::StackArray(T* stackMemory, std::size_t size) :
m_size(size),

View File

@@ -8,6 +8,7 @@
#define NAZARA_STACKVECTOR_HPP
#include <Nazara/Core/MemoryHelper.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#ifdef NAZARA_ALLOCA_SUPPORT
#define NazaraStackVector(T, capacity) Nz::StackVector<T>(static_cast<T*>(NAZARA_ALLOCA((capacity) * sizeof(T))), capacity)
@@ -37,7 +38,10 @@ namespace Nz
using reverse_iterator = std::reverse_iterator<iterator>;
using size_type = std::size_t;
StackVector();
StackVector(T* stackMemory, std::size_t capacity);
StackVector(const StackVector&) = delete;
StackVector(StackVector&&) = default;
~StackVector();
reference back();
@@ -99,10 +103,13 @@ namespace Nz
reference operator[](size_type pos);
const_reference operator[](size_type pos) const;
StackVector& operator=(const StackVector&) = delete;
StackVector& operator=(StackVector&&) = default;
private:
std::size_t m_capacity;
std::size_t m_size;
T* m_ptr;
MovablePtr<T> m_ptr;
};
}

View File

@@ -24,6 +24,14 @@ namespace Nz
* \class Nz::StackVector
* \brief Core class that represents a stack-allocated (if alloca is present) vector, that is with a capacity different from its size
*/
template<typename T>
StackVector<T>::StackVector() :
m_capacity(0),
m_size(0),
m_ptr(nullptr)
{
}
template<typename T>
StackVector<T>::StackVector(T* stackMemory, std::size_t capacity) :
m_capacity(capacity),
@@ -123,14 +131,16 @@ namespace Nz
assert(m_size < m_capacity);
assert(pos >= begin() && pos <= end());
std::size_t index = std::distance<const_iterator>(begin(), pos);
std::size_t index = std::distance(cbegin(), pos);
if (pos < end())
{
iterator lastElement = end() - 1;
PlacementNew(&m_ptr[m_size], std::move(*lastElement));
if (&m_ptr[index] < lastElement)
std::move(&m_ptr[index], lastElement, &m_ptr[index + 1]);
std::move_backward(&m_ptr[index], &m_ptr[m_size - 1], &m_ptr[m_size]);
PlacementDestroy(&m_ptr[index]);
}
m_size++;
@@ -167,8 +177,8 @@ namespace Nz
typename StackVector<T>::iterator StackVector<T>::erase(const_iterator pos)
{
assert(pos < end());
std::size_t index = std::distance(begin(), pos);
std::move(pos + 1, end(), pos);
std::size_t index = std::distance(cbegin(), pos);
std::move(begin() + index + 1, end(), begin() + index);
pop_back();
return iterator(&m_ptr[index]);
@@ -177,15 +187,18 @@ namespace Nz
template<typename T>
typename StackVector<T>::iterator StackVector<T>::erase(const_iterator first, const_iterator last)
{
std::size_t index = std::distance(cbegin(), first);
if (first == last)
return first;
return begin() + index;
assert(first < last);
assert(first >= begin() && last <= end());
std::size_t index = std::distance(begin(), first);
std::move(last, end(), first);
resize(size() - (last - first));
std::size_t count = std::distance(first, last);
std::move(begin() + index + count, end(), begin() + index);
resize(size() - count);
return iterator(&m_ptr[index]);
}
@@ -244,7 +257,7 @@ namespace Nz
template<typename T>
void StackVector<T>::resize(size_type count)
{
assert(count < m_capacity);
assert(count <= m_capacity);
if (count > m_size)
{
for (std::size_t i = m_size; i < count; ++i)
@@ -264,7 +277,7 @@ namespace Nz
template<typename T>
void StackVector<T>::resize(size_type count, const value_type& value)
{
assert(count < m_capacity);
assert(count <= m_capacity);
if (count > m_size)
{
for (std::size_t i = m_size; i < count; ++i)

View File

@@ -41,7 +41,7 @@ namespace Nz
inline void String::ReleaseString()
{
m_sharedString = std::move(GetEmptyString());
m_sharedString = GetEmptyString();
}
/*!

View File

@@ -10,7 +10,10 @@
namespace Nz
{
template<typename T>
struct TypeTag {};
struct TypeTag
{
using Type = T;
};
}
#endif // NAZARA_TYPETAG_HPP

View File

@@ -136,6 +136,8 @@ namespace Nz
{
friend CullingList;
using ParentType = Entry<CullTest::Box>;
public:
BoxEntry();
BoxEntry(BoxEntry&&) = default;
@@ -154,6 +156,8 @@ namespace Nz
{
friend CullingList;
using ParentType = Entry<CullTest::NoTest>;
public:
NoTestEntry();
NoTestEntry(NoTestEntry&&) = default;
@@ -170,6 +174,8 @@ namespace Nz
{
friend CullingList;
using ParentType = Entry<CullTest::Sphere>;
public:
SphereEntry();
SphereEntry(SphereEntry&&) = default;
@@ -188,6 +194,8 @@ namespace Nz
{
friend CullingList;
using ParentType = Entry<CullTest::Volume>;
public:
VolumeEntry();
VolumeEntry(VolumeEntry&&) = default;

View File

@@ -424,13 +424,13 @@ namespace Nz
template<typename T>
CullingList<T>::BoxEntry::BoxEntry() :
Entry<CullTest::Box>()
ParentType()
{
}
template<typename T>
CullingList<T>::BoxEntry::BoxEntry(CullingList* parent, std::size_t index) :
Entry<CullTest::Box>(parent, index)
ParentType(parent, index)
{
}
@@ -444,13 +444,13 @@ namespace Nz
template<typename T>
CullingList<T>::NoTestEntry::NoTestEntry() :
Entry<CullTest::NoTest>()
ParentType()
{
}
template<typename T>
CullingList<T>::NoTestEntry::NoTestEntry(CullingList* parent, std::size_t index) :
Entry<CullTest::NoTest>(parent, index)
ParentType(parent, index)
{
}
@@ -458,13 +458,13 @@ namespace Nz
template<typename T>
CullingList<T>::SphereEntry::SphereEntry() :
Entry<CullTest::Sphere>()
ParentType()
{
}
template<typename T>
CullingList<T>::SphereEntry::SphereEntry(CullingList* parent, std::size_t index) :
Entry<CullTest::Sphere>(parent, index)
ParentType(parent, index)
{
}
@@ -478,13 +478,13 @@ namespace Nz
template<typename T>
CullingList<T>::VolumeEntry::VolumeEntry() :
Entry<CullTest::Volume>()
ParentType()
{
}
template<typename T>
CullingList<T>::VolumeEntry::VolumeEntry(CullingList* parent, std::size_t index) :
Entry<CullTest::Volume>(parent, index)
ParentType(parent, index)
{
}

View File

@@ -51,8 +51,16 @@ namespace Nz
int textureOverlay;
};
struct SpriteBatch
{
std::size_t spriteCount;
const Material* material;
const Texture* overlayTexture;
Recti scissorRect;
};
mutable std::unordered_map<const Shader*, ShaderUniforms> m_shaderUniforms;
mutable std::vector<std::pair<const VertexStruct_XYZ_Color_UV*, std::size_t>> m_spriteChains;
mutable std::vector<SpriteBatch> m_spriteBatches;
Buffer m_vertexBuffer;
RenderStates m_clearStates;
ShaderRef m_clearShader;

View File

@@ -61,8 +61,16 @@ namespace Nz
int textureOverlay;
};
struct SpriteBatch
{
std::size_t spriteCount;
const Material* material;
const Texture* overlayTexture;
Recti scissorRect;
};
mutable std::unordered_map<const Shader*, ShaderUniforms> m_shaderUniforms;
mutable std::vector<std::pair<const VertexStruct_XYZ_Color_UV*, std::size_t>> m_spriteChains;
mutable std::vector<SpriteBatch> m_spriteBatches;
Buffer m_vertexBuffer;
RenderStates m_clearStates;
ShaderRef m_clearShader;

View File

@@ -119,6 +119,14 @@ namespace Nz
{
m_pipelineInfo = pipelineInfo;
// Temp and dirty fix for pipeline overriding has*Map
m_pipelineInfo.hasAlphaMap = m_alphaMap.IsValid();
m_pipelineInfo.hasDiffuseMap = m_diffuseMap.IsValid();
m_pipelineInfo.hasEmissiveMap = m_emissiveMap.IsValid();
m_pipelineInfo.hasHeightMap = m_heightMap.IsValid();
m_pipelineInfo.hasNormalMap = m_normalMap.IsValid();
m_pipelineInfo.hasSpecularMap = m_specularMap.IsValid();
InvalidatePipeline();
}

View File

@@ -59,6 +59,31 @@ namespace Nz
void OnAtlasLayerChange(const AbstractAtlas* atlas, AbstractImage* oldLayer, AbstractImage* newLayer);
void UpdateData(InstanceData* instanceData) const override;
struct RenderKey
{
Texture* texture;
int renderOrder;
bool operator==(const RenderKey& rhs) const
{
return texture == rhs.texture && renderOrder == rhs.renderOrder;
}
bool operator!=(const RenderKey& rhs) const
{
return !operator==(rhs);
}
};
struct HashRenderKey
{
std::size_t operator()(const RenderKey& key) const
{
// Since renderOrder will be very small, this will be enough
return std::hash<Texture*>()(key.texture) + key.renderOrder;
}
};
struct RenderIndices
{
unsigned int first;
@@ -74,10 +99,10 @@ namespace Nz
};
std::unordered_map<const AbstractAtlas*, AtlasSlots> m_atlases;
mutable std::unordered_map<Texture*, RenderIndices> m_renderInfos;
mutable std::unordered_map<RenderKey, RenderIndices, HashRenderKey> m_renderInfos;
mutable std::vector<VertexStruct_XY_Color_UV> m_localVertices;
Color m_color;
Recti m_localBounds;
Rectf m_localBounds;
float m_scale;
static TextSpriteLibrary::LibraryMap s_library;

View File

@@ -14,7 +14,7 @@ namespace Nz
inline TextSprite::TextSprite() :
m_color(Color::White),
m_localBounds(Nz::Recti::Zero()),
m_localBounds(Nz::Rectf::Zero()),
m_scale(1.f)
{
ResetMaterials(1U);

View File

@@ -35,15 +35,15 @@
namespace Nz
{
template<typename T> /*constexpr*/ T Approach(T value, T objective, T increment);
template<typename T> constexpr T Approach(T value, T objective, T increment);
template<typename T> constexpr T Clamp(T value, T min, T max);
template<typename T> /*constexpr*/ std::size_t CountBits(T value);
template<typename T> constexpr std::size_t CountBits(T value);
template<typename T> constexpr T FromDegrees(T degrees);
template<typename T> constexpr T FromRadians(T radians);
template<typename T> constexpr T DegreeToRadian(T degrees);
template<typename T> /*constexpr*/ T GetNearestPowerOfTwo(T number);
/*constexpr*/ unsigned int GetNumberLength(signed char number);
/*constexpr*/ unsigned int GetNumberLength(unsigned char number);
template<typename T> constexpr T GetNearestPowerOfTwo(T number);
constexpr unsigned int GetNumberLength(signed char number);
constexpr unsigned int GetNumberLength(unsigned char number);
unsigned int GetNumberLength(int number);
/*constexpr*/ unsigned int GetNumberLength(unsigned int number);
unsigned int GetNumberLength(long long number);
@@ -53,12 +53,12 @@ namespace Nz
unsigned int GetNumberLength(long double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS);
template<typename T> /*constexpr*/ unsigned int IntegralLog2(T number);
template<typename T> /*constexpr*/ unsigned int IntegralLog2Pot(T pot);
template<typename T> /*constexpr*/ T IntegralPow(T base, unsigned int exponent);
template<typename T> constexpr T IntegralPow(T base, unsigned int exponent);
template<typename T, typename T2> constexpr T Lerp(const T& from, const T& to, const T2& interpolation);
template<typename T> constexpr T MultiplyAdd(T x, T y, T z);
template<typename T> /*constexpr*/ T NormalizeAngle(T angle);
template<typename T> /*constexpr*/ bool NumberEquals(T a, T b);
template<typename T> /*constexpr*/ bool NumberEquals(T a, T b, T maxDifference);
template<typename T> constexpr T NormalizeAngle(T angle);
template<typename T> constexpr bool NumberEquals(T a, T b);
template<typename T> constexpr bool NumberEquals(T a, T b, T maxDifference);
String NumberToString(long long number, UInt8 radix = 10);
template<typename T> constexpr T RadianToDegree(T radians);
long long StringToNumber(String str, UInt8 radix = 10, bool* ok = nullptr);

View File

@@ -98,13 +98,13 @@ namespace Nz
return 0;
}
template<typename T> /*constexpr*/ std::enable_if_t<std::is_floating_point<T>::value, bool> NumberEquals(T a, T b, T maxDifference)
template<typename T> constexpr std::enable_if_t<std::is_floating_point<T>::value, bool> NumberEquals(T a, T b, T maxDifference)
{
T diff = std::abs(a - b);
return diff <= maxDifference;
}
template<typename T> /*constexpr*/ std::enable_if_t<!std::is_signed<T>::value || (!std::is_integral<T>::value && !std::is_floating_point<T>::value), bool> NumberEquals(T a, T b, T maxDifference)
template<typename T> constexpr std::enable_if_t<!std::is_signed<T>::value || (!std::is_integral<T>::value && !std::is_floating_point<T>::value), bool> NumberEquals(T a, T b, T maxDifference)
{
if (b > a)
std::swap(a, b);
@@ -113,7 +113,7 @@ namespace Nz
return diff <= maxDifference;
}
template<typename T> /*constexpr*/ std::enable_if_t<std::is_signed<T>::value && std::is_integral<T>::value, bool> NumberEquals(T a, T b, T maxDifference)
template<typename T> constexpr std::enable_if_t<std::is_signed<T>::value && std::is_integral<T>::value, bool> NumberEquals(T a, T b, T maxDifference)
{
if (b > a)
std::swap(a, b);
@@ -132,10 +132,8 @@ namespace Nz
* \param objective Target value
* \param increment One step value
*/
template<typename T>
//TODO: Mark as constexpr when supported by all major compilers
/*constexpr*/ inline T Approach(T value, T objective, T increment)
constexpr inline T Approach(T value, T objective, T increment)
{
if (value < objective)
return std::min(value + increment, objective);
@@ -154,7 +152,6 @@ namespace Nz
* \param min Minimum of the interval
* \param max Maximum of the interval
*/
template<typename T>
constexpr T Clamp(T value, T min, T max)
{
@@ -168,10 +165,8 @@ namespace Nz
*
* \param value The value to count bits
*/
template<typename T>
//TODO: Mark as constexpr when supported by all major compilers
/*constexpr*/ inline std::size_t CountBits(T value)
constexpr inline std::size_t CountBits(T value)
{
// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
std::size_t count = 0;
@@ -191,7 +186,6 @@ namespace Nz
*
* \param degrees Angle in degree (this is expected between 0..360)
*/
template<typename T>
constexpr T DegreeToRadian(T degrees)
{
@@ -205,7 +199,6 @@ namespace Nz
*
* \param degrees Convert degree to NAZARA_MATH_ANGLE_RADIAN unit
*/
template<typename T>
constexpr T FromDegrees(T degrees)
{
@@ -223,7 +216,6 @@ namespace Nz
*
* \param radians Convert radian to NAZARA_MATH_ANGLE_RADIAN unit
*/
template<typename T>
constexpr T FromRadians(T radians)
{
@@ -241,10 +233,8 @@ namespace Nz
*
* \param number Number to get nearest power
*/
template<typename T>
//TODO: Mark as constexpr when supported by all major compilers
/*constexpr*/ inline T GetNearestPowerOfTwo(T number)
constexpr inline T GetNearestPowerOfTwo(T number)
{
T x = 1;
while (x < number)
@@ -260,9 +250,7 @@ namespace Nz
*
* \param number Number to get number of digits
*/
//TODO: Mark as constexpr when supported by all major compilers
/*constexpr*/ inline unsigned int GetNumberLength(signed char number)
constexpr inline unsigned int GetNumberLength(signed char number)
{
// Char is expected to be 1 byte
static_assert(sizeof(number) == 1, "Signed char must be one byte-sized");
@@ -288,9 +276,7 @@ namespace Nz
*
* \param number Number to get number of digits
*/
//TODO: Mark as constexpr when supported by all major compilers
/*constexpr*/ inline unsigned int GetNumberLength(unsigned char number)
constexpr inline unsigned int GetNumberLength(unsigned char number)
{
// Char is expected to be 1 byte
static_assert(sizeof(number) == 1, "Unsigned char must be one byte-sized");
@@ -310,7 +296,6 @@ namespace Nz
*
* \param number Number to get number of digits
*/
inline unsigned int GetNumberLength(int number)
{
if (number == 0)
@@ -326,7 +311,6 @@ namespace Nz
*
* \param number Number to get number of digits
*/
//TODO: Mark as constexpr when supported by all major compilers
/*constexpr*/ inline unsigned int GetNumberLength(unsigned int number)
{
@@ -343,7 +327,6 @@ namespace Nz
*
* \param number Number to get number of digits
*/
inline unsigned int GetNumberLength(long long number)
{
if (number == 0)
@@ -359,7 +342,6 @@ namespace Nz
*
* \param number Number to get number of digits
*/
//TODO: Mark as constexpr when supported by all major compilers
/*constexpr*/ inline unsigned int GetNumberLength(unsigned long long number)
{
@@ -377,7 +359,6 @@ namespace Nz
* \param number Number to get number of digits
* \param precision Number of digit after the dot
*/
inline unsigned int GetNumberLength(float number, UInt8 precision)
{
// The imprecision of floats need a cast (log10(9.99999) = 0.99999)
@@ -392,7 +373,6 @@ namespace Nz
* \param number Number to get number of digits
* \param precision Number of digit after the dot
*/
inline unsigned int GetNumberLength(double number, UInt8 precision)
{
// The imprecision of floats need a cast (log10(9.99999) = 0.99999)
@@ -407,7 +387,6 @@ namespace Nz
* \param number Number to get number of digits
* \param precision Number of digit after the dot
*/
inline unsigned int GetNumberLength(long double number, UInt8 precision)
{
// The imprecision of floats need a cast (log10(9.99999) = 0.99999)
@@ -423,7 +402,6 @@ namespace Nz
*
* \remark If number is 0, 0 is returned
*/
template<typename T>
//TODO: Mark as constexpr when supported by all major compilers
/*constexpr*/ inline unsigned int IntegralLog2(T number)
@@ -442,7 +420,6 @@ namespace Nz
* \remark Only works for power of two
* \remark If number is 0, 0 is returned
*/
template<typename T>
//TODO: Mark as constexpr when supported by all major compilers
/*constexpr*/ inline unsigned int IntegralLog2Pot(T pot)
@@ -458,10 +435,8 @@ namespace Nz
* \param base Base of the exponentation
* \param exponent Power for the base
*/
//TODO: Mark as constexpr when supported by all major compilers
template<typename T>
/*constexpr*/ T IntegralPow(T base, unsigned int exponent)
constexpr T IntegralPow(T base, unsigned int exponent)
{
T r = 1;
for (unsigned int i = 0; i < exponent; ++i)
@@ -484,7 +459,6 @@ namespace Nz
*
* \see Lerp
*/
template<typename T, typename T2>
constexpr T Lerp(const T& from, const T& to, const T2& interpolation)
{
@@ -540,10 +514,8 @@ namespace Nz
*
* \param angle Angle to normalize
*/
template<typename T>
//TODO: Mark as constexpr when supported by all major compilers
/*constexpr*/ inline T NormalizeAngle(T angle)
constexpr inline T NormalizeAngle(T angle)
{
#if NAZARA_MATH_ANGLE_RADIAN
const T limit = T(M_PI);
@@ -567,10 +539,8 @@ namespace Nz
* \param a First value
* \param b Second value
*/
template<typename T>
//TODO: Mark as constexpr when supported by all major compilers
/*constexpr*/ inline bool NumberEquals(T a, T b)
constexpr inline bool NumberEquals(T a, T b)
{
return NumberEquals(a, b, std::numeric_limits<T>::epsilon());
}
@@ -584,10 +554,8 @@ namespace Nz
* \param b Second value
* \param maxDifference Epsilon of comparison (expected to be positive)
*/
template<typename T>
//TODO: Mark as constexpr when supported by all major compilers
/*constexpr*/ inline bool NumberEquals(T a, T b, T maxDifference)
constexpr inline bool NumberEquals(T a, T b, T maxDifference)
{
return Detail::NumberEquals(a, b, maxDifference);
}
@@ -603,7 +571,6 @@ namespace Nz
* \remark radix is meant to be between 2 and 36, other values are potentially undefined behavior
* \remark With NAZARA_MATH_SAFE, a NazaraError is produced and String() is returned
*/
inline String NumberToString(long long number, UInt8 radix)
{
#if NAZARA_MATH_SAFE
@@ -651,7 +618,6 @@ namespace Nz
*
* \param radians Angle in radian (this is expected between 0..2*pi)
*/
template<typename T>
constexpr T RadianToDegree(T radians)
{
@@ -670,7 +636,6 @@ namespace Nz
* \remark radix is meant to be between 2 and 36, other values are potentially undefined behavior
* \remark With NAZARA_MATH_SAFE, a NazaraError is produced and 0 is returned
*/
inline long long StringToNumber(String str, UInt8 radix, bool* ok)
{
#if NAZARA_MATH_SAFE
@@ -727,7 +692,6 @@ namespace Nz
*
* \param angle Convert degree from NAZARA_MATH_ANGLE_RADIAN unit to degrees
*/
template<typename T>
constexpr T ToDegrees(T angle)
{
@@ -745,7 +709,6 @@ namespace Nz
*
* \param angle Convert degree from NAZARA_MATH_ANGLE_RADIAN unit to radians
*/
template<typename T>
constexpr T ToRadians(T angle)
{

View File

@@ -63,7 +63,6 @@ namespace Nz
Box& Set(T Width, T Height, T Depth);
Box& Set(T X, T Y, T Z, T Width, T Height, T Depth);
Box& Set(const T box[6]);
Box& Set(const Box& box);
Box& Set(const Rect<T>& rect);
Box& Set(const Vector3<T>& lengths);
Box& Set(const Vector3<T>& vec1, const Vector3<T>& vec2);

View File

@@ -585,21 +585,6 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the box with components from another
* \return A reference to this box
*
* \param box The other box
*/
template<typename T>
Box<T>& Box<T>::Set(const Box& box)
{
std::memcpy(this, &box, sizeof(Box));
return *this;
}
/*!
* \brief Sets the components of the box with components from a Rect
* \return A reference to this box

View File

@@ -37,7 +37,6 @@ namespace Nz
EulerAngles& Set(T P, T Y, T R);
EulerAngles& Set(const T angles[3]);
template<AngleUnit Unit> EulerAngles& Set(const Angle<Unit, T>& angles);
EulerAngles& Set(const EulerAngles<T>& angles);
//EulerAngles& Set(const Matrix3<T>& mat);
EulerAngles& Set(const Quaternion<T>& quat);
template<typename U> EulerAngles& Set(const EulerAngles<U>& angles);

View File

@@ -169,20 +169,6 @@ namespace Nz
return Set(angle.ToEulerAngles());
}
/*!
* \brief Sets the components of the euler angle from another euler angle
* \return A reference to this euler angle
*
* \param angles The other euler angle
*/
template<typename T>
EulerAngles<T>& EulerAngles<T>::Set(const EulerAngles& angles)
{
std::memcpy(this, &angles, sizeof(EulerAngles));
return *this;
}
/*!
* \brief Sets the components of the euler angle from a quaternion
* \return A reference to this euler angle

View File

@@ -52,7 +52,6 @@ namespace Nz
Frustum& operator=(const Frustum& other) = default;
Frustum& Set(const Frustum& frustum);
template<typename U> Frustum& Set(const Frustum<U>& frustum);
String ToString() const;

View File

@@ -623,21 +623,6 @@ namespace Nz
return (c == 6) ? IntersectionSide_Inside : IntersectionSide_Intersecting;
}
/*!
* \brief Sets the components of the frustum from another frustum
* \return A reference to this frustum
*
* \param frustum The other frustum
*/
template<typename T>
Frustum<T>& Frustum<T>::Set(const Frustum& frustum)
{
std::memcpy(this, &frustum, sizeof(Frustum));
return *this;
}
/*!
* \brief Sets the components of the frustum from another type of Frustum
* \return A reference to this frustum

View File

@@ -44,6 +44,8 @@ namespace Nz
Matrix4& Concatenate(const Matrix4& matrix);
Matrix4& ConcatenateAffine(const Matrix4& matrix);
void Decompose(Vector3<T>& translation, Quaternion<T>& rotation, Vector3<T>& scale);
Vector4<T> GetColumn(unsigned int column) const;
T GetDeterminant() const;
T GetDeterminantAffine() const;
@@ -82,9 +84,7 @@ namespace Nz
T r21, T r22, T r23, T r24,
T r31, T r32, T r33, T r34,
T r41, T r42, T r43, T r44);
Matrix4& Set(const T matrix[16]);
//Matrix4(const Matrix3<T>& matrix);
Matrix4& Set(const Matrix4& matrix);
template<typename U> Matrix4& Set(const Matrix4<U>& matrix);
Matrix4& SetRotation(const Quaternion<T>& rotation);
Matrix4& SetScale(const Vector3<T>& scale);

View File

@@ -55,9 +55,12 @@ namespace Nz
*/
template<typename T>
Matrix4<T>::Matrix4(const T matrix[16])
Matrix4<T>::Matrix4(const T matrix[16]) :
Matrix4(matrix[ 0], matrix[ 1], matrix[ 2], matrix[ 3],
matrix[ 4], matrix[ 5], matrix[ 6], matrix[ 7],
matrix[ 8], matrix[ 9], matrix[10], matrix[11],
matrix[12], matrix[13], matrix[14], matrix[15])
{
Set(matrix);
}
/*!
@@ -217,6 +220,25 @@ namespace Nz
F(1.0));
}
template<typename T>
void Matrix4<T>::Decompose(Vector3<T>& translation, Quaternion<T>& rotation, Vector3<T>& scale)
{
Matrix4f localMat(*this);
translation = localMat.GetTranslation();
scale = localMat.GetScale();
Vector3<T> invScale;
invScale.x = T(1) / scale.x;
invScale.y = T(1) / scale.y;
invScale.z = T(1) / scale.z;
localMat.ApplyScale(invScale);
rotation = localMat.GetRotation();
}
/*!
* \brief Gets the ith column of the matrix
* \return Vector4 which is the transformation of this axis
@@ -448,7 +470,7 @@ namespace Nz
for (unsigned int i = 0; i < 16; ++i)
inv[i] *= invDet;
dest->Set(inv);
*dest = inv;
return true;
}
else
@@ -550,7 +572,7 @@ namespace Nz
inv[15] = F(1.0);
dest->Set(inv);
*dest = inv;
return true;
}
else
@@ -1097,37 +1119,6 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the matrix from an array of sixteen elements
* \return A reference to this matrix
*
* \param matrix[16] Matrix components
*/
template<typename T>
Matrix4<T>& Matrix4<T>::Set(const T matrix[16])
{
// Here we are confident of the continuity of memory elements
std::memcpy(&m11, matrix, 16 * sizeof(T));
return *this;
}
/*!
* \brief Sets the components of the matrix from another matrix
* \return A reference to this matrix
*
* \param matrix The other matrix
*/
template<typename T>
Matrix4<T>& Matrix4<T>::Set(const Matrix4& matrix)
{
std::memcpy(this, &matrix, sizeof(Matrix4));
return *this;
}
/*!
* \brief Sets the components of the matrix from another type of Matrix4
* \return A reference to this matrix

View File

@@ -36,7 +36,6 @@ namespace Nz
OrientedBox& Set(T X, T Y, T Z, T Width, T Height, T Depth);
OrientedBox& Set(const Box<T>& box);
OrientedBox& Set(const OrientedBox& orientedBox);
OrientedBox& Set(const Vector3<T>& vec1, const Vector3<T>& vec2);
template<typename U> OrientedBox& Set(const OrientedBox<U>& orientedBox);

View File

@@ -164,21 +164,6 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the oriented box with components from another
* \return A reference to this oriented box
*
* \param orientedBox The other OrientedBox
*/
template<typename T>
OrientedBox<T>& OrientedBox<T>::Set(const OrientedBox& orientedBox)
{
std::memcpy(this, &orientedBox, sizeof(OrientedBox));
return *this;
}
/*!
* \brief Sets a OrientedBox object from two vectors representing point of the space
* (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum

View File

@@ -37,7 +37,6 @@ namespace Nz
Plane& Set(T normalX, T normalY, T normalZ, T Distance);
Plane& Set(const T plane[4]);
Plane& Set(const Plane& plane);
Plane& Set(const Vector3<T>& Normal, T Distance);
Plane& Set(const Vector3<T>& Normal, const Vector3<T>& point);
Plane& Set(const Vector3<T>& point1, const Vector3<T>& point2, const Vector3<T>& point3);

View File

@@ -212,21 +212,6 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the plane from another plane
* \return A reference to this plane
*
* \param plane The other plane
*/
template<typename T>
Plane<T>& Plane<T>::Set(const Plane& plane)
{
std::memcpy(this, &plane, sizeof(Plane));
return *this;
}
/*!
* \brief Sets the components of the plane from a normal and a distance
* \return A reference to this plane

View File

@@ -56,7 +56,6 @@ namespace Nz
Quaternion& Set(T angle, const Vector3<T>& normalizedAxis);
Quaternion& Set(const T quat[4]);
//Quaternion& Set(const Matrix3<T>& mat);
Quaternion& Set(const Quaternion& quat);
template<typename U> Quaternion& Set(const Quaternion<U>& quat);
T SquaredMagnitude() const;

View File

@@ -430,21 +430,6 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the quaternion from another quaternion
* \return A reference to this quaternion
*
* \param quat The other quaternion
*/
template<typename T>
Quaternion<T>& Quaternion<T>::Set(const Quaternion& quat)
{
std::memcpy(this, &quat, sizeof(Quaternion));
return *this;
}
/*!
* \brief Sets the components of the quaternion from another type of Quaternion
* \return A reference to this quaternion

View File

@@ -54,7 +54,6 @@ namespace Nz
Ray& Set(const Vector3<T>& origin, const Vector3<T>& direction);
Ray& Set(const T origin[3], const T direction[3]);
Ray& Set(const Plane<T>& planeOne, const Plane<T>& planeTwo);
Ray& Set(const Ray& ray);
template<typename U> Ray& Set(const Ray<U>& ray);
template<typename U> Ray& Set(const Vector3<U>& origin, const Vector3<U>& direction);

View File

@@ -593,21 +593,6 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the ray with components from another
* \return A reference to this ray
*
* \param ray The other ray
*/
template<typename T>
Ray<T>& Ray<T>::Set(const Ray& ray)
{
std::memcpy(this, &ray, sizeof(Ray));
return *this;
}
/*!
* \brief Sets the components of the ray from another type of Ray
* \return A reference to this ray

View File

@@ -55,7 +55,6 @@ namespace Nz
Rect& Set(T Width, T Height);
Rect& Set(T X, T Y, T Width, T Height);
Rect& Set(const T rect[4]);
Rect& Set(const Rect<T>& rect);
Rect& Set(const Vector2<T>& lengths);
Rect& Set(const Vector2<T>& vec1, const Vector2<T>& vec2);
template<typename U> Rect& Set(const Rect<U>& rect);
@@ -92,7 +91,9 @@ namespace Nz
using Recti = Rect<int>;
using Rectui = Rect<unsigned int>;
using Recti32 = Rect<Int32>;
using Recti64 = Rect<Int64>;
using Rectui32 = Rect<UInt32>;
using Rectui64 = Rect<UInt64>;
template<typename T> bool Serialize(SerializationContext& context, const Rect<T>& rect, TypeTag<Rect<T>>);
template<typename T> bool Unserialize(SerializationContext& context, Rect<T>* rect, TypeTag<Rect<T>>);

View File

@@ -475,21 +475,6 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the rectangle with components from another
* \return A reference to this rectangle
*
* \param rect The other Rect
*/
template<typename T>
Rect<T>& Rect<T>::Set(const Rect<T>& rect)
{
std::memcpy(this, &rect, sizeof(Rect));
return *this;
}
/*!
* \brief Sets the components of the rectange from a vector representing width and height
* \return A reference to this rectangle

View File

@@ -53,7 +53,6 @@ namespace Nz
Sphere& Set(T X, T Y, T Z, T Radius);
//Sphere& Set(const Circle<T>& rect);
Sphere& Set(const Sphere& sphere);
Sphere& Set(const Vector3<T>& center, T Radius);
Sphere& Set(const T sphere[4]);
template<typename U> Sphere& Set(const Sphere<U>& sphere);

View File

@@ -397,21 +397,6 @@ namespace Nz
}
*/
/*!
* \brief Sets the components of the sphere with center and radius from another
* \return A reference to this sphere
*
* \param sphere The other sphere
*/
template<typename T>
Sphere<T>& Sphere<T>::Set(const Sphere& sphere)
{
std::memcpy(this, &sphere, sizeof(Sphere));
return *this;
}
/*!
* \brief Sets the components of the sphere from an array of four elements
* \return A reference to this sphere

View File

@@ -55,7 +55,6 @@ namespace Nz
Vector2& Set(T X, T Y);
Vector2& Set(T scale);
Vector2& Set(const T vec[2]);
Vector2& Set(const Vector2& vec);
Vector2& Set(const Vector3<T>& vec);
Vector2& Set(const Vector4<T>& vec);
template<typename U> Vector2& Set(const Vector2<U>& vec);

View File

@@ -367,22 +367,8 @@ namespace Nz
template<typename T>
Vector2<T>& Vector2<T>::Set(const T vec[2])
{
std::memcpy(&x, vec, 2*sizeof(T));
return *this;
}
/*!
* \brief Sets the components of the vector from another vector
* \return A reference to this vector
*
* \param vec The other vector
*/
template<typename T>
Vector2<T>& Vector2<T>::Set(const Vector2& vec)
{
std::memcpy(this, &vec, sizeof(Vector2));
x = vec[0];
y = vec[1];
return *this;
}

View File

@@ -67,7 +67,6 @@ namespace Nz
Vector3& Set(T scale);
Vector3& Set(const T vec[3]);
Vector3& Set(const Vector2<T>& vec, T Z = 0.0);
Vector3& Set(const Vector3<T>& vec);
template<typename U> Vector3& Set(const Vector3<U>& vec);
Vector3& Set(const Vector4<T>& vec);

View File

@@ -523,20 +523,6 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the vector from another vector
* \return A reference to this vector
*
* \param vec The other vector
*/
template<typename T>
Vector3<T>& Vector3<T>::Set(const Vector3& vec)
{
std::memcpy(this, &vec, sizeof(Vector3));
return *this;
}
/*!
* \brief Sets the components of the vector from another type of Vector3
* \return A reference to this vector

View File

@@ -57,7 +57,6 @@ namespace Nz
Vector4& Set(const T vec[4]);
Vector4& Set(const Vector2<T>& vec, T Z = 0.0, T W = 1.0);
Vector4& Set(const Vector3<T>& vec, T W = 1.0);
Vector4& Set(const Vector4<T>& vec);
template<typename U> Vector4& Set(const Vector4<U>& vec);
String ToString() const;

View File

@@ -417,7 +417,10 @@ namespace Nz
template<typename T>
Vector4<T>& Vector4<T>::Set(const T vec[4])
{
std::memcpy(&x, vec, 4*sizeof(T));
x = vec[0];
y = vec[1];
z = vec[2];
w = vec[3];
return *this;
}
@@ -459,21 +462,6 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the vector from another vector
* \return A reference to this vector
*
* \param vec The other vector
*/
template<typename T>
Vector4<T>& Vector4<T>::Set(const Vector4& vec)
{
std::memcpy(this, &vec, sizeof(Vector4));
return *this;
}
/*!
* \brief Sets the components of the vector from another type of Vector4
* \return A reference to this vector

View File

@@ -44,6 +44,8 @@ namespace Nz
ENetHost(ENetHost&&) = default;
inline ~ENetHost();
inline void AllowsIncomingConnections(bool allow = true);
void Broadcast(UInt8 channelId, ENetPacketFlags flags, NetPacket&& packet);
bool CheckEvents(ENetEvent* event);
@@ -56,6 +58,8 @@ namespace Nz
bool Create(const IpAddress& listenAddress, std::size_t peerCount, std::size_t channelCount, UInt32 incomingBandwidth, UInt32 outgoingBandwidth);
inline void Destroy();
inline bool DoesAllowIncomingConnections() const;
void Flush();
inline IpAddress GetBoundAddress() const;

View File

@@ -20,6 +20,13 @@ namespace Nz
Destroy();
}
inline void ENetHost::AllowsIncomingConnections(bool allow)
{
NazaraAssert(m_address.IsValid() && !m_address.IsLoopback(), "Only server hosts can allow incoming connections");
m_allowsIncomingConnections = allow;
}
inline bool ENetHost::Create(NetProtocol protocol, UInt16 port, std::size_t peerCount, std::size_t channelCount)
{
NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol");
@@ -54,6 +61,11 @@ namespace Nz
m_socket.Close();
}
inline bool ENetHost::DoesAllowIncomingConnections() const
{
return m_allowsIncomingConnections;
}
inline IpAddress ENetHost::GetBoundAddress() const
{
return m_address;

View File

@@ -56,8 +56,11 @@ namespace Nz
inline UInt16 GetPeerId() const;
inline UInt32 GetRoundTripTime() const;
inline ENetPeerState GetState() const;
inline UInt64 GetTotalPacketLost() const;
inline UInt64 GetTotalPacketSent() const;
inline UInt64 GetTotalByteReceived() const;
inline UInt64 GetTotalByteSent() const;
inline UInt32 GetTotalPacketReceived() const;
inline UInt32 GetTotalPacketLost() const;
inline UInt32 GetTotalPacketSent() const;
inline bool HasPendingCommands();
@@ -236,9 +239,12 @@ namespace Nz
UInt32 m_timeoutLimit;
UInt32 m_timeoutMaximum;
UInt32 m_timeoutMinimum;
UInt32 m_totalPacketReceived;
UInt32 m_totalPacketLost;
UInt32 m_totalPacketSent;
UInt32 m_windowSize;
UInt64 m_totalPacketLost;
UInt64 m_totalPacketSent;
UInt64 m_totalByteReceived;
UInt64 m_totalByteSent;
bool m_isSimulationEnabled;
};
}

View File

@@ -62,12 +62,27 @@ namespace Nz
return m_state;
}
inline UInt64 ENetPeer::GetTotalPacketLost() const
inline UInt64 ENetPeer::GetTotalByteReceived() const
{
return m_totalByteReceived;
}
inline UInt64 ENetPeer::GetTotalByteSent() const
{
return m_totalByteSent;
}
inline UInt32 ENetPeer::GetTotalPacketReceived() const
{
return m_totalPacketReceived;
}
inline UInt32 ENetPeer::GetTotalPacketLost() const
{
return m_totalPacketLost;
}
inline UInt64 ENetPeer::GetTotalPacketSent() const
inline UInt32 ENetPeer::GetTotalPacketSent() const
{
return m_totalPacketSent;
}

View File

@@ -41,9 +41,11 @@ namespace Nz
Collider2D(Collider2D&&) = delete;
virtual ~Collider2D();
virtual Nz::Vector2f ComputeCenterOfMass() const = 0;
virtual Vector2f ComputeCenterOfMass() const = 0;
virtual float ComputeMomentOfInertia(float mass) const = 0;
virtual void ForEachPolygon(const std::function<void(const Vector2f* vertices, std::size_t vertexCount)>& callback) const;
inline UInt32 GetCategoryMask() const;
inline UInt32 GetCollisionGroup() const;
inline unsigned int GetCollisionId() const;
@@ -228,13 +230,16 @@ namespace Nz
{
public:
inline SegmentCollider2D(const Vector2f& first, const Vector2f& second, float thickness = 1.f);
inline SegmentCollider2D(const Vector2f& first, const Vector2f& firstNeighbor, const Vector2f& second, const Vector2f& secondNeighbor, float thickness = 1.f);
Nz::Vector2f ComputeCenterOfMass() const override;
float ComputeMomentOfInertia(float mass) const override;
inline const Vector2f& GetFirstPoint() const;
inline const Vector2f& GetFirstPointNeighbor() const;
inline float GetLength() const;
inline const Vector2f& GetSecondPoint() const;
inline const Vector2f& GetSecondPointNeighbor() const;
inline float GetThickness() const;
ColliderType2D GetType() const override;
@@ -244,7 +249,9 @@ namespace Nz
std::size_t CreateShapes(RigidBody2D* body, std::vector<cpShape*>* shapes) const override;
Vector2f m_first;
Vector2f m_firstNeighbor;
Vector2f m_second;
Vector2f m_secondNeighbor;
float m_thickness;
};
}

View File

@@ -12,10 +12,10 @@ namespace Nz
m_categoryMask(0xFFFFFFFF),
m_collisionGroup(0),
m_collisionMask(0xFFFFFFFF),
m_surfaceVelocity(Vector2f::Zero()),
m_trigger(false),
m_elasticity(0.f),
m_friction(0.f),
m_surfaceVelocity(Vector2f::Zero()),
m_collisionId(0)
{
}
@@ -191,8 +191,15 @@ namespace Nz
}
SegmentCollider2D::SegmentCollider2D(const Vector2f& first, const Vector2f& second, float thickness) :
SegmentCollider2D(first, first, second, second, thickness)
{
}
inline SegmentCollider2D::SegmentCollider2D(const Vector2f& first, const Vector2f& firstNeighbor, const Vector2f& second, const Vector2f& secondNeighbor, float thickness) :
m_first(first),
m_firstNeighbor(firstNeighbor),
m_second(second),
m_secondNeighbor(secondNeighbor),
m_thickness(thickness)
{
}
@@ -202,6 +209,11 @@ namespace Nz
return m_first;
}
inline const Vector2f& SegmentCollider2D::GetFirstPointNeighbor() const
{
return m_firstNeighbor;
}
inline float SegmentCollider2D::GetLength() const
{
return m_first.Distance(m_second);
@@ -212,6 +224,11 @@ namespace Nz
return m_second;
}
inline const Vector2f& SegmentCollider2D::GetSecondPointNeighbor() const
{
return m_secondNeighbor;
}
inline float SegmentCollider2D::GetThickness() const
{
return m_thickness;

View File

@@ -8,7 +8,9 @@
#define NAZARA_CONSTRAINT2D_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/HandledObject.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Core/ObjectHandle.hpp>
#include <Nazara/Math/Angle.hpp>
#include <Nazara/Physics2D/Config.hpp>
#include <Nazara/Physics2D/PhysWorld2D.hpp>
@@ -21,11 +23,9 @@ namespace Nz
{
class Constraint2D;
using Constraint2DConstRef = ObjectRef<const Constraint2D>;
using Constraint2DLibrary = ObjectLibrary<Constraint2D>;
using Constraint2DRef = ObjectRef<Constraint2D>;
using Constraint2DHandle = ObjectHandle<Constraint2D>;
class NAZARA_PHYSICS2D_API Constraint2D : public RefCounted
class NAZARA_PHYSICS2D_API Constraint2D : public HandledObject<Constraint2D>
{
public:
Constraint2D(const Constraint2D&) = delete;
@@ -57,16 +57,12 @@ namespace Nz
Constraint2D(Nz::PhysWorld2D* world, cpConstraint* constraint);
MovablePtr<cpConstraint> m_constraint;
private:
static Constraint2DLibrary s_library;
};
class DampedSpringConstraint2D;
using DampedSpringConstraint2DConstRef = ObjectRef<const DampedSpringConstraint2D>;
using DampedSpringConstraint2DRef = ObjectRef<DampedSpringConstraint2D>;
using DampedSpringConstraint2DHandle = ObjectHandle<DampedSpringConstraint2D>;
class NAZARA_PHYSICS2D_API DampedSpringConstraint2D : public Constraint2D
{
public:
@@ -84,14 +80,11 @@ namespace Nz
void SetRestLength(float newLength);
void SetSecondAnchor(const Vector2f& firstAnchor);
void SetStiffness(float newStiffness);
template<typename... Args> static DampedSpringConstraint2DRef New(Args&&... args);
};
class DampedRotarySpringConstraint2D;
using DampedRotarySpringConstraint2DConstRef = ObjectRef<const DampedRotarySpringConstraint2D>;
using DampedRotarySpringConstraint2DRef = ObjectRef<DampedRotarySpringConstraint2D>;
using DampedRotarySpringConstraint2DHandle = ObjectHandle<DampedRotarySpringConstraint2D>;
class NAZARA_PHYSICS2D_API DampedRotarySpringConstraint2D : public Constraint2D
{
@@ -106,13 +99,11 @@ namespace Nz
void SetDamping(float newDamping);
void SetRestAngle(const RadianAnglef& newAngle);
void SetStiffness(float newStiffness);
template<typename... Args> static DampedRotarySpringConstraint2DRef New(Args&&... args);
};
class GearConstraint2D;
using GearConstraint2DConstRef = ObjectRef<const GearConstraint2D>;
using GearConstraint2DHandle = ObjectHandle<GearConstraint2D>;
using GearConstraint2DRef = ObjectRef<GearConstraint2D>;
class NAZARA_PHYSICS2D_API GearConstraint2D : public Constraint2D
@@ -132,8 +123,7 @@ namespace Nz
class MotorConstraint2D;
using MotorConstraint2DConstRef = ObjectRef<const MotorConstraint2D>;
using MotorConstraint2DRef = ObjectRef<MotorConstraint2D>;
using MotorConstraint2DHandle = ObjectHandle<MotorConstraint2D>;
class NAZARA_PHYSICS2D_API MotorConstraint2D : public Constraint2D
{
@@ -143,14 +133,11 @@ namespace Nz
float GetRate() const;
void SetRate(float rate);
template<typename... Args> static MotorConstraint2DRef New(Args&&... args);
};
class PinConstraint2D;
using PinConstraint2DConstRef = ObjectRef<const PinConstraint2D>;
using PinConstraint2DRef = ObjectRef<PinConstraint2D>;
using PinConstraint2DHandle = ObjectHandle<PinConstraint2D>;
class NAZARA_PHYSICS2D_API PinConstraint2D : public Constraint2D
{
@@ -165,14 +152,11 @@ namespace Nz
void SetDistance(float newDistance);
void SetFirstAnchor(const Vector2f& firstAnchor);
void SetSecondAnchor(const Vector2f& firstAnchor);
template<typename... Args> static PinConstraint2DRef New(Args&&... args);
};
class PivotConstraint2D;
using PivotConstraint2DConstRef = ObjectRef<const PivotConstraint2D>;
using PivotConstraint2DRef = ObjectRef<PivotConstraint2D>;
using PivotConstraint2DHandle = ObjectHandle<PivotConstraint2D>;
class NAZARA_PHYSICS2D_API PivotConstraint2D : public Constraint2D
{
@@ -186,14 +170,11 @@ namespace Nz
void SetFirstAnchor(const Vector2f& firstAnchor);
void SetSecondAnchor(const Vector2f& firstAnchor);
template<typename... Args> static PivotConstraint2DRef New(Args&&... args);
};
class RatchetConstraint2D;
using RatchetConstraint2DConstRef = ObjectRef<const RatchetConstraint2D>;
using RatchetConstraint2DRef = ObjectRef<RatchetConstraint2D>;
using RatchetConstraint2DHandle = ObjectHandle<RatchetConstraint2D>;
class NAZARA_PHYSICS2D_API RatchetConstraint2D : public Constraint2D
{
@@ -208,14 +189,11 @@ namespace Nz
void SetAngle(const RadianAnglef& angle);
void SetPhase(float phase);
void SetRatchet(float ratchet);
template<typename... Args> static RatchetConstraint2DRef New(Args&&... args);
};
class RotaryLimitConstraint2D;
using RotaryLimitConstraint2DConstRef = ObjectRef<const RotaryLimitConstraint2D>;
using RotaryLimitConstraint2DRef = ObjectRef<RotaryLimitConstraint2D>;
using RotaryLimitConstraint2DHandle = ObjectHandle<RotaryLimitConstraint2D>;
class NAZARA_PHYSICS2D_API RotaryLimitConstraint2D : public Constraint2D
{
@@ -228,14 +206,11 @@ namespace Nz
void SetMaxAngle(const RadianAnglef& maxAngle);
void SetMinAngle(const RadianAnglef& minAngle);
template<typename... Args> static RotaryLimitConstraint2DRef New(Args&&... args);
};
class SlideConstraint2D;
using SlideConstraint2DConstRef = ObjectRef<const SlideConstraint2D>;
using SlideConstraint2DRef = ObjectRef<SlideConstraint2D>;
using SlideConstraint2DHandle = ObjectHandle<SlideConstraint2D>;
class NAZARA_PHYSICS2D_API SlideConstraint2D : public Constraint2D
{
@@ -252,8 +227,6 @@ namespace Nz
void SetMaxDistance(float newMaxDistance);
void SetMinDistance(float newMinDistance);
void SetSecondAnchor(const Vector2f& firstAnchor);
template<typename... Args> static SlideConstraint2DRef New(Args&&... args);
};
}

View File

@@ -8,86 +8,6 @@
namespace Nz
{
template<typename... Args>
DampedSpringConstraint2DRef DampedSpringConstraint2D::New(Args&&... args)
{
std::unique_ptr<DampedSpringConstraint2D> object(new DampedSpringConstraint2D(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
template<typename... Args>
DampedRotarySpringConstraint2DRef DampedRotarySpringConstraint2D::New(Args&&... args)
{
std::unique_ptr<DampedRotarySpringConstraint2D> object(new DampedRotarySpringConstraint2D(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
template<typename... Args>
GearConstraint2DRef GearConstraint2D::New(Args&&... args)
{
std::unique_ptr<GearConstraint2D> object(new GearConstraint2D(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
template<typename... Args>
MotorConstraint2DRef MotorConstraint2D::New(Args&&... args)
{
std::unique_ptr<MotorConstraint2D> object(new MotorConstraint2D(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
template<typename... Args>
PinConstraint2DRef PinConstraint2D::New(Args&&... args)
{
std::unique_ptr<PinConstraint2D> object(new PinConstraint2D(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
template<typename... Args>
PivotConstraint2DRef PivotConstraint2D::New(Args&&... args)
{
std::unique_ptr<PivotConstraint2D> object(new PivotConstraint2D(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
template<typename... Args>
RatchetConstraint2DRef RatchetConstraint2D::New(Args&&... args)
{
std::unique_ptr<RatchetConstraint2D> object(new RatchetConstraint2D(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
template<typename... Args>
RotaryLimitConstraint2DRef RotaryLimitConstraint2D::New(Args&&... args)
{
std::unique_ptr<RotaryLimitConstraint2D> object(new RotaryLimitConstraint2D(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
template<typename... Args>
SlideConstraint2DRef SlideConstraint2D::New(Args&&... args)
{
std::unique_ptr<SlideConstraint2D> object(new SlideConstraint2D(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
}
#include <Nazara/Physics2D/DebugOff.hpp>

View File

@@ -64,18 +64,21 @@ namespace Nz
bool NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RigidBody2D** nearestBody = nullptr);
bool NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, NearestQueryResult* result);
void RaycastQuery(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, const std::function<void(const RaycastHit&)>& callback);
bool RaycastQuery(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector<RaycastHit>* hitInfos);
bool RaycastQueryFirst(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RaycastHit* hitInfo = nullptr);
void RegionQuery(const Nz::Rectf& boundingBox, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, const std::function<void(Nz::RigidBody2D*)>& callback);
void RegionQuery(const Nz::Rectf& boundingBox, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector<Nz::RigidBody2D*>* bodies);
void RegisterCallbacks(unsigned int collisionId, const Callback& callbacks);
void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, const Callback& callbacks);
void RegisterCallbacks(unsigned int collisionId, Callback callbacks);
void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, Callback callbacks);
void SetDamping(float dampingValue);
void SetGravity(const Vector2f& gravity);
void SetIterationCount(std::size_t iterationCount);
void SetMaxStepCount(std::size_t maxStepCount);
void SetSleepTime(float sleepTime);
void SetStepSize(float stepSize);
void Step(float timestep);
@@ -91,7 +94,7 @@ namespace Nz
ContactPreSolveCallback preSolveCallback = nullptr;
ContactPostSolveCallback postSolveCallback = nullptr;
ContactStartCallback startCallback = nullptr;
void* userdata;
void* userdata = nullptr;
};
struct DebugDrawOptions
@@ -130,7 +133,7 @@ namespace Nz
NazaraSignal(OnPhysWorld2DPostStep, const PhysWorld2D* /*physWorld*/, float /*invStepCount*/);
private:
void InitCallbacks(cpCollisionHandler* handler, const Callback& callbacks);
void InitCallbacks(cpCollisionHandler* handler, Callback callbacks);
using PostStep = std::function<void(Nz::RigidBody2D* body)>;

View File

@@ -32,7 +32,7 @@ namespace Nz
RigidBody2D(PhysWorld2D* world, float mass);
RigidBody2D(PhysWorld2D* world, float mass, Collider2DRef geom);
RigidBody2D(const RigidBody2D& object);
RigidBody2D(RigidBody2D&& object);
RigidBody2D(RigidBody2D&& object) noexcept;
~RigidBody2D();
void AddForce(const Vector2f& force, CoordSys coordSys = CoordSys_Global);
@@ -46,6 +46,7 @@ namespace Nz
void EnableSimulation(bool simulation);
void ForEachArbiter(std::function<void(Nz::Arbiter2D& /*arbiter*/)> callback);
void ForceSleep();
Rectf GetAABB() const;
inline float GetAngularDamping() const;
@@ -60,6 +61,7 @@ namespace Nz
Vector2f GetMassCenter(CoordSys coordSys = CoordSys_Local) const;
float GetMomentOfInertia() const;
Vector2f GetPosition() const;
inline const Vector2f& GetPositionOffset() const;
RadianAnglef GetRotation() const;
inline std::size_t GetShapeCount() const;
std::size_t GetShapeIndex(cpShape* shape) const;
@@ -87,6 +89,7 @@ namespace Nz
void SetMassCenter(const Vector2f& center, CoordSys coordSys = CoordSys_Local);
void SetMomentOfInertia(float moment);
void SetPosition(const Vector2f& position);
void SetPositionOffset(const Vector2f& offset);
void SetRotation(const RadianAnglef& rotation);
void SetSurfaceVelocity(const Vector2f& surfaceVelocity);
void SetSurfaceVelocity(std::size_t shapeIndex, const Vector2f& surfaceVelocity);
@@ -97,6 +100,8 @@ namespace Nz
void UpdateVelocity(const Nz::Vector2f& gravity, float damping, float deltaTime);
void Wakeup();
RigidBody2D& operator=(const RigidBody2D& object);
RigidBody2D& operator=(RigidBody2D&& object);
@@ -114,6 +119,7 @@ namespace Nz
static void CopyBodyData(cpBody* from, cpBody* to);
static void CopyShapeData(cpShape* from, cpShape* to);
Vector2f m_positionOffset;
VelocityFunc m_velocityFunc;
std::vector<cpShape*> m_shapes;
Collider2DRef m_geom;

View File

@@ -17,6 +17,11 @@ namespace Nz
return GetMassCenter(coordSys);
}
inline const Vector2f& RigidBody2D::GetPositionOffset() const
{
return m_positionOffset;
}
inline std::size_t RigidBody2D::GetShapeCount() const
{
return m_shapes.size();

View File

@@ -54,7 +54,7 @@ namespace Nz
virtual void ComputeInertialMatrix(Vector3f* inertia, Vector3f* center) const;
virtual float ComputeVolume() const;
virtual void ForEachPolygon(const std::function<void(const float* vertices, std::size_t vertexCount)>& callback) const;
virtual void ForEachPolygon(const std::function<void(const Vector3f* vertices, std::size_t vertexCount)>& callback) const;
NewtonCollision* GetHandle(PhysWorld3D* world) const;
virtual ColliderType3D GetType() const = 0;

View File

@@ -58,6 +58,8 @@ namespace Nz
struct MouseWheelEvent
{
float delta;
int x;
int y;
};
// Used by:

View File

@@ -77,7 +77,7 @@
// Nazara version macro
#define NAZARA_VERSION_MAJOR 0
#define NAZARA_VERSION_MINOR 3
#define NAZARA_VERSION_MINOR 4
#define NAZARA_VERSION_PATCH 0
#include <Nazara/Core/Config.hpp>
@@ -137,9 +137,9 @@
#define NAZARA_CORE_API
#endif
// Détection 64 bits
// Detect 64 bits
#if !defined(NAZARA_PLATFORM_x64) && (defined(_WIN64) || defined(__amd64__) || defined(__x86_64__) || defined(__ia64__) || defined(__ia64) || \
defined(_M_IA64) || defined(__itanium__) || defined(__MINGW64__) || defined(_M_AMD64) || defined (_M_X64))
defined(_M_IA64) || defined(__itanium__) || defined(__MINGW64__) || defined(_M_AMD64) || defined (_M_X64))
#define NAZARA_PLATFORM_x64
#endif

View File

@@ -38,7 +38,6 @@ namespace Nz
public:
Texture() = default;
Texture(ImageType type, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth = 1, UInt8 levelCount = 1);
explicit Texture(const Image* image);
Texture(const Texture&) = delete;
Texture(Texture&&) = delete;
~Texture();

View File

@@ -54,6 +54,7 @@
#include <Nazara/Utility/MeshData.hpp>
#include <Nazara/Utility/Node.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
#include <Nazara/Utility/RichTextDrawer.hpp>
#include <Nazara/Utility/Sequence.hpp>
#include <Nazara/Utility/SimpleTextDrawer.hpp>
#include <Nazara/Utility/SkeletalMesh.hpp>

View File

@@ -22,6 +22,8 @@ namespace Nz
{
public:
AbstractAtlas() = default;
AbstractAtlas(const AbstractAtlas&) = delete;
AbstractAtlas(AbstractAtlas&&) noexcept = default;
virtual ~AbstractAtlas();
virtual void Clear() = 0;
@@ -31,6 +33,9 @@ namespace Nz
virtual UInt32 GetStorage() const = 0;
virtual bool Insert(const Image& image, Rectui* rect, bool* flipped, unsigned int* layerIndex) = 0;
AbstractAtlas& operator=(const AbstractAtlas&) = delete;
AbstractAtlas& operator=(AbstractAtlas&&) noexcept = default;
// Signals:
NazaraSignal(OnAtlasCleared, const AbstractAtlas* /*atlas*/);
NazaraSignal(OnAtlasLayerChange, const AbstractAtlas* /*atlas*/, AbstractImage* /*oldLayer*/, AbstractImage* /*newLayer*/);

View File

@@ -27,7 +27,9 @@ namespace Nz
AbstractTextDrawer() = default;
virtual ~AbstractTextDrawer();
virtual const Recti& GetBounds() const = 0;
virtual void Clear() = 0;
virtual const Rectf& GetBounds() const = 0;
virtual Font* GetFont(std::size_t index) const = 0;
virtual std::size_t GetFontCount() const = 0;
virtual const Glyph& GetGlyph(std::size_t index) const = 0;
@@ -35,6 +37,9 @@ namespace Nz
virtual const Line& GetLine(std::size_t index) const = 0;
virtual std::size_t GetLineCount() const = 0;
inline std::size_t GetLineGlyphCount(std::size_t index) const;
virtual float GetMaxLineWidth() const = 0;
virtual void SetMaxLineWidth(float lineWidth) = 0;
struct Glyph
{
@@ -44,6 +49,7 @@ namespace Nz
Vector2f corners[4];
AbstractImage* atlas;
bool flipped;
int renderOrder;
};
struct Line

View File

@@ -329,18 +329,26 @@ namespace Nz
TextAlign_Max = TextAlign_Right
};
enum TextStyleFlags
enum TextStyle
{
TextStyle_Regular = 0x0,
TextStyle_Bold,
TextStyle_Italic,
TextStyle_StrikeThrough,
TextStyle_Underlined,
TextStyle_Bold = 0x1,
TextStyle_Italic = 0x2,
TextStyle_StrikeThrough = 0x4,
TextStyle_Underlined = 0x8,
TextStyle_Max = TextStyle_Underlined*2-1
TextStyle_Max = TextStyle_Underlined
};
template<>
struct EnumAsFlags<TextStyle>
{
static constexpr TextStyle max = TextStyle_Max;
};
using TextStyleFlags = Flags<TextStyle>;
constexpr TextStyleFlags TextStyle_Regular = 0;
enum VertexComponent
{
VertexComponent_Unused = -1,

View File

@@ -16,6 +16,7 @@
#include <Nazara/Core/ResourceLoader.hpp>
#include <Nazara/Core/ResourceParameters.hpp>
#include <Nazara/Utility/AbstractAtlas.hpp>
#include <Nazara/Utility/Enums.hpp>
#include <memory>
#include <unordered_map>
@@ -58,14 +59,14 @@ namespace Nz
bool Create(FontData* data);
void Destroy();
bool ExtractGlyph(unsigned int characterSize, char32_t character, UInt32 style, FontGlyph* glyph) const;
bool ExtractGlyph(unsigned int characterSize, char32_t character, TextStyleFlags style, float outlineThickness, FontGlyph* glyph) const;
const std::shared_ptr<AbstractAtlas>& GetAtlas() const;
std::size_t GetCachedGlyphCount(unsigned int characterSize, UInt32 style) const;
std::size_t GetCachedGlyphCount(unsigned int characterSize, TextStyleFlags style, float outlineThickness) const;
std::size_t GetCachedGlyphCount() const;
String GetFamilyName() const;
int GetKerning(unsigned int characterSize, char32_t first, char32_t second) const;
const Glyph& GetGlyph(unsigned int characterSize, UInt32 style, char32_t character) const;
const Glyph& GetGlyph(unsigned int characterSize, TextStyleFlags style, float outlineThickness, char32_t character) const;
unsigned int GetGlyphBorder() const;
unsigned int GetMinimumStepSize() const;
const SizeInfo& GetSizeInfo(unsigned int characterSize) const;
@@ -73,8 +74,8 @@ namespace Nz
bool IsValid() const;
bool Precache(unsigned int characterSize, UInt32 style, char32_t character) const;
bool Precache(unsigned int characterSize, UInt32 style, const String& characterSet) const;
bool Precache(unsigned int characterSize, TextStyleFlags style, float outlineThickness, char32_t character) const;
bool Precache(unsigned int characterSize, TextStyleFlags style, float outlineThickness, const String& characterSet) const;
void SetAtlas(const std::shared_ptr<AbstractAtlas>& atlas);
void SetGlyphBorder(unsigned int borderSize);
@@ -106,6 +107,7 @@ namespace Nz
bool requireFauxItalic;
bool flipped;
bool valid;
float fauxOutlineThickness;
int advance;
unsigned int layerIndex;
};
@@ -130,11 +132,11 @@ namespace Nz
private:
using GlyphMap = std::unordered_map<char32_t, Glyph>;
UInt64 ComputeKey(unsigned int characterSize, UInt32 style) const;
UInt64 ComputeKey(unsigned int characterSize, TextStyleFlags style, float outlineThickness) const;
void OnAtlasCleared(const AbstractAtlas* atlas);
void OnAtlasLayerChange(const AbstractAtlas* atlas, AbstractImage* oldLayer, AbstractImage* newLayer);
void OnAtlasRelease(const AbstractAtlas* atlas);
const Glyph& PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, UInt32 style, char32_t character) const;
const Glyph& PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, TextStyleFlags style, float outlineThickness, char32_t character) const;
static bool Initialize();
static void Uninitialize();

View File

@@ -10,6 +10,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Utility/Config.hpp>
#include <Nazara/Utility/Enums.hpp>
namespace Nz
{
@@ -21,7 +22,7 @@ namespace Nz
FontData() = default;
virtual ~FontData();
virtual bool ExtractGlyph(unsigned int characterSize, char32_t character, UInt32 style, FontGlyph* dst) = 0;
virtual bool ExtractGlyph(unsigned int characterSize, char32_t character, TextStyleFlags style, float outlineThickness, FontGlyph* dst) = 0;
virtual String GetFamilyName() const = 0;
virtual String GetStyleName() const = 0;
@@ -35,7 +36,8 @@ namespace Nz
virtual float QueryUnderlinePosition(unsigned int characterSize) const = 0;
virtual float QueryUnderlineThickness(unsigned int characterSize) const = 0;
virtual bool SupportsStyle(UInt32 style) const = 0;
virtual bool SupportsOutline(float outlineThickness) const = 0;
virtual bool SupportsStyle(TextStyleFlags style) const = 0;
};
}

View File

@@ -41,10 +41,10 @@ namespace Nz
virtual Vector3f GetLeft() const;
virtual NodeType GetNodeType() const;
const Node* GetParent() const;
Vector3f GetPosition(CoordSys coordSys = CoordSys_Global) const;
Vector3f GetPosition(CoordSys coordSys = CoordSys_Local) const;
virtual Vector3f GetRight() const;
Quaternionf GetRotation(CoordSys coordSys = CoordSys_Global) const;
Vector3f GetScale(CoordSys coordSys = CoordSys_Global) const;
Quaternionf GetRotation(CoordSys coordSys = CoordSys_Local) const;
Vector3f GetScale(CoordSys coordSys = CoordSys_Local) const;
const Matrix4f& GetTransformMatrix() const;
virtual Vector3f GetUp() const;
@@ -75,6 +75,7 @@ namespace Nz
void SetPosition(const Vector3f& translation, CoordSys coordSys = CoordSys_Local);
void SetPosition(float translationX, float translationY, float translationZ = 0.f, CoordSys coordSys = CoordSys_Local);
void SetRotation(const Quaternionf& quat, CoordSys coordSys = CoordSys_Local);
void SetScale(const Vector2f& scale, CoordSys coordSys = CoordSys_Local);
void SetScale(const Vector3f& scale, CoordSys coordSys = CoordSys_Local);
void SetScale(float scale, CoordSys coordSys = CoordSys_Local);
void SetScale(float scaleX, float scaleY, float scaleZ = 1.f, CoordSys coordSys = CoordSys_Local);
@@ -105,6 +106,8 @@ namespace Nz
virtual void UpdateDerived() const;
virtual void UpdateTransformMatrix() const;
static Quaternionf ScaleQuaternion(const Vector3f& scale, Quaternionf quaternion);
mutable std::vector<Node*> m_childs;
mutable Matrix4f m_transformMatrix;
mutable Quaternionf m_derivedRotation;

View File

@@ -0,0 +1,212 @@
// Copyright (C) 2016 Jérôme Leclercq
// This file is part of the "Nazara Engine - Utility module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_RICHTEXTDRAWER_HPP
#define NAZARA_RICHTEXTDRAWER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Utility/AbstractTextDrawer.hpp>
#include <Nazara/Utility/Enums.hpp>
#include <Nazara/Utility/Font.hpp>
#include <vector>
namespace Nz
{
class NAZARA_UTILITY_API RichTextDrawer : public AbstractTextDrawer
{
public:
class BlockRef;
RichTextDrawer();
RichTextDrawer(const RichTextDrawer& drawer);
RichTextDrawer(RichTextDrawer&& drawer);
~RichTextDrawer();
BlockRef AppendText(const String& str, bool forceNewBlock = false);
void Clear() override;
inline std::size_t FindBlock(std::size_t glyphIndex) const;
inline unsigned int GetBlockCharacterSize(std::size_t index) const;
inline float GetBlockCharacterSpacingOffset(std::size_t index) const;
inline const Color& GetBlockColor(std::size_t index) const;
inline std::size_t GetBlockCount() const;
inline std::size_t GetBlockFirstGlyphIndex(std::size_t index) const;
inline const FontRef& GetBlockFont(std::size_t index) const;
inline float GetBlockLineHeight(std::size_t index) const;
inline float GetBlockLineSpacingOffset(std::size_t index) const;
inline const Color& GetBlockOutlineColor(std::size_t index) const;
inline float GetBlockOutlineThickness(std::size_t index) const;
inline TextStyleFlags GetBlockStyle(std::size_t index) const;
inline const String& GetBlockText(std::size_t index) const;
inline BlockRef GetBlock(std::size_t index);
const Rectf& GetBounds() const override;
inline unsigned int GetDefaultCharacterSize() const;
inline float GetDefaultCharacterSpacingOffset() const;
inline const Color& GetDefaultColor() const;
inline const FontRef& GetDefaultFont() const;
inline float GetDefaultLineSpacingOffset() const;
inline const Color& GetDefaultOutlineColor() const;
inline float GetDefaultOutlineThickness() const;
inline TextStyleFlags GetDefaultStyle() const;
Font* GetFont(std::size_t index) const override;
std::size_t GetFontCount() const override;
const Glyph& GetGlyph(std::size_t index) const override;
std::size_t GetGlyphCount() const override;
const Line& GetLine(std::size_t index) const override;
std::size_t GetLineCount() const override;
float GetMaxLineWidth() const override;
inline bool HasBlocks() const;
void MergeBlocks();
void RemoveBlock(std::size_t index);
inline void SetBlockCharacterSize(std::size_t index, unsigned int characterSize);
inline void SetBlockCharacterSpacingOffset(std::size_t index, float offset);
inline void SetBlockColor(std::size_t index, const Color& color);
inline void SetBlockFont(std::size_t index, FontRef font);
inline void SetBlockLineSpacingOffset(std::size_t index, float offset);
inline void SetBlockOutlineColor(std::size_t index, const Color& color);
inline void SetBlockOutlineThickness(std::size_t index, float thickness);
inline void SetBlockStyle(std::size_t index, TextStyleFlags style);
inline void SetBlockText(std::size_t index, String str);
inline void SetDefaultCharacterSize(unsigned int characterSize);
inline void SetDefaultCharacterSpacingOffset(float offset);
inline void SetDefaultColor(const Color& color);
inline void SetDefaultFont(const FontRef& font);
inline void SetDefaultLineSpacingOffset(float offset);
inline void SetDefaultOutlineColor(const Color& color);
inline void SetDefaultOutlineThickness(float thickness);
inline void SetDefaultStyle(TextStyleFlags style);
void SetMaxLineWidth(float lineWidth) override;
RichTextDrawer& operator=(const RichTextDrawer& drawer);
RichTextDrawer& operator=(RichTextDrawer&& drawer);
static constexpr std::size_t InvalidBlockIndex = std::numeric_limits<std::size_t>::max();
private:
struct Block;
inline void AppendNewLine(const Font* font, unsigned int characterSize, float lineSpacingOffset) const;
void AppendNewLine(const Font* font, unsigned int characterSize, float lineSpacingOffset, std::size_t glyphIndex, float glyphPosition) const;
inline void ClearGlyphs() const;
inline void ConnectFontSlots();
inline void DisconnectFontSlots();
bool GenerateGlyph(Glyph& glyph, char32_t character, float outlineThickness, bool lineWrap, const Font* font, const Color& color, TextStyleFlags style, float lineSpacingOffset, unsigned int characterSize, int renderOrder, int* advance) const;
void GenerateGlyphs(const Font* font, const Color& color, TextStyleFlags style, unsigned int characterSize, const Color& outlineColor, float characterSpacingOffset, float lineSpacingOffset, float outlineThickness, const String& text) const;
inline float GetLineHeight(const Block& block) const;
inline float GetLineHeight(float lineSpacingOffset, const Font::SizeInfo& sizeInfo) const;
inline std::size_t HandleFontAddition(const FontRef& font);
inline void InvalidateGlyphs();
inline void ReleaseFont(std::size_t fontIndex);
inline bool ShouldLineWrap(float size) const;
void OnFontAtlasLayerChanged(const Font* font, AbstractImage* oldLayer, AbstractImage* newLayer);
void OnFontInvalidated(const Font* font);
void OnFontRelease(const Font* object);
void UpdateGlyphs() const;
static constexpr std::size_t InvalidGlyph = std::numeric_limits<std::size_t>::max();
struct Block
{
std::size_t fontIndex;
std::size_t glyphIndex;
Color color;
Color outlineColor;
String text;
TextStyleFlags style;
float characterSpacingOffset;
float lineSpacingOffset;
float outlineThickness;
unsigned int characterSize;
};
struct FontData
{
FontRef font;
std::size_t useCount = 0;
NazaraSlot(Font, OnFontAtlasChanged, atlasChangedSlot);
NazaraSlot(Font, OnFontAtlasLayerChanged, atlasLayerChangedSlot);
NazaraSlot(Font, OnFontGlyphCacheCleared, glyphCacheClearedSlot);
NazaraSlot(Font, OnFontRelease, fontReleaseSlot);
};
Color m_defaultColor;
Color m_defaultOutlineColor;
TextStyleFlags m_defaultStyle;
FontRef m_defaultFont;
mutable std::size_t m_lastSeparatorGlyph;
std::unordered_map<FontRef, std::size_t> m_fontIndexes;
std::vector<Block> m_blocks;
std::vector<FontData> m_fonts;
mutable std::vector<Glyph> m_glyphs;
mutable std::vector<Line> m_lines;
mutable Rectf m_bounds;
mutable Vector2f m_drawPos;
mutable bool m_glyphUpdated;
float m_defaultCharacterSpacingOffset;
float m_defaultLineSpacingOffset;
float m_defaultOutlineThickness;
float m_maxLineWidth;
unsigned int m_defaultCharacterSize;
mutable float m_lastSeparatorPosition;
};
class RichTextDrawer::BlockRef
{
friend RichTextDrawer;
public:
BlockRef(const BlockRef&) = default;
BlockRef(BlockRef&&) = default;
~BlockRef() = default;
inline float GetCharacterSpacingOffset() const;
inline unsigned int GetCharacterSize() const;
inline Color GetColor() const;
inline std::size_t GetFirstGlyphIndex() const;
inline const FontRef& GetFont() const;
inline float GetLineSpacingOffset() const;
inline Color GetOutlineColor() const;
inline float GetOutlineThickness() const;
inline TextStyleFlags GetStyle() const;
inline const String& GetText() const;
inline void SetCharacterSpacingOffset(float offset);
inline void SetCharacterSize(unsigned int size);
inline void SetColor(Color color);
inline void SetFont(FontRef font);
inline void SetLineSpacingOffset(float offset);
inline void SetOutlineColor(Color color);
inline void SetOutlineThickness(float thickness);
inline void SetStyle(TextStyleFlags style);
inline void SetText(const String& text);
BlockRef& operator=(const BlockRef&) = default;
BlockRef& operator=(BlockRef&&) = default;
private:
inline BlockRef(RichTextDrawer& drawer, std::size_t index);
std::size_t m_blockIndex;
RichTextDrawer& m_drawer;
};
}
#include <Nazara/Utility/RichTextDrawer.inl>
#endif // NAZARA_RICHTEXTDRAWER_HPP

View File

@@ -0,0 +1,631 @@
// Copyright (C) 2016 Jérôme Leclercq
// This file is part of the "Nazara Engine - Utility module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Utility/RichTextDrawer.hpp>
#include <Nazara/Utility/Debug.hpp>
namespace Nz
{
inline std::size_t RichTextDrawer::FindBlock(std::size_t glyphIndex) const
{
auto it = m_blocks.begin();
for (; it != m_blocks.end(); ++it)
{
if (it->glyphIndex > glyphIndex)
break;
}
assert(it != m_blocks.begin());
return std::distance(m_blocks.begin(), it) - 1;
/*
// Binary search
std::size_t count = m_blocks.size();
std::size_t step;
std::size_t i = InvalidBlockIndex;
std::size_t first = 0;
std::size_t last = count;
while (count > 0)
{
i = first;
step = count / 2;
i += step;
if (m_blocks[i].glyphIndex < glyphIndex)
{
first = ++i;
count -= step + 1;
}
else
count = step;
}
return i;*/
}
inline auto RichTextDrawer::GetBlock(std::size_t index) -> BlockRef
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return BlockRef(*this, index);
}
inline unsigned int RichTextDrawer::GetBlockCharacterSize(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return m_blocks[index].characterSize;
}
inline float RichTextDrawer::GetBlockCharacterSpacingOffset(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return m_blocks[index].characterSpacingOffset;
}
inline const Color& RichTextDrawer::GetBlockColor(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return m_blocks[index].color;
}
inline std::size_t RichTextDrawer::GetBlockCount() const
{
return m_blocks.size();
}
inline std::size_t RichTextDrawer::GetBlockFirstGlyphIndex(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return m_blocks[index].glyphIndex;
}
inline const FontRef& RichTextDrawer::GetBlockFont(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
std::size_t fontIndex = m_blocks[index].fontIndex;
assert(fontIndex < m_fonts.size());
return m_fonts[fontIndex].font;
}
inline float RichTextDrawer::GetBlockLineHeight(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return m_blocks[index].lineSpacingOffset;
}
inline float RichTextDrawer::GetBlockLineSpacingOffset(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return m_blocks[index].lineSpacingOffset;
}
inline const Color& RichTextDrawer::GetBlockOutlineColor(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return m_blocks[index].outlineColor;
}
inline float RichTextDrawer::GetBlockOutlineThickness(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return m_blocks[index].outlineThickness;
}
inline TextStyleFlags RichTextDrawer::GetBlockStyle(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return m_blocks[index].style;
}
inline const String& RichTextDrawer::GetBlockText(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return m_blocks[index].text;
}
inline unsigned int RichTextDrawer::GetDefaultCharacterSize() const
{
return m_defaultCharacterSize;
}
inline float RichTextDrawer::GetDefaultCharacterSpacingOffset() const
{
return m_defaultCharacterSpacingOffset;
}
inline const Color& RichTextDrawer::GetDefaultColor() const
{
return m_defaultColor;
}
inline const FontRef& RichTextDrawer::GetDefaultFont() const
{
return m_defaultFont;
}
inline float RichTextDrawer::GetDefaultLineSpacingOffset() const
{
return m_defaultLineSpacingOffset;
}
inline const Color& RichTextDrawer::GetDefaultOutlineColor() const
{
return m_defaultOutlineColor;
}
inline float RichTextDrawer::GetDefaultOutlineThickness() const
{
return m_defaultOutlineThickness;
}
inline TextStyleFlags RichTextDrawer::GetDefaultStyle() const
{
return m_defaultStyle;
}
inline void RichTextDrawer::AppendNewLine(const Font* font, unsigned int characterSize, float lineSpacingOffset) const
{
AppendNewLine(font, characterSize, lineSpacingOffset, InvalidGlyph, 0);
}
inline void RichTextDrawer::ClearGlyphs() const
{
m_bounds.MakeZero();
m_lastSeparatorGlyph = InvalidGlyph;
m_lines.clear();
m_glyphs.clear();
m_glyphUpdated = true;
m_bounds.MakeZero(); //< Compute bounds as float to speedup bounds computation (as casting between floats and integers is costly)
}
inline void RichTextDrawer::ConnectFontSlots()
{
for (auto& fontData : m_fonts)
{
fontData.atlasChangedSlot.Connect(fontData.font->OnFontAtlasChanged, this, &RichTextDrawer::OnFontInvalidated);
fontData.atlasLayerChangedSlot.Connect(fontData.font->OnFontAtlasLayerChanged, this, &RichTextDrawer::OnFontAtlasLayerChanged);
fontData.fontReleaseSlot.Connect(fontData.font->OnFontDestroy, this, &RichTextDrawer::OnFontRelease);
fontData.glyphCacheClearedSlot.Connect(fontData.font->OnFontGlyphCacheCleared, this, &RichTextDrawer::OnFontInvalidated);
}
}
inline void RichTextDrawer::DisconnectFontSlots()
{
for (auto& fontData : m_fonts)
{
fontData.atlasChangedSlot.Disconnect();
fontData.atlasLayerChangedSlot.Disconnect();
fontData.fontReleaseSlot.Disconnect();
fontData.glyphCacheClearedSlot.Disconnect();
}
}
inline float RichTextDrawer::GetLineHeight(const Block& block) const
{
assert(block.fontIndex < m_fonts.size());
const FontData& fontData = m_fonts[block.fontIndex];
return GetLineHeight(block.lineSpacingOffset, fontData.font->GetSizeInfo(block.characterSize));
}
inline float RichTextDrawer::GetLineHeight(float lineSpacingOffset, const Font::SizeInfo& sizeInfo) const
{
return float(sizeInfo.lineHeight) + lineSpacingOffset;
}
inline std::size_t RichTextDrawer::HandleFontAddition(const FontRef& font)
{
auto it = m_fontIndexes.find(font);
if (it == m_fontIndexes.end())
{
std::size_t fontIndex = m_fonts.size();
m_fonts.emplace_back();
auto& fontData = m_fonts.back();
fontData.font = font;
fontData.atlasChangedSlot.Connect(font->OnFontAtlasChanged, this, &RichTextDrawer::OnFontInvalidated);
fontData.atlasLayerChangedSlot.Connect(font->OnFontAtlasLayerChanged, this, &RichTextDrawer::OnFontAtlasLayerChanged);
fontData.fontReleaseSlot.Connect(font->OnFontDestroy, this, &RichTextDrawer::OnFontRelease);
fontData.glyphCacheClearedSlot.Connect(font->OnFontGlyphCacheCleared, this, &RichTextDrawer::OnFontInvalidated);
it = m_fontIndexes.emplace(font, fontIndex).first;
}
return it->second;
}
inline void RichTextDrawer::ReleaseFont(std::size_t fontIndex)
{
assert(fontIndex < m_fonts.size());
FontData& fontData = m_fonts[fontIndex];
assert(fontData.useCount > 0);
if (--fontData.useCount == 0)
{
// Shift font indexes
m_fontIndexes.erase(fontData.font);
for (auto& fontIndexe : m_fontIndexes)
{
if (fontIndexe.second > fontIndex)
fontIndexe.second--;
}
m_fonts.erase(m_fonts.begin() + fontIndex);
}
}
inline bool RichTextDrawer::ShouldLineWrap(float size) const
{
if (m_lines.back().glyphIndex > m_glyphs.size())
return false;
return m_lines.back().bounds.GetMaximum().x + size > m_maxLineWidth;
}
inline bool RichTextDrawer::HasBlocks() const
{
return !m_blocks.empty();
}
inline void RichTextDrawer::SetBlockCharacterSize(std::size_t index, unsigned int characterSize)
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
m_blocks[index].characterSize = characterSize;
InvalidateGlyphs();
}
inline void RichTextDrawer::SetBlockCharacterSpacingOffset(std::size_t index, float offset)
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
m_blocks[index].characterSpacingOffset = offset;
InvalidateGlyphs();
}
inline void RichTextDrawer::SetBlockColor(std::size_t index, const Color& color)
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
m_blocks[index].color = color;
InvalidateGlyphs();
}
inline void RichTextDrawer::SetBlockFont(std::size_t index, FontRef font)
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
std::size_t fontIndex = HandleFontAddition(font);
std::size_t oldFontIndex = m_blocks[index].fontIndex;
if (oldFontIndex != fontIndex)
{
ReleaseFont(oldFontIndex);
m_fonts[fontIndex].useCount++;
m_blocks[index].fontIndex = fontIndex;
}
InvalidateGlyphs();
}
inline void RichTextDrawer::SetBlockLineSpacingOffset(std::size_t index, float offset)
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
m_blocks[index].lineSpacingOffset = offset;
InvalidateGlyphs();
}
inline void RichTextDrawer::SetBlockOutlineColor(std::size_t index, const Color& color)
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
m_blocks[index].outlineColor = color;
InvalidateGlyphs();
}
inline void RichTextDrawer::SetBlockOutlineThickness(std::size_t index, float thickness)
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
m_blocks[index].outlineThickness = thickness;
InvalidateGlyphs();
}
inline void RichTextDrawer::SetBlockStyle(std::size_t index, TextStyleFlags style)
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
m_blocks[index].style = style;
InvalidateGlyphs();
}
inline void RichTextDrawer::SetBlockText(std::size_t index, String str)
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
std::size_t previousLength = m_blocks[index].text.GetLength();
m_blocks[index].text = std::move(str);
std::size_t newLength = m_blocks[index].text.GetLength();
if (newLength != previousLength)
{
std::size_t delta = newLength - previousLength; //< Underflow allowed
for (std::size_t i = index + 1; i < m_blocks.size(); ++i)
m_blocks[i].glyphIndex += delta;
}
InvalidateGlyphs();
}
inline void RichTextDrawer::SetDefaultCharacterSize(unsigned int characterSize)
{
m_defaultCharacterSize = characterSize;
}
inline void RichTextDrawer::SetDefaultCharacterSpacingOffset(float offset)
{
m_defaultCharacterSpacingOffset = offset;
}
inline void RichTextDrawer::SetDefaultColor(const Color& color)
{
m_defaultColor = color;
}
inline void RichTextDrawer::SetDefaultFont(const FontRef& font)
{
m_defaultFont = font;
}
inline void RichTextDrawer::SetDefaultLineSpacingOffset(float offset)
{
m_defaultLineSpacingOffset = offset;
}
inline void RichTextDrawer::SetDefaultOutlineColor(const Color& color)
{
m_defaultOutlineColor = color;
}
inline void RichTextDrawer::SetDefaultOutlineThickness(float thickness)
{
m_defaultOutlineThickness = thickness;
}
inline void RichTextDrawer::SetDefaultStyle(TextStyleFlags style)
{
m_defaultStyle = style;
}
inline void RichTextDrawer::InvalidateGlyphs()
{
m_glyphUpdated = false;
}
/*!
* \class Nz::RichTextDrawer::BlockRef
* \brief Helper class representing a block inside a RichTextDrawer, allowing easier access.
*
* \warning This class is meant for temporary use, moving or destroying the RichTextDrawer or one of its blocks invalidates all BlockRef
*/
inline RichTextDrawer::BlockRef::BlockRef(RichTextDrawer& drawer, std::size_t index) :
m_blockIndex(index),
m_drawer(drawer)
{
}
/*!
* Returns the character spacing offset used for the characters of the referenced block
* \return The referenced block character size
*
* \see GetColor, GetFont, GetStyle, GetText, SetCharacterSize
*/
inline float RichTextDrawer::BlockRef::GetCharacterSpacingOffset() const
{
return m_drawer.GetBlockCharacterSpacingOffset(m_blockIndex);
}
/*!
* Returns the character size used for the characters of the referenced block
* \return The referenced block character size
*
* \see GetColor, GetFont, GetStyle, GetText, SetCharacterSize
*/
inline unsigned int RichTextDrawer::BlockRef::GetCharacterSize() const
{
return m_drawer.GetBlockCharacterSize(m_blockIndex);
}
/*!
* Returns the color used for the characters of the referenced block
* \return The referenced block color
*
* \see GetCharacterSize, GetFont, GetStyle, GetText, SetColor
*/
inline Color RichTextDrawer::BlockRef::GetColor() const
{
return m_drawer.GetBlockColor(m_blockIndex);
}
/*!
* Returns the font used for the characters of the referenced block
* \return A reference on the referenced block font
*
* \see GetCharacterSize, GetColor, GetStyle, GetText, SetFont
*/
inline const FontRef& RichTextDrawer::BlockRef::GetFont() const
{
return m_drawer.GetBlockFont(m_blockIndex);
}
/*!
* Returns the line spacing offset used for the characters of the referenced block
* \return The referenced block character size
*
* \see GetColor, GetFont, GetStyle, GetText, SetCharacterSize
*/
inline float RichTextDrawer::BlockRef::GetLineSpacingOffset() const
{
return m_drawer.GetBlockLineSpacingOffset(m_blockIndex);
}
/*!
* Returns the outline color used for the characters of the referenced block
* \return The referenced block outline color
*
* \see GetCharacterSize, GetColor, GetStyle, GetText, SetFont
*/
inline Color RichTextDrawer::BlockRef::GetOutlineColor() const
{
return m_drawer.GetBlockOutlineColor(m_blockIndex);
}
/*!
* Returns the outline thickness used for the characters of the referenced block
* \return The referenced block outline thickness
*
* \see GetCharacterSize, GetColor, GetStyle, GetText, SetFont
*/
inline float RichTextDrawer::BlockRef::GetOutlineThickness() const
{
return m_drawer.GetBlockOutlineThickness(m_blockIndex);
}
/*!
* Returns the style flags used for the characters of the referenced block
* \return The referenced block style flags (see TextStyleFlags)
*
* \see GetCharacterSize, GetColor, GetFont, GetText, SetStyle
*/
inline TextStyleFlags RichTextDrawer::BlockRef::GetStyle() const
{
return m_drawer.GetBlockStyle(m_blockIndex);
}
/*!
* Returns the first glyph index at which starts the referenced block
* \return The first glyph index concerned by this block
*
* \see GetText
*/
inline std::size_t RichTextDrawer::BlockRef::GetFirstGlyphIndex() const
{
return m_drawer.GetBlockFirstGlyphIndex(m_blockIndex);
}
/*!
* Returns the text of the referenced block
* \return The referenced block text
*
* \see GetCharacterSize, GetColor, GetFont, GetStyle, SetText
*/
inline const String& RichTextDrawer::BlockRef::GetText() const
{
return m_drawer.GetBlockText(m_blockIndex);
}
/*!
* Changes the character spacing offset of the referenced block characters
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
*
* \see GetCharacterSpacingOffset, SetColor, SetFont, SetStyle, SetText
*/
inline void RichTextDrawer::BlockRef::SetCharacterSpacingOffset(float offset)
{
m_drawer.SetBlockCharacterSpacingOffset(m_blockIndex, offset);
}
/*!
* Changes the character size of the referenced block characters
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
*
* \see GetCharacterSize, SetColor, SetFont, SetStyle, SetText
*/
inline void RichTextDrawer::BlockRef::SetCharacterSize(unsigned int size)
{
m_drawer.SetBlockCharacterSize(m_blockIndex, size);
}
/*!
* Changes the color of the referenced block characters
* \remark This is the only property that can be changed without forcing a glyph regeneration
*
* \see GetColor, SetCharacterSize, SetFont, SetStyle, SetText
*/
inline void RichTextDrawer::BlockRef::SetColor(Color color)
{
m_drawer.SetBlockColor(m_blockIndex, color);
}
/*!
* Changes the font of the referenced block characters
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
*
* \see GetCharacterSize, SetCharacterSize, SetColor, SetStyle, SetText
*/
inline void RichTextDrawer::BlockRef::SetFont(FontRef font)
{
m_drawer.SetBlockFont(m_blockIndex, std::move(font));
}
/*!
* Changes the line spacing offset of the referenced block characters
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
*
* \see GetLineSpacingOffset, SetColor, SetFont, SetStyle, SetText
*/
inline void RichTextDrawer::BlockRef::SetLineSpacingOffset(float offset)
{
m_drawer.SetBlockLineSpacingOffset(m_blockIndex, offset);
}
/*!
* Changes the outline color of the referenced block characters
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
*
* \see GetCharacterSize, SetCharacterSize, SetColor, SetStyle, SetText
*/
inline void RichTextDrawer::BlockRef::SetOutlineColor(Color color)
{
m_drawer.SetBlockOutlineColor(m_blockIndex, std::move(color));
}
/*!
* Changes the outline thickness of the referenced block characters
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
*
* \see GetCharacterSize, SetCharacterSize, SetColor, SetStyle, SetText
*/
inline void RichTextDrawer::BlockRef::SetOutlineThickness(float thickness)
{
m_drawer.SetBlockOutlineThickness(m_blockIndex, thickness);
}
/*!
* Changes the style flags of the referenced block characters
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
*
* \see GetStyle, SetCharacterSize, SetColor, SetFont, SetText
*/
inline void RichTextDrawer::BlockRef::SetStyle(TextStyleFlags style)
{
m_drawer.SetBlockStyle(m_blockIndex, style);
}
/*!
* Changes the text of the referenced block
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
*
* \see GetText, SetCharacterSize, SetColor, SetFont, SetStyle
*/
inline void RichTextDrawer::BlockRef::SetText(const String& text)
{
m_drawer.SetBlockText(m_blockIndex, text);
}
}
#include <Nazara/Utility/DebugOff.hpp>

View File

@@ -19,70 +19,108 @@ namespace Nz
class NAZARA_UTILITY_API SimpleTextDrawer : public AbstractTextDrawer
{
public:
SimpleTextDrawer();
SimpleTextDrawer(const SimpleTextDrawer& drawer);
SimpleTextDrawer(SimpleTextDrawer&& drawer);
virtual ~SimpleTextDrawer();
inline SimpleTextDrawer();
inline SimpleTextDrawer(const SimpleTextDrawer& drawer);
inline SimpleTextDrawer(SimpleTextDrawer&& drawer);
~SimpleTextDrawer() = default;
void AppendText(const String& str);
inline void AppendText(const String& str);
void Clear();
void Clear() override;
const Recti& GetBounds() const override;
unsigned int GetCharacterSize() const;
const Color& GetColor() const;
Font* GetFont() const;
const Rectf& GetBounds() const override;
inline float GetCharacterSpacingOffset() const;
inline unsigned int GetCharacterSize() const;
inline const Color& GetColor() const;
inline Font* GetFont() const;
Font* GetFont(std::size_t index) const override;
std::size_t GetFontCount() const override;
const Glyph& GetGlyph(std::size_t index) const override;
std::size_t GetGlyphCount() const override;
const Line& GetLine(std::size_t index) const override;
std::size_t GetLineCount() const override;
UInt32 GetStyle() const;
const String& GetText() const;
inline float GetLineHeight() const;
inline float GetLineSpacingOffset() const;
float GetMaxLineWidth() const override;
inline const Color& GetOutlineColor() const;
inline float GetOutlineThickness() const;
inline TextStyleFlags GetStyle() const;
inline const String& GetText() const;
void SetCharacterSize(unsigned int characterSize);
void SetColor(const Color& color);
void SetFont(Font* font);
void SetStyle(UInt32 style);
void SetText(const String& str);
inline void SetCharacterSpacingOffset(float offset);
inline void SetCharacterSize(unsigned int characterSize);
inline void SetColor(const Color& color);
inline void SetFont(Font* font);
inline void SetLineSpacingOffset(float offset);
inline void SetMaxLineWidth(float lineWidth) override;
inline void SetOutlineColor(const Color& color);
inline void SetOutlineThickness(float thickness);
inline void SetStyle(TextStyleFlags style);
inline void SetText(const String& str);
SimpleTextDrawer& operator=(const SimpleTextDrawer& drawer);
SimpleTextDrawer& operator=(SimpleTextDrawer&& drawer);
inline SimpleTextDrawer& operator=(const SimpleTextDrawer& drawer);
inline SimpleTextDrawer& operator=(SimpleTextDrawer&& drawer);
static SimpleTextDrawer Draw(const String& str, unsigned int characterSize, UInt32 style = TextStyle_Regular, const Color& color = Color::White);
static SimpleTextDrawer Draw(Font* font, const String& str, unsigned int characterSize, UInt32 style = TextStyle_Regular, const Color& color = Color::White);
static inline SimpleTextDrawer Draw(const String& str, unsigned int characterSize, TextStyleFlags style = TextStyle_Regular, const Color& color = Color::White);
static inline SimpleTextDrawer Draw(const String& str, unsigned int characterSize, TextStyleFlags style, const Color& color, float outlineThickness, const Color& outlineColor);
static inline SimpleTextDrawer Draw(Font* font, const String& str, unsigned int characterSize, TextStyleFlags style = TextStyle_Regular, const Color& color = Color::White);
static inline SimpleTextDrawer Draw(Font* font, const String& str, unsigned int characterSize, TextStyleFlags style, const Color& color, float outlineThickness, const Color& outlineColor);
private:
inline void AppendNewLine() const;
void AppendNewLine(std::size_t glyphIndex, float glyphPosition) const;
void ClearGlyphs() const;
void ConnectFontSlots();
void DisconnectFontSlots();
inline void ConnectFontSlots();
inline void DisconnectFontSlots();
bool GenerateGlyph(Glyph& glyph, char32_t character, float outlineThickness, bool lineWrap, Nz::Color color, int renderOrder, int* advance) const;
void GenerateGlyphs(const String& text) const;
inline float GetLineHeight(const Font::SizeInfo& sizeInfo) const;
inline void InvalidateColor();
inline void InvalidateGlyphs();
void OnFontAtlasLayerChanged(const Font* font, AbstractImage* oldLayer, AbstractImage* newLayer);
void OnFontInvalidated(const Font* font);
void OnFontRelease(const Font* object);
void UpdateGlyphColor() const;
void UpdateGlyphs() const;
inline bool ShouldLineWrap(float size) const;
inline void UpdateGlyphColor() const;
inline void UpdateGlyphs() const;
static constexpr std::size_t InvalidGlyph = std::numeric_limits<std::size_t>::max();
NazaraSlot(Font, OnFontAtlasChanged, m_atlasChangedSlot);
NazaraSlot(Font, OnFontAtlasLayerChanged, m_atlasLayerChangedSlot);
NazaraSlot(Font, OnFontGlyphCacheCleared, m_glyphCacheClearedSlot);
NazaraSlot(Font, OnFontRelease, m_fontReleaseSlot);
mutable std::size_t m_lastSeparatorGlyph;
mutable std::vector<Glyph> m_glyphs;
mutable std::vector<Line> m_lines;
Color m_color;
Color m_outlineColor;
FontRef m_font;
mutable Rectf m_workingBounds;
mutable Recti m_bounds;
mutable Rectf m_bounds;
String m_text;
TextStyleFlags m_style;
mutable UInt32 m_previousCharacter;
UInt32 m_style;
mutable Vector2ui m_drawPos;
mutable Vector2f m_drawPos;
mutable bool m_colorUpdated;
mutable bool m_glyphUpdated;
mutable float m_lastSeparatorPosition;
float m_characterSpacingOffset;
float m_lineSpacingOffset;
float m_maxLineWidth;
float m_outlineThickness;
unsigned int m_characterSize;
};
}
#include <Nazara/Utility/SimpleTextDrawer.inl>
#endif // NAZARA_SIMPLETEXTDRAWER_HPP

View File

@@ -0,0 +1,385 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Utility module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Utility/SimpleTextDrawer.hpp>
#include <Nazara/Utility/Debug.hpp>
namespace Nz
{
inline SimpleTextDrawer::SimpleTextDrawer() :
m_color(Color::White),
m_outlineColor(Color::Black),
m_style(TextStyle_Regular),
m_colorUpdated(true),
m_glyphUpdated(true),
m_characterSpacingOffset(0.f),
m_lineSpacingOffset(0.f),
m_maxLineWidth(std::numeric_limits<float>::infinity()),
m_outlineThickness(0.f),
m_characterSize(24)
{
SetFont(Font::GetDefault());
}
inline SimpleTextDrawer::SimpleTextDrawer(const SimpleTextDrawer& drawer) :
m_color(drawer.m_color),
m_outlineColor(drawer.m_outlineColor),
m_text(drawer.m_text),
m_style(drawer.m_style),
m_colorUpdated(false),
m_glyphUpdated(false),
m_characterSpacingOffset(drawer.m_characterSpacingOffset),
m_lineSpacingOffset(drawer.m_lineSpacingOffset),
m_maxLineWidth(drawer.m_maxLineWidth),
m_outlineThickness(drawer.m_outlineThickness),
m_characterSize(drawer.m_characterSize)
{
SetFont(drawer.m_font);
}
inline SimpleTextDrawer::SimpleTextDrawer(SimpleTextDrawer&& drawer)
{
operator=(std::move(drawer));
}
inline void SimpleTextDrawer::AppendText(const String& str)
{
m_text.Append(str);
if (m_glyphUpdated)
GenerateGlyphs(str);
}
inline float SimpleTextDrawer::GetCharacterSpacingOffset() const
{
return m_characterSpacingOffset;
}
inline unsigned int SimpleTextDrawer::GetCharacterSize() const
{
return m_characterSize;
}
inline const Color& SimpleTextDrawer::GetColor() const
{
return m_color;
}
inline Font* SimpleTextDrawer::GetFont() const
{
return m_font;
}
inline float SimpleTextDrawer::GetLineHeight() const
{
NazaraAssert(m_font, "SimpleTextDrawer has no font");
return GetLineHeight(m_font->GetSizeInfo(m_characterSize));
}
inline float SimpleTextDrawer::GetLineSpacingOffset() const
{
return m_lineSpacingOffset;
}
inline const Color& SimpleTextDrawer::GetOutlineColor() const
{
return m_outlineColor;
}
inline float SimpleTextDrawer::GetOutlineThickness() const
{
return m_outlineThickness;
}
inline TextStyleFlags SimpleTextDrawer::GetStyle() const
{
return m_style;
}
inline const String& SimpleTextDrawer::GetText() const
{
return m_text;
}
inline void SimpleTextDrawer::SetCharacterSpacingOffset(float offset)
{
if (m_characterSpacingOffset != offset)
{
m_characterSpacingOffset = offset;
InvalidateGlyphs();
}
}
inline void SimpleTextDrawer::SetCharacterSize(unsigned int characterSize)
{
if (m_characterSize != characterSize)
{
m_characterSize = characterSize;
InvalidateGlyphs();
}
}
inline void SimpleTextDrawer::SetColor(const Color& color)
{
if (m_color != color)
{
m_color = color;
InvalidateColor();
}
}
inline void SimpleTextDrawer::SetFont(Font* font)
{
if (m_font != font)
{
m_font = font;
if (m_font)
ConnectFontSlots();
else
DisconnectFontSlots();
InvalidateGlyphs();
}
}
inline void SimpleTextDrawer::SetLineSpacingOffset(float offset)
{
if (m_lineSpacingOffset != offset)
{
m_lineSpacingOffset = offset;
InvalidateGlyphs();
}
}
inline void SimpleTextDrawer::SetMaxLineWidth(float lineWidth)
{
if (m_maxLineWidth != lineWidth)
{
NazaraAssert(lineWidth > 0.f, "Max line width must be positive");
m_maxLineWidth = lineWidth;
InvalidateGlyphs();
}
}
inline void SimpleTextDrawer::SetOutlineColor(const Color& color)
{
if (m_outlineColor != color)
{
m_outlineColor = color;
InvalidateColor();
}
}
inline void SimpleTextDrawer::SetOutlineThickness(float thickness)
{
if (m_outlineThickness != thickness)
{
NazaraAssert(thickness >= 0.f, "Thickness must be zero or positive");
m_outlineThickness = thickness;
InvalidateGlyphs();
}
}
inline void SimpleTextDrawer::SetStyle(TextStyleFlags style)
{
if (m_style != style)
{
m_style = style;
InvalidateGlyphs();
}
}
inline void SimpleTextDrawer::SetText(const String& str)
{
if (m_text != str)
{
m_text = str;
InvalidateGlyphs();
}
}
inline SimpleTextDrawer& SimpleTextDrawer::operator=(const SimpleTextDrawer& drawer)
{
m_characterSize = drawer.m_characterSize;
m_characterSpacingOffset = drawer.m_characterSpacingOffset;
m_color = drawer.m_color;
m_lineSpacingOffset = drawer.m_lineSpacingOffset;
m_maxLineWidth = drawer.m_maxLineWidth;
m_outlineColor = drawer.m_outlineColor;
m_outlineThickness = drawer.m_outlineThickness;
m_style = drawer.m_style;
m_text = drawer.m_text;
SetFont(drawer.m_font);
InvalidateGlyphs();
return *this;
}
inline SimpleTextDrawer& SimpleTextDrawer::operator=(SimpleTextDrawer&& drawer)
{
DisconnectFontSlots();
m_bounds = std::move(drawer.m_bounds);
m_colorUpdated = std::move(drawer.m_colorUpdated);
m_characterSize = std::move(drawer.m_characterSize);
m_characterSpacingOffset = drawer.m_characterSpacingOffset;
m_color = std::move(drawer.m_color);
m_glyphs = std::move(drawer.m_glyphs);
m_glyphUpdated = std::move(drawer.m_glyphUpdated);
m_font = std::move(drawer.m_font);
m_lineSpacingOffset = drawer.m_lineSpacingOffset;
m_maxLineWidth = drawer.m_maxLineWidth;
m_outlineColor = std::move(drawer.m_outlineColor);
m_outlineThickness = std::move(drawer.m_outlineThickness);
m_style = std::move(drawer.m_style);
m_text = std::move(drawer.m_text);
// Update slot pointers (TODO: Improve the way of doing this)
if (m_font)
{
drawer.DisconnectFontSlots();
ConnectFontSlots();
}
return *this;
}
inline SimpleTextDrawer SimpleTextDrawer::Draw(const String& str, unsigned int characterSize, TextStyleFlags style, const Color& color)
{
SimpleTextDrawer drawer;
drawer.SetCharacterSize(characterSize);
drawer.SetColor(color);
drawer.SetStyle(style);
drawer.SetText(str);
return drawer;
}
inline SimpleTextDrawer SimpleTextDrawer::Draw(const String& str, unsigned int characterSize, TextStyleFlags style, const Color& color, float outlineThickness, const Color& outlineColor)
{
SimpleTextDrawer drawer;
drawer.SetCharacterSize(characterSize);
drawer.SetColor(color);
drawer.SetOutlineColor(outlineColor);
drawer.SetOutlineThickness(outlineThickness);
drawer.SetStyle(style);
drawer.SetText(str);
return drawer;
}
inline SimpleTextDrawer SimpleTextDrawer::Draw(Font* font, const String& str, unsigned int characterSize, TextStyleFlags style, const Color& color)
{
SimpleTextDrawer drawer;
drawer.SetCharacterSize(characterSize);
drawer.SetColor(color);
drawer.SetFont(font);
drawer.SetStyle(style);
drawer.SetText(str);
return drawer;
}
inline SimpleTextDrawer SimpleTextDrawer::Draw(Font* font, const String& str, unsigned int characterSize, TextStyleFlags style, const Color& color, float outlineThickness, const Color& outlineColor)
{
SimpleTextDrawer drawer;
drawer.SetCharacterSize(characterSize);
drawer.SetColor(color);
drawer.SetFont(font);
drawer.SetOutlineColor(outlineColor);
drawer.SetOutlineThickness(outlineThickness);
drawer.SetStyle(style);
drawer.SetText(str);
return drawer;
}
inline void SimpleTextDrawer::AppendNewLine() const
{
AppendNewLine(InvalidGlyph, 0);
}
inline void SimpleTextDrawer::ConnectFontSlots()
{
m_atlasChangedSlot.Connect(m_font->OnFontAtlasChanged, this, &SimpleTextDrawer::OnFontInvalidated);
m_atlasLayerChangedSlot.Connect(m_font->OnFontAtlasLayerChanged, this, &SimpleTextDrawer::OnFontAtlasLayerChanged);
m_fontReleaseSlot.Connect(m_font->OnFontRelease, this, &SimpleTextDrawer::OnFontRelease);
m_glyphCacheClearedSlot.Connect(m_font->OnFontGlyphCacheCleared, this, &SimpleTextDrawer::OnFontInvalidated);
}
inline void SimpleTextDrawer::DisconnectFontSlots()
{
m_atlasChangedSlot.Disconnect();
m_atlasLayerChangedSlot.Disconnect();
m_fontReleaseSlot.Disconnect();
m_glyphCacheClearedSlot.Disconnect();
}
inline float SimpleTextDrawer::GetLineHeight(const Font::SizeInfo& sizeInfo) const
{
return float(sizeInfo.lineHeight) + m_lineSpacingOffset;
}
inline void SimpleTextDrawer::InvalidateColor()
{
m_colorUpdated = false;
}
inline void SimpleTextDrawer::InvalidateGlyphs()
{
m_glyphUpdated = false;
}
inline bool SimpleTextDrawer::ShouldLineWrap(float size) const
{
if (m_lines.back().glyphIndex > m_glyphs.size())
return false;
return m_lines.back().bounds.GetMaximum().x + size > m_maxLineWidth;
}
inline void SimpleTextDrawer::UpdateGlyphColor() const
{
if (m_outlineThickness > 0.f)
{
for (std::size_t glyphIndex = 0; glyphIndex < m_glyphs.size(); ++glyphIndex)
{
Glyph& glyph = m_glyphs[glyphIndex];
if (glyphIndex % 2 == 0)
glyph.color = m_outlineColor;
else
glyph.color = m_color;
}
}
else
{
for (Glyph& glyph : m_glyphs)
glyph.color = m_color;
}
m_colorUpdated = true;
}
inline void SimpleTextDrawer::UpdateGlyphs() const
{
NazaraAssert(m_font && m_font->IsValid(), "Invalid font");
ClearGlyphs();
GenerateGlyphs(m_text);
}
}
#include <Nazara/Utility/DebugOff.hpp>