Merge branch 'master' into vulkan
This commit is contained in:
@@ -10,31 +10,15 @@
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Audio/SoundEmitter.hpp>
|
||||
#include <Nazara/Audio/SoundStream.hpp>
|
||||
#include <Nazara/Core/MovablePtr.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/ResourceParameters.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
struct MusicParams : ResourceParameters
|
||||
{
|
||||
bool forceMono = false;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
class Music;
|
||||
class SoundStream;
|
||||
|
||||
using MusicLoader = ResourceLoader<Music, MusicParams>;
|
||||
|
||||
struct MusicImpl;
|
||||
|
||||
class NAZARA_AUDIO_API Music : public Resource, public SoundEmitter
|
||||
{
|
||||
friend MusicLoader;
|
||||
|
||||
public:
|
||||
Music() = default;
|
||||
Music(const Music&) = delete;
|
||||
@@ -55,9 +39,9 @@ namespace Nz
|
||||
|
||||
bool IsLooping() const override;
|
||||
|
||||
bool OpenFromFile(const String& filePath, const MusicParams& params = MusicParams());
|
||||
bool OpenFromMemory(const void* data, std::size_t size, const MusicParams& params = MusicParams());
|
||||
bool OpenFromStream(Stream& stream, const MusicParams& params = MusicParams());
|
||||
bool OpenFromFile(const String& filePath, const SoundStreamParams& params = SoundStreamParams());
|
||||
bool OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params = SoundStreamParams());
|
||||
bool OpenFromStream(Stream& stream, const SoundStreamParams& params = SoundStreamParams());
|
||||
|
||||
void Pause() override;
|
||||
void Play() override;
|
||||
@@ -75,8 +59,6 @@ namespace Nz
|
||||
bool FillAndQueueBuffer(unsigned int buffer);
|
||||
void MusicThread();
|
||||
void StopThread();
|
||||
|
||||
static MusicLoader::LoaderList s_loaders;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -66,16 +66,17 @@ namespace Nz
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
bool LoadFromFile(const String& filePath, const SoundBufferParams& params = SoundBufferParams());
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params = SoundBufferParams());
|
||||
bool LoadFromStream(Stream& stream, const SoundBufferParams& params = SoundBufferParams());
|
||||
|
||||
static bool IsFormatSupported(AudioFormat format);
|
||||
template<typename... Args> static SoundBufferRef New(Args&&... args);
|
||||
|
||||
SoundBuffer& operator=(const SoundBuffer&) = delete;
|
||||
SoundBuffer& operator=(SoundBuffer&&) = delete;
|
||||
|
||||
static bool IsFormatSupported(AudioFormat format);
|
||||
|
||||
static SoundBufferRef LoadFromFile(const String& filePath, const SoundBufferParams& params = SoundBufferParams());
|
||||
static SoundBufferRef LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params = SoundBufferParams());
|
||||
static SoundBufferRef LoadFromStream(Stream& stream, const SoundBufferParams& params = SoundBufferParams());
|
||||
|
||||
template<typename... Args> static SoundBufferRef New(Args&&... args);
|
||||
|
||||
// Signals:
|
||||
NazaraSignal(OnSoundBufferDestroy, const SoundBuffer* /*soundBuffer*/);
|
||||
NazaraSignal(OnSoundBufferRelease, const SoundBuffer* /*soundBuffer*/);
|
||||
|
||||
@@ -10,22 +10,50 @@
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Core/ObjectRef.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/ResourceParameters.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_AUDIO_API SoundStream
|
||||
struct SoundStreamParams : public ResourceParameters
|
||||
{
|
||||
bool forceMono = false;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
class Mutex;
|
||||
class SoundStream;
|
||||
|
||||
using SoundStreamLoader = ResourceLoader<SoundStream, SoundStreamParams>;
|
||||
using SoundStreamRef = Nz::ObjectRef<SoundStream>;
|
||||
|
||||
class NAZARA_AUDIO_API SoundStream : public RefCounted, public Resource
|
||||
{
|
||||
friend SoundStreamLoader;
|
||||
|
||||
public:
|
||||
SoundStream() = default;
|
||||
virtual ~SoundStream();
|
||||
|
||||
virtual UInt32 GetDuration() const = 0;
|
||||
virtual AudioFormat GetFormat() const = 0;
|
||||
virtual Mutex& GetMutex() = 0;
|
||||
virtual UInt64 GetSampleCount() const = 0;
|
||||
virtual UInt32 GetSampleRate() const = 0;
|
||||
|
||||
virtual UInt64 Read(void* buffer, UInt64 sampleCount) = 0;
|
||||
virtual void Seek(UInt64 offset) = 0;
|
||||
virtual UInt64 Tell() = 0;
|
||||
|
||||
static SoundStreamRef OpenFromFile(const String& filePath, const SoundStreamParams& params = SoundStreamParams());
|
||||
static SoundStreamRef OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params = SoundStreamParams());
|
||||
static SoundStreamRef OpenFromStream(Stream& stream, const SoundStreamParams& params = SoundStreamParams());
|
||||
|
||||
private:
|
||||
static SoundStreamLoader::LoaderList s_loaders;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -82,6 +83,8 @@
|
||||
#include <Nazara/Core/SerializationContext.hpp>
|
||||
#include <Nazara/Core/Signal.hpp>
|
||||
#include <Nazara/Core/SparsePtr.hpp>
|
||||
#include <Nazara/Core/StackArray.hpp>
|
||||
#include <Nazara/Core/StackVector.hpp>
|
||||
#include <Nazara/Core/StdLogger.hpp>
|
||||
#include <Nazara/Core/Stream.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
|
||||
43
include/Nazara/Core/ByteArrayPool.hpp
Normal file
43
include/Nazara/Core/ByteArrayPool.hpp
Normal 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
|
||||
44
include/Nazara/Core/ByteArrayPool.inl
Normal file
44
include/Nazara/Core/ByteArrayPool.inl
Normal 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>
|
||||
@@ -27,6 +27,8 @@ namespace Nz
|
||||
ByteStream(ByteStream&& stream) noexcept = default;
|
||||
virtual ~ByteStream();
|
||||
|
||||
inline void ClearStream();
|
||||
|
||||
inline Endianness GetDataEndianness() const;
|
||||
inline Nz::UInt64 GetSize() const;
|
||||
inline Stream* GetStream() const;
|
||||
|
||||
@@ -30,6 +30,18 @@ namespace Nz
|
||||
NazaraWarning("Failed to flush bits at serializer destruction");
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reset stream
|
||||
*/
|
||||
inline void ByteStream::ClearStream()
|
||||
{
|
||||
// We don't want to lose some bits..
|
||||
FlushBits();
|
||||
|
||||
m_context.stream = nullptr;
|
||||
m_ownedStream.reset();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the stream endianness
|
||||
* \return Type of the endianness
|
||||
@@ -113,22 +125,15 @@ namespace Nz
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets this with a stream
|
||||
* \brief Changes stream
|
||||
*
|
||||
* \param stream Stream existing
|
||||
*
|
||||
* \remark Produces a NazaraAssert if stream is invalid
|
||||
*/
|
||||
|
||||
inline void ByteStream::SetStream(Stream* stream)
|
||||
{
|
||||
NazaraAssert(stream, "Invalid stream");
|
||||
|
||||
// We don't want to lose some bits..
|
||||
FlushBits();
|
||||
ClearStream();
|
||||
|
||||
m_context.stream = stream;
|
||||
m_ownedStream.reset();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#define NAZARA_CORE_FILE_BUFFERSIZE 4096
|
||||
|
||||
// Incorporate the Unicode Character Data table (Necessary to make it work with the flag String::HandleUTF8)
|
||||
#define NAZARA_CORE_INCLUDE_UNICODEDATA 0
|
||||
#define NAZARA_CORE_INCLUDE_UNICODEDATA 1
|
||||
|
||||
// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower)
|
||||
#define NAZARA_CORE_MANAGE_MEMORY 0
|
||||
|
||||
46
include/Nazara/Core/EmptyStream.hpp
Normal file
46
include/Nazara/Core/EmptyStream.hpp
Normal 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
|
||||
22
include/Nazara/Core/EmptyStream.inl
Normal file
22
include/Nazara/Core/EmptyStream.inl
Normal 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>
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -8,11 +8,22 @@
|
||||
#define NAZARA_OBJECTHANDLER_HPP
|
||||
|
||||
#include <Nazara/Core/Bitset.hpp>
|
||||
#include <Nazara/Core/Signal.hpp>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace Detail
|
||||
{
|
||||
struct NAZARA_CORE_API HandleData
|
||||
{
|
||||
void* object;
|
||||
|
||||
static std::shared_ptr<HandleData> GetEmptyObject();
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T> class ObjectHandle;
|
||||
|
||||
template<typename T>
|
||||
@@ -31,15 +42,16 @@ namespace Nz
|
||||
HandledObject& operator=(const HandledObject& object);
|
||||
HandledObject& operator=(HandledObject&& object) noexcept;
|
||||
|
||||
NazaraSignal(OnHandledObjectDestruction, HandledObject* /*emitter*/);
|
||||
|
||||
protected:
|
||||
void UnregisterAllHandles() noexcept;
|
||||
|
||||
private:
|
||||
void RegisterHandle(ObjectHandle<T>* handle);
|
||||
void UnregisterHandle(ObjectHandle<T>* handle) noexcept;
|
||||
void UpdateHandle(ObjectHandle<T>* oldHandle, ObjectHandle<T>* newHandle) noexcept;
|
||||
std::shared_ptr<const Detail::HandleData> GetHandleData();
|
||||
void InitHandleData();
|
||||
|
||||
std::vector<ObjectHandle<T>*> m_handles;
|
||||
std::shared_ptr<Detail::HandleData> m_handleData;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
// This file is part of the "Nazara Development Kit"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#include <Nazara/Core/HandledObject.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/ObjectHandle.hpp>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
@@ -35,10 +36,10 @@ namespace Nz
|
||||
*/
|
||||
template<typename T>
|
||||
HandledObject<T>::HandledObject(HandledObject&& object) noexcept :
|
||||
m_handles(std::move(object.m_handles))
|
||||
m_handleData(std::move(object.m_handleData))
|
||||
{
|
||||
for (ObjectHandle<T>* handle : m_handles)
|
||||
handle->OnObjectMoved(static_cast<T*>(this));
|
||||
if (m_handleData)
|
||||
m_handleData->object = static_cast<T*>(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -74,7 +75,7 @@ namespace Nz
|
||||
NazaraUnused(object);
|
||||
|
||||
// Nothing to do
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -88,73 +89,44 @@ namespace Nz
|
||||
{
|
||||
UnregisterAllHandles();
|
||||
|
||||
m_handles = std::move(object.m_handles);
|
||||
for (ObjectHandle<T>* handle : m_handles)
|
||||
handle->OnObjectMoved(static_cast<T*>(this));
|
||||
m_handleData = std::move(object.m_handleData);
|
||||
|
||||
if (m_handleData)
|
||||
m_handleData->object = static_cast<T*>(this);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Registers a handle
|
||||
*
|
||||
* \param handle Handle to register
|
||||
*
|
||||
* \remark One handle can only be registered once, errors can occur if it's more than once
|
||||
*/
|
||||
template<typename T>
|
||||
void HandledObject<T>::RegisterHandle(ObjectHandle<T>* handle)
|
||||
{
|
||||
m_handles.push_back(handle);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Unregisters all handles
|
||||
*/
|
||||
template<typename T>
|
||||
void HandledObject<T>::UnregisterAllHandles() noexcept
|
||||
{
|
||||
// Tell every handle we got destroyed, to null them
|
||||
for (ObjectHandle<T>* handle : m_handles)
|
||||
handle->OnObjectDestroyed();
|
||||
if (m_handleData)
|
||||
{
|
||||
OnHandledObjectDestruction(this);
|
||||
|
||||
m_handles.clear();
|
||||
m_handleData->object = nullptr;
|
||||
m_handleData.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Unregisters a handle
|
||||
*
|
||||
* \param handle Handle to unregister
|
||||
*
|
||||
* \remark One handle can only be unregistered once, crash can occur if it's more than once
|
||||
* \remark Produces a NazaraAssert if handle not registered
|
||||
*/
|
||||
template<typename T>
|
||||
void HandledObject<T>::UnregisterHandle(ObjectHandle<T>* handle) noexcept
|
||||
std::shared_ptr<const Detail::HandleData> HandledObject<T>::GetHandleData()
|
||||
{
|
||||
auto it = std::find(m_handles.begin(), m_handles.end(), handle);
|
||||
NazaraAssert(it != m_handles.end(), "Handle not registered");
|
||||
if (!m_handleData)
|
||||
InitHandleData();
|
||||
|
||||
// Swap and pop idiom, more efficient than vector::erase
|
||||
std::swap(*it, m_handles.back());
|
||||
m_handles.pop_back();
|
||||
return std::shared_ptr<const Detail::HandleData>(m_handleData);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates one handle with another
|
||||
*
|
||||
* \param oldHandle Old handle to replace
|
||||
* \param newHandle New handle to take place
|
||||
*
|
||||
* \remark Produces a NazaraAssert if handle not registered
|
||||
*/
|
||||
template<typename T>
|
||||
void HandledObject<T>::UpdateHandle(ObjectHandle<T>* oldHandle, ObjectHandle<T>* newHandle) noexcept
|
||||
void HandledObject<T>::InitHandleData()
|
||||
{
|
||||
auto it = std::find(m_handles.begin(), m_handles.end(), oldHandle);
|
||||
NazaraAssert(it != m_handles.end(), "Handle not registered");
|
||||
assert(!m_handleData);
|
||||
|
||||
// Simply update the handle
|
||||
*it = newHandle;
|
||||
m_handleData = std::make_shared<Detail::HandleData>();
|
||||
m_handleData->object = static_cast<T*>(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define NAZARA_ALLOCA_SUPPORT
|
||||
|
||||
#elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
|
||||
|
||||
#include <alloca.h>
|
||||
|
||||
// with Clang/GCC, using alloca with a size of zero does nothing good
|
||||
@@ -24,16 +25,7 @@
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef NAZARA_ALLOCA_SUPPORT
|
||||
#define NazaraStackAllocation(T, size) Nz::StackArray<T>(static_cast<T*>(NAZARA_ALLOCA((size) * sizeof(T))), size)
|
||||
#define NazaraStackAllocationNoInit(T, size) Nz::StackArray<T>(static_cast<T*>(NAZARA_ALLOCA((size) * sizeof(T))), size, Nz::NoInitTag())
|
||||
#else
|
||||
#define NazaraStackAllocation(T, size) Nz::StackArray<T>(static_cast<T*>(Nz::OperatorNew((size) * sizeof(T))), size)
|
||||
#define NazaraStackAllocationNoInit(T, size) Nz::StackArray<T>(static_cast<T*>(Nz::OperatorNew((size) * sizeof(T))), size, Nz::NoInitTag())
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
@@ -45,71 +37,6 @@ namespace Nz
|
||||
|
||||
template<typename T>
|
||||
void PlacementDestroy(T* ptr);
|
||||
|
||||
struct NoInitTag {};
|
||||
|
||||
template<typename T>
|
||||
class StackArray
|
||||
{
|
||||
public:
|
||||
using value_type = T;
|
||||
using const_iterator = const value_type*;
|
||||
using const_pointer = const value_type*;
|
||||
using const_reference = const value_type&;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using iterator = value_type*;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using size_type = std::size_t;
|
||||
|
||||
StackArray(T* stackMemory, std::size_t size);
|
||||
StackArray(T* stackMemory, std::size_t size, NoInitTag);
|
||||
~StackArray();
|
||||
|
||||
reference back();
|
||||
const_reference back() const;
|
||||
|
||||
iterator begin() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
|
||||
const_iterator cbegin() const noexcept;
|
||||
const_iterator cend() const noexcept;
|
||||
const_reverse_iterator crbegin() const noexcept;
|
||||
const_reverse_iterator crend() const noexcept;
|
||||
|
||||
T* data() noexcept;
|
||||
const T* data() const noexcept;
|
||||
|
||||
bool empty() const noexcept;
|
||||
|
||||
iterator end() noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
|
||||
void fill(const T& value);
|
||||
|
||||
reference front() noexcept;
|
||||
const_reference front() const noexcept;
|
||||
|
||||
size_type max_size() const noexcept;
|
||||
|
||||
reverse_iterator rbegin() noexcept;
|
||||
const_reverse_iterator rbegin() const noexcept;
|
||||
|
||||
reverse_iterator rend() noexcept;
|
||||
const_reverse_iterator rend() const noexcept;
|
||||
|
||||
size_type size() const noexcept;
|
||||
|
||||
reference operator[](size_type pos);
|
||||
const_reference operator[](size_type pos) const;
|
||||
|
||||
private:
|
||||
std::size_t m_size;
|
||||
T* m_ptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include <Nazara/Core/MemoryHelper.inl>
|
||||
|
||||
@@ -11,10 +11,8 @@
|
||||
|
||||
#include <Nazara/Core/MemoryHelper.hpp>
|
||||
#include <Nazara/Core/MemoryManager.hpp>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
@@ -79,187 +77,6 @@ namespace Nz
|
||||
if (ptr)
|
||||
ptr->~T();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup core
|
||||
* \class Nz::StackArray
|
||||
* \brief Core class that represents a stack-allocated (if alloca is present) array
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
StackArray<T>::StackArray(T* stackMemory, std::size_t size) :
|
||||
m_size(size),
|
||||
m_ptr(stackMemory)
|
||||
{
|
||||
for (std::size_t i = 0; i < m_size; ++i)
|
||||
PlacementNew(&m_ptr[i]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
StackArray<T>::StackArray(T* stackMemory, std::size_t size, NoInitTag) :
|
||||
m_size(size),
|
||||
m_ptr(stackMemory)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
StackArray<T>::~StackArray()
|
||||
{
|
||||
for (std::size_t i = 0; i < m_size; ++i)
|
||||
m_ptr[i].~T();
|
||||
|
||||
#ifndef NAZARA_ALLOCA_SUPPORT
|
||||
OperatorDelete(m_ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::reference StackArray<T>::back()
|
||||
{
|
||||
assert(m_size != 0);
|
||||
return m_ptr[m_size - 1];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reference StackArray<T>::back() const
|
||||
{
|
||||
assert(m_size != 0);
|
||||
return m_ptr[m_size - 1];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::iterator StackArray<T>::begin() noexcept
|
||||
{
|
||||
return iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_iterator StackArray<T>::begin() const noexcept
|
||||
{
|
||||
return const_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_iterator StackArray<T>::cbegin() const noexcept
|
||||
{
|
||||
return const_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_iterator StackArray<T>::cend() const noexcept
|
||||
{
|
||||
return const_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reverse_iterator StackArray<T>::crbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reverse_iterator StackArray<T>::crend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* StackArray<T>::data() noexcept
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T* StackArray<T>::data() const noexcept
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool StackArray<T>::empty() const noexcept
|
||||
{
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::iterator StackArray<T>::end() noexcept
|
||||
{
|
||||
return iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_iterator StackArray<T>::end() const noexcept
|
||||
{
|
||||
return const_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void StackArray<T>::fill(const T& value)
|
||||
{
|
||||
std::fill(begin(), end(), value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::reference StackArray<T>::front() noexcept
|
||||
{
|
||||
return m_ptr[0];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reference StackArray<T>::front() const noexcept
|
||||
{
|
||||
return m_ptr[0];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::size_type StackArray<T>::max_size() const noexcept
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::reverse_iterator StackArray<T>::rbegin() noexcept
|
||||
{
|
||||
return reverse_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reverse_iterator StackArray<T>::rbegin() const noexcept
|
||||
{
|
||||
return reverse_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::reverse_iterator StackArray<T>::rend() noexcept
|
||||
{
|
||||
return reverse_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reverse_iterator StackArray<T>::rend() const noexcept
|
||||
{
|
||||
return reverse_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::size_type StackArray<T>::size() const noexcept
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::reference StackArray<T>::operator[](size_type pos)
|
||||
{
|
||||
assert(pos < m_size);
|
||||
return m_ptr[pos];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reference StackArray<T>::operator[](size_type pos) const
|
||||
{
|
||||
assert(pos < m_size);
|
||||
return m_ptr[pos];
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
#define NAZARA_OBJECTHANDLE_HPP
|
||||
|
||||
#include <Nazara/Core/Algorithm.hpp>
|
||||
#include <Nazara/Core/HandledObject.hpp>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
template<typename T> class HandledObject;
|
||||
|
||||
template<typename T>
|
||||
class ObjectHandle
|
||||
{
|
||||
@@ -22,7 +22,7 @@ namespace Nz
|
||||
public:
|
||||
ObjectHandle();
|
||||
explicit ObjectHandle(T* object);
|
||||
ObjectHandle(const ObjectHandle& handle);
|
||||
ObjectHandle(const ObjectHandle& handle) = default;
|
||||
ObjectHandle(ObjectHandle&& handle) noexcept;
|
||||
~ObjectHandle();
|
||||
|
||||
@@ -43,16 +43,13 @@ namespace Nz
|
||||
T* operator->() const;
|
||||
|
||||
ObjectHandle& operator=(T* object);
|
||||
ObjectHandle& operator=(const ObjectHandle& handle);
|
||||
ObjectHandle& operator=(const ObjectHandle& handle) = default;
|
||||
ObjectHandle& operator=(ObjectHandle&& handle) noexcept;
|
||||
|
||||
static const ObjectHandle InvalidHandle;
|
||||
|
||||
protected:
|
||||
void OnObjectDestroyed() noexcept;
|
||||
void OnObjectMoved(T* newObject) noexcept;
|
||||
|
||||
T* m_object;
|
||||
std::shared_ptr<const Detail::HandleData> m_handleData;
|
||||
};
|
||||
|
||||
template<typename T> std::ostream& operator<<(std::ostream& out, const ObjectHandle<T>& handle);
|
||||
|
||||
@@ -15,37 +15,15 @@ namespace Nz
|
||||
* \brief Core class that represents a object handle
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a ObjectHandle object by default
|
||||
*/
|
||||
template<typename T>
|
||||
ObjectHandle<T>::ObjectHandle() :
|
||||
m_object(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a ObjectHandle object with a pointer to an object
|
||||
*
|
||||
* \param object Pointer to handle like an object (can be nullptr)
|
||||
*/
|
||||
template<typename T>
|
||||
ObjectHandle<T>::ObjectHandle(T* object) :
|
||||
ObjectHandle()
|
||||
ObjectHandle<T>::ObjectHandle() :
|
||||
m_handleData(Detail::HandleData::GetEmptyObject())
|
||||
{
|
||||
Reset(object);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a ObjectHandle object by assignation
|
||||
*
|
||||
* \param handle ObjectHandle to assign into this
|
||||
*/
|
||||
template<typename T>
|
||||
ObjectHandle<T>::ObjectHandle(const ObjectHandle& handle) :
|
||||
ObjectHandle()
|
||||
{
|
||||
Reset(handle);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -54,12 +32,22 @@ namespace Nz
|
||||
* \param handle ObjectHandle to move into this
|
||||
*/
|
||||
template<typename T>
|
||||
ObjectHandle<T>::ObjectHandle(ObjectHandle&& handle) noexcept :
|
||||
ObjectHandle()
|
||||
ObjectHandle<T>::ObjectHandle(ObjectHandle&& handle) noexcept
|
||||
{
|
||||
Reset(std::move(handle));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a ObjectHandle object with a pointer to an object
|
||||
*
|
||||
* \param object Pointer to handle like an object (can be nullptr)
|
||||
*/
|
||||
template<typename T>
|
||||
ObjectHandle<T>::ObjectHandle(T* object)
|
||||
{
|
||||
Reset(object);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destructs the object and calls reset with nullptr
|
||||
*
|
||||
@@ -78,7 +66,7 @@ namespace Nz
|
||||
template<typename T>
|
||||
T* ObjectHandle<T>::GetObject() const
|
||||
{
|
||||
return m_object;
|
||||
return static_cast<T*>(m_handleData->object);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -88,7 +76,7 @@ namespace Nz
|
||||
template<typename T>
|
||||
bool ObjectHandle<T>::IsValid() const
|
||||
{
|
||||
return m_object != nullptr;
|
||||
return m_handleData->object != nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -99,14 +87,10 @@ namespace Nz
|
||||
template<typename T>
|
||||
void ObjectHandle<T>::Reset(T* object)
|
||||
{
|
||||
// If we already have an entity, we must alert it that we are not pointing to it anymore
|
||||
if (m_object)
|
||||
m_object->UnregisterHandle(this);
|
||||
|
||||
m_object = object;
|
||||
if (m_object)
|
||||
// We alert the new entity that we are pointing to it
|
||||
m_object->RegisterHandle(this);
|
||||
if (object)
|
||||
m_handleData = object->GetHandleData();
|
||||
else
|
||||
m_handleData = Detail::HandleData::GetEmptyObject();
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -117,7 +101,7 @@ namespace Nz
|
||||
template<typename T>
|
||||
void ObjectHandle<T>::Reset(const ObjectHandle& handle)
|
||||
{
|
||||
Reset(handle.GetObject());
|
||||
m_handleData = handle.m_handleData;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -128,18 +112,8 @@ namespace Nz
|
||||
template<typename T>
|
||||
void ObjectHandle<T>::Reset(ObjectHandle&& handle) noexcept
|
||||
{
|
||||
if (this == &handle)
|
||||
return;
|
||||
|
||||
if (m_object)
|
||||
m_object->UnregisterHandle(this);
|
||||
|
||||
if (T* object = handle.GetObject())
|
||||
{
|
||||
m_object = handle.m_object;
|
||||
handle.m_object = nullptr;
|
||||
object->UpdateHandle(&handle, this);
|
||||
}
|
||||
m_handleData = std::move(handle.m_handleData);
|
||||
handle.m_handleData = Detail::HandleData::GetEmptyObject();
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -151,23 +125,8 @@ namespace Nz
|
||||
template<typename T>
|
||||
ObjectHandle<T>& ObjectHandle<T>::Swap(ObjectHandle& handle)
|
||||
{
|
||||
// As we swap the two handles, we must alert the entities
|
||||
// The default version with swap (move) would be working,
|
||||
// but will register handles one more time (due to temporary copy).
|
||||
if (m_object)
|
||||
{
|
||||
m_object->UnregisterHandle(this);
|
||||
m_object->RegisterHandle(&handle);
|
||||
}
|
||||
|
||||
if (handle.m_object)
|
||||
{
|
||||
handle.m_object->UnregisterHandle(&handle);
|
||||
handle.m_object->RegisterHandle(this);
|
||||
}
|
||||
|
||||
// We do the swap
|
||||
std::swap(m_object, handle.m_object);
|
||||
std::swap(m_handleData, handle.m_handleData);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -181,7 +140,7 @@ namespace Nz
|
||||
Nz::StringStream ss;
|
||||
ss << "ObjectHandle(";
|
||||
if (IsValid())
|
||||
ss << m_object->ToString();
|
||||
ss << GetObject()->ToString();
|
||||
else
|
||||
ss << "Null";
|
||||
|
||||
@@ -209,7 +168,7 @@ namespace Nz
|
||||
template<typename T>
|
||||
ObjectHandle<T>::operator T*() const
|
||||
{
|
||||
return m_object;
|
||||
return GetObject();
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -219,7 +178,7 @@ namespace Nz
|
||||
template<typename T>
|
||||
T* ObjectHandle<T>::operator->() const
|
||||
{
|
||||
return m_object;
|
||||
return GetObject();
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -229,23 +188,9 @@ namespace Nz
|
||||
* \param entity Pointer to handle like an object (can be nullptr)
|
||||
*/
|
||||
template<typename T>
|
||||
ObjectHandle<T>& ObjectHandle<T>::operator=(T* entity)
|
||||
ObjectHandle<T>& ObjectHandle<T>::operator=(T* object)
|
||||
{
|
||||
Reset(entity);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the handle of the ObjectHandle with the handle from another
|
||||
* \return A reference to this
|
||||
*
|
||||
* \param handle The other ObjectHandle
|
||||
*/
|
||||
template<typename T>
|
||||
ObjectHandle<T>& ObjectHandle<T>::operator=(const ObjectHandle& handle)
|
||||
{
|
||||
Reset(handle);
|
||||
Reset(object);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -264,26 +209,6 @@ namespace Nz
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Action to do on object destruction
|
||||
*/
|
||||
template<typename T>
|
||||
void ObjectHandle<T>::OnObjectDestroyed() noexcept
|
||||
{
|
||||
// Shortcut
|
||||
m_object = nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Action to do on object move
|
||||
*/
|
||||
template<typename T>
|
||||
void ObjectHandle<T>::OnObjectMoved(T* newObject) noexcept
|
||||
{
|
||||
// The object has been moved, update our pointer
|
||||
m_object = newObject;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Output operator
|
||||
* \return The stream
|
||||
@@ -386,7 +311,7 @@ namespace Nz
|
||||
template<typename T>
|
||||
bool operator<(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
||||
{
|
||||
return lhs.m_object < rhs.m_object;
|
||||
return lhs.GetObject() < rhs.GetObject();
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -399,7 +324,7 @@ namespace Nz
|
||||
template<typename T>
|
||||
bool operator<(const T& lhs, const ObjectHandle<T>& rhs)
|
||||
{
|
||||
return &lhs < rhs.m_object;
|
||||
return &lhs < rhs.GetObject();
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -412,7 +337,7 @@ namespace Nz
|
||||
template<typename T>
|
||||
bool operator<(const ObjectHandle<T>& lhs, const T& rhs)
|
||||
{
|
||||
return lhs.m_object < &rhs;
|
||||
return lhs.GetObject() < &rhs;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace Nz
|
||||
ObjectLibrary() = delete;
|
||||
~ObjectLibrary() = delete;
|
||||
|
||||
static void Clear();
|
||||
|
||||
static ObjectRef<Type> Get(const String& name);
|
||||
static bool Has(const String& name);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// 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/ObjectLibrary.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
@@ -9,10 +10,19 @@ namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \ingroup core
|
||||
* \class Nz::ObjectRef
|
||||
* \brief Core class that represents a reference to an object
|
||||
* \class Nz::ObjectLibrary
|
||||
* \brief Core class containing a collection of objects
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Clears the library, freeing every object it contains
|
||||
*/
|
||||
template<typename Type>
|
||||
void ObjectLibrary<Type>::Clear()
|
||||
{
|
||||
Type::s_library.clear();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the ObjectRef object by name
|
||||
* \return Optional reference
|
||||
|
||||
@@ -68,6 +68,10 @@ namespace Nz
|
||||
template<typename T> bool operator>=(const T& lhs, const ObjectRef<T>& rhs);
|
||||
template<typename T> bool operator>=(const ObjectRef<T>& lhs, const T& rhs);
|
||||
|
||||
template<typename T, typename U> ObjectRef<T> ConstRefCast(const ObjectRef<U>& ref);
|
||||
template<typename T, typename U> ObjectRef<T> DynamicRefCast(const ObjectRef<U>& ref);
|
||||
template<typename T, typename U> ObjectRef<T> ReinterpretRefCast(const ObjectRef<U>& ref);
|
||||
template<typename T, typename U> ObjectRef<T> StaticRefCast(const ObjectRef<U>& ref);
|
||||
|
||||
template<typename T> struct PointedType<ObjectRef<T>> { using type = T; };
|
||||
template<typename T> struct PointedType<ObjectRef<T> const> { using type = T; };
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -480,6 +480,60 @@ namespace Nz
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Casts an ObjectRef from one type to another using static_cast
|
||||
* \return Reference to the casted object
|
||||
*
|
||||
* \param ref The reference to convert
|
||||
*
|
||||
* \remark It is an undefined behavior to cast between incompatible types
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
ObjectRef<T> ConstRefCast(const ObjectRef<U>& ref)
|
||||
{
|
||||
return ObjectRef<T>(const_cast<T*>(ref.Get()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Casts an ObjectRef from one type to another using static_cast
|
||||
* \return Reference to the casted object
|
||||
*
|
||||
* \param ref The reference to convert
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
ObjectRef<T> DynamicRefCast(const ObjectRef<U>& ref)
|
||||
{
|
||||
return ObjectRef<T>(dynamic_cast<T*>(ref.Get()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Casts an ObjectRef from one type to another using static_cast
|
||||
* \return Reference to the casted object
|
||||
*
|
||||
* \param ref The reference to convert
|
||||
*
|
||||
* \remark It is an undefined behavior to cast between incompatible types
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
ObjectRef<T> ReinterpretRefCast(const ObjectRef<U>& ref)
|
||||
{
|
||||
return ObjectRef<T>(static_cast<T*>(ref.Get()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Casts an ObjectRef from one type to another using static_cast
|
||||
* \return Reference to the casted object
|
||||
*
|
||||
* \param ref The reference to convert
|
||||
*
|
||||
* \remark It is an undefined behavior to cast between incompatible types
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
ObjectRef<T> StaticRefCast(const ObjectRef<U>& ref)
|
||||
{
|
||||
return ObjectRef<T>(static_cast<T*>(ref.Get()));
|
||||
}
|
||||
}
|
||||
|
||||
namespace std
|
||||
@@ -504,3 +558,4 @@ namespace std
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
#include "ObjectRef.hpp"
|
||||
|
||||
46
include/Nazara/Core/PoolByteStream.hpp
Normal file
46
include/Nazara/Core/PoolByteStream.hpp
Normal 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
|
||||
30
include/Nazara/Core/PoolByteStream.inl
Normal file
30
include/Nazara/Core/PoolByteStream.inl
Normal 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>
|
||||
@@ -8,6 +8,8 @@
|
||||
#define NAZARA_RESOURCELOADER_HPP
|
||||
|
||||
#include <Nazara/Core/Enums.hpp>
|
||||
#include <Nazara/Core/ObjectRef.hpp>
|
||||
#include <Nazara/Core/RefCounted.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceParameters.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
@@ -28,19 +30,19 @@ namespace Nz
|
||||
|
||||
public:
|
||||
using ExtensionGetter = bool (*)(const String& extension);
|
||||
using FileLoader = bool (*)(Type* resource, const String& filePath, const Parameters& parameters);
|
||||
using MemoryLoader = bool (*)(Type* resource, const void* data, std::size_t size, const Parameters& parameters);
|
||||
using FileLoader = ObjectRef<Type> (*)(const String& filePath, const Parameters& parameters);
|
||||
using MemoryLoader = ObjectRef<Type> (*)(const void* data, std::size_t size, const Parameters& parameters);
|
||||
using StreamChecker = Ternary (*)(Stream& stream, const Parameters& parameters);
|
||||
using StreamLoader = bool (*)(Type* resource, Stream& stream, const Parameters& parameters);
|
||||
using StreamLoader = ObjectRef<Type> (*)(Stream& stream, const Parameters& parameters);
|
||||
|
||||
ResourceLoader() = delete;
|
||||
~ResourceLoader() = delete;
|
||||
|
||||
static bool IsExtensionSupported(const String& extension);
|
||||
|
||||
static bool LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters = Parameters());
|
||||
static bool LoadFromMemory(Type* resource, const void* data, std::size_t size, const Parameters& parameters = Parameters());
|
||||
static bool LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters = Parameters());
|
||||
static ObjectRef<Type> LoadFromFile(const String& filePath, const Parameters& parameters = Parameters());
|
||||
static ObjectRef<Type> LoadFromMemory(const void* data, std::size_t size, const Parameters& parameters = Parameters());
|
||||
static ObjectRef<Type> LoadFromStream(Stream& stream, const Parameters& parameters = Parameters());
|
||||
|
||||
static void RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr);
|
||||
static void UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr);
|
||||
|
||||
@@ -53,9 +53,8 @@ namespace Nz
|
||||
* \remark Produces a NazaraError if all loaders failed or no loader was found
|
||||
*/
|
||||
template<typename Type, typename Parameters>
|
||||
bool ResourceLoader<Type, Parameters>::LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters)
|
||||
ObjectRef<Type> ResourceLoader<Type, Parameters>::LoadFromFile(const String& filePath, const Parameters& parameters)
|
||||
{
|
||||
NazaraAssert(resource, "Invalid resource");
|
||||
NazaraAssert(parameters.IsValid(), "Invalid parameters");
|
||||
|
||||
String path = File::NormalizePath(filePath);
|
||||
@@ -63,7 +62,7 @@ namespace Nz
|
||||
if (ext.IsEmpty())
|
||||
{
|
||||
NazaraError("Failed to get file extension from \"" + filePath + '"');
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
File file(path); // Open only if needed
|
||||
@@ -84,7 +83,7 @@ namespace Nz
|
||||
if (!file.Open(OpenMode_ReadOnly))
|
||||
{
|
||||
NazaraError("Failed to load file: unable to open \"" + filePath + '"');
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,10 +106,11 @@ namespace Nz
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (fileLoader(resource, filePath, parameters))
|
||||
ObjectRef<Type> resource = fileLoader(filePath, parameters);
|
||||
if (resource)
|
||||
{
|
||||
resource->SetFilePath(filePath);
|
||||
return true;
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -125,10 +125,11 @@ namespace Nz
|
||||
|
||||
file.SetCursorPos(0);
|
||||
|
||||
if (streamLoader(resource, file, parameters))
|
||||
ObjectRef<Type> resource = streamLoader(file, parameters);
|
||||
if (resource)
|
||||
{
|
||||
resource->SetFilePath(filePath);
|
||||
return true;
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +142,7 @@ namespace Nz
|
||||
else
|
||||
NazaraError("Failed to load file: no loader found for extension \"" + ext + '"');
|
||||
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -160,9 +161,8 @@ namespace Nz
|
||||
* \remark Produces a NazaraError if all loaders failed or no loader was found
|
||||
*/
|
||||
template<typename Type, typename Parameters>
|
||||
bool ResourceLoader<Type, Parameters>::LoadFromMemory(Type* resource, const void* data, std::size_t size, const Parameters& parameters)
|
||||
ObjectRef<Type> ResourceLoader<Type, Parameters>::LoadFromMemory(const void* data, std::size_t size, const Parameters& parameters)
|
||||
{
|
||||
NazaraAssert(resource, "Invalid resource");
|
||||
NazaraAssert(data, "Invalid data pointer");
|
||||
NazaraAssert(size, "No data to load");
|
||||
NazaraAssert(parameters.IsValid(), "Invalid parameters");
|
||||
@@ -195,8 +195,9 @@ namespace Nz
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (memoryLoader(resource, data, size, parameters))
|
||||
return true;
|
||||
ObjectRef<Type> resource = memoryLoader(data, size, parameters);
|
||||
if (resource)
|
||||
return resource;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -210,8 +211,9 @@ namespace Nz
|
||||
|
||||
stream.SetCursorPos(0);
|
||||
|
||||
if (streamLoader(resource, stream, parameters))
|
||||
return true;
|
||||
ObjectRef<Type> resource = streamLoader(stream, parameters);
|
||||
if (resource)
|
||||
return resource;
|
||||
}
|
||||
|
||||
if (recognized == Ternary_True)
|
||||
@@ -223,7 +225,7 @@ namespace Nz
|
||||
else
|
||||
NazaraError("Failed to load file: no loader found");
|
||||
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -241,9 +243,8 @@ namespace Nz
|
||||
* \remark Produces a NazaraError if all loaders failed or no loader was found
|
||||
*/
|
||||
template<typename Type, typename Parameters>
|
||||
bool ResourceLoader<Type, Parameters>::LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters)
|
||||
ObjectRef<Type> ResourceLoader<Type, Parameters>::LoadFromStream(Stream& stream, const Parameters& parameters)
|
||||
{
|
||||
NazaraAssert(resource, "Invalid resource");
|
||||
NazaraAssert(stream.GetCursorPos() < stream.GetSize(), "No data to load");
|
||||
NazaraAssert(parameters.IsValid(), "Invalid parameters");
|
||||
|
||||
@@ -267,8 +268,9 @@ namespace Nz
|
||||
stream.SetCursorPos(streamPos);
|
||||
|
||||
// Load of the resource
|
||||
if (streamLoader(resource, stream, parameters))
|
||||
return true;
|
||||
ObjectRef<Type> resource = streamLoader(stream, parameters);
|
||||
if (resource)
|
||||
return resource;
|
||||
|
||||
if (recognized == Ternary_True)
|
||||
NazaraWarning("Loader failed");
|
||||
@@ -279,7 +281,7 @@ namespace Nz
|
||||
else
|
||||
NazaraError("Failed to load file: no loader found");
|
||||
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -37,14 +37,8 @@ namespace Nz
|
||||
auto it = Type::s_managerMap.find(absolutePath);
|
||||
if (it == Type::s_managerMap.end())
|
||||
{
|
||||
ObjectRef<Type> resource = Type::New();
|
||||
ObjectRef<Type> resource = Type::LoadFromFile(absolutePath, GetDefaultParameters());
|
||||
if (!resource)
|
||||
{
|
||||
NazaraError("Failed to create resource");
|
||||
return ObjectRef<Type>();
|
||||
}
|
||||
|
||||
if (!resource->LoadFromFile(absolutePath, GetDefaultParameters()))
|
||||
{
|
||||
NazaraError("Failed to load resource from file: " + absolutePath);
|
||||
return ObjectRef<Type>();
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Nz
|
||||
class ConnectionGuard;
|
||||
|
||||
Signal();
|
||||
Signal(const Signal&) = delete;
|
||||
Signal(const Signal&);
|
||||
Signal(Signal&& signal) noexcept;
|
||||
~Signal() = default;
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Nz
|
||||
|
||||
void operator()(Args... args) const;
|
||||
|
||||
Signal& operator=(const Signal&) = delete;
|
||||
Signal& operator=(const Signal&);
|
||||
Signal& operator=(Signal&& signal) noexcept;
|
||||
|
||||
private:
|
||||
|
||||
@@ -18,13 +18,23 @@ namespace Nz
|
||||
/*!
|
||||
* \brief Constructs a Signal object by default
|
||||
*/
|
||||
|
||||
template<typename... Args>
|
||||
Signal<Args...>::Signal() :
|
||||
m_slotIterator(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Signal object by default
|
||||
*
|
||||
* \remark It doesn't make sense to copy a signal, this is only available for convenience to allow compiler-generated copy constructors
|
||||
*/
|
||||
template<typename ...Args>
|
||||
Signal<Args...>::Signal(const Signal&) :
|
||||
Signal()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Signal object by move semantic
|
||||
*
|
||||
@@ -174,13 +184,24 @@ namespace Nz
|
||||
m_slots[m_slotIterator]->callback(args...);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Doesn't do anything
|
||||
* \return A reference to this
|
||||
*
|
||||
* \remark This is only for convenience to allow compiled-generated assignation operator
|
||||
*/
|
||||
template<typename... Args>
|
||||
Signal<Args...>& Signal<Args...>::operator=(const Signal&)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Moves the signal into this
|
||||
* \return A reference to this
|
||||
*
|
||||
* \param signal Signal to move in this
|
||||
*/
|
||||
|
||||
template<typename... Args>
|
||||
Signal<Args...>& Signal<Args...>::operator=(Signal&& signal) noexcept
|
||||
{
|
||||
|
||||
100
include/Nazara/Core/StackArray.hpp
Normal file
100
include/Nazara/Core/StackArray.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
// 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_STACKARRAY_HPP
|
||||
#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)
|
||||
#define NazaraStackArrayNoInit(T, size) Nz::StackArray<T>(static_cast<T*>(NAZARA_ALLOCA((size) * sizeof(T))), size, typename Nz::StackArray<T>::NoInitTag())
|
||||
#else
|
||||
#define NazaraStackArray(T, size) Nz::StackArray<T>(static_cast<T*>(Nz::OperatorNew((size) * sizeof(T))), size)
|
||||
#define NazaraStackArrayNoInit(T, size) Nz::StackArray<T>(static_cast<T*>(Nz::OperatorNew((size) * sizeof(T))), size, typename Nz::StackArray<T>::NoInitTag())
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
template<typename T>
|
||||
class StackArray
|
||||
{
|
||||
public:
|
||||
struct NoInitTag {};
|
||||
|
||||
using value_type = T;
|
||||
using const_iterator = const value_type*;
|
||||
using const_pointer = const value_type*;
|
||||
using const_reference = const value_type&;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using iterator = value_type*;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
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();
|
||||
const_reference back() const;
|
||||
|
||||
iterator begin() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
|
||||
const_iterator cbegin() const noexcept;
|
||||
const_iterator cend() const noexcept;
|
||||
const_reverse_iterator crbegin() const noexcept;
|
||||
const_reverse_iterator crend() const noexcept;
|
||||
|
||||
T* data() noexcept;
|
||||
const T* data() const noexcept;
|
||||
|
||||
bool empty() const noexcept;
|
||||
|
||||
iterator end() noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
|
||||
void fill(const T& value);
|
||||
|
||||
reference front() noexcept;
|
||||
const_reference front() const noexcept;
|
||||
|
||||
size_type max_size() const noexcept;
|
||||
|
||||
reverse_iterator rbegin() noexcept;
|
||||
const_reverse_iterator rbegin() const noexcept;
|
||||
|
||||
reverse_iterator rend() noexcept;
|
||||
const_reverse_iterator rend() const noexcept;
|
||||
|
||||
size_type size() const noexcept;
|
||||
|
||||
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;
|
||||
MovablePtr<T> m_ptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include <Nazara/Core/StackArray.inl>
|
||||
|
||||
#endif // NAZARA_STACKARRAY_HPP
|
||||
216
include/Nazara/Core/StackArray.inl
Normal file
216
include/Nazara/Core/StackArray.inl
Normal file
@@ -0,0 +1,216 @@
|
||||
// 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
|
||||
|
||||
// I'm not proud of those five following lines but ti's hard to do with another way now
|
||||
#ifdef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
|
||||
#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED
|
||||
#else
|
||||
#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
|
||||
#endif
|
||||
|
||||
#include <Nazara/Core/StackArray.hpp>
|
||||
#include <Nazara/Core/MemoryManager.hpp>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \ingroup core
|
||||
* \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),
|
||||
m_ptr(stackMemory)
|
||||
{
|
||||
for (std::size_t i = 0; i < m_size; ++i)
|
||||
PlacementNew(&m_ptr[i]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
StackArray<T>::StackArray(T* stackMemory, std::size_t size, NoInitTag) :
|
||||
m_size(size),
|
||||
m_ptr(stackMemory)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
StackArray<T>::~StackArray()
|
||||
{
|
||||
for (std::size_t i = 0; i < m_size; ++i)
|
||||
PlacementDestroy(&m_ptr[i]);
|
||||
|
||||
#ifndef NAZARA_ALLOCA_SUPPORT
|
||||
OperatorDelete(m_ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::reference StackArray<T>::back()
|
||||
{
|
||||
assert(m_size != 0);
|
||||
return m_ptr[m_size - 1];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reference StackArray<T>::back() const
|
||||
{
|
||||
assert(m_size != 0);
|
||||
return m_ptr[m_size - 1];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::iterator StackArray<T>::begin() noexcept
|
||||
{
|
||||
return iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_iterator StackArray<T>::begin() const noexcept
|
||||
{
|
||||
return const_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_iterator StackArray<T>::cbegin() const noexcept
|
||||
{
|
||||
return const_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_iterator StackArray<T>::cend() const noexcept
|
||||
{
|
||||
return const_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reverse_iterator StackArray<T>::crbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reverse_iterator StackArray<T>::crend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* StackArray<T>::data() noexcept
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T* StackArray<T>::data() const noexcept
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool StackArray<T>::empty() const noexcept
|
||||
{
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::iterator StackArray<T>::end() noexcept
|
||||
{
|
||||
return iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_iterator StackArray<T>::end() const noexcept
|
||||
{
|
||||
return const_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void StackArray<T>::fill(const T& value)
|
||||
{
|
||||
std::fill(begin(), end(), value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::reference StackArray<T>::front() noexcept
|
||||
{
|
||||
return m_ptr[0];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reference StackArray<T>::front() const noexcept
|
||||
{
|
||||
return m_ptr[0];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::size_type StackArray<T>::max_size() const noexcept
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::reverse_iterator StackArray<T>::rbegin() noexcept
|
||||
{
|
||||
return reverse_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reverse_iterator StackArray<T>::rbegin() const noexcept
|
||||
{
|
||||
return reverse_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::reverse_iterator StackArray<T>::rend() noexcept
|
||||
{
|
||||
return reverse_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reverse_iterator StackArray<T>::rend() const noexcept
|
||||
{
|
||||
return reverse_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::size_type StackArray<T>::size() const noexcept
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::reference StackArray<T>::operator[](size_type pos)
|
||||
{
|
||||
assert(pos < m_size);
|
||||
return m_ptr[pos];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackArray<T>::const_reference StackArray<T>::operator[](size_type pos) const
|
||||
{
|
||||
assert(pos < m_size);
|
||||
return m_ptr[pos];
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
||||
// If we have defined the constant, then we have to undefine it (to avoid bloating in the engine)
|
||||
#ifndef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED
|
||||
#undef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
|
||||
#endif
|
||||
119
include/Nazara/Core/StackVector.hpp
Normal file
119
include/Nazara/Core/StackVector.hpp
Normal file
@@ -0,0 +1,119 @@
|
||||
// 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_STACKVECTOR_HPP
|
||||
#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)
|
||||
#else
|
||||
#define NazaraStackVector(T, capacity) Nz::StackVector<T>(static_cast<T*>(Nz::OperatorNew((capacity) * sizeof(T))), capacity)
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
template<typename T>
|
||||
class StackVector
|
||||
{
|
||||
public:
|
||||
using value_type = T;
|
||||
using const_iterator = const value_type*;
|
||||
using const_pointer = const value_type*;
|
||||
using const_reference = const value_type&;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using iterator = value_type*;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
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();
|
||||
const_reference back() const;
|
||||
|
||||
iterator begin() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
|
||||
size_type capacity() const noexcept;
|
||||
|
||||
void clear() noexcept;
|
||||
|
||||
const_iterator cbegin() const noexcept;
|
||||
const_iterator cend() const noexcept;
|
||||
const_reverse_iterator crbegin() const noexcept;
|
||||
const_reverse_iterator crend() const noexcept;
|
||||
|
||||
T* data() noexcept;
|
||||
const T* data() const noexcept;
|
||||
|
||||
template<typename... Args>
|
||||
iterator emplace(const_iterator pos, Args&&... args);
|
||||
|
||||
template<typename... Args>
|
||||
reference emplace_back(Args&&... args);
|
||||
|
||||
bool empty() const noexcept;
|
||||
|
||||
iterator end() noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
|
||||
iterator erase(const_iterator pos);
|
||||
iterator erase(const_iterator first, const_iterator last);
|
||||
|
||||
reference front() noexcept;
|
||||
const_reference front() const noexcept;
|
||||
|
||||
iterator insert(const_iterator pos, const T& value);
|
||||
iterator insert(const_iterator pos, T&& value);
|
||||
|
||||
size_type max_size() const noexcept;
|
||||
|
||||
reference push_back(const T& value) noexcept(std::is_nothrow_copy_constructible<T>::value);
|
||||
reference push_back(T&& value) noexcept(std::is_nothrow_move_constructible<T>::value);
|
||||
|
||||
void pop_back();
|
||||
|
||||
void resize(size_type count);
|
||||
void resize(size_type count, const value_type& value);
|
||||
|
||||
reverse_iterator rbegin() noexcept;
|
||||
const_reverse_iterator rbegin() const noexcept;
|
||||
|
||||
reverse_iterator rend() noexcept;
|
||||
const_reverse_iterator rend() const noexcept;
|
||||
|
||||
size_type size() const noexcept;
|
||||
|
||||
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;
|
||||
MovablePtr<T> m_ptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include <Nazara/Core/StackVector.inl>
|
||||
|
||||
#endif // NAZARA_STACKVECTOR_HPP
|
||||
347
include/Nazara/Core/StackVector.inl
Normal file
347
include/Nazara/Core/StackVector.inl
Normal file
@@ -0,0 +1,347 @@
|
||||
// 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
|
||||
|
||||
// I'm not proud of those five following lines but ti's hard to do with another way now
|
||||
#ifdef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
|
||||
#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED
|
||||
#else
|
||||
#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
|
||||
#endif
|
||||
|
||||
#include <Nazara/Core/StackVector.hpp>
|
||||
#include <Nazara/Core/MemoryManager.hpp>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \ingroup core
|
||||
* \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),
|
||||
m_size(0),
|
||||
m_ptr(stackMemory)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
StackVector<T>::~StackVector()
|
||||
{
|
||||
clear();
|
||||
|
||||
#ifndef NAZARA_ALLOCA_SUPPORT
|
||||
OperatorDelete(m_ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::reference StackVector<T>::back()
|
||||
{
|
||||
assert(m_size != 0);
|
||||
return m_ptr[m_size - 1];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::const_reference StackVector<T>::back() const
|
||||
{
|
||||
assert(m_size != 0);
|
||||
return m_ptr[m_size - 1];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::iterator StackVector<T>::begin() noexcept
|
||||
{
|
||||
return iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::const_iterator StackVector<T>::begin() const noexcept
|
||||
{
|
||||
return const_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::size_type StackVector<T>::capacity() const noexcept
|
||||
{
|
||||
return m_capacity;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void StackVector<T>::clear() noexcept
|
||||
{
|
||||
resize(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::const_iterator StackVector<T>::cbegin() const noexcept
|
||||
{
|
||||
return const_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::const_iterator StackVector<T>::cend() const noexcept
|
||||
{
|
||||
return const_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::const_reverse_iterator StackVector<T>::crbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::const_reverse_iterator StackVector<T>::crend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* StackVector<T>::data() noexcept
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T* StackVector<T>::data() const noexcept
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename... Args>
|
||||
typename StackVector<T>::iterator StackVector<T>::emplace(const_iterator pos, Args&& ...args)
|
||||
{
|
||||
assert(m_size < m_capacity);
|
||||
assert(pos >= begin() && pos <= end());
|
||||
|
||||
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_backward(&m_ptr[index], &m_ptr[m_size - 1], &m_ptr[m_size]);
|
||||
|
||||
PlacementDestroy(&m_ptr[index]);
|
||||
}
|
||||
m_size++;
|
||||
|
||||
return PlacementNew(&m_ptr[index], std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename... Args>
|
||||
typename StackVector<T>::reference Nz::StackVector<T>::emplace_back(Args&&... args)
|
||||
{
|
||||
assert(m_size < m_capacity);
|
||||
return *PlacementNew(&m_ptr[m_size++], std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool StackVector<T>::empty() const noexcept
|
||||
{
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::iterator StackVector<T>::end() noexcept
|
||||
{
|
||||
return iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::const_iterator StackVector<T>::end() const noexcept
|
||||
{
|
||||
return const_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::iterator StackVector<T>::erase(const_iterator pos)
|
||||
{
|
||||
assert(pos < end());
|
||||
std::size_t index = std::distance(cbegin(), pos);
|
||||
std::move(begin() + index + 1, end(), begin() + index);
|
||||
pop_back();
|
||||
|
||||
return iterator(&m_ptr[index]);
|
||||
}
|
||||
|
||||
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 begin() + index;
|
||||
|
||||
assert(first < last);
|
||||
assert(first >= begin() && last <= end());
|
||||
|
||||
std::size_t count = std::distance(first, last);
|
||||
|
||||
std::move(begin() + index + count, end(), begin() + index);
|
||||
resize(size() - count);
|
||||
|
||||
return iterator(&m_ptr[index]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::reference StackVector<T>::front() noexcept
|
||||
{
|
||||
return m_ptr[0];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::const_reference StackVector<T>::front() const noexcept
|
||||
{
|
||||
return m_ptr[0];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::iterator StackVector<T>::insert(const_iterator pos, const T& value)
|
||||
{
|
||||
return emplace(pos, value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::iterator StackVector<T>::insert(const_iterator pos, T&& value)
|
||||
{
|
||||
return emplace(pos, std::move(value));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::size_type StackVector<T>::max_size() const noexcept
|
||||
{
|
||||
return capacity();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::reference StackVector<T>::push_back(const T& value) noexcept(std::is_nothrow_copy_constructible<T>::value)
|
||||
{
|
||||
assert(m_size < m_capacity);
|
||||
return *PlacementNew(&m_ptr[m_size++], value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::reference StackVector<T>::push_back(T&& value) noexcept(std::is_nothrow_move_constructible<T>::value)
|
||||
{
|
||||
assert(m_size < m_capacity);
|
||||
return *PlacementNew(&m_ptr[m_size++], std::move(value));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void StackVector<T>::pop_back()
|
||||
{
|
||||
assert(!empty());
|
||||
PlacementDestroy(&m_ptr[--m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void StackVector<T>::resize(size_type count)
|
||||
{
|
||||
assert(count <= m_capacity);
|
||||
if (count > m_size)
|
||||
{
|
||||
for (std::size_t i = m_size; i < count; ++i)
|
||||
PlacementNew(&m_ptr[i]);
|
||||
|
||||
m_size = count;
|
||||
}
|
||||
else if (count < m_size)
|
||||
{
|
||||
for (std::size_t i = count; i < m_size; ++i)
|
||||
PlacementDestroy(&m_ptr[i]);
|
||||
|
||||
m_size = count;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void StackVector<T>::resize(size_type count, const value_type& value)
|
||||
{
|
||||
assert(count <= m_capacity);
|
||||
if (count > m_size)
|
||||
{
|
||||
for (std::size_t i = m_size; i < count; ++i)
|
||||
PlacementNew(&m_ptr[i], value);
|
||||
|
||||
m_size = count;
|
||||
}
|
||||
else if (count < m_size)
|
||||
{
|
||||
for (std::size_t i = count; i < m_size; ++i)
|
||||
PlacementDestroy(&m_ptr[i]);
|
||||
|
||||
m_size = count;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::reverse_iterator StackVector<T>::rbegin() noexcept
|
||||
{
|
||||
return reverse_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::const_reverse_iterator StackVector<T>::rbegin() const noexcept
|
||||
{
|
||||
return reverse_iterator(&m_ptr[m_size]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::reverse_iterator StackVector<T>::rend() noexcept
|
||||
{
|
||||
return reverse_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::const_reverse_iterator StackVector<T>::rend() const noexcept
|
||||
{
|
||||
return reverse_iterator(&m_ptr[0]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::size_type StackVector<T>::size() const noexcept
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::reference StackVector<T>::operator[](size_type pos)
|
||||
{
|
||||
assert(pos < m_size);
|
||||
return m_ptr[pos];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename StackVector<T>::const_reference StackVector<T>::operator[](size_type pos) const
|
||||
{
|
||||
assert(pos < m_size);
|
||||
return m_ptr[pos];
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
||||
// If we have defined the constant, then we have to undefine it (to avoid bloating in the engine)
|
||||
#ifndef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED
|
||||
#undef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
|
||||
#endif
|
||||
@@ -41,7 +41,7 @@ namespace Nz
|
||||
|
||||
inline void String::ReleaseString()
|
||||
{
|
||||
m_sharedString = std::move(GetEmptyString());
|
||||
m_sharedString = GetEmptyString();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -10,7 +10,10 @@
|
||||
namespace Nz
|
||||
{
|
||||
template<typename T>
|
||||
struct TypeTag {};
|
||||
struct TypeTag
|
||||
{
|
||||
using Type = T;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NAZARA_TYPETAG_HPP
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Nz
|
||||
Category_Other_PrivateUse = Category_Other | 0x0800, // Co
|
||||
Category_Other_Surrogate = Category_Other | 0x1000, // Cs
|
||||
|
||||
// Ponctuations
|
||||
// Punctuations
|
||||
Category_Punctuation = 0x10, // P
|
||||
Category_Punctuation_Close = Category_Punctuation | 0x0100, // Pe
|
||||
Category_Punctuation_Connector = Category_Punctuation | 0x0200, // Pc
|
||||
@@ -81,25 +81,29 @@ namespace Nz
|
||||
|
||||
enum Direction : UInt8
|
||||
{
|
||||
Direction_Arabic_Letter, // AL
|
||||
Direction_Arabic_Number, // AN
|
||||
Direction_Boundary_Neutral, // BN
|
||||
Direction_Common_Separator, // CS
|
||||
Direction_European_Number, // EN
|
||||
Direction_European_Separator, // ES
|
||||
Direction_European_Terminator, // ET
|
||||
Direction_Left_To_Right, // L
|
||||
Direction_Left_To_Right_Embedding, // LRE
|
||||
Direction_Left_To_Right_Override, // LRO
|
||||
Direction_Nonspacing_Mark, // NSM
|
||||
Direction_Other_Neutral, // ON
|
||||
Direction_Paragraph_Separator, // B
|
||||
Direction_Pop_Directional_Format, // PDF
|
||||
Direction_Right_To_Left, // R
|
||||
Direction_Right_To_Left_Embedding, // RLE
|
||||
Direction_Right_To_Left_Override, // RLO
|
||||
Direction_Segment_Separator, // S
|
||||
Direction_White_Space // WS
|
||||
Direction_Arabic_Letter, // AL
|
||||
Direction_Arabic_Number, // AN
|
||||
Direction_Boundary_Neutral, // BN
|
||||
Direction_Common_Separator, // CS
|
||||
Direction_European_Number, // EN
|
||||
Direction_European_Separator, // ES
|
||||
Direction_European_Terminator, // ET
|
||||
Direction_First_Strong_Isolate, // FSI
|
||||
Direction_Left_To_Right, // L
|
||||
Direction_Left_To_Right_Embedding, // LRE
|
||||
Direction_Left_To_Right_Isolate, // LRI
|
||||
Direction_Left_To_Right_Override, // LRO
|
||||
Direction_Nonspacing_Mark, // NSM
|
||||
Direction_Other_Neutral, // ON
|
||||
Direction_Paragraph_Separator, // B
|
||||
Direction_Pop_Directional_Formatting, // PDF
|
||||
Direction_Pop_Directional_Isolate, // PDI
|
||||
Direction_Right_To_Left, // R
|
||||
Direction_Right_To_Left_Embedding, // RLE
|
||||
Direction_Right_To_Left_Isolate, // RLI
|
||||
Direction_Right_To_Left_Override, // RLO
|
||||
Direction_Segment_Separator, // S
|
||||
Direction_White_Space // WS
|
||||
};
|
||||
|
||||
static Category GetCategory(char32_t character);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Math/Angle.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
@@ -34,14 +35,14 @@ namespace Nz
|
||||
std::unique_ptr<InstancedRenderable> Clone() const override;
|
||||
|
||||
inline const Color& GetColor() const;
|
||||
inline float GetRotation() const;
|
||||
inline const RadianAnglef& GetRotation() const;
|
||||
inline const Vector2f& GetSize() const;
|
||||
|
||||
inline void SetColor(const Color& color);
|
||||
inline void SetDefaultMaterial();
|
||||
inline void SetMaterial(MaterialRef material, bool resizeBillboard = true);
|
||||
inline void SetMaterial(std::size_t skinIndex, MaterialRef material, bool resizeBillboard = true);
|
||||
inline void SetRotation(float rotation);
|
||||
inline void SetRotation(const RadianAnglef& rotation);
|
||||
inline void SetSize(const Vector2f& size);
|
||||
inline void SetSize(float sizeX, float sizeY);
|
||||
inline void SetTexture(TextureRef texture, bool resizeBillboard = true);
|
||||
@@ -58,7 +59,7 @@ namespace Nz
|
||||
Color m_color;
|
||||
Vector2f m_sinCos;
|
||||
Vector2f m_size;
|
||||
float m_rotation;
|
||||
RadianAnglef m_rotation;
|
||||
|
||||
static BillboardLibrary::LibraryMap s_library;
|
||||
};
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace Nz
|
||||
* \return Current rotation
|
||||
*/
|
||||
|
||||
inline float Billboard::GetRotation() const
|
||||
inline const RadianAnglef& Billboard::GetRotation() const
|
||||
{
|
||||
return m_rotation;
|
||||
}
|
||||
@@ -161,10 +161,12 @@ namespace Nz
|
||||
* \param rotation Rotation for the billboard
|
||||
*/
|
||||
|
||||
inline void Billboard::SetRotation(float rotation)
|
||||
inline void Billboard::SetRotation(const RadianAnglef& rotation)
|
||||
{
|
||||
m_rotation = rotation;
|
||||
m_sinCos.Set(std::sin(m_rotation), std::cos(m_rotation));
|
||||
|
||||
auto sincos = rotation.GetSinCos();
|
||||
m_sinCos.Set(sincos.first, sincos.second);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -23,11 +23,13 @@ namespace Nz
|
||||
{
|
||||
public:
|
||||
template<CullTest> class Entry;
|
||||
class BoxEntry;
|
||||
class NoTestEntry;
|
||||
class SphereEntry;
|
||||
class VolumeEntry;
|
||||
|
||||
template<CullTest> friend class Entry;
|
||||
friend BoxEntry;
|
||||
friend NoTestEntry;
|
||||
friend SphereEntry;
|
||||
friend VolumeEntry;
|
||||
@@ -41,6 +43,12 @@ namespace Nz
|
||||
|
||||
std::size_t Cull(const Frustumf& frustum, bool* forceInvalidation = nullptr);
|
||||
|
||||
std::size_t FillWithAllEntries(bool* forceInvalidation = nullptr);
|
||||
|
||||
const ResultContainer& GetFullyVisibleResults() const;
|
||||
const ResultContainer& GetPartiallyVisibleResults() const;
|
||||
|
||||
BoxEntry RegisterBoxTest(const T* renderable);
|
||||
NoTestEntry RegisterNoTest(const T* renderable);
|
||||
SphereEntry RegisterSphereTest(const T* renderable);
|
||||
VolumeEntry RegisterVolumeTest(const T* renderable);
|
||||
@@ -48,37 +56,24 @@ namespace Nz
|
||||
CullingList& operator=(const CullingList& renderable) = delete;
|
||||
CullingList& operator=(CullingList&& renderable) = delete;
|
||||
|
||||
// STL API
|
||||
typename ResultContainer::iterator begin();
|
||||
typename ResultContainer::const_iterator begin() const;
|
||||
|
||||
typename ResultContainer::const_iterator cbegin() const;
|
||||
typename ResultContainer::const_iterator cend() const;
|
||||
typename ResultContainer::const_reverse_iterator crbegin() const;
|
||||
typename ResultContainer::const_reverse_iterator crend() const;
|
||||
|
||||
bool empty() const;
|
||||
|
||||
typename ResultContainer::iterator end();
|
||||
typename ResultContainer::const_iterator end() const;
|
||||
|
||||
typename ResultContainer::reverse_iterator rbegin();
|
||||
typename ResultContainer::const_reverse_iterator rbegin() const;
|
||||
|
||||
typename ResultContainer::reverse_iterator rend();
|
||||
typename ResultContainer::const_reverse_iterator rend() const;
|
||||
|
||||
typename ResultContainer::size_type size() const;
|
||||
|
||||
NazaraSignal(OnCullingListRelease, CullingList* /*cullingList*/);
|
||||
|
||||
private:
|
||||
inline void NotifyBoxUpdate(std::size_t index, const Boxf& boundingVolume);
|
||||
inline void NotifyForceInvalidation(CullTest type, std::size_t index);
|
||||
inline void NotifyMovement(CullTest type, std::size_t index, void* oldPtr, void* newPtr);
|
||||
inline void NotifyRelease(CullTest type, std::size_t index);
|
||||
inline void NotifySphereUpdate(std::size_t index, const Spheref& sphere);
|
||||
inline void NotifyVolumeUpdate(std::size_t index, const BoundingVolumef& boundingVolume);
|
||||
|
||||
struct BoxVisibilityEntry
|
||||
{
|
||||
Boxf box;
|
||||
BoxEntry* entry;
|
||||
const T* renderable;
|
||||
bool forceInvalidation;
|
||||
};
|
||||
|
||||
struct NoTestVisibilityEntry
|
||||
{
|
||||
NoTestEntry* entry;
|
||||
@@ -102,10 +97,12 @@ namespace Nz
|
||||
bool forceInvalidation;
|
||||
};
|
||||
|
||||
std::vector<BoxVisibilityEntry> m_boxTestList;
|
||||
std::vector<NoTestVisibilityEntry> m_noTestList;
|
||||
std::vector<SphereVisibilityEntry> m_sphereTestList;
|
||||
std::vector<VolumeVisibilityEntry> m_volumeTestList;
|
||||
ResultContainer m_results;
|
||||
ResultContainer m_fullyVisibleResults;
|
||||
ResultContainer m_partiallyVisibleResults;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -133,43 +130,73 @@ namespace Nz
|
||||
std::size_t m_index;
|
||||
CullingList* m_parent;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CullingList<T>::BoxEntry : public CullingList<T>::template Entry<CullTest::Box>
|
||||
{
|
||||
friend CullingList;
|
||||
|
||||
public:
|
||||
BoxEntry();
|
||||
BoxEntry(BoxEntry&&) = default;
|
||||
~BoxEntry() = default;
|
||||
|
||||
void UpdateBox(const Boxf& box);
|
||||
|
||||
BoxEntry& operator=(BoxEntry&&) = default;
|
||||
|
||||
private:
|
||||
BoxEntry(CullingList* parent, std::size_t index);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CullingList<T>::NoTestEntry : public CullingList::template Entry<CullTest::NoTest>
|
||||
class CullingList<T>::NoTestEntry : public CullingList<T>::template Entry<CullTest::NoTest>
|
||||
{
|
||||
friend CullingList;
|
||||
|
||||
public:
|
||||
NoTestEntry();
|
||||
NoTestEntry(NoTestEntry&&) = default;
|
||||
~NoTestEntry() = default;
|
||||
|
||||
NoTestEntry& operator=(NoTestEntry&&) = default;
|
||||
|
||||
private:
|
||||
NoTestEntry(CullingList* parent, std::size_t index);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CullingList<T>::SphereEntry : public CullingList::template Entry<CullTest::Sphere>
|
||||
class CullingList<T>::SphereEntry : public CullingList<T>::template Entry<CullTest::Sphere>
|
||||
{
|
||||
friend CullingList;
|
||||
|
||||
public:
|
||||
SphereEntry();
|
||||
SphereEntry(SphereEntry&&) = default;
|
||||
~SphereEntry() = default;
|
||||
|
||||
void UpdateSphere(const Spheref& sphere);
|
||||
|
||||
SphereEntry& operator=(SphereEntry&&) = default;
|
||||
|
||||
private:
|
||||
SphereEntry(CullingList* parent, std::size_t index);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CullingList<T>::VolumeEntry : public CullingList::template Entry<CullTest::Volume>
|
||||
class CullingList<T>::VolumeEntry : public CullingList<T>::template Entry<CullTest::Volume>
|
||||
{
|
||||
friend CullingList;
|
||||
|
||||
public:
|
||||
VolumeEntry();
|
||||
VolumeEntry(VolumeEntry&&) = default;
|
||||
~VolumeEntry() = default;
|
||||
|
||||
void UpdateVolume(const BoundingVolumef& sphere);
|
||||
|
||||
VolumeEntry& operator=(VolumeEntry&&) = default;
|
||||
|
||||
private:
|
||||
VolumeEntry(CullingList* parent, std::size_t index);
|
||||
};
|
||||
|
||||
@@ -16,16 +16,48 @@ namespace Nz
|
||||
template<typename T>
|
||||
std::size_t CullingList<T>::Cull(const Frustumf& frustum, bool* forceInvalidation)
|
||||
{
|
||||
m_results.clear();
|
||||
m_fullyVisibleResults.clear();
|
||||
m_partiallyVisibleResults.clear();
|
||||
|
||||
bool forcedInvalidation = false;
|
||||
|
||||
std::size_t visibleHash = 0U;
|
||||
std::size_t fullyVisibleHash = 5U;
|
||||
std::size_t partiallyVisibleHash = 5U;
|
||||
|
||||
auto CombineHash = [](std::size_t currentHash, std::size_t newHash)
|
||||
{
|
||||
return currentHash * 23 + newHash;
|
||||
};
|
||||
|
||||
for (BoxVisibilityEntry& entry : m_boxTestList)
|
||||
{
|
||||
switch (frustum.Intersect(entry.box))
|
||||
{
|
||||
case IntersectionSide_Inside:
|
||||
m_fullyVisibleResults.push_back(entry.renderable);
|
||||
fullyVisibleHash = CombineHash(fullyVisibleHash, std::hash<const T*>()(entry.renderable));
|
||||
|
||||
forcedInvalidation = forcedInvalidation | entry.forceInvalidation;
|
||||
entry.forceInvalidation = false;
|
||||
break;
|
||||
|
||||
case IntersectionSide_Intersecting:
|
||||
m_partiallyVisibleResults.push_back(entry.renderable);
|
||||
partiallyVisibleHash = CombineHash(partiallyVisibleHash, std::hash<const T*>()(entry.renderable));
|
||||
|
||||
forcedInvalidation = forcedInvalidation | entry.forceInvalidation;
|
||||
entry.forceInvalidation = false;
|
||||
break;
|
||||
|
||||
case IntersectionSide_Outside:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (NoTestVisibilityEntry& entry : m_noTestList)
|
||||
{
|
||||
m_results.push_back(entry.renderable);
|
||||
Nz::HashCombine(visibleHash, entry.renderable);
|
||||
m_fullyVisibleResults.push_back(entry.renderable);
|
||||
CombineHash(fullyVisibleHash, std::hash<const T*>()(entry.renderable));
|
||||
|
||||
if (entry.forceInvalidation)
|
||||
{
|
||||
@@ -36,34 +68,87 @@ namespace Nz
|
||||
|
||||
for (SphereVisibilityEntry& entry : m_sphereTestList)
|
||||
{
|
||||
if (frustum.Contains(entry.sphere))
|
||||
switch (frustum.Intersect(entry.sphere))
|
||||
{
|
||||
m_results.push_back(entry.renderable);
|
||||
Nz::HashCombine(visibleHash, entry.renderable);
|
||||
case IntersectionSide_Inside:
|
||||
m_fullyVisibleResults.push_back(entry.renderable);
|
||||
fullyVisibleHash = CombineHash(fullyVisibleHash, std::hash<const T*>()(entry.renderable));
|
||||
|
||||
if (entry.forceInvalidation)
|
||||
{
|
||||
forcedInvalidation = true;
|
||||
forcedInvalidation = forcedInvalidation | entry.forceInvalidation;
|
||||
entry.forceInvalidation = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case IntersectionSide_Intersecting:
|
||||
m_partiallyVisibleResults.push_back(entry.renderable);
|
||||
partiallyVisibleHash = CombineHash(partiallyVisibleHash, std::hash<const T*>()(entry.renderable));
|
||||
|
||||
forcedInvalidation = forcedInvalidation | entry.forceInvalidation;
|
||||
entry.forceInvalidation = false;
|
||||
break;
|
||||
|
||||
case IntersectionSide_Outside:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (VolumeVisibilityEntry& entry : m_volumeTestList)
|
||||
{
|
||||
if (frustum.Contains(entry.volume))
|
||||
switch (frustum.Intersect(entry.volume))
|
||||
{
|
||||
m_results.push_back(entry.renderable);
|
||||
Nz::HashCombine(visibleHash, entry.renderable);
|
||||
case IntersectionSide_Inside:
|
||||
m_fullyVisibleResults.push_back(entry.renderable);
|
||||
fullyVisibleHash = CombineHash(fullyVisibleHash, std::hash<const T*>()(entry.renderable));
|
||||
|
||||
if (entry.forceInvalidation)
|
||||
{
|
||||
forcedInvalidation = true;
|
||||
forcedInvalidation = forcedInvalidation | entry.forceInvalidation;
|
||||
entry.forceInvalidation = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case IntersectionSide_Intersecting:
|
||||
m_partiallyVisibleResults.push_back(entry.renderable);
|
||||
partiallyVisibleHash = CombineHash(partiallyVisibleHash, std::hash<const T*>()(entry.renderable));
|
||||
|
||||
forcedInvalidation = forcedInvalidation | entry.forceInvalidation;
|
||||
entry.forceInvalidation = false;
|
||||
break;
|
||||
|
||||
case IntersectionSide_Outside:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (forceInvalidation)
|
||||
*forceInvalidation = forcedInvalidation;
|
||||
|
||||
return 5 + partiallyVisibleHash * 17 + fullyVisibleHash;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::size_t CullingList<T>::FillWithAllEntries(bool* forceInvalidation)
|
||||
{
|
||||
m_fullyVisibleResults.clear();
|
||||
m_partiallyVisibleResults.clear();
|
||||
|
||||
bool forcedInvalidation = false;
|
||||
|
||||
std::size_t visibleHash = 5U;
|
||||
|
||||
auto FillWithList = [&](auto& testList)
|
||||
{
|
||||
for (auto& entry : testList)
|
||||
{
|
||||
m_fullyVisibleResults.push_back(entry.renderable);
|
||||
visibleHash = visibleHash * 23 + std::hash<const T*>()(entry.renderable);
|
||||
|
||||
forcedInvalidation = forcedInvalidation | entry.forceInvalidation;
|
||||
entry.forceInvalidation = false;
|
||||
}
|
||||
};
|
||||
|
||||
FillWithList(m_boxTestList);
|
||||
FillWithList(m_noTestList);
|
||||
FillWithList(m_sphereTestList);
|
||||
FillWithList(m_volumeTestList);
|
||||
|
||||
if (forceInvalidation)
|
||||
*forceInvalidation = forcedInvalidation;
|
||||
|
||||
@@ -71,115 +156,57 @@ namespace Nz
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::NoTestEntry CullingList<T>::RegisterNoTest(const T* renderable)
|
||||
auto CullingList<T>::GetFullyVisibleResults() const -> const ResultContainer&
|
||||
{
|
||||
NoTestEntry entry(this, m_noTestList.size());
|
||||
m_noTestList.emplace_back(NoTestVisibilityEntry{&entry, renderable, false}); //< Address of entry will be updated when moving
|
||||
|
||||
return entry;
|
||||
return m_fullyVisibleResults;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::SphereEntry CullingList<T>::RegisterSphereTest(const T* renderable)
|
||||
auto CullingList<T>::GetPartiallyVisibleResults() const -> const ResultContainer&
|
||||
{
|
||||
SphereEntry entry(this, m_sphereTestList.size());
|
||||
m_sphereTestList.emplace_back(SphereVisibilityEntry{Nz::Spheref(), &entry, renderable, false}); //< Address of entry will be updated when moving
|
||||
|
||||
return entry;
|
||||
return m_partiallyVisibleResults;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::VolumeEntry CullingList<T>::RegisterVolumeTest(const T* renderable)
|
||||
auto CullingList<T>::RegisterBoxTest(const T* renderable) -> BoxEntry
|
||||
{
|
||||
VolumeEntry entry(this, m_volumeTestList.size());
|
||||
m_volumeTestList.emplace_back(VolumeVisibilityEntry{Nz::BoundingVolumef(), &entry, renderable, false}); //< Address of entry will be updated when moving
|
||||
BoxEntry newEntry(this, m_boxTestList.size());
|
||||
m_boxTestList.emplace_back(BoxVisibilityEntry{ Nz::Boxf(), &newEntry, renderable, false }); //< Address of entry will be updated when moving
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
// Interface STD
|
||||
template<typename T>
|
||||
typename CullingList<T>::ResultContainer::iterator CullingList<T>::begin()
|
||||
{
|
||||
return m_results.begin();
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::ResultContainer::const_iterator CullingList<T>::begin() const
|
||||
auto CullingList<T>::RegisterNoTest(const T* renderable) -> NoTestEntry
|
||||
{
|
||||
return m_results.begin();
|
||||
NoTestEntry newEntry(this, m_volumeTestList.size());
|
||||
m_noTestList.emplace_back(NoTestVisibilityEntry{&newEntry, renderable, false}); //< Address of entry will be updated when moving
|
||||
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::ResultContainer::const_iterator CullingList<T>::cbegin() const
|
||||
auto CullingList<T>::RegisterSphereTest(const T* renderable) -> SphereEntry
|
||||
{
|
||||
return m_results.cbegin();
|
||||
SphereEntry newEntry(this, m_sphereTestList.size());
|
||||
m_sphereTestList.emplace_back(SphereVisibilityEntry{Nz::Spheref(), &newEntry, renderable, false}); //< Address of entry will be updated when moving
|
||||
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::ResultContainer::const_iterator CullingList<T>::cend() const
|
||||
auto CullingList<T>::RegisterVolumeTest(const T* renderable) -> VolumeEntry
|
||||
{
|
||||
return m_results.cend();
|
||||
VolumeEntry newEntry(this, m_volumeTestList.size());
|
||||
m_volumeTestList.emplace_back(VolumeVisibilityEntry{Nz::BoundingVolumef(), &newEntry, renderable, false}); //< Address of entry will be updated when moving
|
||||
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::ResultContainer::const_reverse_iterator CullingList<T>::crbegin() const
|
||||
inline void CullingList<T>::NotifyBoxUpdate(std::size_t index, const Boxf& box)
|
||||
{
|
||||
return m_results.crbegin();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::ResultContainer::const_reverse_iterator CullingList<T>::crend() const
|
||||
{
|
||||
return m_results.crend();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool CullingList<T>::empty() const
|
||||
{
|
||||
return m_results.empty();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::ResultContainer::iterator CullingList<T>::end()
|
||||
{
|
||||
return m_results.end();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::ResultContainer::const_iterator CullingList<T>::end() const
|
||||
{
|
||||
return m_results.end();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::ResultContainer::reverse_iterator CullingList<T>::rbegin()
|
||||
{
|
||||
return m_results.rbegin();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::ResultContainer::const_reverse_iterator CullingList<T>::rbegin() const
|
||||
{
|
||||
return m_results.rbegin();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::ResultContainer::reverse_iterator CullingList<T>::rend()
|
||||
{
|
||||
return m_results.rend();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::ResultContainer::const_reverse_iterator CullingList<T>::rend() const
|
||||
{
|
||||
return m_results.rend();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename CullingList<T>::ResultContainer::size_type CullingList<T>::size() const
|
||||
{
|
||||
return m_results.size();
|
||||
m_boxTestList[index].box = box;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -187,6 +214,12 @@ namespace Nz
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case CullTest::Box:
|
||||
{
|
||||
m_boxTestList[index].forceInvalidation = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case CullTest::NoTest:
|
||||
{
|
||||
m_noTestList[index].forceInvalidation = true;
|
||||
@@ -218,6 +251,15 @@ namespace Nz
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CullTest::Box:
|
||||
{
|
||||
BoxVisibilityEntry& entry = m_boxTestList[index];
|
||||
NazaraAssert(entry.entry == oldPtr, "Invalid box entry");
|
||||
|
||||
entry.entry = static_cast<BoxEntry*>(newPtr);
|
||||
break;
|
||||
}
|
||||
|
||||
case CullTest::NoTest:
|
||||
{
|
||||
NoTestVisibilityEntry& entry = m_noTestList[index];
|
||||
@@ -256,6 +298,14 @@ namespace Nz
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case CullTest::Box:
|
||||
{
|
||||
m_boxTestList[index] = std::move(m_boxTestList.back());
|
||||
m_boxTestList[index].entry->UpdateIndex(index);
|
||||
m_boxTestList.pop_back();
|
||||
break;
|
||||
}
|
||||
|
||||
case CullTest::NoTest:
|
||||
{
|
||||
m_noTestList[index] = std::move(m_noTestList.back());
|
||||
@@ -358,12 +408,7 @@ namespace Nz
|
||||
|
||||
template<typename T>
|
||||
template<CullTest Type>
|
||||
#ifdef NAZARA_COMPILER_MSVC
|
||||
// MSVC bug
|
||||
typename CullingList<T>::Entry<Type>& CullingList<T>::Entry<Type>::operator=(Entry&& entry)
|
||||
#else
|
||||
typename CullingList<T>::template Entry<Type>& CullingList<T>::Entry<Type>::operator=(Entry&& entry)
|
||||
#endif
|
||||
{
|
||||
m_index = entry.m_index;
|
||||
m_parent = entry.m_parent;
|
||||
@@ -374,6 +419,26 @@ namespace Nz
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename T>
|
||||
CullingList<T>::BoxEntry::BoxEntry() :
|
||||
Entry<CullTest::Box>()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
CullingList<T>::BoxEntry::BoxEntry(CullingList* parent, std::size_t index) :
|
||||
Entry<CullTest::Box>(parent, index)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void CullingList<T>::BoxEntry::UpdateBox(const Boxf& box)
|
||||
{
|
||||
this->m_parent->NotifyBoxUpdate(this->m_index, box);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace Nz
|
||||
|
||||
enum class CullTest
|
||||
{
|
||||
Box,
|
||||
NoTest,
|
||||
Sphere,
|
||||
Volume
|
||||
|
||||
@@ -83,6 +83,7 @@ namespace Nz
|
||||
inline void EnableShadowCasting(bool castShadows);
|
||||
inline void EnableShadowReceive(bool receiveShadows);
|
||||
inline void EnableStencilTest(bool stencilTest);
|
||||
inline void EnableVertexColor(bool vertexColor);
|
||||
|
||||
inline void EnsurePipelineUpdate() const;
|
||||
|
||||
@@ -121,6 +122,7 @@ namespace Nz
|
||||
inline bool HasHeightMap() const;
|
||||
inline bool HasNormalMap() const;
|
||||
inline bool HasSpecularMap() const;
|
||||
inline bool HasVertexColor() const;
|
||||
|
||||
inline bool IsAlphaTestEnabled() const;
|
||||
inline bool IsBlendingEnabled() const;
|
||||
@@ -135,10 +137,6 @@ namespace Nz
|
||||
inline bool IsShadowCastingEnabled() const;
|
||||
inline bool IsShadowReceiveEnabled() const;
|
||||
|
||||
inline bool LoadFromFile(const String& filePath, const MaterialParams& params = MaterialParams());
|
||||
inline bool LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params = MaterialParams());
|
||||
inline bool LoadFromStream(Stream& stream, const MaterialParams& params = MaterialParams());
|
||||
|
||||
void Reset();
|
||||
|
||||
void SaveToParameters(ParameterList* matData);
|
||||
@@ -178,6 +176,11 @@ namespace Nz
|
||||
|
||||
inline static MaterialRef GetDefault();
|
||||
inline static int GetTextureUnit(TextureMap textureMap);
|
||||
|
||||
static inline MaterialRef LoadFromFile(const String& filePath, const MaterialParams& params = MaterialParams());
|
||||
static inline MaterialRef LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params = MaterialParams());
|
||||
static inline MaterialRef LoadFromStream(Stream& stream, const MaterialParams& params = MaterialParams());
|
||||
|
||||
template<typename... Args> static MaterialRef New(Args&&... args);
|
||||
|
||||
// Signals:
|
||||
|
||||
@@ -72,7 +72,8 @@ namespace Nz
|
||||
*/
|
||||
inline Material::Material(const Material& material) :
|
||||
RefCounted(),
|
||||
Resource(material)
|
||||
Resource(material),
|
||||
m_reflectionMode(ReflectionMode_Skybox)
|
||||
{
|
||||
Copy(material);
|
||||
}
|
||||
@@ -118,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();
|
||||
}
|
||||
|
||||
@@ -392,6 +401,25 @@ namespace Nz
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable/Disable vertex coloring on this material
|
||||
*
|
||||
* This is a temporary option, until the new material pipeline system is ready, allowing to enable vertex coloring.
|
||||
* This option only works with meshes using vertex colors.
|
||||
*
|
||||
* \param vertexColor Defines if this material will use vertex color or not
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*
|
||||
* \see HasVertexColor
|
||||
*/
|
||||
inline void Material::EnableVertexColor(bool vertexColor)
|
||||
{
|
||||
m_pipelineInfo.hasVertexColor = vertexColor;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Ensures the pipeline gets updated
|
||||
*
|
||||
@@ -756,6 +784,15 @@ namespace Nz
|
||||
return m_specularMap.IsValid();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this material uses vertex coloring
|
||||
* \return true If it is the case
|
||||
*/
|
||||
inline bool Material::HasVertexColor() const
|
||||
{
|
||||
return m_pipelineInfo.hasVertexColor;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this material has alpha test enabled
|
||||
* \return true If it is the case
|
||||
@@ -866,43 +903,6 @@ namespace Nz
|
||||
return m_pipelineInfo.shadowReceive;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the material from file
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param filePath Path to the file
|
||||
* \param params Parameters for the material
|
||||
*/
|
||||
inline bool Material::LoadFromFile(const String& filePath, const MaterialParams& params)
|
||||
{
|
||||
return MaterialLoader::LoadFromFile(this, filePath, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the material from memory
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param data Raw memory
|
||||
* \param size Size of the memory
|
||||
* \param params Parameters for the material
|
||||
*/
|
||||
inline bool Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params)
|
||||
{
|
||||
return MaterialLoader::LoadFromMemory(this, data, size, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the material from stream
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param stream Stream to the material
|
||||
* \param params Parameters for the material
|
||||
*/
|
||||
inline bool Material::LoadFromStream(Stream& stream, const MaterialParams& params)
|
||||
{
|
||||
return MaterialLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the alpha map by name
|
||||
* \return true If successful
|
||||
@@ -1437,6 +1437,43 @@ namespace Nz
|
||||
return s_textureUnits[textureMap];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the material from file
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param filePath Path to the file
|
||||
* \param params Parameters for the material
|
||||
*/
|
||||
inline MaterialRef Material::LoadFromFile(const String& filePath, const MaterialParams& params)
|
||||
{
|
||||
return MaterialLoader::LoadFromFile(filePath, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the material from memory
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param data Raw memory
|
||||
* \param size Size of the memory
|
||||
* \param params Parameters for the material
|
||||
*/
|
||||
inline MaterialRef Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params)
|
||||
{
|
||||
return MaterialLoader::LoadFromMemory(data, size, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Loads the material from stream
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param stream Stream to the material
|
||||
* \param params Parameters for the material
|
||||
*/
|
||||
inline MaterialRef Material::LoadFromStream(Stream& stream, const MaterialParams& params)
|
||||
{
|
||||
return MaterialLoader::LoadFromStream(stream, params);
|
||||
}
|
||||
|
||||
inline void Material::InvalidatePipeline()
|
||||
{
|
||||
m_pipelineUpdated = false;
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace Nz
|
||||
bool hasHeightMap = false;
|
||||
bool hasNormalMap = false;
|
||||
bool hasSpecularMap = false;
|
||||
bool hasVertexColor = false;
|
||||
bool reflectionMapping = false;
|
||||
bool shadowReceive = true;
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ namespace Nz
|
||||
NazaraPipelineBoolMember(hasHeightMap);
|
||||
NazaraPipelineBoolMember(hasNormalMap);
|
||||
NazaraPipelineBoolMember(hasSpecularMap);
|
||||
NazaraPipelineBoolMember(hasVertexColor);
|
||||
NazaraPipelineBoolMember(reflectionMapping);
|
||||
NazaraPipelineBoolMember(shadowReceive);
|
||||
|
||||
@@ -127,6 +128,7 @@ namespace std
|
||||
NazaraPipelineBoolMember(hasHeightMap);
|
||||
NazaraPipelineBoolMember(hasNormalMap);
|
||||
NazaraPipelineBoolMember(hasSpecularMap);
|
||||
NazaraPipelineBoolMember(hasVertexColor);
|
||||
NazaraPipelineBoolMember(reflectionMapping);
|
||||
NazaraPipelineBoolMember(shadowReceive);
|
||||
|
||||
|
||||
@@ -65,10 +65,6 @@ namespace Nz
|
||||
|
||||
virtual bool IsAnimated() const;
|
||||
|
||||
bool LoadFromFile(const String& filePath, const ModelParameters& params = ModelParameters());
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params = ModelParameters());
|
||||
bool LoadFromStream(Stream& stream, const ModelParameters& params = ModelParameters());
|
||||
|
||||
using InstancedRenderable::SetMaterial;
|
||||
bool SetMaterial(const String& subMeshName, MaterialRef material);
|
||||
bool SetMaterial(std::size_t skinIndex, const String& subMeshName, MaterialRef material);
|
||||
@@ -78,6 +74,10 @@ namespace Nz
|
||||
Model& operator=(const Model& node) = default;
|
||||
Model& operator=(Model&& node) = delete;
|
||||
|
||||
static ModelRef LoadFromFile(const String& filePath, const ModelParameters& params = ModelParameters());
|
||||
static ModelRef LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params = ModelParameters());
|
||||
static ModelRef LoadFromStream(Stream& stream, const ModelParameters& params = ModelParameters());
|
||||
|
||||
template<typename... Args> static ModelRef New(Args&&... args);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -25,6 +25,14 @@ namespace Nz
|
||||
InstancedRenderable(model)
|
||||
{
|
||||
SetMesh(model.m_mesh);
|
||||
|
||||
// Since SetMesh does reset materials, we need reapply them
|
||||
SetSkinCount(model.GetSkinCount());
|
||||
for (std::size_t skin = 0; skin < model.GetSkinCount(); ++skin)
|
||||
{
|
||||
for (std::size_t matIndex = 0; matIndex < model.GetMaterialCount(); ++matIndex)
|
||||
SetMaterial(skin, matIndex, model.GetMaterial(skin, matIndex));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -51,7 +59,6 @@ namespace Nz
|
||||
*
|
||||
* \param args Arguments for the model
|
||||
*/
|
||||
|
||||
template<typename... Args>
|
||||
ModelRef Model::New(Args&&... args)
|
||||
{
|
||||
|
||||
@@ -26,12 +26,10 @@ namespace Nz
|
||||
|
||||
class SkeletalModel;
|
||||
|
||||
using SkeletalModelLoader = ResourceLoader<SkeletalModel, SkeletalModelParameters>;
|
||||
using SkeletalModelRef = ObjectRef<SkeletalModel>;
|
||||
|
||||
class NAZARA_GRAPHICS_API SkeletalModel : public Model, Updatable
|
||||
{
|
||||
friend SkeletalModelLoader;
|
||||
|
||||
public:
|
||||
SkeletalModel();
|
||||
SkeletalModel(const SkeletalModel& model) = default;
|
||||
@@ -55,10 +53,6 @@ namespace Nz
|
||||
bool IsAnimated() const override;
|
||||
bool IsAnimationEnabled() const;
|
||||
|
||||
bool LoadFromFile(const String& filePath, const SkeletalModelParameters& params = SkeletalModelParameters());
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const SkeletalModelParameters& params = SkeletalModelParameters());
|
||||
bool LoadFromStream(Stream& stream, const SkeletalModelParameters& params = SkeletalModelParameters());
|
||||
|
||||
bool SetAnimation(Animation* animation);
|
||||
void SetMesh(Mesh* mesh) override;
|
||||
bool SetSequence(const String& sequenceName);
|
||||
@@ -67,6 +61,8 @@ namespace Nz
|
||||
SkeletalModel& operator=(const SkeletalModel& node) = default;
|
||||
SkeletalModel& operator=(SkeletalModel&& node) = default;
|
||||
|
||||
template<typename... Args> static SkeletalModelRef New(Args&&... args);
|
||||
|
||||
private:
|
||||
void MakeBoundingVolume() const override;
|
||||
/*void Register() override;
|
||||
@@ -80,9 +76,9 @@ namespace Nz
|
||||
float m_interpolation;
|
||||
unsigned int m_currentFrame;
|
||||
unsigned int m_nextFrame;
|
||||
|
||||
static SkeletalModelLoader::LoaderList s_loaders;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/SkeletalModel.inl>
|
||||
|
||||
#endif // NAZARA_SKELETALMODEL_HPP
|
||||
|
||||
27
include/Nazara/Graphics/SkeletalModel.inl
Normal file
27
include/Nazara/Graphics/SkeletalModel.inl
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/SkeletalModel.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \brief Creates a new SkeletalModel from the arguments
|
||||
* \return A reference to the newly created SkeletalModel
|
||||
*
|
||||
* \param args Arguments for the skeletal model
|
||||
*/
|
||||
template<typename... Args>
|
||||
SkeletalModelRef SkeletalModel::New(Args&&... args)
|
||||
{
|
||||
std::unique_ptr<SkeletalModel> object(new SkeletalModel(std::forward<Args>(args)...));
|
||||
object->SetPersistent(false);
|
||||
|
||||
return object.release();
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -29,7 +29,7 @@ namespace Nz
|
||||
inline Sprite();
|
||||
inline Sprite(MaterialRef material);
|
||||
inline Sprite(Texture* texture);
|
||||
inline Sprite(const Sprite& sprite);
|
||||
Sprite(const Sprite&) = default;
|
||||
Sprite(Sprite&&) = delete;
|
||||
~Sprite() = default;
|
||||
|
||||
|
||||
@@ -50,21 +50,6 @@ namespace Nz
|
||||
SetTexture(texture, true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Sprite object by assignation
|
||||
*
|
||||
* \param sprite Sprite to copy into this
|
||||
*/
|
||||
|
||||
inline Sprite::Sprite(const Sprite& sprite) :
|
||||
InstancedRenderable(sprite),
|
||||
m_color(sprite.m_color),
|
||||
m_textureCoords(sprite.m_textureCoords),
|
||||
m_size(sprite.m_size),
|
||||
m_origin(sprite.m_origin)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the color of the sprite
|
||||
*
|
||||
@@ -295,8 +280,10 @@ namespace Nz
|
||||
else
|
||||
{
|
||||
material->SetDiffuseMap(std::move(texture));
|
||||
if (resizeSprite && texture && texture->IsValid())
|
||||
SetSize(Vector2f(Vector2ui(texture->GetSize())));
|
||||
const TextureRef& newTexture = material->GetDiffuseMap();
|
||||
|
||||
if (resizeSprite && newTexture && newTexture->IsValid())
|
||||
SetSize(Vector2f(Vector2ui(newTexture->GetSize())));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Nz
|
||||
struct Tile;
|
||||
|
||||
inline TileMap(const Nz::Vector2ui& mapSize, const Nz::Vector2f& tileSize, std::size_t materialCount = 1);
|
||||
TileMap(const TileMap& TileMap) = default;
|
||||
TileMap(const TileMap&) = default;
|
||||
TileMap(TileMap&&) = delete;
|
||||
~TileMap() = default;
|
||||
|
||||
|
||||
@@ -149,8 +149,8 @@ namespace Nz
|
||||
m_layers[materialIndex].tiles.insert(tileIndex);
|
||||
else if (materialIndex != tile.layerIndex)
|
||||
{
|
||||
m_layers[materialIndex].tiles.erase(tileIndex);
|
||||
m_layers[tile.layerIndex].tiles.insert(tileIndex);
|
||||
m_layers[tile.layerIndex].tiles.erase(tileIndex);
|
||||
m_layers[materialIndex].tiles.insert(tileIndex);
|
||||
|
||||
invalidatedLayers |= 1U << tile.layerIndex;
|
||||
}
|
||||
@@ -285,8 +285,8 @@ namespace Nz
|
||||
m_layers[materialIndex].tiles.insert(tileIndex);
|
||||
else if (materialIndex != tile.layerIndex)
|
||||
{
|
||||
m_layers[materialIndex].tiles.erase(tileIndex);
|
||||
m_layers[tile.layerIndex].tiles.insert(tileIndex);
|
||||
m_layers[tile.layerIndex].tiles.erase(tileIndex);
|
||||
m_layers[materialIndex].tiles.insert(tileIndex);
|
||||
|
||||
invalidatedLayers |= 1U << tile.layerIndex;
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@ namespace Nz
|
||||
{
|
||||
LuaState::operator=(std::move(instance));
|
||||
|
||||
m_ref = instance.m_ref;
|
||||
instance.m_ref = -1;
|
||||
std::swap(m_ref, instance.m_ref);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -157,6 +157,8 @@ namespace Nz
|
||||
void* PushUserdata(std::size_t size) const;
|
||||
void PushValue(int index) const;
|
||||
|
||||
bool RawEqual(int index1, int index2) const;
|
||||
|
||||
void Remove(int index) const;
|
||||
void Replace(int index) const;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Algorithm.hpp>
|
||||
#include <Nazara/Core/CallOnExit.hpp>
|
||||
#include <Nazara/Core/Flags.hpp>
|
||||
#include <Nazara/Core/MemoryHelper.hpp>
|
||||
#include <Nazara/Core/StringStream.hpp>
|
||||
@@ -159,6 +160,35 @@ namespace Nz
|
||||
return LuaImplQueryArg(instance, index, arg, defValue, TypeTag<T>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
unsigned int LuaImplQueryArg(const LuaState& instance, int index, std::vector<T>* container, TypeTag<std::vector<T>>)
|
||||
{
|
||||
instance.CheckType(index, Nz::LuaType_Table);
|
||||
std::size_t pos = 1;
|
||||
|
||||
container->clear();
|
||||
for (;;)
|
||||
{
|
||||
Nz::CallOnExit popStack { [&instance]() { instance.Pop(); } };
|
||||
instance.PushInteger(pos++);
|
||||
|
||||
int tableIndex = (index < 0) ? index - 1 : index;
|
||||
if (instance.GetTable(tableIndex) == Nz::LuaType_Nil)
|
||||
break;
|
||||
|
||||
T arg;
|
||||
if (LuaImplQueryArg(instance, -1, &arg, TypeTag<T>()) != 1)
|
||||
{
|
||||
instance.Error("Type needs more than one place to be initialized");
|
||||
return 0;
|
||||
}
|
||||
|
||||
container->push_back(arg);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Function returns
|
||||
inline int LuaImplReplyVal(const LuaState& instance, bool val, TypeTag<bool>)
|
||||
{
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#define NAZARA_GLOBAL_MATH_HPP
|
||||
|
||||
#include <Nazara/Math/Algorithm.hpp>
|
||||
#include <Nazara/Math/Angle.hpp>
|
||||
#include <Nazara/Math/BoundingVolume.hpp>
|
||||
#include <Nazara/Math/Box.hpp>
|
||||
#include <Nazara/Math/Config.hpp>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
106
include/Nazara/Math/Angle.hpp
Normal file
106
include/Nazara/Math/Angle.hpp
Normal file
@@ -0,0 +1,106 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_ANGLE_HPP
|
||||
#define NAZARA_ANGLE_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Algorithm.hpp>
|
||||
#include <Nazara/Math/Enums.hpp>
|
||||
#include <ostream>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
struct SerializationContext;
|
||||
|
||||
template<typename T> class EulerAngles;
|
||||
template<typename T> class Quaternion;
|
||||
|
||||
template<AngleUnit Unit, typename T>
|
||||
class Angle
|
||||
{
|
||||
public:
|
||||
Angle() = default;
|
||||
Angle(T angle);
|
||||
template<typename U> explicit Angle(const Angle<Unit, U>& Angle);
|
||||
Angle(const Angle&) = default;
|
||||
~Angle() = default;
|
||||
|
||||
T GetCos() const;
|
||||
T GetSin() const;
|
||||
std::pair<T, T> GetSinCos() const;
|
||||
T GetTan() const;
|
||||
|
||||
Angle& MakeZero();
|
||||
|
||||
void Normalize();
|
||||
|
||||
Angle& Set(const Angle& ang);
|
||||
template<typename U> Angle& Set(const Angle<Unit, U>& ang);
|
||||
|
||||
T ToDegrees() const;
|
||||
Angle<AngleUnit::Degree, T> ToDegreeAngle() const;
|
||||
EulerAngles<T> ToEulerAngles() const;
|
||||
Quaternion<T> ToQuaternion() const;
|
||||
T ToRadians() const;
|
||||
Angle<AngleUnit::Radian, T> ToRadianAngle() const;
|
||||
String ToString() const;
|
||||
|
||||
template<AngleUnit U = Unit, typename = std::enable_if_t<U != AngleUnit::Degree>> operator Angle<AngleUnit::Degree, T>() const { return ToDegreeAngle(); } // GCC < 8 bug
|
||||
template<AngleUnit U = Unit, typename = std::enable_if_t<U != AngleUnit::Radian>> operator Angle<AngleUnit::Radian, T>() const { return ToRadianAngle(); } // GCC < 8 bug
|
||||
|
||||
Angle& operator=(const Angle&) = default;
|
||||
|
||||
Angle operator+(const Angle& other) const;
|
||||
Angle operator-(const Angle& other) const;
|
||||
Angle operator*(T scalar) const;
|
||||
Angle operator/(T divider) const;
|
||||
|
||||
Angle& operator+=(const Angle& other);
|
||||
Angle& operator-=(const Angle& other);
|
||||
Angle& operator*=(T scalar);
|
||||
Angle& operator/=(T divider);
|
||||
|
||||
bool operator==(const Angle& other) const;
|
||||
bool operator!=(const Angle& other) const;
|
||||
|
||||
static Angle FromDegrees(T ang);
|
||||
static Angle FromRadians(T ang);
|
||||
static Angle Zero();
|
||||
|
||||
T value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using DegreeAngle = Angle<AngleUnit::Degree, T>;
|
||||
|
||||
using DegreeAngled = DegreeAngle<double>;
|
||||
using DegreeAnglef = DegreeAngle<float>;
|
||||
|
||||
template<typename T>
|
||||
using RadianAngle = Angle<AngleUnit::Radian, T>;
|
||||
|
||||
using RadianAngled = RadianAngle<double>;
|
||||
using RadianAnglef = RadianAngle<float>;
|
||||
|
||||
template<AngleUnit Unit, typename T> bool Serialize(SerializationContext& context, const Angle<Unit, T>& angle, TypeTag<Angle<Unit, T>>);
|
||||
template<AngleUnit Unit, typename T> bool Unserialize(SerializationContext& context, Angle<Unit, T>* angle, TypeTag<Angle<Unit, T>>);
|
||||
}
|
||||
|
||||
template<Nz::AngleUnit Unit, typename T>
|
||||
Nz::Angle<Unit, T> operator*(T scale, const Nz::Angle<Unit, T>& angle);
|
||||
|
||||
template<Nz::AngleUnit Unit, typename T>
|
||||
Nz::Angle<Unit, T> operator/(T divider, const Nz::Angle<Unit, T>& angle);
|
||||
|
||||
template<Nz::AngleUnit Unit, typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const Nz::Angle<Unit, T>& angle);
|
||||
|
||||
#include <Nazara/Math/Angle.inl>
|
||||
|
||||
#endif // NAZARA_ANGLE_HPP
|
||||
599
include/Nazara/Math/Angle.inl
Normal file
599
include/Nazara/Math/Angle.inl
Normal file
@@ -0,0 +1,599 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Math/Angle.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef NAZARA_PLATFORM_POSIX
|
||||
#include <math.h> //< sincos
|
||||
#endif
|
||||
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace Detail
|
||||
{
|
||||
template<AngleUnit Unit> struct AngleUtils;
|
||||
|
||||
template<>
|
||||
struct AngleUtils<AngleUnit::Degree>
|
||||
{
|
||||
template<typename T> static constexpr T GetEpsilon()
|
||||
{
|
||||
return T(1e-4);
|
||||
}
|
||||
|
||||
template<typename T> static constexpr T GetLimit()
|
||||
{
|
||||
return 180;
|
||||
}
|
||||
|
||||
template<typename T> static T FromDegrees(T degrees)
|
||||
{
|
||||
return degrees;
|
||||
}
|
||||
|
||||
template<typename T> static T FromRadians(T radians)
|
||||
{
|
||||
return RadianToDegree(radians);
|
||||
}
|
||||
|
||||
template<typename T> static T ToDegrees(T degrees)
|
||||
{
|
||||
return degrees;
|
||||
}
|
||||
|
||||
template<typename T> static T ToRadians(T degrees)
|
||||
{
|
||||
return DegreeToRadian(degrees);
|
||||
}
|
||||
|
||||
template<typename T> static String ToString(T value)
|
||||
{
|
||||
return "Angle(" + String::Number(value) + "deg)";
|
||||
}
|
||||
|
||||
template<typename T> static std::ostream& ToString(std::ostream& out, T value)
|
||||
{
|
||||
return out << "Angle(" << value << "deg)";
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct AngleUtils<AngleUnit::Radian>
|
||||
{
|
||||
template<typename T> static constexpr T GetEpsilon()
|
||||
{
|
||||
return T(1e-5);
|
||||
}
|
||||
|
||||
template<typename T> static constexpr T GetLimit()
|
||||
{
|
||||
return T(M_PI);
|
||||
}
|
||||
|
||||
template<typename T> static T FromDegrees(T degrees)
|
||||
{
|
||||
return DegreeToRadian(degrees);
|
||||
}
|
||||
|
||||
template<typename T> static T FromRadians(T radians)
|
||||
{
|
||||
return radians;
|
||||
}
|
||||
|
||||
template<typename T> static T ToDegrees(T radians)
|
||||
{
|
||||
return RadianToDegree(radians);
|
||||
}
|
||||
|
||||
template<typename T> static T ToRadians(T radians)
|
||||
{
|
||||
return radians;
|
||||
}
|
||||
|
||||
template<typename T> static String ToString(T value)
|
||||
{
|
||||
return "Angle(" + String::Number(value) + "rad)";
|
||||
}
|
||||
|
||||
template<typename T> static std::ostream& ToString(std::ostream& out, T value)
|
||||
{
|
||||
return out << "Angle(" << value << "rad)";
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef NAZARA_PLATFORM_POSIX
|
||||
template<typename T>
|
||||
void SinCos(std::enable_if_t<!std::is_same<T, float>::value && !std::is_same<T, long double>::value, double> x, T* sin, T* cos)
|
||||
{
|
||||
double s, c;
|
||||
::sincos(x, &s, &c);
|
||||
|
||||
*sin = static_cast<T>(s);
|
||||
*cos = static_cast<T>(c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SinCos(std::enable_if_t<std::is_same<T, float>::value, float> x, float* s, float* c)
|
||||
{
|
||||
::sincosf(x, s, c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SinCos(std::enable_if_t<std::is_same<T, long double>::value, long double> x, long double* s, long double* c)
|
||||
{
|
||||
::sincosl(x, sin, cos);
|
||||
}
|
||||
#else
|
||||
// Naive implementation, hopefully optimized by the compiler
|
||||
template<typename T>
|
||||
void SinCos(T x, T* sin, T* cos)
|
||||
{
|
||||
*sin = std::sin(x);
|
||||
*cos = std::cos(x);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \class Nz::Angle
|
||||
* \brief Math class that represents an angle
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs an Angle object with an angle value
|
||||
*
|
||||
* \param value value of the angle
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T>::Angle(T angle) :
|
||||
value(angle)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Computes the cosine of the angle
|
||||
* \return Cosine of angle
|
||||
*
|
||||
* \see GetSinCos
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
T Angle<Unit, T>::GetCos() const
|
||||
{
|
||||
return std::cos(ToRadians());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Computes the sine of the angle
|
||||
* \return Sine of angle
|
||||
*
|
||||
* \see GetSinCos
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
T Angle<Unit, T>::GetSin() const
|
||||
{
|
||||
return std::sin(ToRadians());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Computes both sines and cosines of the angle
|
||||
* \return Sine and cosine of the angle
|
||||
*
|
||||
* \remark This is potentially faster than calling both GetSin and GetCos separately as it can computes both values at the same time.
|
||||
*
|
||||
* \see GetCos, GetSin
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
std::pair<T, T> Angle<Unit, T>::GetSinCos() const
|
||||
{
|
||||
T sin, cos;
|
||||
Detail::SinCos<T>(ToRadians(), &sin, &cos);
|
||||
|
||||
return std::make_pair(sin, cos);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Computes the tangent of the angle
|
||||
* \return Tangent value of the angle
|
||||
*
|
||||
* \see GetCos, GetSin
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
T Angle<Unit, T>::GetTan() const
|
||||
{
|
||||
return std::tan(ToRadians());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Changes the angle value to zero
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T>& Angle<Unit, T>::MakeZero()
|
||||
{
|
||||
value = T(0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Normalizes the angle value
|
||||
*
|
||||
* If angle exceeds local limits positively or negatively, bring it back between them.
|
||||
* For degree angles, local limits are [-180, 180]
|
||||
* For radian angles, local limits are [-M_PI, M_PI]
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
void Angle<Unit, T>::Normalize()
|
||||
{
|
||||
constexpr T limit = Detail::AngleUtils<Unit>::template GetLimit<T>();
|
||||
constexpr T twoLimit = limit * T(2);
|
||||
|
||||
value = std::fmod(value, twoLimit);
|
||||
if (value < T(0))
|
||||
value += twoLimit;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Copies the angle value of an angle
|
||||
*
|
||||
* \param Angle Angle which will be copied
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T>& Angle<Unit, T>::Set(const Angle& ang)
|
||||
{
|
||||
value = ang.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Changes the angle value to the same as an Angle of a different type
|
||||
*
|
||||
* \param Angle Angle which will be casted
|
||||
*
|
||||
* \remark Conversion from U to T occurs using static_cast
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
template<typename U>
|
||||
Angle<Unit, T>& Angle<Unit, T>::Set(const Angle<Unit, U>& ang)
|
||||
{
|
||||
value = static_cast<T>(ang.value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the degree angle that is equivalent to this one
|
||||
* \return Equivalent degree angle value
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
T Angle<Unit, T>::ToDegrees() const
|
||||
{
|
||||
return Detail::AngleUtils<Unit>::ToDegrees(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the degree angle that is equivalent to this one
|
||||
* \return Equivalent degree angle
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<AngleUnit::Degree, T> Angle<Unit, T>::ToDegreeAngle() const
|
||||
{
|
||||
return DegreeAngle<T>(ToDegrees());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts the angle to an Euler Angles representation
|
||||
* \return A 2D rotation expressed in Euler angles
|
||||
*
|
||||
* This will assume two-dimensional usage, and will set the angle value (as degrees) as the roll value of the Euler Angles, leaving pitch and yaw to zero
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
EulerAngles<T> Angle<Unit, T>::ToEulerAngles() const
|
||||
{
|
||||
return EulerAngles<T>(0, 0, ToDegrees());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts the angle to a Quaternion representation
|
||||
* \return A 2D rotation expressed with Quaternion
|
||||
*
|
||||
* This will assume two-dimensional usage, as if the angle was first converted to Euler Angles and then to a Quaternion
|
||||
*
|
||||
* \see ToEulerAngles
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Quaternion<T> Angle<Unit, T>::ToQuaternion() const
|
||||
{
|
||||
auto halfAngle = Angle(*this) / 2.f;
|
||||
auto sincos = halfAngle.GetSinCos();
|
||||
return Quaternion<T>(sincos.second, 0, 0, sincos.first);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the radian angle that is equivalent to this angle
|
||||
* \return Equivalent radian angle value
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
T Angle<Unit, T>::ToRadians() const
|
||||
{
|
||||
return Detail::AngleUtils<Unit>::ToRadians(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the radian angle that is equivalent to this angle
|
||||
* \return Equivalent radian angle
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<AngleUnit::Radian, T> Angle<Unit, T>::ToRadianAngle() const
|
||||
{
|
||||
return RadianAngle<T>(ToRadians());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts the angle to a string representation
|
||||
* \return String representation of the angle
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
String Angle<Unit, T>::ToString() const
|
||||
{
|
||||
return Detail::AngleUtils<Unit>::ToString(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the degree angle that is equivalent to this one
|
||||
* \return Equivalent degree angle
|
||||
*/
|
||||
/*template<AngleUnit Unit, typename T>
|
||||
template<AngleUnit U, typename>
|
||||
Angle<Unit, T>::operator Angle<AngleUnit::Degree, T>() const
|
||||
{
|
||||
return ToDegreeAngle();
|
||||
}*/
|
||||
|
||||
/*!
|
||||
* \brief Converts the angle to a string representation
|
||||
* \return String representation of the angle
|
||||
*/
|
||||
/*template<AngleUnit Unit, typename T>
|
||||
template<AngleUnit U, typename>
|
||||
Angle<Unit, T>::operator Angle<AngleUnit::Radian, T>() const
|
||||
{
|
||||
return ToRadianAngle();
|
||||
}*/
|
||||
|
||||
/*!
|
||||
* \brief Addition operator
|
||||
* \return Adds two angles together
|
||||
*
|
||||
* \param other Angle to add
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T> Angle<Unit, T>::operator+(const Angle& other) const
|
||||
{
|
||||
return Angle(value + other.value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Subtraction operator
|
||||
* \return Subtracts two angles together
|
||||
*
|
||||
* \param other Angle to subtract
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T> Angle<Unit, T>::operator-(const Angle& other) const
|
||||
{
|
||||
return Angle(value - other.value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplication operator
|
||||
* \return A copy of the angle, scaled by the multiplier
|
||||
*
|
||||
* \param scalar Multiplier
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T> Angle<Unit, T>::operator*(T scalar) const
|
||||
{
|
||||
return Angle(value * scalar);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the angle by a scalar
|
||||
* \return A copy of the angle, divided by the divider
|
||||
*
|
||||
* \param divider Divider
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T> Angle<Unit, T>::operator/(T divider) const
|
||||
{
|
||||
return Angle(value / divider);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds an angle by another
|
||||
* \return A reference to the angle
|
||||
*
|
||||
* \param other Angle to add
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T>& Angle<Unit, T>::operator+=(const Angle& other)
|
||||
{
|
||||
value += other.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Subtract an angle by another
|
||||
* \return A reference to the angle
|
||||
*
|
||||
* \param other Angle to subtract
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T>& Angle<Unit, T>::operator-=(const Angle& other)
|
||||
{
|
||||
value -= other.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Scales the angle by a scalar
|
||||
* \return A reference to the angle
|
||||
*
|
||||
* \param scalar Multiplier
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T>& Angle<Unit, T>::operator*=(T scalar)
|
||||
{
|
||||
value *= scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the angle by a scalar
|
||||
* \return A reference to the angle
|
||||
*
|
||||
* \param divider Divider
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T>& Angle<Unit, T>::operator/=(T divider)
|
||||
{
|
||||
value /= divider;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the angle to another for equality
|
||||
* \return True if both angles are equal
|
||||
*
|
||||
* \param other The other angle to compare to
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
bool Angle<Unit, T>::operator==(const Angle& other) const
|
||||
{
|
||||
return NumberEquals(value, other.value, Detail::AngleUtils<Unit>::template GetEpsilon<T>());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the angle to another for inequality
|
||||
* \return True if both angles are equal
|
||||
*
|
||||
* \param other The other angle to compare to
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
bool Angle<Unit, T>::operator!=(const Angle& other) const
|
||||
{
|
||||
return !NumberEquals(value, other.value, Detail::AngleUtils<Unit>::template GetEpsilon<T>());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Builds an Angle instance using a degree angle, converting if needed
|
||||
* \return An angle describing the degree angle as Unit
|
||||
*
|
||||
* \param ang Degree angle
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T> Angle<Unit, T>::FromDegrees(T ang)
|
||||
{
|
||||
return Angle(Detail::AngleUtils<Unit>::FromDegrees(ang));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Builds an Angle instance using a radian angle, converting if needed
|
||||
* \return An angle describing the radian angle as Unit
|
||||
*
|
||||
* \param ang Radian angle
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T> Angle<Unit, T>::FromRadians(T ang)
|
||||
{
|
||||
return Angle(Detail::AngleUtils<Unit>::FromRadians(ang));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns an angle with an angle of zero
|
||||
* \return Zero angle
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
Angle<Unit, T> Angle<Unit, T>::Zero()
|
||||
{
|
||||
Angle angle;
|
||||
angle.MakeZero();
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Serializes an Angle
|
||||
* \return true if successfully serialized
|
||||
*
|
||||
* \param context Serialization context
|
||||
* \param angle Input Angle
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
bool Serialize(SerializationContext& context, const Angle<Unit, T>& angle, TypeTag<Angle<Unit, T>>)
|
||||
{
|
||||
if (!Serialize(context, angle.value))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Unserializes an Angle
|
||||
* \return true if successfully unserialized
|
||||
*
|
||||
* \param context Serialization context
|
||||
* \param angle Output Angle
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
bool Unserialize(SerializationContext& context, Angle<Unit, T>* angle, TypeTag<Angle<Unit, T>>)
|
||||
{
|
||||
if (!Unserialize(context, &angle->value))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplication operator
|
||||
* \return An angle corresponding to scale * angle
|
||||
*
|
||||
* \param scale Multiplier
|
||||
* \param angle Angle
|
||||
*/
|
||||
template<Nz::AngleUnit Unit, typename T>
|
||||
Nz::Angle<Unit, T> operator*(T scale, const Nz::Angle<Unit, T>& angle)
|
||||
{
|
||||
return Nz::Angle<Unit, T>(scale * angle.value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Division operator
|
||||
* \return An angle corresponding to scale / angle
|
||||
*
|
||||
* \param scale Divisor
|
||||
* \param angle Angle
|
||||
*/
|
||||
template<Nz::AngleUnit Unit, typename T>
|
||||
Nz::Angle<Unit, T> operator/(T scale, const Nz::Angle<Unit, T>& angle)
|
||||
{
|
||||
return Nz::Angle<Unit, T>(scale / angle.value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Output operator
|
||||
* \return The stream
|
||||
*
|
||||
* \param out The stream
|
||||
* \param box The box to output
|
||||
*/
|
||||
template<Nz::AngleUnit Unit, typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const Nz::Angle<Unit, T>& angle)
|
||||
{
|
||||
return Nz::Detail::AngleUtils<Unit>::ToString(out, angle.value);
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
enum class AngleUnit
|
||||
{
|
||||
Degree,
|
||||
Radian
|
||||
};
|
||||
|
||||
enum BoxCorner
|
||||
{
|
||||
BoxCorner_FarLeftBottom,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define NAZARA_EULERANGLES_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Angle.hpp>
|
||||
#include <Nazara/Math/Quaternion.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
|
||||
@@ -22,6 +23,7 @@ namespace Nz
|
||||
EulerAngles() = default;
|
||||
EulerAngles(T P, T Y, T R);
|
||||
EulerAngles(const T angles[3]);
|
||||
template<AngleUnit Unit> EulerAngles(const Angle<Unit, T>& angle);
|
||||
//EulerAngles(const Matrix3<T>& mat);
|
||||
EulerAngles(const Quaternion<T>& quat);
|
||||
template<typename U> explicit EulerAngles(const EulerAngles<U>& angles);
|
||||
@@ -34,7 +36,7 @@ namespace Nz
|
||||
|
||||
EulerAngles& Set(T P, T Y, T R);
|
||||
EulerAngles& Set(const T angles[3]);
|
||||
EulerAngles& Set(const EulerAngles<T>& angles);
|
||||
template<AngleUnit Unit> EulerAngles& Set(const Angle<Unit, T>& angles);
|
||||
//EulerAngles& Set(const Matrix3<T>& mat);
|
||||
EulerAngles& Set(const Quaternion<T>& quat);
|
||||
template<typename U> EulerAngles& Set(const EulerAngles<U>& angles);
|
||||
|
||||
@@ -50,12 +50,23 @@ namespace Nz
|
||||
Set(angles);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a EulerAngles object from an angle
|
||||
*
|
||||
* \param angle Angle representing a 2D rotation
|
||||
*/
|
||||
template<typename T>
|
||||
template<AngleUnit Unit>
|
||||
EulerAngles<T>::EulerAngles(const Angle<Unit, T>& angle)
|
||||
{
|
||||
Set(angle);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a EulerAngles object from a quaternion
|
||||
*
|
||||
* \param quat Quaternion representing a rotation of space
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
EulerAngles<T>::EulerAngles(const Quaternion<T>& quat)
|
||||
{
|
||||
@@ -142,19 +153,20 @@ namespace Nz
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the euler angle from another euler angle
|
||||
* \brief Sets the components of the euler angle from a 2D rotation specified by an Angle
|
||||
* \return A reference to this euler angle
|
||||
*
|
||||
* \param angles The other euler angle
|
||||
* \param angle 2D angle
|
||||
*
|
||||
* \see Angle
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
EulerAngles<T>& EulerAngles<T>::Set(const EulerAngles& angles)
|
||||
template<AngleUnit Unit>
|
||||
EulerAngles<T>& EulerAngles<T>::Set(const Angle<Unit, T>& angle)
|
||||
{
|
||||
std::memcpy(this, &angles, sizeof(EulerAngles));
|
||||
|
||||
return *this;
|
||||
return Set(angle.ToEulerAngles());
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -394,3 +406,4 @@ std::ostream& operator<<(std::ostream& out, const Nz::EulerAngles<T>& angles)
|
||||
#undef F
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
#include "EulerAngles.hpp"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define NAZARA_QUATERNION_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Angle.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
@@ -21,6 +22,7 @@ namespace Nz
|
||||
public:
|
||||
Quaternion() = default;
|
||||
Quaternion(T W, T X, T Y, T Z);
|
||||
template<AngleUnit Unit> Quaternion(const Angle<Unit, T>& angle);
|
||||
Quaternion(const EulerAngles<T>& angles);
|
||||
Quaternion(T angle, const Vector3<T>& axis);
|
||||
Quaternion(const T quat[4]);
|
||||
@@ -49,11 +51,11 @@ namespace Nz
|
||||
Quaternion& Normalize(T* length = nullptr);
|
||||
|
||||
Quaternion& Set(T W, T X, T Y, T Z);
|
||||
template<AngleUnit Unit> Quaternion& Set(const Angle<Unit, T>& angle);
|
||||
Quaternion& Set(const EulerAngles<T>& angles);
|
||||
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;
|
||||
|
||||
@@ -39,6 +39,18 @@ namespace Nz
|
||||
Set(W, X, Y, Z);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Quaternion object from an angle
|
||||
*
|
||||
* \param angle Angle representing a 2D rotation
|
||||
*/
|
||||
template<typename T>
|
||||
template<AngleUnit Unit>
|
||||
Quaternion<T>::Quaternion(const Angle<Unit, T>& angle)
|
||||
{
|
||||
Set(angle);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Quaternion object from a EulerAngles
|
||||
*
|
||||
@@ -46,7 +58,6 @@ namespace Nz
|
||||
*
|
||||
* \see EulerAngles
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>::Quaternion(const EulerAngles<T>& angles)
|
||||
{
|
||||
@@ -343,6 +354,21 @@ namespace Nz
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets this quaternion from a 2D rotation specified by an Angle
|
||||
* \return A reference to this quaternion
|
||||
*
|
||||
* \param angle 2D angle
|
||||
*
|
||||
* \see Angle
|
||||
*/
|
||||
template<typename T>
|
||||
template<AngleUnit Unit>
|
||||
Quaternion<T>& Quaternion<T>::Set(const Angle<Unit, T>& angle)
|
||||
{
|
||||
return Set(angle.ToQuaternion());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets this quaternion from rotation specified by Euler angle
|
||||
* \return A reference to this quaternion
|
||||
@@ -351,7 +377,6 @@ namespace Nz
|
||||
*
|
||||
* \see EulerAngles
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::Set(const EulerAngles<T>& angles)
|
||||
{
|
||||
@@ -405,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
|
||||
@@ -886,3 +896,4 @@ std::ostream& operator<<(std::ostream& out, const Nz::Quaternion<T>& quat)
|
||||
#undef F
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
#include "Quaternion.hpp"
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>>);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace Nz
|
||||
T AbsDotProduct(const Vector2& vec) const;
|
||||
T AngleBetween(const Vector2& vec) const;
|
||||
|
||||
T Distance(const Vector2& vec) const;
|
||||
float Distancef(const Vector2& vec) const;
|
||||
template<typename U = T>
|
||||
U Distance(const Vector2& vec) const;
|
||||
T DotProduct(const Vector2& vec) const;
|
||||
|
||||
T GetLength() const;
|
||||
@@ -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);
|
||||
@@ -92,6 +91,7 @@ namespace Nz
|
||||
bool operator>(const Vector2& vec) const;
|
||||
bool operator>=(const Vector2& vec) const;
|
||||
|
||||
template<typename U = T> static U Distance(const Vector2& vec1, const Vector2& vec2);
|
||||
static T DotProduct(const Vector2& vec1, const Vector2& vec2);
|
||||
static Vector2 Lerp(const Vector2& from, const Vector2& to, T interpolation);
|
||||
static Vector2 Normalize(const Vector2& vec);
|
||||
@@ -108,7 +108,9 @@ namespace Nz
|
||||
using Vector2i = Vector2<int>;
|
||||
using Vector2ui = Vector2<unsigned int>;
|
||||
using Vector2i32 = Vector2<Int32>;
|
||||
using Vector2i64 = Vector2<Int64>;
|
||||
using Vector2ui32 = Vector2<UInt32>;
|
||||
using Vector2ui64 = Vector2<UInt64>;
|
||||
|
||||
template<typename T> bool Serialize(SerializationContext& context, const Vector2<T>& vector, TypeTag<Vector2<T>>);
|
||||
template<typename T> bool Unserialize(SerializationContext& context, Vector2<T>* vector, TypeTag<Vector2<T>>);
|
||||
|
||||
@@ -124,22 +124,10 @@ namespace Nz
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Vector2<T>::Distance(const Vector2& vec) const
|
||||
template<typename U>
|
||||
U Vector2<T>::Distance(const Vector2& vec) const
|
||||
{
|
||||
return std::sqrt(SquaredDistance(vec));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the distance between two vectors
|
||||
* \return The metric distance in float between two vectors with euclidean norm
|
||||
*
|
||||
* \param vec The other vector to measure the distance with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
float Vector2<T>::Distancef(const Vector2& vec) const
|
||||
{
|
||||
return std::sqrt(static_cast<float>(SquaredDistance(vec)));
|
||||
return static_cast<U>(std::sqrt(SquaredDistance(vec)));
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -379,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;
|
||||
}
|
||||
@@ -835,6 +809,24 @@ namespace Nz
|
||||
return !operator<(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Measure the distance between two points
|
||||
* Shorthand for vec1.Distance(vec2)
|
||||
*
|
||||
* param vec1 the first point
|
||||
* param vec2 the second point
|
||||
*
|
||||
* \return The distance between the two vectors
|
||||
*
|
||||
* \see SquaredDistance
|
||||
*/
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
U Vector2<T>::Distance(const Vector2& vec1, const Vector2& vec2)
|
||||
{
|
||||
return vec1.Distance<U>(vec2);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the dot (scalar) product with two vectors
|
||||
* \return The value of the dot product
|
||||
|
||||
@@ -36,8 +36,8 @@ namespace Nz
|
||||
|
||||
Vector3 CrossProduct(const Vector3& vec) const;
|
||||
|
||||
T Distance(const Vector3& vec) const;
|
||||
float Distancef(const Vector3& vec) const;
|
||||
template<typename U = T>
|
||||
U Distance(const Vector3& vec) const;
|
||||
T DotProduct(const Vector3& vec) const;
|
||||
|
||||
T GetLength() const;
|
||||
@@ -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);
|
||||
|
||||
@@ -106,8 +105,7 @@ namespace Nz
|
||||
static Vector3 Backward();
|
||||
static Vector3 CrossProduct(const Vector3& vec1, const Vector3& vec2);
|
||||
static T DotProduct(const Vector3& vec1, const Vector3& vec2);
|
||||
static T Distance(const Vector3& vec1, const Vector3& vec2);
|
||||
static float Distancef(const Vector3& vec1, const Vector3& vec2);
|
||||
template<typename U = T> static U Distance(const Vector3& vec1, const Vector3& vec2);
|
||||
static Vector3 Down();
|
||||
static Vector3 Forward();
|
||||
static Vector3 Left();
|
||||
@@ -130,7 +128,9 @@ namespace Nz
|
||||
using Vector3i = Vector3<int>;
|
||||
using Vector3ui = Vector3<unsigned int>;
|
||||
using Vector3i32 = Vector3<Int32>;
|
||||
using Vector3i64 = Vector3<Int64>;
|
||||
using Vector3ui32 = Vector3<UInt32>;
|
||||
using Vector3ui64 = Vector3<UInt64>;
|
||||
|
||||
template<typename T> bool Serialize(SerializationContext& context, const Vector3<T>& vector, TypeTag<Vector3<T>>);
|
||||
template<typename T> bool Unserialize(SerializationContext& context, Vector3<T>* vector, TypeTag<Vector3<T>>);
|
||||
|
||||
@@ -162,21 +162,10 @@ namespace Nz
|
||||
* \see SquaredDistance
|
||||
*/
|
||||
template<typename T>
|
||||
T Vector3<T>::Distance(const Vector3& vec) const
|
||||
template<typename U>
|
||||
U Vector3<T>::Distance(const Vector3& vec) const
|
||||
{
|
||||
return std::sqrt(SquaredDistance(vec));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the distance between two vectors
|
||||
* \return The metric distance in float between two vectors with euclidean norm
|
||||
*
|
||||
* \param vec The other vector to measure the distance with
|
||||
*/
|
||||
template<typename T>
|
||||
float Vector3<T>::Distancef(const Vector3& vec) const
|
||||
{
|
||||
return std::sqrt(static_cast<float>(SquaredDistance(vec)));
|
||||
return static_cast<U>(std::sqrt(SquaredDistance(vec)));
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -534,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
|
||||
@@ -1014,26 +989,10 @@ namespace Nz
|
||||
* \see SquaredDistance
|
||||
*/
|
||||
template<typename T>
|
||||
T Vector3<T>::Distance(const Vector3& vec1, const Vector3& vec2)
|
||||
template<typename U>
|
||||
U Vector3<T>::Distance(const Vector3& vec1, const Vector3& vec2)
|
||||
{
|
||||
return vec1.Distance(vec2);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Measure the distance between two points as a float
|
||||
* Shorthand for vec1.Distancef(vec2)
|
||||
*
|
||||
* param vec1 the first point
|
||||
* param vec2 the second point
|
||||
*
|
||||
* \return The distance between the two vectors as a float
|
||||
*
|
||||
* \see SquaredDistancef
|
||||
*/
|
||||
template<typename T>
|
||||
float Vector3<T>::Distancef(const Vector3& vec1, const Vector3& vec2)
|
||||
{
|
||||
return vec1.Distancef(vec2);
|
||||
return vec1.Distance<U>(vec2);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -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;
|
||||
@@ -106,7 +105,9 @@ namespace Nz
|
||||
using Vector4i = Vector4<int>;
|
||||
using Vector4ui = Vector4<unsigned int>;
|
||||
using Vector4i32 = Vector4<Int32>;
|
||||
using Vector4i64 = Vector4<Int64>;
|
||||
using Vector4ui32 = Vector4<UInt32>;
|
||||
using Vector4ui64 = Vector4<UInt64>;
|
||||
|
||||
template<typename T> bool Serialize(SerializationContext& context, const Vector4<T>& vector, TypeTag<Vector4<T>>);
|
||||
template<typename T> bool Unserialize(SerializationContext& context, Vector4<T>* vector, TypeTag<Vector4<T>>);
|
||||
|
||||
@@ -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
|
||||
@@ -899,6 +887,21 @@ namespace Nz
|
||||
return !operator<(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the dot (scalar) product with two vectors
|
||||
* \return The value of the dot product
|
||||
*
|
||||
* \param vec1 The first vector to calculate the dot product with
|
||||
* \param vec2 The second vector to calculate the dot product with
|
||||
*
|
||||
* \see AbsDotProduct, DotProduct
|
||||
*/
|
||||
template<typename T>
|
||||
T Vector4<T>::DotProduct(const Vector4& vec1, const Vector4& vec2)
|
||||
{
|
||||
return vec1.DotProduct(vec2);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Interpolates the vector to other one with a factor of interpolation
|
||||
* \return A new vector which is the interpolation of two vectors
|
||||
@@ -911,7 +914,6 @@ namespace Nz
|
||||
*
|
||||
* \see Lerp
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::Lerp(const Vector4& from, const Vector4& to, T interpolation)
|
||||
{
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Nz
|
||||
AbstractSocket& operator=(AbstractSocket&& abstractSocket);
|
||||
|
||||
// Signals:
|
||||
NazaraSignal(OnStateChange, const AbstractSocket* /*socket*/, SocketState /*newState*/);
|
||||
NazaraSignal(OnStateChanged, const AbstractSocket* /*socket*/, SocketState /*oldState*/, SocketState /*newState*/);
|
||||
|
||||
protected:
|
||||
AbstractSocket(SocketType type);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
@@ -66,8 +66,9 @@ namespace Nz
|
||||
{
|
||||
if (m_state != newState)
|
||||
{
|
||||
OnStateChange(this, newState);
|
||||
SocketState oldState = m_state;
|
||||
m_state = newState;
|
||||
OnStateChanged(this, oldState, newState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,10 +58,16 @@ 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 Nz::IpAddress GetBoundAddress() const;
|
||||
inline IpAddress GetBoundAddress() const;
|
||||
inline UInt32 GetServiceTime() const;
|
||||
inline UInt32 GetTotalReceivedPackets() const;
|
||||
inline UInt64 GetTotalReceivedData() const;
|
||||
inline UInt64 GetTotalSentData() const;
|
||||
inline UInt32 GetTotalSentPackets() const;
|
||||
|
||||
int Service(ENetEvent* event, UInt32 timeout);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Network/ENetHost.hpp>
|
||||
#include <utility>
|
||||
#include <Nazara/Network/Debug.hpp>
|
||||
|
||||
@@ -19,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");
|
||||
@@ -53,6 +61,11 @@ namespace Nz
|
||||
m_socket.Close();
|
||||
}
|
||||
|
||||
inline bool ENetHost::DoesAllowIncomingConnections() const
|
||||
{
|
||||
return m_allowsIncomingConnections;
|
||||
}
|
||||
|
||||
inline IpAddress ENetHost::GetBoundAddress() const
|
||||
{
|
||||
return m_address;
|
||||
@@ -63,6 +76,26 @@ namespace Nz
|
||||
return m_serviceTime;
|
||||
}
|
||||
|
||||
inline UInt32 ENetHost::GetTotalReceivedPackets() const
|
||||
{
|
||||
return m_totalReceivedPackets;
|
||||
}
|
||||
|
||||
inline UInt64 ENetHost::GetTotalReceivedData() const
|
||||
{
|
||||
return m_totalReceivedData;
|
||||
}
|
||||
|
||||
inline UInt64 ENetHost::GetTotalSentData() const
|
||||
{
|
||||
return m_totalSentData;
|
||||
}
|
||||
|
||||
inline UInt32 ENetHost::GetTotalSentPackets() const
|
||||
{
|
||||
return m_totalSentPackets;
|
||||
}
|
||||
|
||||
inline void ENetHost::SetCompressor(std::unique_ptr<ENetCompressor>&& compressor)
|
||||
{
|
||||
m_compressor = std::move(compressor);
|
||||
|
||||
@@ -56,6 +56,11 @@ namespace Nz
|
||||
inline UInt16 GetPeerId() const;
|
||||
inline UInt32 GetRoundTripTime() const;
|
||||
inline ENetPeerState GetState() const;
|
||||
inline UInt64 GetTotalByteReceived() const;
|
||||
inline UInt64 GetTotalByteSent() const;
|
||||
inline UInt32 GetTotalPacketReceived() const;
|
||||
inline UInt32 GetTotalPacketLost() const;
|
||||
inline UInt32 GetTotalPacketSent() const;
|
||||
|
||||
inline bool HasPendingCommands();
|
||||
|
||||
@@ -234,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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -62,9 +62,34 @@ namespace Nz
|
||||
return m_state;
|
||||
}
|
||||
|
||||
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 UInt32 ENetPeer::GetTotalPacketSent() const
|
||||
{
|
||||
return m_totalPacketSent;
|
||||
}
|
||||
|
||||
inline bool ENetPeer::HasPendingCommands()
|
||||
{
|
||||
return m_outgoingReliableCommands.empty() && m_outgoingUnreliableCommands.empty() && m_sentReliableCommands.empty();
|
||||
return m_outgoingReliableCommands.empty() && m_outgoingUnreliableCommands.empty() && m_sentReliableCommands.empty() && m_sentUnreliableCommands.empty();
|
||||
}
|
||||
|
||||
inline bool ENetPeer::IsConnected() const
|
||||
@@ -94,3 +119,4 @@ namespace Nz
|
||||
}
|
||||
|
||||
#include <Nazara/Network/DebugOff.hpp>
|
||||
#include "ENetPeer.hpp"
|
||||
|
||||
@@ -46,10 +46,10 @@ namespace Nz
|
||||
NetPacket& operator=(const NetPacket&) = delete;
|
||||
NetPacket& operator=(NetPacket&& packet);
|
||||
|
||||
static bool DecodeHeader(const void* data, UInt16* packetSize, UInt16* netCode);
|
||||
static bool EncodeHeader(void* data, UInt16 packetSize, UInt16 netCode);
|
||||
static bool DecodeHeader(const void* data, UInt32* packetSize, UInt16* netCode);
|
||||
static bool EncodeHeader(void* data, UInt32 packetSize, UInt16 netCode);
|
||||
|
||||
static constexpr std::size_t HeaderSize = sizeof(UInt16) + sizeof(UInt16); //< PacketSize + NetCode
|
||||
static constexpr std::size_t HeaderSize = sizeof(UInt32) + sizeof(UInt16); //< PacketSize + NetCode
|
||||
|
||||
private:
|
||||
void OnEmptyStream() override;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user