Merge remote-tracking branch 'refs/remotes/origin/master' into culling

This commit is contained in:
Lynix
2016-11-23 14:07:52 +01:00
100 changed files with 2585 additions and 1294 deletions

View File

@@ -1,10 +0,0 @@
// Copyright (C) 2015 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
/*!
* \ingroup core
* \class Nz::AbstractLogger
* \brief Logger interface
*/

View File

@@ -22,6 +22,7 @@ namespace Nz
template<typename F, typename Tuple> decltype(auto) Apply(F&& fn, Tuple&& t);
template<typename O, typename F, typename Tuple> decltype(auto) Apply(O& object, F&& fn, Tuple&& t);
template<typename T> constexpr std::size_t BitCount();
template<typename T> ByteArray ComputeHash(HashType hash, const T& v);
template<typename T> ByteArray ComputeHash(AbstractHash* hash, const T& v);
template<typename T, std::size_t N> constexpr std::size_t CountOf(T(&name)[N]) noexcept;

View File

@@ -11,6 +11,7 @@
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Stream.hpp>
#include <climits>
#include <Nazara/Core/Debug.hpp>
namespace Nz
@@ -70,6 +71,17 @@ namespace Nz
return Detail::ApplyImplMethod(object, std::forward<F>(fn), std::forward<Tuple>(t), std::make_index_sequence<tSize>());
}
/*!
* \ingroup core
* \brief Returns the number of bits occupied by the type T
* \return Number of bits occupied by the type
*/
template<typename T>
constexpr std::size_t BitCount()
{
return CHAR_BIT * sizeof(T);
}
/*!
* \ingroup core
* \brief Computes the hash of a hashable object

View File

@@ -8,6 +8,7 @@
#define NAZARA_BITSET_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/String.hpp>
#include <limits>
#include <memory>
@@ -24,6 +25,7 @@ namespace Nz
public:
class Bit;
using PointerSequence = std::pair<const void*, std::size_t>; //< Start pointer, bit offset
Bitset();
explicit Bitset(std::size_t bitCount, bool val);
@@ -35,6 +37,8 @@ namespace Nz
Bitset(Bitset&& bitset) noexcept = default;
~Bitset() noexcept = default;
template<typename T> void AppendBits(T bits, std::size_t bitCount);
void Clear() noexcept;
std::size_t Count() const;
void Flip();
@@ -47,6 +51,9 @@ namespace Nz
std::size_t GetCapacity() const;
std::size_t GetSize() const;
PointerSequence Read(const void* ptr, std::size_t bitCount);
PointerSequence Read(const PointerSequence& sequence, std::size_t bitCount);
void PerformsAND(const Bitset& a, const Bitset& b);
void PerformsNOT(const Bitset& a);
void PerformsOR(const Bitset& a, const Bitset& b);
@@ -60,6 +67,8 @@ namespace Nz
void Reset();
void Reset(std::size_t bit);
void Reverse();
void Set(bool val = true);
void Set(std::size_t bit, bool val = true);
void SetBlock(std::size_t i, Block block);
@@ -102,9 +111,11 @@ namespace Nz
Bitset& operator^=(const Bitset& bitset);
static constexpr Block fullBitMask = std::numeric_limits<Block>::max();
static constexpr std::size_t bitsPerBlock = std::numeric_limits<Block>::digits;
static constexpr std::size_t bitsPerBlock = BitCount<Block>();
static constexpr std::size_t npos = std::numeric_limits<std::size_t>::max();
static Bitset FromPointer(const void* ptr, std::size_t bitCount, PointerSequence* sequence = nullptr);
private:
std::size_t FindFirstFrom(std::size_t blockIndex) const;
Block GetLastBlockMask() const;
@@ -154,6 +165,9 @@ namespace Nz
Block m_mask;
};
template<typename Block, class Allocator>
std::ostream& operator<<(std::ostream& out, const Bitset<Block, Allocator>& bitset);
template<typename Block, class Allocator>
bool operator==(const Bitset<Block, Allocator>& lhs, const Nz::Bitset<Block, Allocator>& rhs);

View File

@@ -6,7 +6,6 @@
#include <Nazara/Core/Error.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <cstdlib>
#include <limits>
#include <utility>
#include <Nazara/Core/Debug.hpp>
@@ -122,13 +121,13 @@ namespace Nz
{
if (sizeof(T) <= sizeof(Block))
{
m_bitCount = std::numeric_limits<T>::digits;
m_bitCount = BitCount<T>();
m_blocks.push_back(static_cast<Block>(value));
}
else
{
// Note: I was kinda tired when I wrote this, there's probably a much easier method than checking bits to write bits
for (std::size_t bitPos = 0; bitPos < std::numeric_limits<T>::digits; bitPos++)
for (std::size_t bitPos = 0; bitPos < BitCount<T>(); bitPos++)
{
if (value & (T(1U) << bitPos))
UnboundedSet(bitPos, true);
@@ -137,11 +136,63 @@ namespace Nz
}
/*!
* \brief Clears the content of the bitset, GetSize() is now equals to 0
* \brief Appends bits to the bitset
*
* \remark The memory allocated is not released
* This function extends the bitset with bits extracted from an integer value
*
* \param bits An integer value from where bits will be extracted
* \param bitCount Number of bits to extract from the value
*
* \remark This function does not require bitCount to be lower or equal to the number of bits of T, thus
* reading 32 bits from a UInt8 will work (by extracting the first 8 bits values and appending 24 zeros afterneath).
*
* \see AppendBits
* \see Read
*/
template<typename Block, class Allocator>
template<typename T>
void Bitset<Block, Allocator>::AppendBits(T bits, std::size_t bitCount)
{
std::size_t bitShift = m_bitCount % bitsPerBlock;
m_bitCount += bitCount;
if (bitShift != 0)
{
std::size_t remainingBits = bitsPerBlock - bitShift;
m_blocks.back() |= Block(bits) << bitShift;
bits >>= bitsPerBlock - bitShift;
bitCount -= std::min(remainingBits, bitCount);
}
if (bitCount > 0)
{
std::size_t blockCount = ComputeBlockCount(bitCount);
for (std::size_t block = 0; block < blockCount - 1; ++block)
{
m_blocks.push_back(static_cast<Block>(bits));
bits = (BitCount<Block>() < BitCount<T>()) ? bits >> BitCount<Block>() : 0U;
bitCount -= BitCount<Block>();
}
// For the last iteration, mask out the bits we don't want
std::size_t remainingBits = bitCount;
bits &= ((Block(1U) << remainingBits) - 1U);
m_blocks.push_back(static_cast<Block>(bits));
}
}
/*!
* \brief Clears the content of the bitset
*
* This function clears the bitset content, resetting its bit and block count at zero.
*
* \remark This does not changes the bits values to zero but empties the bitset, to reset the bits use the Reset() function
* \remark This call does not changes the bitset capacity
*
* \see Reset()
*/
template<typename Block, class Allocator>
void Bitset<Block, Allocator>::Clear() noexcept
{
@@ -151,9 +202,9 @@ namespace Nz
/*!
* \brief Counts the number of bits set to 1
*
* \return Number of bits set to 1
*/
template<typename Block, class Allocator>
std::size_t Bitset<Block, Allocator>::Count() const
{
@@ -169,8 +220,9 @@ namespace Nz
/*!
* \brief Flips each bit of the bitset
*
* This function flips every bit of the bitset, which means every '1' turns into a '0' and conversely.
*/
template<typename Block, class Allocator>
void Bitset<Block, Allocator>::Flip()
{
@@ -182,9 +234,9 @@ namespace Nz
/*!
* \brief Finds the first bit set to one in the bitset
* \return Index of the first bit
*
* \return The 0-based index of the first bit enabled
*/
template<typename Block, class Allocator>
std::size_t Bitset<Block, Allocator>::FindFirst() const
{
@@ -192,14 +244,14 @@ namespace Nz
}
/*!
* \brief Finds the next bit set to one in the bitset
* \return Index of the next bit if exists or npos
* \brief Finds the next enabled in the bitset
*
* \param bit Index of the bit, the search begin with bit + 1
* \param bit Index of the last bit found, which will not be treated by this function
*
* \remark Produce a NazaraAssert if bit is greather than number of bits in bitset
* \return Index of the next enabled bit or npos if all the following bits are disabled
*
* \remark This function is typically used in for-loops to iterate on bits
*/
template<typename Block, class Allocator>
std::size_t Bitset<Block, Allocator>::FindNext(std::size_t bit) const
{
@@ -275,6 +327,76 @@ namespace Nz
return m_bitCount;
}
/*!
* \brief Read a byte sequence into a bitset
*
* This function extends the bitset with bits read from a byte sequence
*
* \param ptr A pointer to the start of the byte sequence
* \param bitCount Number of bits to read from the byte sequence
*
* \returns A pointer to the next byte to read along with the next bit index (useful when reading multiple times)
*
* \remark For technical reasons, ceil(bitCount / 8) bytes from the sequence will always be read (even with non-multiple-of-8 bitCount)
*
* \see AppendBits
* \see Read
*/
template<typename Block, class Allocator>
typename Bitset<Block, Allocator>::PointerSequence Bitset<Block, Allocator>::Read(const void* ptr, std::size_t bitCount)
{
return Read(PointerSequence(ptr, 0U), bitCount);
}
/*!
* \brief Read a byte sequence into a bitset
*
* This function extends the bitset with bits read from a pointer sequence (made of a pointer and a bit index)
*
* \param sequence A pointer sequence to the start of the byte sequence
* \param bitCount Number of bits to read from the byte sequence
*
* \returns A pointer to the next byte to read along with the next bit index (useful when reading multiple times)
*
* \remark For technical reasons, ceil(bitCount / 8) bytes from the sequence will always be read (even with non-multiple-of-8 bitCount)
*
* \see AppendBits
* \see Read
*/
template<typename Block, class Allocator>
typename Bitset<Block, Allocator>::PointerSequence Bitset<Block, Allocator>::Read(const PointerSequence& sequence, std::size_t bitCount)
{
NazaraAssert(sequence.first, "Invalid pointer sequence");
NazaraAssert(sequence.second < 8, "Invalid next bit index (must be < 8)");
std::size_t totalBitCount = sequence.second + bitCount;
const UInt8* u8Ptr = static_cast<const UInt8*>(sequence.first);
const UInt8* endPtr = u8Ptr + ((totalBitCount != 0) ? (totalBitCount - 1) / 8 : 0);
const UInt8* nextPtr = endPtr + ((totalBitCount % 8 != 0) ? 0 : 1);
// Read the first block apart to apply a mask on the first byte if necessary
if (sequence.second != 0)
{
UInt8 mask = ~((1U << sequence.second) - 1U);
std::size_t readCount = std::min(bitCount, 8 - sequence.second);
AppendBits(Block(*u8Ptr++ & mask) >> sequence.second, readCount);
bitCount -= readCount;
}
// And then read the remaining bytes
while (u8Ptr <= endPtr)
{
std::size_t bitToRead = std::min<std::size_t>(bitCount, 8);
AppendBits(*u8Ptr++, bitToRead);
bitCount -= bitToRead;
}
// Returns informations to continue reading
return PointerSequence(nextPtr, totalBitCount % 8);
}
/*!
* \brief Performs the "AND" operator between two bitsets
*
@@ -289,15 +411,17 @@ namespace Nz
{
std::pair<std::size_t, std::size_t> minmax = std::minmax(a.GetBlockCount(), b.GetBlockCount());
// We reinitialise our blocks with zero
m_blocks.clear();
m_blocks.resize(minmax.second, 0U);
m_blocks.resize(minmax.second);
m_bitCount = std::max(a.GetSize(), b.GetSize());
// In case of the "AND", we can stop with the smallest size (because x & 0 = 0)
for (std::size_t i = 0; i < minmax.first; ++i)
m_blocks[i] = a.GetBlock(i) & b.GetBlock(i);
// And then reset every other block to zero
for (std::size_t i = minmax.first; i < minmax.second; ++i)
m_blocks[i] = 0U;
ResetExtraBits();
}
@@ -458,6 +582,30 @@ namespace Nz
Set(bit, false);
}
/*!
* \brief Reverse the order of bits in a bitset
*
* Reverse the order of bits in the bitset (first bit swap with the last one, etc.)
*/
template<typename Block, class Allocator>
void Bitset<Block, Allocator>::Reverse()
{
if (m_bitCount == 0)
return;
std::size_t i = 0;
std::size_t j = m_bitCount - 1;
while (i < j)
{
bool bit1 = Test(i);
bool bit2 = Test(j);
Set(i++, bit2);
Set(j--, bit1);
}
}
/*!
* \brief Sets the bitset to val
*
@@ -535,27 +683,28 @@ namespace Nz
return;
}
auto div = std::lldiv(pos, bitsPerBlock);
if (div.rem != 0)
std::size_t blockShift = pos / bitsPerBlock;
std::size_t remainder = pos % bitsPerBlock;
if (remainder != 0)
{
std::size_t lastIndex = m_blocks.size() - 1;
std::size_t remaining = bitsPerBlock - div.rem;
std::size_t remaining = bitsPerBlock - remainder;
for (std::size_t i = lastIndex - div.quot; i > 0; --i)
m_blocks[i + div.quot] = (m_blocks[i] << div.rem) | (m_blocks[i - 1] >> remaining);
for (std::size_t i = lastIndex - blockShift; i > 0; --i)
m_blocks[i + blockShift] = (m_blocks[i] << remainder) | (m_blocks[i - 1] >> remaining);
m_blocks[div.quot] = m_blocks[0] << div.rem;
m_blocks[blockShift] = m_blocks[0] << remainder;
std::fill_n(m_blocks.begin(), div.quot, Block(0));
std::fill_n(m_blocks.begin(), blockShift, Block(0));
}
else
{
for (auto it = m_blocks.rbegin(); it != m_blocks.rend(); ++it)
{
if (static_cast<std::size_t>(std::distance(m_blocks.rbegin(), it) + div.quot) < m_blocks.size())
if (static_cast<std::size_t>(std::distance(m_blocks.rbegin(), it) + blockShift) < m_blocks.size())
{
auto shiftedIt = it;
std::advance(shiftedIt, div.quot);
std::advance(shiftedIt, blockShift);
*it = *shiftedIt;
}
@@ -588,27 +737,28 @@ namespace Nz
return;
}
auto div = std::lldiv(pos, bitsPerBlock);
if (div.rem != 0)
std::size_t blockShift = pos / bitsPerBlock;
std::size_t remainder = pos % bitsPerBlock;
if (remainder != 0)
{
std::size_t lastIndex = m_blocks.size() - 1;
std::size_t remaining = bitsPerBlock - div.rem;
std::size_t remaining = bitsPerBlock - remainder;
for (std::size_t i = div.quot; i < lastIndex; ++i)
m_blocks[i - div.quot] = (m_blocks[i] >> div.rem) | (m_blocks[i + 1] << remaining);
for (std::size_t i = blockShift; i < lastIndex; ++i)
m_blocks[i - blockShift] = (m_blocks[i] >> remainder) | (m_blocks[i + 1] << remaining);
m_blocks[lastIndex - div.quot] = m_blocks[lastIndex] >> div.rem;
m_blocks[lastIndex - blockShift] = m_blocks[lastIndex] >> remainder;
std::fill_n(m_blocks.begin() + (m_blocks.size() - div.quot), div.quot, Block(0));
std::fill_n(m_blocks.begin() + (m_blocks.size() - blockShift), blockShift, Block(0));
}
else
{
for (auto it = m_blocks.begin(); it != m_blocks.end(); ++it)
{
if (static_cast<std::size_t>(std::distance(m_blocks.begin(), it) + div.quot) < m_blocks.size())
if (static_cast<std::size_t>(std::distance(m_blocks.begin(), it) + blockShift) < m_blocks.size())
{
auto shiftedIt = it;
std::advance(shiftedIt, div.quot);
std::advance(shiftedIt, blockShift);
*it = *shiftedIt;
}
@@ -716,7 +866,7 @@ namespace Nz
{
static_assert(std::is_integral<T>() && std::is_unsigned<T>(), "T must be a unsigned integral type");
NazaraAssert(m_bitCount <= std::numeric_limits<T>::digits, "Bit count cannot be greater than T bit count");
NazaraAssert(m_bitCount <= BitCount<T>(), "Bit count cannot be greater than T bit count");
T value = 0;
for (std::size_t i = 0; i < m_blocks.size(); ++i)
@@ -989,13 +1139,41 @@ namespace Nz
return *this;
}
/*!
* \brief Builds a bitset from a byte sequence
*
* This function builds a bitset using a byte sequence by reading bitCount bits from it
*
* \param ptr A pointer to the start of the byte sequence
* \param bitCount Number of bits to read from the byte sequence
* \param sequence Optional data to pass to a next call to Read
*
* \return The constructed bitset
*
* \remark For technical reasons, ceil(bitCount / 8) bytes from the sequence will always be read (even with non-multiple-of-8 bitCount)
*
* \see AppendBits
* \see Read
*/
template<typename Block, class Allocator>
Bitset<Block, Allocator> Bitset<Block, Allocator>::FromPointer(const void* ptr, std::size_t bitCount, PointerSequence* sequence)
{
Bitset bitset;
if (sequence)
*sequence = bitset.Read(ptr, bitCount);
else
bitset.Read(ptr, bitCount);
return bitset;
}
/*!
* \brief Finds the position of the first bit set to true after the blockIndex
* \return The position of the bit
*
* \param blockIndex Index of the block
*/
template<typename Block, class Allocator>
std::size_t Bitset<Block, Allocator>::FindFirstFrom(std::size_t blockIndex) const
{
@@ -1124,7 +1302,7 @@ namespace Nz
template<typename Block, class Allocator>
bool Bitset<Block, Allocator>::Bit::Test() const
{
return m_block & m_mask;
return (m_block & m_mask) != 0;
}
/*!
@@ -1269,6 +1447,14 @@ namespace Nz
return *this;
}
template<typename Block, class Allocator>
std::ostream& operator<<(std::ostream& out, const Bitset<Block, Allocator>& bitset)
{
return out << bitset.ToString();
}
/*!
* \brief Compares two bitsets
* \return true if the two bitsets are the same

View File

@@ -88,7 +88,7 @@ namespace Nz
inline void ShrinkToFit();
inline void Swap(ByteArray& other);
inline String ToHex() const;
String ToHex() const;
inline String ToString() const;
// STL interface

View File

@@ -465,22 +465,6 @@ namespace Nz
m_array.swap(other.m_array);
}
/*!
* \brief Gives a string representation in base 16
* \return String in base 16
*/
inline String ByteArray::ToHex() const
{
std::size_t length = m_array.size() * 2;
String hexOutput(length, '\0');
for (std::size_t i = 0; i < m_array.size(); ++i)
std::sprintf(&hexOutput[i * 2], "%02x", m_array[i]);
return hexOutput;
}
/*!
* \brief Gives a string representation
* \return String where each byte is converted to char

View File

@@ -60,10 +60,10 @@ namespace Nz
{
struct UserdataValue
{
UserdataValue(Destructor Destructor, void* value) :
UserdataValue(Destructor func, void* ud) :
counter(1),
destructor(Destructor),
ptr(value)
destructor(func),
ptr(ud)
{
}

View File

@@ -87,7 +87,7 @@ namespace Nz
struct SpriteChain_XYZ_Color_UV
{
const VertexStruct_XYZ_Color_UV* vertices;
unsigned int spriteCount;
std::size_t spriteCount;
};
struct BatchedSpriteEntry
@@ -160,7 +160,7 @@ namespace Nz
const Material* material;
};
typedef std::vector<unsigned int> TransparentModelContainer;
typedef std::vector<std::size_t> TransparentModelContainer;
struct Layer
{

View File

@@ -36,10 +36,10 @@ namespace Nz
~ParticleDeclaration();
void DisableComponent(ParticleComponent component);
void EnableComponent(ParticleComponent component, ComponentType type, unsigned int offset);
void EnableComponent(ParticleComponent component, ComponentType type, std::size_t offset);
void GetComponent(ParticleComponent component, bool* enabled, ComponentType* type, unsigned int* offset) const;
unsigned int GetStride() const;
void GetComponent(ParticleComponent component, bool* enabled, ComponentType* type, std::size_t* offset) const;
std::size_t GetStride() const;
void SetStride(unsigned int stride);
@@ -60,7 +60,7 @@ namespace Nz
{
ComponentType type;
bool enabled = false;
unsigned int offset;
std::size_t offset;
/*
** -Lynix:
@@ -71,7 +71,7 @@ namespace Nz
};
std::array<Component, ParticleComponent_Max + 1> m_components;
unsigned int m_stride;
std::size_t m_stride;
static std::array<ParticleDeclaration, ParticleLayout_Max + 1> s_declarations;
static ParticleDeclarationLibrary::LibraryMap s_library;

View File

@@ -28,12 +28,12 @@ namespace Nz
void EnableLagCompensation(bool enable);
unsigned int GetEmissionCount() const;
std::size_t GetEmissionCount() const;
float GetEmissionRate() const;
bool IsLagCompensationEnabled() const;
void SetEmissionCount(unsigned int count);
void SetEmissionCount(std::size_t count);
void SetEmissionRate(float rate);
ParticleEmitter& operator=(const ParticleEmitter& emitter) = default;
@@ -49,7 +49,7 @@ namespace Nz
bool m_lagCompensationEnabled;
mutable float m_emissionAccumulator;
float m_emissionRate;
unsigned int m_emissionCount;
std::size_t m_emissionCount;
};
}

View File

@@ -45,11 +45,11 @@ namespace Nz
void* GenerateParticles(unsigned int count);
const ParticleDeclarationConstRef& GetDeclaration() const;
unsigned int GetMaxParticleCount() const;
unsigned int GetParticleCount() const;
unsigned int GetParticleSize() const;
std::size_t GetMaxParticleCount() const;
std::size_t GetParticleCount() const;
std::size_t GetParticleSize() const;
void KillParticle(unsigned int index);
void KillParticle(std::size_t index);
void KillParticles();
void RemoveController(ParticleController* controller);
@@ -81,6 +81,9 @@ namespace Nz
};
std::set<unsigned int, std::greater<unsigned int>> m_dyingParticles;
std::size_t m_maxParticleCount;
std::size_t m_particleCount;
std::size_t m_particleSize;
mutable std::vector<UInt8> m_buffer;
std::vector<ParticleControllerRef> m_controllers;
std::vector<EmitterEntry> m_emitters;
@@ -88,9 +91,6 @@ namespace Nz
ParticleDeclarationConstRef m_declaration;
ParticleRendererRef m_renderer;
bool m_processing;
unsigned int m_maxParticleCount;
unsigned int m_particleCount;
unsigned int m_particleSize;
};
}

View File

@@ -23,7 +23,7 @@ namespace Nz
// Then the component that are interesting
bool enabled;
ComponentType type;
unsigned int offset;
std::size_t offset;
m_declaration->GetComponent(component, &enabled, &type, &offset);
if (enabled)
@@ -54,7 +54,7 @@ namespace Nz
// Then the component that are interesting
bool enabled;
ComponentType type;
unsigned int offset;
std::size_t offset;
m_declaration->GetComponent(component, &enabled, &type, &offset);
if (enabled)

View File

@@ -29,7 +29,7 @@ namespace Nz
static AbstractRenderTechnique* GetByName(const String& name, int* techniqueRanking = nullptr);
static AbstractRenderTechnique* GetByRanking(int maxRanking, int* techniqueRanking = nullptr);
static unsigned int GetCount();
static std::size_t GetCount();
static void Register(const String& name, int ranking, RenderTechniqueFactory factory);

View File

@@ -47,9 +47,11 @@ namespace Nz
inline void SetCornerColor(RectCorner corner, const Color& color);
inline void SetDefaultMaterial();
inline void SetMaterial(MaterialRef material, bool resizeSprite = true);
bool SetMaterial(String materialName, bool resizeSprite = true);
inline void SetOrigin(const Vector3f& origin);
inline void SetSize(const Vector2f& size);
inline void SetSize(float sizeX, float sizeY);
bool SetTexture(String textureName, bool resizeSprite = true);
inline void SetTexture(TextureRef texture, bool resizeSprite = true);
inline void SetTextureCoords(const Rectf& coords);
inline void SetTextureRect(const Rectui& rect);

View File

@@ -184,12 +184,11 @@ namespace Nz
}
/*!
* \brief Sets the material of the sprite
* \brief Changes the material of the sprite
*
* \param material Material for the sprite
* \param resizeSprite Should sprite be resized to the material size (diffuse map)
* \param resizeSprite Should the sprite be resized to the texture size?
*/
inline void Sprite::SetMaterial(MaterialRef material, bool resizeSprite)
{
m_material = std::move(material);
@@ -249,16 +248,19 @@ namespace Nz
/*!
* \brief Sets the texture of the sprite
*
* Assign a texture to the sprite material
*
* \param texture Texture for the sprite
* \param resizeSprite Should sprite be resized to the texture size
* \param resizeSprite Should the sprite be resized to the texture size?
*
* \remark The sprite material gets copied to prevent accidentally changing other drawable materials
*/
inline void Sprite::SetTexture(TextureRef texture, bool resizeSprite)
{
if (!m_material)
SetDefaultMaterial();
else if (m_material->GetReferenceCount() > 1)
m_material = Material::New(*m_material); // Copie
m_material = Material::New(*m_material); // Copy the material
if (resizeSprite && texture && texture->IsValid())
SetSize(Vector2f(Vector2ui(texture->GetSize())));

View File

@@ -37,7 +37,7 @@ namespace Nz
{
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*/ 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);

View File

@@ -147,10 +147,10 @@ namespace Nz
template<typename T>
//TODO: Mark as constexpr when supported by all major compilers
/*constexpr*/ inline T CountBits(T value)
/*constexpr*/ inline std::size_t CountBits(T value)
{
// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
unsigned int count = 0;
std::size_t count = 0;
while (value)
{
value &= value - 1;

View File

@@ -17,11 +17,11 @@ namespace Nz
{
/*!
* \ingroup math
* \ingroup math
* \class Nz::EulerAngles
* \brief Math class that represents an Euler angle. Those describe a rotation transformation by rotating an object on its various axes in specified amounts per axis, and a specified axis order
*
* \remark Rotation are "left-handed", it means that you take your left hand, put your thumb finger in the direction you want and you other fingers represent the way of rotating
* \remark Rotation are "right-handed", it means that you take your right hand, put your thumb finger in the direction you want and you other fingers represent the way of rotating
*/
/*!
@@ -197,6 +197,7 @@ namespace Nz
template<typename T>
Quaternion<T> EulerAngles<T>::ToQuaternion() const
{
// XYZ
T c1 = std::cos(ToRadians(yaw) / F(2.0));
T c2 = std::cos(ToRadians(roll) / F(2.0));
T c3 = std::cos(ToRadians(pitch) / F(2.0));

View File

@@ -714,10 +714,10 @@ namespace Nz
#endif
Quaternion interpolated;
interpolated.w = Lerp(from.w, to.w, interpolation);
interpolated.x = Lerp(from.x, to.x, interpolation);
interpolated.y = Lerp(from.y, to.y, interpolation);
interpolated.z = Lerp(from.z, to.z, interpolation);
interpolated.w = Nz::Lerp(from.w, to.w, interpolation);
interpolated.x = Nz::Lerp(from.x, to.x, interpolation);
interpolated.y = Nz::Lerp(from.y, to.y, interpolation);
interpolated.z = Nz::Lerp(from.z, to.z, interpolation);
return interpolated;
}

View File

@@ -125,6 +125,33 @@ namespace Nz
private:
std::vector<cpShape*> CreateShapes(RigidBody2D* body) const override;
};
class SegmentCollider2D;
using SegmentCollider2DConstRef = ObjectRef<const SegmentCollider2D>;
using SegmentCollider2DRef = ObjectRef<SegmentCollider2D>;
class NAZARA_PHYSICS2D_API SegmentCollider2D : public Collider2D
{
public:
inline SegmentCollider2D(const Vector2f& first, const Vector2f& second, float thickness = 1.f);
float ComputeInertialMatrix(float mass) const override;
inline const Vector2f& GetFirstPoint() const;
inline float GetLength() const;
inline const Vector2f& GetSecondPoint() const;
ColliderType2D GetType() const override;
template<typename... Args> static SegmentCollider2DRef New(Args&&... args);
private:
std::vector<cpShape*> CreateShapes(RigidBody2D* body) const override;
Vector2f m_first;
Vector2f m_second;
float m_thickness;
};
}
#include <Nazara/Physics2D/Collider2D.inl>

View File

@@ -49,6 +49,36 @@ namespace Nz
return object.release();
}
SegmentCollider2D::SegmentCollider2D(const Vector2f& first, const Vector2f& second, float thickness) :
m_first(first),
m_second(second),
m_thickness(thickness)
{
}
inline const Vector2f& SegmentCollider2D::GetFirstPoint() const
{
return m_first;
}
inline float SegmentCollider2D::GetLength() const
{
return m_first.Distance(m_second);
}
inline const Vector2f& SegmentCollider2D::GetSecondPoint() const
{
return m_second;
}
template<typename... Args>
SegmentCollider2DRef SegmentCollider2D::New(Args&&... args)
{
std::unique_ptr<SegmentCollider2D> object(new SegmentCollider2D(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
}
#include <Nazara/Physics2D/DebugOff.hpp>

View File

@@ -49,6 +49,7 @@ namespace Nz
bool IsSleeping() const;
void SetAngularVelocity(float angularVelocity);
void SetGeom(Collider2DRef geom);
void SetMass(float mass);
void SetMassCenter(const Vector2f& center);
void SetPosition(const Vector2f& position);
@@ -59,8 +60,8 @@ namespace Nz
RigidBody2D& operator=(RigidBody2D&& object);
private:
void Create(float mass = 1.f, float moment = 1.f);
void Destroy();
void SetGeom(Collider2DRef geom);
std::vector<cpShape*> m_shapes;
Collider2DRef m_geom;

View File

@@ -25,8 +25,7 @@
#ifndef NAZARA_PREREQUESITES_HPP
#define NAZARA_PREREQUESITES_HPP
// Identification du compilateur
///TODO: Rajouter des tests d'identification de compilateurs
// Try to identify the compiler
#if defined(__BORLANDC__)
#define NAZARA_COMPILER_BORDLAND
#define NAZARA_COMPILER_SUPPORTS_CPP11 (defined(__cplusplus) && __cplusplus >= 201103L)
@@ -63,10 +62,10 @@
#pragma warning(disable: 4251)
#else
#define NAZARA_COMPILER_UNKNOWN
#define NAZARA_COMPILER_SUPPORTS_CPP11 (defined(__cplusplus) && __cplusplus >= 201103L)
#define NAZARA_DEPRECATED(txt)
#define NAZARA_FUNCTION __func__ // __func__ est standard depuis le C++11
#define NAZARA_FUNCTION __func__ // __func__ has been standardized in C++ 2011
/// Cette ligne n'est là que pour prévenir, n'hésitez pas à la commenter si elle vous empêche de compiler
#pragma message This compiler is not fully supported
#endif
@@ -76,20 +75,20 @@
// Nazara version macro
#define NAZARA_VERSION_MAJOR 0
#define NAZARA_VERSION_MINOR 1
#define NAZARA_VERSION_MINOR 2
#define NAZARA_VERSION_PATCH 1
#include <Nazara/Core/Config.hpp>
// Identification de la plateforme
// Try to identify target platform via defines
#if defined(_WIN32)
#define NAZARA_PLATFORM_WINDOWS
#define NAZARA_EXPORT __declspec(dllexport)
#define NAZARA_IMPORT __declspec(dllimport)
// Des defines pour le header Windows
#if defined(NAZARA_BUILD) // Pour ne pas entrer en conflit avec les defines de l'application ou d'une autre bibliothèque
// Somes defines for windows.h include..
#if defined(NAZARA_BUILD)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
@@ -99,13 +98,12 @@
#endif
#if NAZARA_CORE_WINDOWS_NT6
// Version de Windows minimale : Vista
#define NAZARA_WINNT 0x0600
#else
#define NAZARA_WINNT 0x0501
#endif
// Pour ne pas casser le define déjà en place s'il est applicable
// Keep the actual define if existing and greater than our requirement
#if defined(_WIN32_WINNT)
#if _WIN32_WINNT < NAZARA_WINNT
#undef _WIN32_WINNT
@@ -128,7 +126,6 @@
#define NAZARA_PLATFORM_MACOSX
#define NAZARA_PLATFORM_POSIX*/
#else
// À commenter pour tenter quand même une compilation
#error This operating system is not fully supported by the Nazara Engine
#define NAZARA_PLATFORM_UNKNOWN
@@ -141,12 +138,7 @@
#define NAZARA_PLATFORM_x64
#endif
// Définit NDEBUG si NAZARA_DEBUG n'est pas présent
#if !defined(NAZARA_DEBUG) && !defined(NDEBUG)
#define NDEBUG
#endif
// Macros supplémentaires
// A bunch of useful macros
#define NazaraPrefix(a, prefix) prefix ## a
#define NazaraPrefixMacro(a, prefix) NazaraPrefix(a, prefix)
#define NazaraSuffix(a, suffix) a ## suffix
@@ -155,8 +147,11 @@
#define NazaraStringifyMacro(s) NazaraStringify(s) // http://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification
#define NazaraUnused(a) (void) a
#include <climits>
#include <cstdint>
static_assert(CHAR_BIT == 8, "CHAR_BIT is expected to be 8");
static_assert(sizeof(int8_t) == 1, "int8_t is not of the correct size" );
static_assert(sizeof(int16_t) == 2, "int16_t is not of the correct size");
static_assert(sizeof(int32_t) == 4, "int32_t is not of the correct size");
@@ -169,17 +164,17 @@ static_assert(sizeof(uint64_t) == 8, "uint64_t is not of the correct size");
namespace Nz
{
typedef int8_t Int8;
typedef uint8_t UInt8;
typedef int8_t Int8;
typedef uint8_t UInt8;
typedef int16_t Int16;
typedef uint16_t UInt16;
typedef int16_t Int16;
typedef uint16_t UInt16;
typedef int32_t Int32;
typedef uint32_t UInt32;
typedef int32_t Int32;
typedef uint32_t UInt32;
typedef int64_t Int64;
typedef uint64_t UInt64;
typedef int64_t Int64;
typedef uint64_t UInt64;
}
#endif // NAZARA_PREREQUESITES_HPP

View File

@@ -38,9 +38,6 @@
// Lors du parsage d'une ressource, déclenche un avertissement si une erreur non-critique est repérée dans une ressource (Plus lent)
#define NAZARA_UTILITY_STRICT_RESOURCE_PARSING 1
// Fait tourner chaque fenêtre dans un thread séparé si le système le supporte
#define NAZARA_UTILITY_THREADED_WINDOW 0
// Protège les classes des accès concurrentiels
//#define NAZARA_UTILITY_THREADSAFE 1

View File

@@ -432,15 +432,17 @@ namespace Nz
enum WindowStyleFlags
{
WindowStyle_None = 0x0,
WindowStyle_Fullscreen = 0x1,
WindowStyle_None = 0x0, ///< Window has no border nor titlebar.
WindowStyle_Fullscreen = 0x1, ///< At the window creation, the OS tries to set it in fullscreen.
WindowStyle_Closable = 0x2,
WindowStyle_Resizable = 0x4,
WindowStyle_Titlebar = 0x8,
WindowStyle_Closable = 0x2, ///< Allows the window to be closed by a button in the titlebar, generating a Quit event.
WindowStyle_Resizable = 0x4, ///< Allows the window to be resized by dragging its corners or by a button of the titlebar.
WindowStyle_Titlebar = 0x8, ///< Adds a titlebar to the window, this option is automatically enabled if buttons of the titlebar are enabled.
WindowStyle_Threaded = 0x10, ///< Runs the window into a thread, allowing the application to keep updating while resizing/dragging the window.
WindowStyle_Default = WindowStyle_Closable | WindowStyle_Resizable | WindowStyle_Titlebar,
WindowStyle_Max = WindowStyle_Titlebar*2-1
WindowStyle_Max = WindowStyle_Threaded*2-1
};
}

View File

@@ -24,6 +24,9 @@ namespace Nz
inline void Dispatch(const WindowEvent& event);
EventHandler& operator=(const EventHandler&) = delete;
EventHandler& operator=(EventHandler&&) = default;
NazaraSignal(OnEvent, const EventHandler* /*eventHandler*/, const WindowEvent& /*event*/);
NazaraSignal(OnGainedFocus, const EventHandler* /*eventHandler*/);
NazaraSignal(OnLostFocus, const EventHandler* /*eventHandler*/);

View File

@@ -91,6 +91,8 @@ namespace Nz
ImageType GetType() const;
unsigned int GetWidth(UInt8 level = 0) const;
bool HasAlpha() const;
bool IsValid() const;
// Load

View File

@@ -39,18 +39,8 @@ namespace Nz
}
inline PixelFormatInfo::PixelFormatInfo(const String& formatName, PixelFormatContent formatContent, Bitset<> rMask, Bitset<> gMask, Bitset<> bMask, Bitset<> aMask, PixelFormatSubType subType) :
redMask(rMask),
greenMask(gMask),
blueMask(bMask),
alphaMask(aMask),
content(formatContent),
redType(subType),
greenType(subType),
blueType(subType),
alphaType(subType),
name(formatName)
PixelFormatInfo(formatName, formatContent, subType, rMask, subType, gMask, subType, bMask, subType, aMask)
{
RecomputeBitsPerPixel();
}
inline PixelFormatInfo::PixelFormatInfo(const String& formatName, PixelFormatContent formatContent, PixelFormatSubType rType, Bitset<> rMask, PixelFormatSubType gType, Bitset<> gMask, PixelFormatSubType bType, Bitset<> bMask, PixelFormatSubType aType, Bitset<> aMask, UInt8 bpp) :
@@ -65,6 +55,11 @@ namespace Nz
alphaType(aType),
name(formatName)
{
redMask.Reverse();
greenMask.Reverse();
blueMask.Reverse();
alphaMask.Reverse();
if (bpp == 0)
RecomputeBitsPerPixel();
}
@@ -123,6 +118,9 @@ namespace Nz
if (usedBits > bitsPerPixel)
return false;
if (usedBits > 64) //< Currently, formats with over 64 bits per component are not supported
return false;
switch (types[i])
{
case PixelFormatSubType_Half:

View File

@@ -19,6 +19,7 @@ namespace Nz
{
public:
VideoMode();
VideoMode(unsigned int w, unsigned int h);
VideoMode(unsigned int w, unsigned int h, UInt8 bpp);
bool IsFullscreenValid() const;

View File

@@ -10,6 +10,8 @@
#define NAZARA_WINDOW_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/ConditionVariable.hpp>
#include <Nazara/Core/Mutex.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Utility/Config.hpp>
@@ -19,11 +21,6 @@
#include <Nazara/Utility/WindowHandle.hpp>
#include <queue>
#if NAZARA_UTILITY_THREADED_WINDOW
#include <Nazara/Core/ConditionVariable.hpp>
#include <Nazara/Core/Mutex.hpp>
#endif
namespace Nz
{
class Cursor;
@@ -114,23 +111,24 @@ namespace Nz
private:
void IgnoreNextMouseEvent(int mouseX, int mouseY) const;
inline void HandleEvent(const WindowEvent& event);
inline void PushEvent(const WindowEvent& event);
static bool Initialize();
static void Uninitialize();
std::queue<WindowEvent> m_events;
#if NAZARA_UTILITY_THREADED_WINDOW
std::vector<WindowEvent> m_pendingEvents;
ConditionVariable m_eventCondition;
EventHandler m_eventHandler;
Mutex m_eventMutex;
Mutex m_eventConditionMutex;
bool m_waitForEvent;
#endif
EventHandler m_eventHandler;
bool m_asyncWindow;
bool m_closed;
bool m_closeOnQuit;
bool m_eventPolling;
bool m_ownsWindow;
bool m_waitForEvent;
};
}

View File

@@ -4,6 +4,7 @@
#include <Nazara/Utility/Window.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/LockGuard.hpp>
#include <Nazara/Utility/Debug.hpp>
namespace Nz
@@ -13,11 +14,10 @@ namespace Nz
*/
inline Window::Window() :
m_impl(nullptr),
#if NAZARA_UTILITY_THREADED_WINDOW
m_waitForEvent(false),
#endif
m_asyncWindow(false),
m_closeOnQuit(true),
m_eventPolling(false)
m_eventPolling(false),
m_waitForEvent(false)
{
}
@@ -41,16 +41,16 @@ namespace Nz
inline Window::Window(Window&& window) noexcept :
m_impl(window.m_impl),
m_events(std::move(window.m_events)),
#if NAZARA_UTILITY_THREADED_WINDOW
m_pendingEvents(std::move(window.m_pendingEvents)),
m_eventCondition(std::move(window.m_eventCondition)),
m_eventHandler(std::move(window.m_eventHandler)),
m_eventMutex(std::move(window.m_eventMutex)),
m_eventConditionMutex(std::move(window.m_eventConditionMutex)),
m_waitForEvent(window.m_waitForEvent),
#endif
m_closed(window.m_closed),
m_closeOnQuit(window.m_closeOnQuit),
m_eventPolling(window.m_eventPolling),
m_ownsWindow(window.m_ownsWindow)
m_ownsWindow(window.m_ownsWindow),
m_waitForEvent(window.m_waitForEvent)
{
window.m_impl = nullptr;
}
@@ -104,12 +104,8 @@ namespace Nz
return m_impl != nullptr;
}
inline void Window::PushEvent(const WindowEvent& event)
inline void Window::HandleEvent(const WindowEvent& event)
{
#if NAZARA_UTILITY_THREADED_WINDOW
m_eventMutex.Lock();
#endif
if (m_eventPolling)
m_events.push(event);
@@ -120,17 +116,27 @@ namespace Nz
if (event.type == WindowEventType_Quit && m_closeOnQuit)
Close();
}
#if NAZARA_UTILITY_THREADED_WINDOW
m_eventMutex.Unlock();
if (m_waitForEvent)
inline void Window::PushEvent(const WindowEvent& event)
{
if (!m_asyncWindow)
HandleEvent(event);
else
{
m_eventConditionMutex.Lock();
m_eventCondition.Signal();
m_eventConditionMutex.Unlock();
{
LockGuard eventLock(m_eventMutex);
m_pendingEvents.push_back(event);
}
if (m_waitForEvent)
{
m_eventConditionMutex.Lock();
m_eventCondition.Signal();
m_eventConditionMutex.Unlock();
}
}
#endif
}
/*!
@@ -141,22 +147,21 @@ namespace Nz
{
Destroy();
m_closed = window.m_closed;
m_closeOnQuit = window.m_closeOnQuit;
m_eventPolling = window.m_eventPolling;
m_impl = window.m_impl;
m_events = std::move(window.m_events);
m_ownsWindow = window.m_ownsWindow;
m_closed = window.m_closed;
m_closeOnQuit = window.m_closeOnQuit;
m_eventCondition = std::move(window.m_eventCondition);
m_eventConditionMutex = std::move(window.m_eventConditionMutex);
m_eventHandler = std::move(window.m_eventHandler);
m_eventMutex = std::move(window.m_eventMutex);
m_eventPolling = window.m_eventPolling;
m_impl = window.m_impl;
m_events = std::move(window.m_events);
m_pendingEvents = std::move(window.m_pendingEvents);
m_ownsWindow = window.m_ownsWindow;
m_waitForEvent = window.m_waitForEvent;
window.m_impl = nullptr;
#if NAZARA_UTILITY_THREADED_WINDOW
m_eventCondition = std::move(window.m_eventCondition);
m_eventMutex = std::move(window.m_eventMutex);
m_eventConditionMutex = std::move(window.m_eventConditionMutex);
m_waitForEvent = window.m_waitForEvent;
#endif
return *this;
}
}