Merge branch 'master' into vulkan
This commit is contained in:
commit
596d65f1ed
|
|
@ -44,13 +44,13 @@ namespace Ndk
|
|||
void UnregisterWidget(std::size_t index);
|
||||
|
||||
private:
|
||||
void OnMouseButtonPressed(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseButtonEvent& event);
|
||||
void OnMouseButtonRelease(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseButtonEvent& event);
|
||||
void OnMouseMoved(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseMoveEvent& event);
|
||||
void OnMouseLeft(const Nz::EventHandler* eventHandler);
|
||||
void OnKeyPressed(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event);
|
||||
void OnKeyReleased(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event);
|
||||
void OnTextEntered(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::TextEvent& event);
|
||||
void OnEventMouseButtonPressed(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseButtonEvent& event);
|
||||
void OnEventMouseButtonRelease(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseButtonEvent& event);
|
||||
void OnEventMouseMoved(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseMoveEvent& event);
|
||||
void OnEventMouseLeft(const Nz::EventHandler* eventHandler);
|
||||
void OnEventKeyPressed(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event);
|
||||
void OnEventKeyReleased(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event);
|
||||
void OnEventTextEntered(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::TextEvent& event);
|
||||
|
||||
struct WidgetBox
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@ namespace Ndk
|
|||
RegisterToCanvas();
|
||||
|
||||
// Connect to every meaningful event
|
||||
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, this, &Canvas::OnKeyPressed);
|
||||
m_keyReleasedSlot.Connect(eventHandler.OnKeyReleased, this, &Canvas::OnKeyReleased);
|
||||
m_mouseButtonPressedSlot.Connect(eventHandler.OnMouseButtonPressed, this, &Canvas::OnMouseButtonPressed);
|
||||
m_mouseButtonReleasedSlot.Connect(eventHandler.OnMouseButtonReleased, this, &Canvas::OnMouseButtonRelease);
|
||||
m_mouseMovedSlot.Connect(eventHandler.OnMouseMoved, this, &Canvas::OnMouseMoved);
|
||||
m_mouseLeftSlot.Connect(eventHandler.OnMouseLeft, this, &Canvas::OnMouseLeft);
|
||||
m_textEnteredSlot.Connect(eventHandler.OnTextEntered, this, &Canvas::OnTextEntered);
|
||||
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, this, &Canvas::OnEventKeyPressed);
|
||||
m_keyReleasedSlot.Connect(eventHandler.OnKeyReleased, this, &Canvas::OnEventKeyReleased);
|
||||
m_mouseButtonPressedSlot.Connect(eventHandler.OnMouseButtonPressed, this, &Canvas::OnEventMouseButtonPressed);
|
||||
m_mouseButtonReleasedSlot.Connect(eventHandler.OnMouseButtonReleased, this, &Canvas::OnEventMouseButtonRelease);
|
||||
m_mouseMovedSlot.Connect(eventHandler.OnMouseMoved, this, &Canvas::OnEventMouseMoved);
|
||||
m_mouseLeftSlot.Connect(eventHandler.OnMouseLeft, this, &Canvas::OnEventMouseLeft);
|
||||
m_textEnteredSlot.Connect(eventHandler.OnTextEntered, this, &Canvas::OnEventTextEntered);
|
||||
|
||||
// Disable padding by default
|
||||
SetPadding(0.f, 0.f, 0.f, 0.f);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Ndk
|
|||
ParticleEmitterComponent(ParticleEmitterComponent&& emitter) = default;
|
||||
~ParticleEmitterComponent() = default;
|
||||
|
||||
void Enable(bool active = true);
|
||||
inline void Enable(bool active = true);
|
||||
|
||||
inline bool IsActive() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,35 @@
|
|||
|
||||
namespace Ndk
|
||||
{
|
||||
namespace Detail
|
||||
{
|
||||
template<bool HasDefaultConstructor>
|
||||
struct AddComponentIf;
|
||||
|
||||
template<>
|
||||
struct AddComponentIf<true>
|
||||
{
|
||||
template<typename T>
|
||||
static int AddComponent(Nz::LuaState& lua, EntityHandle& handle)
|
||||
{
|
||||
T& component = handle->AddComponent<T>();
|
||||
lua.Push(component.CreateHandle());
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct AddComponentIf<false>
|
||||
{
|
||||
template<typename T>
|
||||
static int AddComponent(Nz::LuaState& lua, EntityHandle& /*handle*/)
|
||||
{
|
||||
lua.Error("Component has no default constructor and cannot be created from Lua yet");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Binds a component to a name
|
||||
*
|
||||
|
|
@ -13,14 +42,15 @@ namespace Ndk
|
|||
*
|
||||
* \remark Produces a NazaraAssert if name is empty
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
void LuaBinding::BindComponent(const Nz::String& name)
|
||||
{
|
||||
NazaraAssert(!name.IsEmpty(), "Component name cannot be empty");
|
||||
|
||||
static_assert(std::is_base_of<BaseComponent, T>::value, "ComponentType must inherit BaseComponent");
|
||||
|
||||
ComponentBinding binding;
|
||||
binding.adder = &AddComponentOfType<T>;
|
||||
binding.adder = &Detail::AddComponentIf<std::is_default_constructible<T>::value>::template AddComponent<T>;
|
||||
binding.getter = &PushComponentOfType<T>;
|
||||
binding.index = T::componentIndex;
|
||||
binding.name = name;
|
||||
|
|
@ -32,21 +62,9 @@ namespace Ndk
|
|||
m_componentBindingByName[name] = T::componentIndex;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int LuaBinding::AddComponentOfType(Nz::LuaState& lua, EntityHandle& handle)
|
||||
{
|
||||
static_assert(std::is_base_of<BaseComponent, T>::value, "ComponentType must inherit BaseComponent");
|
||||
|
||||
T& component = handle->AddComponent<T>();
|
||||
lua.Push(component.CreateHandle());
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int LuaBinding::PushComponentOfType(Nz::LuaState& lua, BaseComponent& component)
|
||||
{
|
||||
static_assert(std::is_base_of<BaseComponent, T>::value, "ComponentType must inherit BaseComponent");
|
||||
|
||||
T& rightComponent = static_cast<T&>(component);
|
||||
lua.Push(rightComponent.CreateHandle());
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -9,5 +9,7 @@ namespace Ndk
|
|||
inline void ButtonWidget::UpdateText(const Nz::AbstractTextDrawer& drawer)
|
||||
{
|
||||
m_textSprite->Update(drawer);
|
||||
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ namespace Ndk
|
|||
|
||||
inline void EnableMultiline(bool enable = true);
|
||||
|
||||
inline std::size_t GetCursorPosition() const;
|
||||
inline const Nz::Vector2ui& GetCursorPosition() const;
|
||||
inline std::size_t GetGlyphUnderCursor() const;
|
||||
inline std::size_t GetLineCount() const;
|
||||
inline const Nz::String& GetText() const;
|
||||
inline const Nz::Color& GetTextColor() const;
|
||||
|
|
@ -43,10 +44,12 @@ namespace Ndk
|
|||
inline bool IsReadOnly() const;
|
||||
|
||||
inline void MoveCursor(int offset);
|
||||
inline void MoveCursor(const Nz::Vector2i& offset);
|
||||
|
||||
void ResizeToContent() override;
|
||||
|
||||
inline void SetCursorPosition(std::size_t cursorPosition);
|
||||
inline void SetCursorPosition(std::size_t glyphIndex);
|
||||
inline void SetCursorPosition(Nz::Vector2ui cursorPosition);
|
||||
inline void SetReadOnly(bool readOnly = true);
|
||||
inline void SetText(const Nz::String& text);
|
||||
inline void SetTextColor(const Nz::Color& text);
|
||||
|
|
@ -82,7 +85,8 @@ namespace Ndk
|
|||
Nz::SimpleTextDrawer m_drawer;
|
||||
Nz::SpriteRef m_cursorSprite;
|
||||
Nz::TextSpriteRef m_textSprite;
|
||||
std::size_t m_cursorPosition;
|
||||
Nz::Vector2ui m_cursorPosition;
|
||||
std::size_t m_cursorGlyph;
|
||||
bool m_multiLineEnabled;
|
||||
bool m_readOnly;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,11 +20,16 @@ namespace Ndk
|
|||
m_multiLineEnabled = enable;
|
||||
}
|
||||
|
||||
inline std::size_t TextAreaWidget::GetCursorPosition() const
|
||||
inline const Nz::Vector2ui& TextAreaWidget::GetCursorPosition() const
|
||||
{
|
||||
return m_cursorPosition;
|
||||
}
|
||||
|
||||
inline std::size_t Ndk::TextAreaWidget::GetGlyphUnderCursor() const
|
||||
{
|
||||
return m_cursorGlyph;
|
||||
}
|
||||
|
||||
inline std::size_t TextAreaWidget::GetLineCount() const
|
||||
{
|
||||
return m_drawer.GetLineCount();
|
||||
|
|
@ -53,22 +58,84 @@ namespace Ndk
|
|||
inline void TextAreaWidget::MoveCursor(int offset)
|
||||
{
|
||||
if (offset >= 0)
|
||||
SetCursorPosition(m_cursorPosition += static_cast<std::size_t>(offset));
|
||||
SetCursorPosition(m_cursorGlyph + static_cast<std::size_t>(offset));
|
||||
else
|
||||
{
|
||||
std::size_t nOffset = static_cast<std::size_t>(-offset);
|
||||
if (nOffset >= m_cursorPosition)
|
||||
if (nOffset >= m_cursorGlyph)
|
||||
SetCursorPosition(0);
|
||||
else
|
||||
SetCursorPosition(m_cursorPosition - nOffset);
|
||||
SetCursorPosition(m_cursorGlyph - nOffset);
|
||||
}
|
||||
}
|
||||
|
||||
inline void TextAreaWidget::SetCursorPosition(std::size_t cursorPosition)
|
||||
inline void TextAreaWidget::MoveCursor(const Nz::Vector2i& offset)
|
||||
{
|
||||
OnTextAreaCursorMove(this, &cursorPosition);
|
||||
auto BoundOffset = [] (unsigned int cursorPosition, int offset) -> unsigned int
|
||||
{
|
||||
if (offset >= 0)
|
||||
return cursorPosition + offset;
|
||||
else
|
||||
{
|
||||
unsigned int nOffset = static_cast<unsigned int>(-offset);
|
||||
if (nOffset >= cursorPosition)
|
||||
return 0;
|
||||
else
|
||||
return cursorPosition - nOffset;
|
||||
}
|
||||
};
|
||||
|
||||
m_cursorPosition = std::min(cursorPosition, m_drawer.GetGlyphCount());
|
||||
Nz::Vector2ui cursorPosition = m_cursorPosition;
|
||||
cursorPosition.x = BoundOffset(static_cast<unsigned int>(cursorPosition.x), offset.x);
|
||||
cursorPosition.y = BoundOffset(static_cast<unsigned int>(cursorPosition.y), offset.y);
|
||||
|
||||
SetCursorPosition(cursorPosition);
|
||||
}
|
||||
|
||||
inline void TextAreaWidget::SetCursorPosition(std::size_t glyphIndex)
|
||||
{
|
||||
OnTextAreaCursorMove(this, &glyphIndex);
|
||||
|
||||
m_cursorGlyph = std::min(glyphIndex, m_drawer.GetGlyphCount());
|
||||
|
||||
std::size_t lineCount = m_drawer.GetLineCount();
|
||||
std::size_t line = 0U;
|
||||
for (std::size_t i = line + 1; i < lineCount; ++i)
|
||||
{
|
||||
if (m_drawer.GetLine(i).glyphIndex > m_cursorGlyph)
|
||||
break;
|
||||
|
||||
line = i;
|
||||
}
|
||||
|
||||
const auto& lineInfo = m_drawer.GetLine(line);
|
||||
|
||||
m_cursorPosition.y = line;
|
||||
m_cursorPosition.x = m_cursorGlyph - lineInfo.glyphIndex;
|
||||
|
||||
RefreshCursor();
|
||||
}
|
||||
|
||||
inline void TextAreaWidget::SetCursorPosition(Nz::Vector2ui cursorPosition)
|
||||
{
|
||||
std::size_t lineCount = m_drawer.GetLineCount();
|
||||
if (cursorPosition.y >= lineCount)
|
||||
cursorPosition.y = static_cast<unsigned int>(lineCount - 1);
|
||||
|
||||
m_cursorPosition = cursorPosition;
|
||||
|
||||
const auto& lineInfo = m_drawer.GetLine(cursorPosition.y);
|
||||
if (cursorPosition.y + 1 < lineCount)
|
||||
{
|
||||
const auto& nextLineInfo = m_drawer.GetLine(cursorPosition.y + 1);
|
||||
cursorPosition.x = std::min(cursorPosition.x, static_cast<unsigned int>(nextLineInfo.glyphIndex - lineInfo.glyphIndex - 1));
|
||||
}
|
||||
|
||||
std::size_t glyphIndex = lineInfo.glyphIndex + cursorPosition.x;
|
||||
|
||||
OnTextAreaCursorMove(this, &glyphIndex);
|
||||
|
||||
m_cursorGlyph = std::min(glyphIndex, m_drawer.GetGlyphCount());
|
||||
|
||||
RefreshCursor();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,20 @@
|
|||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::BaseWidget
|
||||
* \brief Abstract class serving as a base class for all widgets
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a BaseWidget object using another widget as its parent
|
||||
*
|
||||
* \param parent Parent widget, must be valid and attached to a canvas
|
||||
*
|
||||
* Constructs a BaseWidget object using another widget as a base.
|
||||
* This will also register the widget to the canvas owning the top-most widget.
|
||||
*/
|
||||
BaseWidget::BaseWidget(BaseWidget* parent) :
|
||||
BaseWidget()
|
||||
{
|
||||
|
|
@ -24,11 +38,19 @@ namespace Ndk
|
|||
RegisterToCanvas();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Frees the widget, unregistering it from its canvas
|
||||
*/
|
||||
BaseWidget::~BaseWidget()
|
||||
{
|
||||
UnregisterFromCanvas();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destroy the widget, deleting it in the process.
|
||||
*
|
||||
* Calling this function immediately destroys the widget, freeing its memory.
|
||||
*/
|
||||
void BaseWidget::Destroy()
|
||||
{
|
||||
NazaraAssert(this != m_canvas, "Canvas cannot be destroyed by calling Destroy()");
|
||||
|
|
@ -36,6 +58,9 @@ namespace Ndk
|
|||
m_widgetParent->DestroyChild(this); //< This does delete us
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable or disables the widget background.
|
||||
*/
|
||||
void BaseWidget::EnableBackground(bool enable)
|
||||
{
|
||||
if (m_backgroundEntity.IsValid() == enable)
|
||||
|
|
@ -142,11 +167,11 @@ namespace Ndk
|
|||
m_canvas->NotifyWidgetBoxUpdate(m_canvasIndex);
|
||||
}
|
||||
|
||||
void BaseWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& key)
|
||||
void BaseWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& /*key*/)
|
||||
{
|
||||
}
|
||||
|
||||
void BaseWidget::OnKeyReleased(const Nz::WindowEvent::KeyEvent& key)
|
||||
void BaseWidget::OnKeyReleased(const Nz::WindowEvent::KeyEvent& /*key*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -154,15 +179,15 @@ namespace Ndk
|
|||
{
|
||||
}
|
||||
|
||||
void BaseWidget::OnMouseMoved(int x, int y, int deltaX, int deltaY)
|
||||
void BaseWidget::OnMouseMoved(int /*x*/, int /*y*/, int /*deltaX*/, int /*deltaY*/)
|
||||
{
|
||||
}
|
||||
|
||||
void BaseWidget::OnMouseButtonPress(int x, int y, Nz::Mouse::Button button)
|
||||
void BaseWidget::OnMouseButtonPress(int /*x*/, int /*y*/, Nz::Mouse::Button /*button*/)
|
||||
{
|
||||
}
|
||||
|
||||
void BaseWidget::OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button)
|
||||
void BaseWidget::OnMouseButtonRelease(int /*x*/, int /*y*/, Nz::Mouse::Button /*button*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -170,11 +195,11 @@ namespace Ndk
|
|||
{
|
||||
}
|
||||
|
||||
void BaseWidget::OnParentResized(const Nz::Vector2f& newSize)
|
||||
void BaseWidget::OnParentResized(const Nz::Vector2f& /*newSize*/)
|
||||
{
|
||||
}
|
||||
|
||||
void BaseWidget::OnTextEntered(char32_t character, bool repeated)
|
||||
void BaseWidget::OnTextEntered(char32_t /*character*/, bool /*repeated*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ namespace Ndk
|
|||
m_widgetBoxes.pop_back();
|
||||
}
|
||||
|
||||
void Canvas::OnMouseButtonPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent& event)
|
||||
void Canvas::OnEventMouseButtonPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent& event)
|
||||
{
|
||||
if (m_hoveredWidget)
|
||||
{
|
||||
|
|
@ -59,7 +59,7 @@ namespace Ndk
|
|||
}
|
||||
}
|
||||
|
||||
void Canvas::OnMouseButtonRelease(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent & event)
|
||||
void Canvas::OnEventMouseButtonRelease(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent & event)
|
||||
{
|
||||
if (m_hoveredWidget)
|
||||
{
|
||||
|
|
@ -70,7 +70,7 @@ namespace Ndk
|
|||
}
|
||||
}
|
||||
|
||||
void Canvas::OnMouseMoved(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseMoveEvent& event)
|
||||
void Canvas::OnEventMouseMoved(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseMoveEvent& event)
|
||||
{
|
||||
const WidgetBox* bestEntry = nullptr;
|
||||
float bestEntryArea = std::numeric_limits<float>::infinity();
|
||||
|
|
@ -120,7 +120,7 @@ namespace Ndk
|
|||
}
|
||||
}
|
||||
|
||||
void Canvas::OnMouseLeft(const Nz::EventHandler* /*eventHandler*/)
|
||||
void Canvas::OnEventMouseLeft(const Nz::EventHandler* /*eventHandler*/)
|
||||
{
|
||||
if (m_hoveredWidget)
|
||||
{
|
||||
|
|
@ -129,19 +129,19 @@ namespace Ndk
|
|||
}
|
||||
}
|
||||
|
||||
void Canvas::OnKeyPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event)
|
||||
void Canvas::OnEventKeyPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event)
|
||||
{
|
||||
if (m_keyboardOwner)
|
||||
m_keyboardOwner->OnKeyPressed(event);
|
||||
}
|
||||
|
||||
void Canvas::OnKeyReleased(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event)
|
||||
void Canvas::OnEventKeyReleased(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event)
|
||||
{
|
||||
if (m_keyboardOwner)
|
||||
m_keyboardOwner->OnKeyReleased(event);
|
||||
}
|
||||
|
||||
void Canvas::OnTextEntered(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::TextEvent& event)
|
||||
void Canvas::OnEventTextEntered(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::TextEvent& event)
|
||||
{
|
||||
if (m_keyboardOwner)
|
||||
m_keyboardOwner->OnTextEntered(event.character, event.repeated);
|
||||
|
|
|
|||
|
|
@ -321,10 +321,11 @@ namespace Ndk
|
|||
state.SetGlobal("CursorPosition");
|
||||
|
||||
// Nz::HashType
|
||||
static_assert(Nz::HashType_Max + 1 == 9, "Nz::HashType has been updated but change was not reflected to Lua binding");
|
||||
state.PushTable(0, 9);
|
||||
static_assert(Nz::HashType_Max + 1 == 10, "Nz::HashType has been updated but change was not reflected to Lua binding");
|
||||
state.PushTable(0, 10);
|
||||
{
|
||||
state.PushField("CRC32", Nz::HashType_CRC32);
|
||||
state.PushField("CRC64", Nz::HashType_CRC64);
|
||||
state.PushField("Fletcher16", Nz::HashType_Fletcher16);
|
||||
state.PushField("MD5", Nz::HashType_MD5);
|
||||
state.PushField("SHA1", Nz::HashType_SHA1);
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ namespace Ndk
|
|||
m_gradientSprite->SetColor(Nz::Color(128, 128, 128));
|
||||
}
|
||||
|
||||
|
||||
void ButtonWidget::OnMouseExit()
|
||||
{
|
||||
m_gradientSprite->SetColor(Nz::Color(74, 74, 74));
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ namespace Ndk
|
|||
{
|
||||
TextAreaWidget::TextAreaWidget(BaseWidget* parent) :
|
||||
BaseWidget(parent),
|
||||
m_cursorPosition(0U),
|
||||
m_cursorPosition(0U, 0U),
|
||||
m_cursorGlyph(0),
|
||||
m_multiLineEnabled(false),
|
||||
m_readOnly(false)
|
||||
{
|
||||
|
|
@ -81,7 +82,7 @@ namespace Ndk
|
|||
|
||||
void TextAreaWidget::Write(const Nz::String& text)
|
||||
{
|
||||
if (m_cursorPosition >= m_drawer.GetGlyphCount())
|
||||
if (m_cursorGlyph >= m_drawer.GetGlyphCount())
|
||||
{
|
||||
AppendText(text);
|
||||
SetCursorPosition(m_drawer.GetGlyphCount());
|
||||
|
|
@ -89,10 +90,10 @@ namespace Ndk
|
|||
else
|
||||
{
|
||||
Nz::String currentText = m_drawer.GetText();
|
||||
currentText.Insert(currentText.GetCharacterPosition(m_cursorPosition), text);
|
||||
currentText.Insert(currentText.GetCharacterPosition(m_cursorGlyph), text);
|
||||
SetText(currentText);
|
||||
|
||||
SetCursorPosition(m_cursorPosition + text.GetLength());
|
||||
SetCursorPosition(m_cursorGlyph + text.GetLength());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,11 +115,11 @@ namespace Ndk
|
|||
const Nz::String& text = m_drawer.GetText();
|
||||
|
||||
Nz::String newText;
|
||||
if (m_cursorPosition > 0)
|
||||
newText.Append(text.SubString(0, text.GetCharacterPosition(m_cursorPosition) - 1));
|
||||
if (m_cursorGlyph > 0)
|
||||
newText.Append(text.SubString(0, text.GetCharacterPosition(m_cursorGlyph) - 1));
|
||||
|
||||
if (m_cursorPosition < m_drawer.GetGlyphCount())
|
||||
newText.Append(text.SubString(text.GetCharacterPosition(m_cursorPosition + 1)));
|
||||
if (m_cursorGlyph < m_drawer.GetGlyphCount())
|
||||
newText.Append(text.SubString(text.GetCharacterPosition(m_cursorGlyph + 1)));
|
||||
|
||||
m_drawer.SetText(newText);
|
||||
m_textSprite->Update(m_drawer);
|
||||
|
|
@ -133,7 +134,7 @@ namespace Ndk
|
|||
if (ignoreDefaultAction)
|
||||
break;
|
||||
|
||||
//TODO
|
||||
MoveCursor({0, 1});
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +146,7 @@ namespace Ndk
|
|||
if (ignoreDefaultAction)
|
||||
break;
|
||||
|
||||
MoveCursor(-1);
|
||||
MoveCursor({-1, 0});
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -157,7 +158,7 @@ namespace Ndk
|
|||
if (ignoreDefaultAction)
|
||||
break;
|
||||
|
||||
MoveCursor(1);
|
||||
MoveCursor({1, 0});
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +170,7 @@ namespace Ndk
|
|||
if (ignoreDefaultAction)
|
||||
break;
|
||||
|
||||
//TODO
|
||||
MoveCursor({0, -1});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -221,13 +222,13 @@ namespace Ndk
|
|||
const Nz::String& text = m_drawer.GetText();
|
||||
|
||||
Nz::String newText;
|
||||
if (m_cursorPosition > 1)
|
||||
newText.Append(text.SubString(0, text.GetCharacterPosition(m_cursorPosition - 1) - 1));
|
||||
if (m_cursorGlyph > 1)
|
||||
newText.Append(text.SubString(0, text.GetCharacterPosition(m_cursorGlyph - 1) - 1));
|
||||
|
||||
if (m_cursorPosition < m_drawer.GetGlyphCount())
|
||||
newText.Append(text.SubString(text.GetCharacterPosition(m_cursorPosition)));
|
||||
if (m_cursorGlyph < m_drawer.GetGlyphCount())
|
||||
newText.Append(text.SubString(text.GetCharacterPosition(m_cursorGlyph)));
|
||||
|
||||
MoveCursor(-1);
|
||||
MoveCursor({-1, 0});
|
||||
SetText(newText);
|
||||
break;
|
||||
}
|
||||
|
|
@ -258,25 +259,15 @@ namespace Ndk
|
|||
|
||||
void TextAreaWidget::RefreshCursor()
|
||||
{
|
||||
std::size_t lineCount = m_drawer.GetLineCount();
|
||||
std::size_t line = 0U;
|
||||
for (std::size_t i = line + 1; i < lineCount; ++i)
|
||||
{
|
||||
if (m_drawer.GetLine(i).glyphIndex > m_cursorPosition)
|
||||
break;
|
||||
|
||||
line = i;
|
||||
}
|
||||
|
||||
const auto& lineInfo = m_drawer.GetLine(line);
|
||||
const auto& lineInfo = m_drawer.GetLine(m_cursorPosition.y);
|
||||
|
||||
std::size_t glyphCount = m_drawer.GetGlyphCount();
|
||||
float position;
|
||||
if (glyphCount > 0 && lineInfo.glyphIndex < m_cursorPosition)
|
||||
if (glyphCount > 0 && lineInfo.glyphIndex < m_cursorGlyph)
|
||||
{
|
||||
const auto& glyph = m_drawer.GetGlyph(std::min(m_cursorPosition, glyphCount - 1));
|
||||
const auto& glyph = m_drawer.GetGlyph(std::min(m_cursorGlyph, glyphCount - 1));
|
||||
position = glyph.bounds.x;
|
||||
if (m_cursorPosition >= glyphCount)
|
||||
if (m_cursorGlyph >= glyphCount)
|
||||
position += glyph.bounds.width;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ namespace Ndk
|
|||
// This is made to avoid that handle warn uselessly entities before their destruction
|
||||
m_entities.clear();
|
||||
m_entityBlocks.clear();
|
||||
m_freeIdList.clear();
|
||||
m_waitingEntities.clear();
|
||||
|
||||
m_aliveEntities.Clear();
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ Configurations = "Debug,Release" -- "Debug,Release,ReleaseWithDebug"
|
|||
-- Setup additionnals install directories, separated by a semi-colon ; (library binaries will be copied there)
|
||||
--InstallDir = "/usr/local/lib64"
|
||||
|
||||
-- Adds a project which will recall premake with its original arguments when built
|
||||
PremakeProject = true
|
||||
|
||||
-- Excludes client-only modules/tools/examples
|
||||
ServerMode = false
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ end
|
|||
|
||||
function NazaraBuild:Execute()
|
||||
if (_ACTION == nil) then -- If no action is specified, the user probably only wants to know how all of this works
|
||||
return -- Alors l'utilisateur voulait probablement savoir comment utiliser le programme, on ne fait rien
|
||||
return
|
||||
end
|
||||
|
||||
local platformData
|
||||
|
|
@ -74,7 +74,6 @@ function NazaraBuild:Execute()
|
|||
includedirs("../extlibs/include")
|
||||
libdirs("../extlibs/lib/common")
|
||||
location(_ACTION)
|
||||
kind("StaticLib")
|
||||
|
||||
for k, libTable in ipairs(self.OrderedExtLibs) do
|
||||
project(libTable.Name)
|
||||
|
|
@ -129,6 +128,13 @@ function NazaraBuild:Execute()
|
|||
language("C++")
|
||||
location(_ACTION)
|
||||
|
||||
if (self.Config["PremakeProject"]) then
|
||||
local commandLine = "premake5.exe " .. table.concat(_ARGV, ' ')
|
||||
project("_PremakeProject")
|
||||
kind("Utility")
|
||||
prebuildcommands("cd .. && " .. commandLine)
|
||||
end
|
||||
|
||||
-- Modules
|
||||
if (_OPTIONS["united"]) then
|
||||
project("NazaraEngine")
|
||||
|
|
@ -517,9 +523,9 @@ function NazaraBuild:LoadConfig()
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
AddBoolOption("BuildDependencies", "with-extlibs", "Builds the extern libraries")
|
||||
AddBoolOption("BuildExamples", "with-examples", "Builds the examples")
|
||||
AddBoolOption("PremakeProject", "premakeproject", "Add a PremakeProject as a shortcut to call Premake")
|
||||
AddBoolOption("ServerMode", "server", "Excludes client-only modules/tools/examples")
|
||||
AddBoolOption("UniteModules", "united", "Builds all the modules as one united library")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "LogoDemo.hpp"
|
||||
#include <Nazara/Core/OffsetOf.hpp>
|
||||
#include <Nazara/Graphics.hpp>
|
||||
#include <Nazara/Utility.hpp>
|
||||
#include <NDK/Components.hpp>
|
||||
|
|
@ -8,12 +9,22 @@
|
|||
namespace
|
||||
{
|
||||
const float duration = 10.f;
|
||||
const float maxVel = 50.f;
|
||||
const float maxSpeed = 100.f;
|
||||
const float maxMouseForce = 1000.f;
|
||||
const float mouseForce = 500.f;
|
||||
const float pauseTime = 3.f;
|
||||
const float startTime = 2.f;
|
||||
const float speed = 3.f;
|
||||
}
|
||||
|
||||
struct ParticleData
|
||||
{
|
||||
Nz::Color color;
|
||||
Nz::Vector2f destination;
|
||||
Nz::Vector2f position;
|
||||
Nz::Vector2f velocity;
|
||||
};
|
||||
|
||||
struct SpriteController : public Nz::ParticleController
|
||||
{
|
||||
void Apply(Nz::ParticleGroup& system, Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) override
|
||||
|
|
@ -21,15 +32,70 @@ struct SpriteController : public Nz::ParticleController
|
|||
if (!enabled)
|
||||
return;
|
||||
|
||||
auto posPtr = mapper.GetComponentPtr<Nz::Vector3f>(Nz::ParticleComponent_Position);
|
||||
auto velPtr = mapper.GetComponentPtr<Nz::Vector3f>(Nz::ParticleComponent_Velocity);
|
||||
auto destPtr = mapper.GetComponentPtr<Nz::Vector2f>(Nz::ParticleComponent_Userdata0);
|
||||
auto posPtr = mapper.GetComponentPtr<Nz::Vector2f>(Nz::ParticleComponent_Position);
|
||||
auto velPtr = mapper.GetComponentPtr<Nz::Vector2f>(Nz::ParticleComponent_Velocity);
|
||||
|
||||
std::uniform_real_distribution<float> dis(-1.f, 1.f);
|
||||
|
||||
for (unsigned int i = startId; i <= endId; ++i)
|
||||
posPtr[i] += velPtr[i] * elapsedTime * factor;
|
||||
{
|
||||
Nz::Vector2f newVel = destPtr[i] - posPtr[i];
|
||||
float length;
|
||||
newVel.Normalize(&length);
|
||||
|
||||
float distance = SquaredDistancePointSegment(oldMousePos, actualMousePos, posPtr[i]);
|
||||
if (distance < 250.f)
|
||||
{
|
||||
Nz::Vector2f mouseLine = actualMousePos - oldMousePos;
|
||||
float mouseLength;
|
||||
mouseLine.Normalize(&mouseLength);
|
||||
if (mouseLength > 5.f)
|
||||
{
|
||||
velPtr[i] += mouseLine * std::min(mouseLength * mouseForce, maxMouseForce) * elapsedTime;
|
||||
velPtr[i] += Nz::Vector2f(dis(randomGen), dis(randomGen)) * std::min(mouseLength, maxMouseForce * 0.1f);
|
||||
}
|
||||
}
|
||||
|
||||
if (length > 1.f || velPtr[i].GetSquaredLength() > Nz::IntegralPow(30.f, 2))
|
||||
{
|
||||
newVel *= maxSpeed;
|
||||
|
||||
velPtr[i] = Nz::Lerp(velPtr[i], newVel, 0.4f * elapsedTime);
|
||||
posPtr[i] += velPtr[i] * elapsedTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
velPtr[i] = Nz::Vector2f::Zero();
|
||||
posPtr[i] = destPtr[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static float SquaredDistancePointSegment(const Nz::Vector2f& s0, const Nz::Vector2f& s1, const Nz::Vector2f& point)
|
||||
{
|
||||
// http://geomalgorithms.com/a02-_lines.html
|
||||
Nz::Vector2f v = s1 - s0;
|
||||
Nz::Vector2f w = point - s0;
|
||||
|
||||
float c1 = Nz::Vector2f::DotProduct(w, v);
|
||||
if (c1 <= 0.f)
|
||||
return point.SquaredDistance(s0);
|
||||
|
||||
float c2 = Nz::Vector2f::DotProduct(v, v);
|
||||
if (c2 <= c1)
|
||||
return point.SquaredDistance(s1);
|
||||
|
||||
float b = c1 / c2;
|
||||
Nz::Vector2f projPoint = s0 + b * v;
|
||||
return projPoint.SquaredDistance(point);
|
||||
}
|
||||
|
||||
std::mt19937 randomGen;
|
||||
bool enabled = false;
|
||||
float factor = 1.f;
|
||||
float factor = 1000.f;
|
||||
Nz::Vector2f actualMousePos;
|
||||
Nz::Vector2f oldMousePos;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -67,9 +133,9 @@ ParticleDemo("Logo", sharedData)
|
|||
unsigned int height = m_logo.GetHeight();
|
||||
m_pixels.reserve(width * height);
|
||||
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
for (unsigned int x = 0; x < width; ++x)
|
||||
{
|
||||
for (unsigned int x = 0; x < width; ++x)
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
Nz::Color color = m_logo.GetPixelColor(x, y);
|
||||
if (color.a == 0)
|
||||
|
|
@ -93,6 +159,12 @@ ParticleDemo("Logo", sharedData)
|
|||
|
||||
m_controller = new SpriteController;
|
||||
m_renderer = new SpriteRenderer(std::move(material));
|
||||
|
||||
m_declaration = Nz::ParticleDeclaration::New();
|
||||
m_declaration->EnableComponent(Nz::ParticleComponent_Color, Nz::ComponentType_Color, NazaraOffsetOf(ParticleData, color));
|
||||
m_declaration->EnableComponent(Nz::ParticleComponent_Position, Nz::ComponentType_Float2, NazaraOffsetOf(ParticleData, position));
|
||||
m_declaration->EnableComponent(Nz::ParticleComponent_Userdata0, Nz::ComponentType_Float2, NazaraOffsetOf(ParticleData, destination));
|
||||
m_declaration->EnableComponent(Nz::ParticleComponent_Velocity, Nz::ComponentType_Float2, NazaraOffsetOf(ParticleData, velocity));
|
||||
}
|
||||
|
||||
void LogoExample::Enter(Ndk::StateMachine& fsm)
|
||||
|
|
@ -106,17 +178,20 @@ void LogoExample::Enter(Ndk::StateMachine& fsm)
|
|||
m_shared.world2D->GetSystem<Ndk::RenderSystem>().SetDefaultBackground(Nz::TextureBackground::New(std::move(backgroundTexture)));
|
||||
|
||||
Ndk::EntityHandle particleGroupEntity = m_shared.world2D->CreateEntity();
|
||||
Ndk::ParticleGroupComponent& particleGroup = particleGroupEntity->AddComponent<Ndk::ParticleGroupComponent>(m_pixels.size(), Nz::ParticleLayout_Sprite);
|
||||
Ndk::ParticleGroupComponent& particleGroup = particleGroupEntity->AddComponent<Ndk::ParticleGroupComponent>(m_pixels.size(), m_declaration);
|
||||
RegisterParticleGroup(particleGroupEntity);
|
||||
|
||||
particleGroup.AddController(m_controller);
|
||||
particleGroup.SetRenderer(m_renderer);
|
||||
|
||||
m_particles = static_cast<Nz::ParticleStruct_Sprite*>(particleGroup.CreateParticles(m_pixels.size()));
|
||||
m_particles = particleGroup.CreateParticles(m_pixels.size());
|
||||
ResetParticles(-duration * (speed / 2.f));
|
||||
|
||||
m_accumulator = pauseTime + duration;
|
||||
m_totalAccumulator = 0.f;
|
||||
|
||||
SpriteController* controller = static_cast<SpriteController*>(m_controller.Get());
|
||||
controller->actualMousePos = controller->oldMousePos = Nz::Vector2f(Nz::Mouse::GetPosition(*m_shared.target));
|
||||
}
|
||||
|
||||
void LogoExample::Leave(Ndk::StateMachine & fsm)
|
||||
|
|
@ -136,35 +211,62 @@ bool LogoExample::Update(Ndk::StateMachine& fsm, float elapsedTime)
|
|||
m_accumulator += elapsedTime;
|
||||
|
||||
SpriteController* controller = static_cast<SpriteController*>(m_controller.Get());
|
||||
if (m_accumulator > pauseTime + 2.f * duration)
|
||||
controller->enabled = (m_accumulator > pauseTime);
|
||||
|
||||
if (m_mouseClock.GetMilliseconds() > 1000/30)
|
||||
{
|
||||
ResetParticles(0.f);
|
||||
m_accumulator = 0.f;
|
||||
m_mouseClock.Restart();
|
||||
|
||||
controller->oldMousePos = controller->actualMousePos;
|
||||
controller->actualMousePos = Nz::Vector2f(Nz::Mouse::GetPosition(*m_shared.target));
|
||||
}
|
||||
|
||||
controller->enabled = (m_accumulator > pauseTime);
|
||||
controller->factor = -speed + speed * (m_accumulator - pauseTime) / (duration);
|
||||
if (Nz::Mouse::IsButtonPressed(Nz::Mouse::Left))
|
||||
{
|
||||
if (!m_hasClicked)
|
||||
{
|
||||
m_hasClicked = true;
|
||||
std::uniform_real_distribution<float> dis(50.f, 60.f);
|
||||
|
||||
ParticleData* sprite = static_cast<ParticleData*>(m_particles);
|
||||
for (std::size_t i = 0; i < m_pixels.size(); ++i)
|
||||
{
|
||||
Nz::Vector2f particleToMouse = sprite[i].position - controller->actualMousePos;
|
||||
float sqDist = particleToMouse.GetSquaredLength();
|
||||
if (sqDist < 10000.f)
|
||||
{
|
||||
float dist = std::sqrt(sqDist);
|
||||
particleToMouse /= std::max(dist, 1.f);
|
||||
|
||||
sprite[i].velocity += particleToMouse * dis(m_shared.randomGen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_hasClicked = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LogoExample::ResetParticles(float elapsed)
|
||||
{
|
||||
Nz::Vector2f center = {m_shared.target->GetWidth() / 2.f, m_shared.target->GetHeight() / 2.f};
|
||||
unsigned int width = m_shared.target->GetWidth();
|
||||
unsigned int height = m_shared.target->GetHeight();
|
||||
|
||||
Nz::Vector2f center = {width / 2.f, height / 2.f};
|
||||
Nz::Vector2f offset = center - Nz::Vector2f(Nz::Vector2ui(m_logo.GetSize()) / 2);
|
||||
|
||||
float ratio = float(m_shared.target->GetWidth()) / m_shared.target->GetHeight();
|
||||
std::uniform_real_distribution<float> disX(-maxVel * ratio, maxVel * ratio);
|
||||
std::uniform_real_distribution<float> disY(-maxVel, maxVel);
|
||||
std::uniform_real_distribution<float> disX(0.f, float(width));
|
||||
std::uniform_real_distribution<float> disY(-float(height) * 0.5f, float(height) * 1.5f);
|
||||
|
||||
Nz::ParticleStruct_Sprite* sprite = m_particles;
|
||||
ParticleData* sprite = static_cast<ParticleData*>(m_particles);
|
||||
for (PixelData& data : m_pixels)
|
||||
{
|
||||
sprite->color = data.color;
|
||||
sprite->position = offset + Nz::Vector2f(data.pos);
|
||||
sprite->rotation = 0.f;
|
||||
sprite->velocity.Set(disX(m_shared.randomGen), disY(m_shared.randomGen), 0.f);
|
||||
sprite->position += sprite->velocity * elapsed;
|
||||
sprite->destination = offset + Nz::Vector2f(data.pos);
|
||||
sprite->position.Set(disX(m_shared.randomGen) - float(width), disY(m_shared.randomGen));
|
||||
sprite->velocity = Nz::Vector2f::Zero();
|
||||
sprite++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,10 +30,13 @@ class LogoExample : public ParticleDemo
|
|||
|
||||
std::vector<PixelData> m_pixels;
|
||||
Nz::BackgroundRef m_oldBackground;
|
||||
Nz::ParticleStruct_Sprite* m_particles;
|
||||
void* m_particles;
|
||||
Nz::Clock m_mouseClock;
|
||||
Nz::Image m_logo;
|
||||
Nz::ParticleControllerRef m_controller;
|
||||
Nz::ParticleDeclarationRef m_declaration;
|
||||
Nz::ParticleRendererRef m_renderer;
|
||||
bool m_hasClicked;
|
||||
float m_accumulator;
|
||||
float m_totalAccumulator;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ int main()
|
|||
fpsNode.SetPosition(5.f, window.GetHeight() - fpsCountBox.height - particleCountBox.height - 5.f);
|
||||
|
||||
|
||||
//shared.demos.push_back(std::make_shared<LogoExample>(shared));
|
||||
shared.demos.push_back(std::make_shared<LogoExample>(shared));
|
||||
shared.demos.push_back(std::make_shared<SpacebattleExample>(shared));
|
||||
|
||||
std::size_t demoIndex = 0;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ namespace Nz
|
|||
enum HashType
|
||||
{
|
||||
HashType_CRC32,
|
||||
HashType_CRC64,
|
||||
HashType_Fletcher16,
|
||||
HashType_MD5,
|
||||
HashType_SHA1,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
// 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_HASH_CRC64_HPP
|
||||
#define NAZARA_HASH_CRC64_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/AbstractHash.hpp>
|
||||
#include <Nazara/Core/ByteArray.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_CORE_API HashCRC64 : public AbstractHash
|
||||
{
|
||||
public:
|
||||
HashCRC64() = default;
|
||||
~HashCRC64() = default;
|
||||
|
||||
void Append(const UInt8* data, std::size_t len) override;
|
||||
void Begin() override;
|
||||
ByteArray End() override;
|
||||
|
||||
std::size_t GetDigestLength() const override;
|
||||
const char* GetHashName() const override;
|
||||
|
||||
private:
|
||||
Nz::UInt64 m_crc;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NAZARA_HASH_CRC64_HPP
|
||||
|
|
@ -788,16 +788,17 @@ namespace Nz
|
|||
template<typename T>
|
||||
std::enable_if_t<std::is_unsigned<T>::value, T> LuaState::CheckBounds(int index, long long value) const
|
||||
{
|
||||
unsigned long long uValue = static_cast<unsigned long long>(value);
|
||||
constexpr unsigned long long minBounds = 0;
|
||||
constexpr unsigned long long maxBounds = std::numeric_limits<T>::max();
|
||||
if (value < minBounds || value > maxBounds)
|
||||
if (uValue < minBounds || uValue > maxBounds)
|
||||
{
|
||||
Nz::StringStream stream;
|
||||
stream << "Argument #" << index << " is outside value range [" << minBounds << ", " << maxBounds << "] (" << value << ')';
|
||||
Error(stream);
|
||||
}
|
||||
|
||||
return static_cast<T>(value);
|
||||
return static_cast<T>(uValue);
|
||||
}
|
||||
|
||||
inline LuaState LuaState::GetState(lua_State* internalState)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@
|
|||
#include <Nazara/Network/AbstractSocket.hpp>
|
||||
#include <Nazara/Network/Algorithm.hpp>
|
||||
#include <Nazara/Network/Config.hpp>
|
||||
#include <Nazara/Network/ENetHost.hpp>
|
||||
#include <Nazara/Network/ENetPacket.hpp>
|
||||
#include <Nazara/Network/ENetPeer.hpp>
|
||||
#include <Nazara/Network/ENetProtocol.hpp>
|
||||
#include <Nazara/Network/Enums.hpp>
|
||||
#include <Nazara/Network/IpAddress.hpp>
|
||||
#include <Nazara/Network/NetBuffer.hpp>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace Nz
|
|||
bool RegisterSocket(AbstractSocket& socket, SocketPollEventFlags eventFlags);
|
||||
void UnregisterSocket(AbstractSocket& socket);
|
||||
|
||||
bool Wait(UInt64 msTimeout);
|
||||
bool Wait(int msTimeout);
|
||||
|
||||
inline SocketPoller& operator=(SocketPoller&& socketPoller);
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ namespace Nz
|
|||
std::size_t QueryMaxDatagramSize();
|
||||
|
||||
bool Receive(void* buffer, std::size_t size, IpAddress* from, std::size_t* received);
|
||||
bool ReceiveMultiple(NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, std::size_t* received);
|
||||
bool ReceivePacket(NetPacket* packet, IpAddress* from);
|
||||
|
||||
bool Send(const IpAddress& to, const void* buffer, std::size_t size, std::size_t* sent);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <Nazara/Core/ObjectRef.hpp>
|
||||
#include <Nazara/Core/ObjectLibrary.hpp>
|
||||
#include <Nazara/Core/Signal.hpp>
|
||||
#include <Nazara/Core/SparsePtr.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Physics2D/Config.hpp>
|
||||
|
|
@ -33,6 +34,7 @@ namespace Nz
|
|||
{
|
||||
friend Collider2DLibrary;
|
||||
friend RigidBody2D;
|
||||
friend class CompoundCollider2D; //< See CompoundCollider2D::CreateShapes
|
||||
|
||||
public:
|
||||
inline Collider2D();
|
||||
|
|
@ -40,7 +42,7 @@ namespace Nz
|
|||
Collider2D(Collider2D&&) = delete;
|
||||
virtual ~Collider2D();
|
||||
|
||||
virtual float ComputeInertialMatrix(float mass) const = 0;
|
||||
virtual float ComputeMomentOfInertia(float mass) const = 0;
|
||||
|
||||
inline Nz::UInt32 GetCategoryMask() const;
|
||||
inline Nz::UInt32 GetCollisionGroup() const;
|
||||
|
|
@ -64,7 +66,7 @@ namespace Nz
|
|||
NazaraSignal(OnColliderRelease, const Collider2D* /*collider*/);
|
||||
|
||||
protected:
|
||||
virtual std::vector<cpShape*> CreateShapes(RigidBody2D* body) const = 0;
|
||||
virtual void CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const = 0;
|
||||
|
||||
bool m_trigger;
|
||||
Nz::UInt32 m_categoryMask;
|
||||
|
|
@ -89,7 +91,7 @@ namespace Nz
|
|||
BoxCollider2D(const Vector2f& size, float radius = 0.f);
|
||||
BoxCollider2D(const Rectf& rect, float radius = 0.f);
|
||||
|
||||
float ComputeInertialMatrix(float mass) const override;
|
||||
float ComputeMomentOfInertia(float mass) const override;
|
||||
|
||||
inline const Rectf& GetRect() const;
|
||||
inline Vector2f GetSize() const;
|
||||
|
|
@ -98,7 +100,7 @@ namespace Nz
|
|||
template<typename... Args> static BoxCollider2DRef New(Args&&... args);
|
||||
|
||||
private:
|
||||
std::vector<cpShape*> CreateShapes(RigidBody2D* body) const override;
|
||||
void CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const override;
|
||||
|
||||
Rectf m_rect;
|
||||
float m_radius;
|
||||
|
|
@ -114,7 +116,7 @@ namespace Nz
|
|||
public:
|
||||
CircleCollider2D(float radius, const Vector2f& offset = Vector2f::Zero());
|
||||
|
||||
float ComputeInertialMatrix(float mass) const override;
|
||||
float ComputeMomentOfInertia(float mass) const override;
|
||||
|
||||
inline float GetRadius() const;
|
||||
ColliderType2D GetType() const override;
|
||||
|
|
@ -122,12 +124,58 @@ namespace Nz
|
|||
template<typename... Args> static CircleCollider2DRef New(Args&&... args);
|
||||
|
||||
private:
|
||||
std::vector<cpShape*> CreateShapes(RigidBody2D* body) const override;
|
||||
void CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const override;
|
||||
|
||||
Vector2f m_offset;
|
||||
float m_radius;
|
||||
};
|
||||
|
||||
class CompoundCollider2D;
|
||||
|
||||
using CompoundCollider2DConstRef = ObjectRef<const CompoundCollider2D>;
|
||||
using CompoundCollider2DRef = ObjectRef<CompoundCollider2D>;
|
||||
|
||||
class NAZARA_PHYSICS2D_API CompoundCollider2D : public Collider2D
|
||||
{
|
||||
public:
|
||||
CompoundCollider2D(std::vector<Collider2DRef> geoms);
|
||||
|
||||
float ComputeMomentOfInertia(float mass) const override;
|
||||
|
||||
inline const std::vector<Collider2DRef>& GetGeoms() const;
|
||||
ColliderType2D GetType() const override;
|
||||
|
||||
template<typename... Args> static CompoundCollider2DRef New(Args&&... args);
|
||||
|
||||
private:
|
||||
void CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const override;
|
||||
|
||||
std::vector<Collider2DRef> m_geoms;
|
||||
};
|
||||
|
||||
class ConvexCollider2D;
|
||||
|
||||
using ConvexCollider2DConstRef = ObjectRef<const ConvexCollider2D>;
|
||||
using ConvexCollider2DRef = ObjectRef<ConvexCollider2D>;
|
||||
|
||||
class NAZARA_PHYSICS2D_API ConvexCollider2D : public Collider2D
|
||||
{
|
||||
public:
|
||||
ConvexCollider2D(SparsePtr<const Vector2f> vertices, std::size_t vertexCount, float radius = 0.f);
|
||||
|
||||
float ComputeMomentOfInertia(float mass) const override;
|
||||
|
||||
ColliderType2D GetType() const override;
|
||||
|
||||
template<typename... Args> static ConvexCollider2DRef New(Args&&... args);
|
||||
|
||||
private:
|
||||
void CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const override;
|
||||
|
||||
std::vector<Vector2d> m_vertices;
|
||||
float m_radius;
|
||||
};
|
||||
|
||||
class NullCollider2D;
|
||||
|
||||
using NullCollider2DConstRef = ObjectRef<const NullCollider2D>;
|
||||
|
|
@ -138,14 +186,14 @@ namespace Nz
|
|||
public:
|
||||
NullCollider2D() = default;
|
||||
|
||||
float ComputeInertialMatrix(float mass) const override;
|
||||
float ComputeMomentOfInertia(float mass) const override;
|
||||
|
||||
ColliderType2D GetType() const override;
|
||||
|
||||
template<typename... Args> static NullCollider2DRef New(Args&&... args);
|
||||
|
||||
private:
|
||||
std::vector<cpShape*> CreateShapes(RigidBody2D* body) const override;
|
||||
void CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const override;
|
||||
};
|
||||
|
||||
class SegmentCollider2D;
|
||||
|
|
@ -158,7 +206,7 @@ namespace Nz
|
|||
public:
|
||||
inline SegmentCollider2D(const Vector2f& first, const Vector2f& second, float thickness = 1.f);
|
||||
|
||||
float ComputeInertialMatrix(float mass) const override;
|
||||
float ComputeMomentOfInertia(float mass) const override;
|
||||
|
||||
inline const Vector2f& GetFirstPoint() const;
|
||||
inline float GetLength() const;
|
||||
|
|
@ -168,7 +216,7 @@ namespace Nz
|
|||
template<typename... Args> static SegmentCollider2DRef New(Args&&... args);
|
||||
|
||||
private:
|
||||
std::vector<cpShape*> CreateShapes(RigidBody2D* body) const override;
|
||||
void CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const override;
|
||||
|
||||
Vector2f m_first;
|
||||
Vector2f m_second;
|
||||
|
|
|
|||
|
|
@ -100,6 +100,20 @@ namespace Nz
|
|||
return object.release();
|
||||
}
|
||||
|
||||
inline const std::vector<Collider2DRef>& Nz::CompoundCollider2D::GetGeoms() const
|
||||
{
|
||||
return m_geoms;
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
CompoundCollider2DRef CompoundCollider2D::New(Args&&... args)
|
||||
{
|
||||
std::unique_ptr<CompoundCollider2D> object(new CompoundCollider2D(std::forward<Args>(args)...));
|
||||
object->SetPersistent(false);
|
||||
|
||||
return object.release();
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
NullCollider2DRef NullCollider2D::New(Args&&... args)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ namespace Nz
|
|||
enum ColliderType2D
|
||||
{
|
||||
ColliderType2D_Box,
|
||||
ColliderType2D_Compound,
|
||||
ColliderType2D_Convex,
|
||||
ColliderType2D_Circle,
|
||||
ColliderType2D_Null,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Physics2D/Config.hpp>
|
||||
#include <Nazara/Physics2D/RigidBody2D.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
|
|
@ -24,10 +25,10 @@ namespace Nz
|
|||
{
|
||||
friend RigidBody2D;
|
||||
|
||||
using ContactEndCallback = void(*)(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata);
|
||||
using ContactPreSolveCallback = bool(*)(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata);
|
||||
using ContactPostSolveCallback = void(*)(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata);
|
||||
using ContactStartCallback = bool(*)(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata);
|
||||
using ContactEndCallback = std::function<void(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata)>;
|
||||
using ContactPreSolveCallback = std::function<bool(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata)>;
|
||||
using ContactPostSolveCallback = std::function<void(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata)>;
|
||||
using ContactStartCallback = std::function<bool(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata)>;
|
||||
|
||||
public:
|
||||
struct Callback;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ namespace Nz
|
|||
float GetRotation() const;
|
||||
void* GetUserdata() const;
|
||||
Vector2f GetVelocity() const;
|
||||
PhysWorld2D* GetWorld() const;
|
||||
|
||||
bool IsMoveable() const;
|
||||
bool IsSleeping() const;
|
||||
|
|
@ -56,6 +57,7 @@ namespace Nz
|
|||
void SetGeom(Collider2DRef geom);
|
||||
void SetMass(float mass);
|
||||
void SetMassCenter(const Vector2f& center);
|
||||
void SetMomentOfInertia(float moment);
|
||||
void SetPosition(const Vector2f& position);
|
||||
void SetRotation(float rotation);
|
||||
void SetUserdata(void* ud);
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ namespace Nz
|
|||
class NAZARA_PHYSICS3D_API CompoundCollider3D : public Collider3D
|
||||
{
|
||||
public:
|
||||
CompoundCollider3D(Collider3D** geoms, std::size_t geomCount);
|
||||
CompoundCollider3D(std::vector<Collider3DRef> geoms);
|
||||
|
||||
const std::vector<Collider3DRef>& GetGeoms() const;
|
||||
ColliderType3D GetType() const override;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ namespace Nz
|
|||
Vector3f GetPosition() const;
|
||||
Quaternionf GetRotation() const;
|
||||
Vector3f GetVelocity() const;
|
||||
PhysWorld3D* GetWorld() const;
|
||||
|
||||
bool IsAutoSleepEnabled() const;
|
||||
bool IsMoveable() const;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||
|
||||
// La taille du buffer d'Instancing (définit le nombre maximum d'instances en un rendu)
|
||||
#define NAZARA_RENDERER_INSTANCE_BUFFER_SIZE 524288 // 8192 matrices 4x4 flottantes
|
||||
#define NAZARA_RENDERER_INSTANCE_BUFFER_SIZE 1 * 1024 * 1024
|
||||
|
||||
// Utilise un manager de mémoire pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes)
|
||||
#define NAZARA_RENDERER_MANAGE_MEMORY 0
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Nz
|
|||
public:
|
||||
inline RenderWindow();
|
||||
inline RenderWindow(VideoMode mode, const String& title, WindowStyleFlags style = WindowStyle_Default, const RenderWindowParameters& parameters = RenderWindowParameters());
|
||||
inline RenderWindow(WindowHandle handle, const RenderWindowParameters& parameters = RenderWindowParameters());
|
||||
inline explicit RenderWindow(WindowHandle handle, const RenderWindowParameters& parameters = RenderWindowParameters());
|
||||
|
||||
inline bool Create(VideoMode mode, const String& title, WindowStyleFlags style = WindowStyle_Default, const RenderWindowParameters& parameters = RenderWindowParameters());
|
||||
inline bool Create(WindowHandle handle, const RenderWindowParameters& parameters = RenderWindowParameters());
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ namespace Nz
|
|||
public:
|
||||
Window();
|
||||
inline Window(VideoMode mode, const String& title, WindowStyleFlags style = WindowStyle_Default);
|
||||
inline Window(WindowHandle handle);
|
||||
inline explicit Window(WindowHandle handle);
|
||||
Window(const Window&) = delete;
|
||||
inline Window(Window&& window) noexcept;
|
||||
virtual ~Window();
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <Nazara/Core/AbstractHash.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Hash/CRC32.hpp>
|
||||
#include <Nazara/Core/Hash/CRC64.hpp>
|
||||
#include <Nazara/Core/Hash/Fletcher16.hpp>
|
||||
#include <Nazara/Core/Hash/MD5.hpp>
|
||||
#include <Nazara/Core/Hash/SHA1.hpp>
|
||||
|
|
@ -48,6 +49,9 @@ namespace Nz
|
|||
case HashType_CRC32:
|
||||
return std::make_unique<HashCRC32>();
|
||||
|
||||
case HashType_CRC64:
|
||||
return std::make_unique<HashCRC64>();
|
||||
|
||||
case HashType_MD5:
|
||||
return std::make_unique<HashMD5>();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
// 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/Hash/CRC64.hpp>
|
||||
#include <Nazara/Core/Endianness.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
struct HashCRC64_state
|
||||
{
|
||||
UInt64 crc;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
static const UInt64 crc64_table[256] = {
|
||||
0x0000000000000000ULL, 0x7ad870c830358979ULL, 0xf5b0e190606b12f2ULL, 0x8f689158505e9b8bULL,
|
||||
0xc038e5739841b68fULL, 0xbae095bba8743ff6ULL, 0x358804e3f82aa47dULL, 0x4f50742bc81f2d04ULL,
|
||||
0xab28ecb46814fe75ULL, 0xd1f09c7c5821770cULL, 0x5e980d24087fec87ULL, 0x24407dec384a65feULL,
|
||||
0x6b1009c7f05548faULL, 0x11c8790fc060c183ULL, 0x9ea0e857903e5a08ULL, 0xe478989fa00bd371ULL,
|
||||
0x7d08ff3b88be6f81ULL, 0x07d08ff3b88be6f8ULL, 0x88b81eabe8d57d73ULL, 0xf2606e63d8e0f40aULL,
|
||||
0xbd301a4810ffd90eULL, 0xc7e86a8020ca5077ULL, 0x4880fbd87094cbfcULL, 0x32588b1040a14285ULL,
|
||||
0xd620138fe0aa91f4ULL, 0xacf86347d09f188dULL, 0x2390f21f80c18306ULL, 0x594882d7b0f40a7fULL,
|
||||
0x1618f6fc78eb277bULL, 0x6cc0863448deae02ULL, 0xe3a8176c18803589ULL, 0x997067a428b5bcf0ULL,
|
||||
0xfa11fe77117cdf02ULL, 0x80c98ebf2149567bULL, 0x0fa11fe77117cdf0ULL, 0x75796f2f41224489ULL,
|
||||
0x3a291b04893d698dULL, 0x40f16bccb908e0f4ULL, 0xcf99fa94e9567b7fULL, 0xb5418a5cd963f206ULL,
|
||||
0x513912c379682177ULL, 0x2be1620b495da80eULL, 0xa489f35319033385ULL, 0xde51839b2936bafcULL,
|
||||
0x9101f7b0e12997f8ULL, 0xebd98778d11c1e81ULL, 0x64b116208142850aULL, 0x1e6966e8b1770c73ULL,
|
||||
0x8719014c99c2b083ULL, 0xfdc17184a9f739faULL, 0x72a9e0dcf9a9a271ULL, 0x08719014c99c2b08ULL,
|
||||
0x4721e43f0183060cULL, 0x3df994f731b68f75ULL, 0xb29105af61e814feULL, 0xc849756751dd9d87ULL,
|
||||
0x2c31edf8f1d64ef6ULL, 0x56e99d30c1e3c78fULL, 0xd9810c6891bd5c04ULL, 0xa3597ca0a188d57dULL,
|
||||
0xec09088b6997f879ULL, 0x96d1784359a27100ULL, 0x19b9e91b09fcea8bULL, 0x636199d339c963f2ULL,
|
||||
0xdf7adabd7a6e2d6fULL, 0xa5a2aa754a5ba416ULL, 0x2aca3b2d1a053f9dULL, 0x50124be52a30b6e4ULL,
|
||||
0x1f423fcee22f9be0ULL, 0x659a4f06d21a1299ULL, 0xeaf2de5e82448912ULL, 0x902aae96b271006bULL,
|
||||
0x74523609127ad31aULL, 0x0e8a46c1224f5a63ULL, 0x81e2d7997211c1e8ULL, 0xfb3aa75142244891ULL,
|
||||
0xb46ad37a8a3b6595ULL, 0xceb2a3b2ba0eececULL, 0x41da32eaea507767ULL, 0x3b024222da65fe1eULL,
|
||||
0xa2722586f2d042eeULL, 0xd8aa554ec2e5cb97ULL, 0x57c2c41692bb501cULL, 0x2d1ab4dea28ed965ULL,
|
||||
0x624ac0f56a91f461ULL, 0x1892b03d5aa47d18ULL, 0x97fa21650afae693ULL, 0xed2251ad3acf6feaULL,
|
||||
0x095ac9329ac4bc9bULL, 0x7382b9faaaf135e2ULL, 0xfcea28a2faafae69ULL, 0x8632586aca9a2710ULL,
|
||||
0xc9622c4102850a14ULL, 0xb3ba5c8932b0836dULL, 0x3cd2cdd162ee18e6ULL, 0x460abd1952db919fULL,
|
||||
0x256b24ca6b12f26dULL, 0x5fb354025b277b14ULL, 0xd0dbc55a0b79e09fULL, 0xaa03b5923b4c69e6ULL,
|
||||
0xe553c1b9f35344e2ULL, 0x9f8bb171c366cd9bULL, 0x10e3202993385610ULL, 0x6a3b50e1a30ddf69ULL,
|
||||
0x8e43c87e03060c18ULL, 0xf49bb8b633338561ULL, 0x7bf329ee636d1eeaULL, 0x012b592653589793ULL,
|
||||
0x4e7b2d0d9b47ba97ULL, 0x34a35dc5ab7233eeULL, 0xbbcbcc9dfb2ca865ULL, 0xc113bc55cb19211cULL,
|
||||
0x5863dbf1e3ac9decULL, 0x22bbab39d3991495ULL, 0xadd33a6183c78f1eULL, 0xd70b4aa9b3f20667ULL,
|
||||
0x985b3e827bed2b63ULL, 0xe2834e4a4bd8a21aULL, 0x6debdf121b863991ULL, 0x1733afda2bb3b0e8ULL,
|
||||
0xf34b37458bb86399ULL, 0x8993478dbb8deae0ULL, 0x06fbd6d5ebd3716bULL, 0x7c23a61ddbe6f812ULL,
|
||||
0x3373d23613f9d516ULL, 0x49aba2fe23cc5c6fULL, 0xc6c333a67392c7e4ULL, 0xbc1b436e43a74e9dULL,
|
||||
0x95ac9329ac4bc9b5ULL, 0xef74e3e19c7e40ccULL, 0x601c72b9cc20db47ULL, 0x1ac40271fc15523eULL,
|
||||
0x5594765a340a7f3aULL, 0x2f4c0692043ff643ULL, 0xa02497ca54616dc8ULL, 0xdafce7026454e4b1ULL,
|
||||
0x3e847f9dc45f37c0ULL, 0x445c0f55f46abeb9ULL, 0xcb349e0da4342532ULL, 0xb1eceec59401ac4bULL,
|
||||
0xfebc9aee5c1e814fULL, 0x8464ea266c2b0836ULL, 0x0b0c7b7e3c7593bdULL, 0x71d40bb60c401ac4ULL,
|
||||
0xe8a46c1224f5a634ULL, 0x927c1cda14c02f4dULL, 0x1d148d82449eb4c6ULL, 0x67ccfd4a74ab3dbfULL,
|
||||
0x289c8961bcb410bbULL, 0x5244f9a98c8199c2ULL, 0xdd2c68f1dcdf0249ULL, 0xa7f41839ecea8b30ULL,
|
||||
0x438c80a64ce15841ULL, 0x3954f06e7cd4d138ULL, 0xb63c61362c8a4ab3ULL, 0xcce411fe1cbfc3caULL,
|
||||
0x83b465d5d4a0eeceULL, 0xf96c151de49567b7ULL, 0x76048445b4cbfc3cULL, 0x0cdcf48d84fe7545ULL,
|
||||
0x6fbd6d5ebd3716b7ULL, 0x15651d968d029fceULL, 0x9a0d8ccedd5c0445ULL, 0xe0d5fc06ed698d3cULL,
|
||||
0xaf85882d2576a038ULL, 0xd55df8e515432941ULL, 0x5a3569bd451db2caULL, 0x20ed197575283bb3ULL,
|
||||
0xc49581ead523e8c2ULL, 0xbe4df122e51661bbULL, 0x3125607ab548fa30ULL, 0x4bfd10b2857d7349ULL,
|
||||
0x04ad64994d625e4dULL, 0x7e7514517d57d734ULL, 0xf11d85092d094cbfULL, 0x8bc5f5c11d3cc5c6ULL,
|
||||
0x12b5926535897936ULL, 0x686de2ad05bcf04fULL, 0xe70573f555e26bc4ULL, 0x9ddd033d65d7e2bdULL,
|
||||
0xd28d7716adc8cfb9ULL, 0xa85507de9dfd46c0ULL, 0x273d9686cda3dd4bULL, 0x5de5e64efd965432ULL,
|
||||
0xb99d7ed15d9d8743ULL, 0xc3450e196da80e3aULL, 0x4c2d9f413df695b1ULL, 0x36f5ef890dc31cc8ULL,
|
||||
0x79a59ba2c5dc31ccULL, 0x037deb6af5e9b8b5ULL, 0x8c157a32a5b7233eULL, 0xf6cd0afa9582aa47ULL,
|
||||
0x4ad64994d625e4daULL, 0x300e395ce6106da3ULL, 0xbf66a804b64ef628ULL, 0xc5bed8cc867b7f51ULL,
|
||||
0x8aeeace74e645255ULL, 0xf036dc2f7e51db2cULL, 0x7f5e4d772e0f40a7ULL, 0x05863dbf1e3ac9deULL,
|
||||
0xe1fea520be311aafULL, 0x9b26d5e88e0493d6ULL, 0x144e44b0de5a085dULL, 0x6e963478ee6f8124ULL,
|
||||
0x21c640532670ac20ULL, 0x5b1e309b16452559ULL, 0xd476a1c3461bbed2ULL, 0xaeaed10b762e37abULL,
|
||||
0x37deb6af5e9b8b5bULL, 0x4d06c6676eae0222ULL, 0xc26e573f3ef099a9ULL, 0xb8b627f70ec510d0ULL,
|
||||
0xf7e653dcc6da3dd4ULL, 0x8d3e2314f6efb4adULL, 0x0256b24ca6b12f26ULL, 0x788ec2849684a65fULL,
|
||||
0x9cf65a1b368f752eULL, 0xe62e2ad306bafc57ULL, 0x6946bb8b56e467dcULL, 0x139ecb4366d1eea5ULL,
|
||||
0x5ccebf68aecec3a1ULL, 0x2616cfa09efb4ad8ULL, 0xa97e5ef8cea5d153ULL, 0xd3a62e30fe90582aULL,
|
||||
0xb0c7b7e3c7593bd8ULL, 0xca1fc72bf76cb2a1ULL, 0x45775673a732292aULL, 0x3faf26bb9707a053ULL,
|
||||
0x70ff52905f188d57ULL, 0x0a2722586f2d042eULL, 0x854fb3003f739fa5ULL, 0xff97c3c80f4616dcULL,
|
||||
0x1bef5b57af4dc5adULL, 0x61372b9f9f784cd4ULL, 0xee5fbac7cf26d75fULL, 0x9487ca0fff135e26ULL,
|
||||
0xdbd7be24370c7322ULL, 0xa10fceec0739fa5bULL, 0x2e675fb4576761d0ULL, 0x54bf2f7c6752e8a9ULL,
|
||||
0xcdcf48d84fe75459ULL, 0xb71738107fd2dd20ULL, 0x387fa9482f8c46abULL, 0x42a7d9801fb9cfd2ULL,
|
||||
0x0df7adabd7a6e2d6ULL, 0x772fdd63e7936bafULL, 0xf8474c3bb7cdf024ULL, 0x829f3cf387f8795dULL,
|
||||
0x66e7a46c27f3aa2cULL, 0x1c3fd4a417c62355ULL, 0x935745fc4798b8deULL, 0xe98f353477ad31a7ULL,
|
||||
0xa6df411fbfb21ca3ULL, 0xdc0731d78f8795daULL, 0x536fa08fdfd90e51ULL, 0x29b7d047efec8728ULL
|
||||
};
|
||||
}
|
||||
|
||||
void HashCRC64::Append(const UInt8* data, std::size_t len)
|
||||
{
|
||||
while (len--)
|
||||
m_crc = crc64_table[(m_crc ^ *data++) & 0xFF] ^ (m_crc >> 8);
|
||||
}
|
||||
|
||||
void HashCRC64::Begin()
|
||||
{
|
||||
m_crc = 0;
|
||||
}
|
||||
|
||||
ByteArray HashCRC64::End()
|
||||
{
|
||||
#ifdef NAZARA_LITTLE_ENDIAN
|
||||
SwapBytes(&m_crc, sizeof(UInt64));
|
||||
#endif
|
||||
|
||||
return ByteArray(reinterpret_cast<UInt8*>(&m_crc), 8);
|
||||
}
|
||||
|
||||
std::size_t HashCRC64::GetDigestLength() const
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
const char* HashCRC64::GetHashName() const
|
||||
{
|
||||
return "CRC64";
|
||||
}
|
||||
}
|
||||
|
|
@ -697,7 +697,7 @@ namespace Nz
|
|||
auto it = layers.find(i);
|
||||
if (it == layers.end())
|
||||
it = layers.insert(std::make_pair(i, Layer())).first;
|
||||
|
||||
|
||||
Layer& layer = it->second;
|
||||
layer.clearCount = 0;
|
||||
|
||||
|
|
@ -729,7 +729,6 @@ namespace Nz
|
|||
void ForwardRenderQueue::SortForOrthographic(const AbstractViewer * viewer)
|
||||
{
|
||||
Planef nearPlane = viewer->GetFrustum().GetPlane(FrustumPlane_Near);
|
||||
Vector3f viewerPos = viewer->GetEyePosition();
|
||||
|
||||
for (auto& pair : layers)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -128,13 +128,18 @@ namespace Nz
|
|||
if (!result.address)
|
||||
continue;
|
||||
|
||||
if (result.socketType != SocketType_UDP)
|
||||
continue;
|
||||
|
||||
hostnameAddress = result.address;
|
||||
break; //< Take first valid address
|
||||
}
|
||||
|
||||
if (!hostnameAddress.IsValid())
|
||||
{
|
||||
if (error)
|
||||
*error = ResolveError_NotFound;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Connect(hostnameAddress, channelCount, data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ namespace Nz
|
|||
m_packetsLost = 0;
|
||||
m_packetLoss = 0;
|
||||
m_packetLossVariance = 0;
|
||||
m_packetThrottle = ENetConstants::ENetProtocol_MaximumWindowSize;
|
||||
m_packetThrottle = ENetConstants::ENetPeer_DefaultPacketThrottle;
|
||||
m_packetThrottleLimit = ENetConstants::ENetPeer_PacketThrottleScale;
|
||||
m_packetThrottleCounter = 0;
|
||||
m_packetThrottleEpoch = 0;
|
||||
|
|
@ -1330,7 +1330,7 @@ namespace Nz
|
|||
{
|
||||
if (rtt < m_lastRoundTripTime)
|
||||
{
|
||||
m_packetThrottle = std::max(m_packetThrottle + m_packetThrottleAcceleration, m_packetThrottleLimit);
|
||||
m_packetThrottle = std::min(m_packetThrottle + m_packetThrottleAcceleration, m_packetThrottleLimit);
|
||||
return 1;
|
||||
}
|
||||
else if (rtt > m_lastRoundTripTime + 2 * m_lastRoundTripTimeVariance)
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ namespace Nz
|
|||
NazaraWarning("An error occured while removing socket from epoll structure (errno " + String::Number(errno) + ": " + Error::GetLastSystemError() + ')');
|
||||
}
|
||||
|
||||
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
|
||||
int SocketPollerImpl::Wait(int msTimeout, SocketError* error)
|
||||
{
|
||||
int activeSockets;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace Nz
|
|||
bool RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags);
|
||||
void UnregisterSocket(SocketHandle socket);
|
||||
|
||||
int Wait(UInt64 msTimeout, SocketError* error);
|
||||
int Wait(int msTimeout, SocketError* error);
|
||||
|
||||
private:
|
||||
std::unordered_set<SocketHandle> m_readyToReadSockets;
|
||||
|
|
|
|||
|
|
@ -509,12 +509,12 @@ namespace Nz
|
|||
NazaraAssert(buffer && length > 0, "Invalid buffer");
|
||||
|
||||
IpAddressImpl::SockAddrBuffer nameBuffer;
|
||||
socklen_t bufferLength = sizeof(sockaddr_in);
|
||||
socklen_t bufferLength = static_cast<socklen_t>(nameBuffer.size());
|
||||
|
||||
IpAddress senderIp;
|
||||
|
||||
int byteRead = recvfrom(handle, buffer, length, 0, reinterpret_cast<sockaddr*>(&nameBuffer), &bufferLength);
|
||||
if (byteRead == SOCKET_ERROR)
|
||||
if (byteRead == -1)
|
||||
{
|
||||
int errorCode = GetLastErrorCode();
|
||||
if (errorCode == EAGAIN)
|
||||
|
|
@ -549,6 +549,92 @@ namespace Nz
|
|||
else // else we received something
|
||||
senderIp = IpAddressImpl::FromSockAddr(reinterpret_cast<const sockaddr*>(&nameBuffer));
|
||||
|
||||
if (from)
|
||||
*from = IpAddressImpl::FromSockAddr(reinterpret_cast<const sockaddr*>(&nameBuffer));
|
||||
|
||||
if (read)
|
||||
*read = byteRead;
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SocketImpl::ReceiveMultiple(SocketHandle handle, NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, int* read, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
NazaraAssert(buffers && bufferCount > 0, "Invalid buffers");
|
||||
|
||||
StackAllocation memory = NazaraStackAllocation(bufferCount * sizeof(iovec));
|
||||
struct iovec* sysBuffers = static_cast<struct iovec*>(memory.GetPtr());
|
||||
for (std::size_t i = 0; i < bufferCount; ++i)
|
||||
{
|
||||
sysBuffers[i].iov_base = buffers[i].data;
|
||||
sysBuffers[i].iov_len = buffers[i].dataLength;
|
||||
}
|
||||
|
||||
struct msghdr msgHdr;
|
||||
std::memset(&msgHdr, 0, sizeof(msgHdr));
|
||||
|
||||
msgHdr.msg_iov = sysBuffers;
|
||||
msgHdr.msg_iovlen = static_cast<int>(bufferCount);
|
||||
|
||||
IpAddressImpl::SockAddrBuffer nameBuffer;
|
||||
if (from)
|
||||
{
|
||||
msgHdr.msg_name = nameBuffer.data();
|
||||
msgHdr.msg_namelen = static_cast<socklen_t>(nameBuffer.size());
|
||||
}
|
||||
|
||||
IpAddress senderIp;
|
||||
|
||||
int byteRead = recvmsg(handle, &msgHdr, MSG_NOSIGNAL);
|
||||
if (byteRead == -1)
|
||||
{
|
||||
int errorCode = GetLastErrorCode();
|
||||
if (errorCode == EAGAIN)
|
||||
errorCode = EWOULDBLOCK;
|
||||
|
||||
switch (errorCode)
|
||||
{
|
||||
case EWOULDBLOCK:
|
||||
{
|
||||
// If we have no data and are not blocking, return true with 0 byte read
|
||||
byteRead = 0;
|
||||
senderIp = IpAddress::Invalid;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(errorCode);
|
||||
|
||||
return false; //< Error
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (byteRead == 0)
|
||||
{
|
||||
if (error)
|
||||
*error = SocketError_ConnectionClosed;
|
||||
|
||||
return false; //< Connection closed
|
||||
}
|
||||
else // else we received something
|
||||
senderIp = IpAddressImpl::FromSockAddr(reinterpret_cast<const sockaddr*>(nameBuffer.data()));
|
||||
|
||||
#ifdef HAS_MSGHDR_FLAGS
|
||||
if (msgHdr.msg_flags & MSG_TRUNC)
|
||||
{
|
||||
if (error)
|
||||
*error = SocketError_DatagramSize;
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (from)
|
||||
*from = senderIp;
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ namespace Nz
|
|||
|
||||
static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error);
|
||||
static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error);
|
||||
static bool ReceiveMultiple(SocketHandle handle, NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, int* read, SocketError* error);
|
||||
|
||||
static bool Send(SocketHandle handle, const void* buffer, int length, int* sent, SocketError* error);
|
||||
static bool SendMultiple(SocketHandle handle, const NetBuffer* buffers, std::size_t bufferCount, const IpAddress& to, int* sent, SocketError* error);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ namespace Nz
|
|||
m_readyToWriteSockets.erase(socket);
|
||||
}
|
||||
|
||||
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
|
||||
int SocketPollerImpl::Wait(int msTimeout, SocketError* error)
|
||||
{
|
||||
int activeSockets;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace Nz
|
|||
bool RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags);
|
||||
void UnregisterSocket(SocketHandle socket);
|
||||
|
||||
int Wait(UInt64 msTimeout, SocketError* error);
|
||||
int Wait(int msTimeout, SocketError* error);
|
||||
|
||||
private:
|
||||
std::unordered_set<SocketHandle> m_readyToReadSockets;
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ namespace Nz
|
|||
* Waits a specific/undetermined amount of time until at least one socket part of the SocketPoller becomes ready.
|
||||
* To query the ready state of the registered socket, use the IsReadyToRead or IsReadyToWrite functions.
|
||||
*
|
||||
* \param msTimeout Maximum time to wait in milliseconds, 0 for infinity
|
||||
* \param msTimeout Maximum time to wait in milliseconds, 0 will returns immediately and -1 will block indefinitely
|
||||
*
|
||||
* \return True if at least one socket registered to the poller is ready.
|
||||
*
|
||||
|
|
@ -179,7 +179,7 @@ namespace Nz
|
|||
* \see IsReady
|
||||
* \see RegisterSocket
|
||||
*/
|
||||
bool SocketPoller::Wait(UInt64 msTimeout)
|
||||
bool SocketPoller::Wait(int msTimeout)
|
||||
{
|
||||
SocketError error;
|
||||
|
||||
|
|
|
|||
|
|
@ -118,6 +118,42 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Receive multiple datagram from one peer
|
||||
* \return true If data were sent
|
||||
*
|
||||
* \param to Destination IpAddress (must match socket protocol)
|
||||
* \param buffers A pointer to an array of NetBuffer containing buffers and size data
|
||||
* \param bufferCount Number of buffers available
|
||||
* \param from IpAddress of the peer
|
||||
* \param received Optional argument to get the number of bytes received
|
||||
*/
|
||||
bool UdpSocket::ReceiveMultiple(NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, std::size_t* received)
|
||||
{
|
||||
NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket hasn't been created");
|
||||
NazaraAssert(buffers && bufferCount > 0, "Invalid buffer");
|
||||
|
||||
int read;
|
||||
if (!SocketImpl::ReceiveMultiple(m_handle, buffers, bufferCount, from, &read, &m_lastError))
|
||||
{
|
||||
switch (m_lastError)
|
||||
{
|
||||
case SocketError_ConnectionClosed:
|
||||
m_lastError = SocketError_NoError;
|
||||
read = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (received)
|
||||
*received = read;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Receives the packet available
|
||||
* \return true If packet received
|
||||
|
|
|
|||
|
|
@ -586,6 +586,72 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SocketImpl::ReceiveMultiple(SocketHandle handle, NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, int* read, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
NazaraAssert(buffers && bufferCount > 0, "Invalid buffers");
|
||||
|
||||
IpAddressImpl::SockAddrBuffer nameBuffer;
|
||||
int bufferLength = static_cast<int>(nameBuffer.size());
|
||||
|
||||
IpAddress senderIp;
|
||||
|
||||
StackAllocation memory = NazaraStackAllocation(bufferCount * sizeof(WSABUF));
|
||||
WSABUF* winBuffers = static_cast<WSABUF*>(memory.GetPtr());
|
||||
for (std::size_t i = 0; i < bufferCount; ++i)
|
||||
{
|
||||
winBuffers[i].buf = static_cast<CHAR*>(buffers[i].data);
|
||||
winBuffers[i].len = static_cast<ULONG>(buffers[i].dataLength);
|
||||
}
|
||||
|
||||
DWORD flags = 0;
|
||||
DWORD byteRead;
|
||||
if (WSARecvFrom(handle, winBuffers, static_cast<DWORD>(bufferCount), &byteRead, &flags, reinterpret_cast<sockaddr*>(nameBuffer.data()), &bufferLength, nullptr, nullptr) == SOCKET_ERROR)
|
||||
{
|
||||
int errorCode = WSAGetLastError();
|
||||
switch (errorCode)
|
||||
{
|
||||
case WSAECONNRESET:
|
||||
case WSAEWOULDBLOCK:
|
||||
{
|
||||
// If we have no data and are not blocking, return true with 0 byte read
|
||||
byteRead = 0;
|
||||
senderIp = IpAddress::Invalid;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateWSAErrorToSocketError(errorCode);
|
||||
|
||||
return false; //< Error
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
senderIp = IpAddressImpl::FromSockAddr(reinterpret_cast<const sockaddr*>(&nameBuffer));
|
||||
|
||||
if (flags & MSG_PARTIAL)
|
||||
{
|
||||
if (error)
|
||||
*error = SocketError_DatagramSize;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (from)
|
||||
*from = senderIp;
|
||||
|
||||
if (read)
|
||||
*read = byteRead;
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SocketImpl::Send(SocketHandle handle, const void* buffer, int length, int* sent, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ namespace Nz
|
|||
|
||||
static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error);
|
||||
static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error);
|
||||
static bool ReceiveMultiple(SocketHandle handle, NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, int* read, SocketError* error);
|
||||
|
||||
static bool Send(SocketHandle handle, const void* buffer, int length, int* sent, SocketError* error);
|
||||
static bool SendMultiple(SocketHandle handle, const NetBuffer* buffers, std::size_t bufferCount, const IpAddress& to, int* sent, SocketError* error);
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ namespace Nz
|
|||
#endif
|
||||
}
|
||||
|
||||
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
|
||||
int SocketPollerImpl::Wait(int msTimeout, SocketError* error)
|
||||
{
|
||||
int activeSockets;
|
||||
|
||||
|
|
@ -179,7 +179,7 @@ namespace Nz
|
|||
tv.tv_sec = static_cast<long>(msTimeout / 1000ULL);
|
||||
tv.tv_usec = static_cast<long>((msTimeout % 1000ULL) * 1000ULL);
|
||||
|
||||
activeSockets = ::select(0xDEADBEEF, readSet, writeSet, nullptr, (msTimeout > 0) ? &tv : nullptr); //< The first argument is ignored on Windows
|
||||
activeSockets = ::select(0xDEADBEEF, readSet, writeSet, nullptr, (msTimeout >= 0) ? &tv : nullptr); //< The first argument is ignored on Windows
|
||||
if (activeSockets == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ namespace Nz
|
|||
bool RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags);
|
||||
void UnregisterSocket(SocketHandle socket);
|
||||
|
||||
int Wait(UInt64 msTimeout, SocketError* error);
|
||||
int Wait(int msTimeout, SocketError* error);
|
||||
|
||||
private:
|
||||
#if NAZARA_NETWORK_POLL_SUPPORT
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@ namespace Nz
|
|||
{
|
||||
cpShapeFilter filter = cpShapeFilterNew(m_collisionGroup, m_categoryMask, m_collisionMask);
|
||||
|
||||
std::vector<cpShape*> shapes = CreateShapes(body);
|
||||
std::vector<cpShape*> shapes;
|
||||
CreateShapes(body, shapes);
|
||||
|
||||
for (cpShape* shape : shapes)
|
||||
{
|
||||
cpShapeSetFilter(shape, filter);
|
||||
|
|
@ -39,9 +41,9 @@ namespace Nz
|
|||
{
|
||||
}
|
||||
|
||||
float BoxCollider2D::ComputeInertialMatrix(float mass) const
|
||||
float BoxCollider2D::ComputeMomentOfInertia(float mass) const
|
||||
{
|
||||
return static_cast<float>(cpMomentForBox2(mass, cpBBNew(m_rect.x, m_rect.y + m_rect.height, m_rect.x + m_rect.width, m_rect.y)));
|
||||
return static_cast<float>(cpMomentForBox2(mass, cpBBNew(m_rect.x, m_rect.y, m_rect.x + m_rect.width, m_rect.y + m_rect.height)));
|
||||
}
|
||||
|
||||
ColliderType2D BoxCollider2D::GetType() const
|
||||
|
|
@ -49,12 +51,9 @@ namespace Nz
|
|||
return ColliderType2D_Box;
|
||||
}
|
||||
|
||||
std::vector<cpShape*> BoxCollider2D::CreateShapes(RigidBody2D* body) const
|
||||
void BoxCollider2D::CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const
|
||||
{
|
||||
std::vector<cpShape*> shapes;
|
||||
shapes.push_back(cpBoxShapeNew2(body->GetHandle(), cpBBNew(m_rect.x, m_rect.y + m_rect.height, m_rect.x + m_rect.width, m_rect.y), m_radius));
|
||||
|
||||
return shapes;
|
||||
shapes.push_back(cpBoxShapeNew2(body->GetHandle(), cpBBNew(m_rect.x, m_rect.y, m_rect.x + m_rect.width, m_rect.y + m_rect.height), m_radius));
|
||||
}
|
||||
|
||||
/******************************** CircleCollider2D *********************************/
|
||||
|
|
@ -65,7 +64,7 @@ namespace Nz
|
|||
{
|
||||
}
|
||||
|
||||
float CircleCollider2D::ComputeInertialMatrix(float mass) const
|
||||
float CircleCollider2D::ComputeMomentOfInertia(float mass) const
|
||||
{
|
||||
return static_cast<float>(cpMomentForCircle(mass, 0.f, m_radius, cpv(m_offset.x, m_offset.y)));
|
||||
}
|
||||
|
|
@ -75,12 +74,66 @@ namespace Nz
|
|||
return ColliderType2D_Circle;
|
||||
}
|
||||
|
||||
std::vector<cpShape*> CircleCollider2D::CreateShapes(RigidBody2D* body) const
|
||||
void CircleCollider2D::CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const
|
||||
{
|
||||
std::vector<cpShape*> shapes;
|
||||
shapes.push_back(cpCircleShapeNew(body->GetHandle(), m_radius, cpv(m_offset.x, m_offset.y)));
|
||||
}
|
||||
|
||||
return shapes;
|
||||
/******************************** CompoundCollider2D *********************************/
|
||||
|
||||
CompoundCollider2D::CompoundCollider2D(std::vector<Collider2DRef> geoms) :
|
||||
m_geoms(std::move(geoms))
|
||||
{
|
||||
}
|
||||
|
||||
float CompoundCollider2D::ComputeMomentOfInertia(float mass) const
|
||||
{
|
||||
///TODO: Correctly compute moment using parallel axis theorem:
|
||||
/// https://chipmunk-physics.net/forum/viewtopic.php?t=1056
|
||||
float momentOfInertia = 0.f;
|
||||
for (const auto& geom : m_geoms)
|
||||
momentOfInertia += geom->ComputeMomentOfInertia(mass); //< Eeeer
|
||||
|
||||
return momentOfInertia;
|
||||
}
|
||||
|
||||
ColliderType2D CompoundCollider2D::GetType() const
|
||||
{
|
||||
return ColliderType2D_Compound;
|
||||
}
|
||||
|
||||
void CompoundCollider2D::CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const
|
||||
{
|
||||
// Since C++ does not allow protected call from other objects, we have to be a friend of Collider2D, yay
|
||||
for (const auto& geom : m_geoms)
|
||||
geom->CreateShapes(body, shapes);
|
||||
}
|
||||
|
||||
/******************************** ConvexCollider2D *********************************/
|
||||
|
||||
ConvexCollider2D::ConvexCollider2D(SparsePtr<const Vector2f> vertices, std::size_t vertexCount, float radius) :
|
||||
m_radius(radius)
|
||||
{
|
||||
m_vertices.resize(vertexCount);
|
||||
for (std::size_t i = 0; i < vertexCount; ++i)
|
||||
m_vertices[i].Set(*vertices++);
|
||||
}
|
||||
|
||||
float ConvexCollider2D::ComputeMomentOfInertia(float mass) const
|
||||
{
|
||||
static_assert(sizeof(cpVect) == sizeof(Vector2d), "Chipmunk vector is not equivalent to Vector2d");
|
||||
|
||||
return static_cast<float>(cpMomentForPoly(mass, int(m_vertices.size()), reinterpret_cast<const cpVect*>(m_vertices.data()), cpv(0.0, 0.0), m_radius));
|
||||
}
|
||||
|
||||
ColliderType2D ConvexCollider2D::GetType() const
|
||||
{
|
||||
return ColliderType2D_Convex;
|
||||
}
|
||||
|
||||
void ConvexCollider2D::CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const
|
||||
{
|
||||
shapes.push_back(cpPolyShapeNew(body->GetHandle(), int(m_vertices.size()), reinterpret_cast<const cpVect*>(m_vertices.data()), cpTransformIdentity, m_radius));
|
||||
}
|
||||
|
||||
/********************************* NullCollider2D **********************************/
|
||||
|
|
@ -90,19 +143,18 @@ namespace Nz
|
|||
return ColliderType2D_Null;
|
||||
}
|
||||
|
||||
float NullCollider2D::ComputeInertialMatrix(float /*mass*/) const
|
||||
float NullCollider2D::ComputeMomentOfInertia(float /*mass*/) const
|
||||
{
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
std::vector<cpShape*> NullCollider2D::CreateShapes(RigidBody2D* /*body*/) const
|
||||
void NullCollider2D::CreateShapes(RigidBody2D* /*body*/, std::vector<cpShape*>& /*shapes*/) const
|
||||
{
|
||||
return std::vector<cpShape*>();
|
||||
}
|
||||
|
||||
/******************************** SegmentCollider2D *********************************/
|
||||
|
||||
float SegmentCollider2D::ComputeInertialMatrix(float mass) const
|
||||
float SegmentCollider2D::ComputeMomentOfInertia(float mass) const
|
||||
{
|
||||
return static_cast<float>(cpMomentForSegment(mass, cpv(m_first.x, m_first.y), cpv(m_second.x, m_second.y), m_thickness));
|
||||
}
|
||||
|
|
@ -112,12 +164,8 @@ namespace Nz
|
|||
return ColliderType2D_Segment;
|
||||
}
|
||||
|
||||
std::vector<cpShape*> SegmentCollider2D::CreateShapes(RigidBody2D* body) const
|
||||
void SegmentCollider2D::CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const
|
||||
{
|
||||
std::vector<cpShape*> shapes;
|
||||
shapes.push_back(cpSegmentShapeNew(body->GetHandle(), cpv(m_first.x, m_first.y), cpv(m_second.x, m_second.y), m_thickness));
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,12 +60,12 @@ namespace Nz
|
|||
{
|
||||
cpPointQueryInfo queryInfo;
|
||||
|
||||
if (cpShape* shape = cpSpacePointQueryNearest(m_handle, { from.x, from.y }, maxDistance, filter, &queryInfo))
|
||||
if (cpSpacePointQueryNearest(m_handle, { from.x, from.y }, maxDistance, filter, &queryInfo))
|
||||
{
|
||||
result->closestPoint.Set(Nz::Vector2<cpFloat>(queryInfo.point.x, queryInfo.point.y));
|
||||
result->distance = float(queryInfo.distance);
|
||||
result->fraction.Set(Nz::Vector2<cpFloat>(queryInfo.gradient.x, queryInfo.gradient.y));
|
||||
result->nearestBody = static_cast<Nz::RigidBody2D*>(cpShapeGetUserData(shape));
|
||||
result->nearestBody = static_cast<Nz::RigidBody2D*>(cpShapeGetUserData(queryInfo.shape));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -74,7 +74,7 @@ namespace Nz
|
|||
}
|
||||
else
|
||||
{
|
||||
if (cpShape* shape = cpSpacePointQueryNearest(m_handle, { from.x, from.y }, maxDistance, filter, nullptr))
|
||||
if (cpSpacePointQueryNearest(m_handle, { from.x, from.y }, maxDistance, filter, nullptr))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
|
@ -114,7 +114,7 @@ namespace Nz
|
|||
{
|
||||
cpSegmentQueryInfo queryInfo;
|
||||
|
||||
if (cpShape* shape = cpSpaceSegmentQueryFirst(m_handle, { from.x, from.y }, { to.x, to.y }, radius, filter, &queryInfo))
|
||||
if (cpSpaceSegmentQueryFirst(m_handle, { from.x, from.y }, { to.x, to.y }, radius, filter, &queryInfo))
|
||||
{
|
||||
hitInfo->fraction = float(queryInfo.alpha);
|
||||
hitInfo->hitNormal.Set(Nz::Vector2<cpFloat>(queryInfo.normal.x, queryInfo.normal.y));
|
||||
|
|
@ -128,7 +128,7 @@ namespace Nz
|
|||
}
|
||||
else
|
||||
{
|
||||
if (cpShape* shape = cpSpaceSegmentQueryFirst(m_handle, { from.x, from.y }, { to.x, to.y }, radius, filter, nullptr))
|
||||
if (cpSpaceSegmentQueryFirst(m_handle, { from.x, from.y }, { to.x, to.y }, radius, filter, nullptr))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
|
@ -146,7 +146,7 @@ namespace Nz
|
|||
};
|
||||
|
||||
cpShapeFilter filter = cpShapeFilterNew(collisionGroup, categoryMask, collisionMask);
|
||||
cpSpaceBBQuery(m_handle, cpBBNew(boundingBox.x, boundingBox.y + boundingBox.height, boundingBox.x + boundingBox.width, boundingBox.y), filter, callback, bodies);
|
||||
cpSpaceBBQuery(m_handle, cpBBNew(boundingBox.x, boundingBox.y, boundingBox.x + boundingBox.width, boundingBox.y + boundingBox.height), filter, callback, bodies);
|
||||
}
|
||||
|
||||
void PhysWorld2D::RegisterCallbacks(unsigned int collisionId, const Callback& callbacks)
|
||||
|
|
|
|||
|
|
@ -191,6 +191,11 @@ namespace Nz
|
|||
return Vector2f(static_cast<float>(vel.x), static_cast<float>(vel.y));
|
||||
}
|
||||
|
||||
PhysWorld2D* RigidBody2D::GetWorld() const
|
||||
{
|
||||
return m_world;
|
||||
}
|
||||
|
||||
bool RigidBody2D::IsMoveable() const
|
||||
{
|
||||
return m_mass > 0.f;
|
||||
|
|
@ -240,7 +245,7 @@ namespace Nz
|
|||
cpSpaceAddShape(space, shape);
|
||||
}
|
||||
|
||||
cpBodySetMoment(m_handle, m_geom->ComputeInertialMatrix(m_mass));
|
||||
cpBodySetMoment(m_handle, m_geom->ComputeMomentOfInertia(m_mass));
|
||||
}
|
||||
|
||||
void RigidBody2D::SetMass(float mass)
|
||||
|
|
@ -252,7 +257,7 @@ namespace Nz
|
|||
m_world->RegisterPostStep(this, [mass](Nz::RigidBody2D* body)
|
||||
{
|
||||
cpBodySetMass(body->GetHandle(), mass);
|
||||
cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeInertialMatrix(mass));
|
||||
cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeMomentOfInertia(mass));
|
||||
});
|
||||
}
|
||||
else
|
||||
|
|
@ -266,7 +271,7 @@ namespace Nz
|
|||
{
|
||||
cpBodySetType(body->GetHandle(), CP_BODY_TYPE_DYNAMIC);
|
||||
cpBodySetMass(body->GetHandle(), mass);
|
||||
cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeInertialMatrix(mass));
|
||||
cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeMomentOfInertia(mass));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -280,6 +285,14 @@ namespace Nz
|
|||
cpBodySetCenterOfGravity(m_handle, cpv(center.x, center.y));
|
||||
}
|
||||
|
||||
void RigidBody2D::SetMomentOfInertia(float moment)
|
||||
{
|
||||
m_world->RegisterPostStep(this, [moment] (Nz::RigidBody2D* body)
|
||||
{
|
||||
cpBodySetMoment(body->GetHandle(), moment);
|
||||
});
|
||||
}
|
||||
|
||||
void RigidBody2D::SetPosition(const Vector2f& position)
|
||||
{
|
||||
cpBodySetPosition(m_handle, cpv(position.x, position.y));
|
||||
|
|
|
|||
|
|
@ -128,12 +128,12 @@ namespace Nz
|
|||
std::size_t primitiveCount = list.GetSize();
|
||||
if (primitiveCount > 1)
|
||||
{
|
||||
std::vector<Collider3D*> geoms(primitiveCount);
|
||||
std::vector<Collider3DRef> geoms(primitiveCount);
|
||||
|
||||
for (unsigned int i = 0; i < primitiveCount; ++i)
|
||||
geoms[i] = CreateGeomFromPrimitive(list.GetPrimitive(i));
|
||||
|
||||
return CompoundCollider3D::New(&geoms[0], primitiveCount);
|
||||
return CompoundCollider3D::New(std::move(geoms));
|
||||
}
|
||||
else if (primitiveCount > 0)
|
||||
return CreateGeomFromPrimitive(list.GetPrimitive(0));
|
||||
|
|
@ -239,11 +239,9 @@ namespace Nz
|
|||
|
||||
/******************************* CompoundCollider3D ********************************/
|
||||
|
||||
CompoundCollider3D::CompoundCollider3D(Collider3D** geoms, std::size_t geomCount)
|
||||
CompoundCollider3D::CompoundCollider3D(std::vector<Collider3DRef> geoms) :
|
||||
m_geoms(std::move(geoms))
|
||||
{
|
||||
m_geoms.reserve(geomCount);
|
||||
for (std::size_t i = 0; i < geomCount; ++i)
|
||||
m_geoms.emplace_back(geoms[i]);
|
||||
}
|
||||
|
||||
const std::vector<Collider3DRef>& CompoundCollider3D::GetGeoms() const
|
||||
|
|
|
|||
|
|
@ -204,6 +204,11 @@ namespace Nz
|
|||
return velocity;
|
||||
}
|
||||
|
||||
PhysWorld3D* RigidBody3D::GetWorld() const
|
||||
{
|
||||
return m_world;
|
||||
}
|
||||
|
||||
bool RigidBody3D::IsAutoSleepEnabled() const
|
||||
{
|
||||
return NewtonBodyGetAutoSleep(m_body) != 0;
|
||||
|
|
@ -314,7 +319,7 @@ namespace Nz
|
|||
NazaraUnused(userData);
|
||||
NewtonBodySetSleepState(body, 0);
|
||||
return 1;
|
||||
},
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,11 +105,10 @@ namespace Nz
|
|||
|
||||
const AbstractTextDrawer::Line& SimpleTextDrawer::GetLine(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_lines.size(), "Line index out of range");
|
||||
|
||||
if (!m_glyphUpdated)
|
||||
UpdateGlyphs();
|
||||
|
||||
NazaraAssert(index < m_lines.size(), "Line index out of range");
|
||||
return m_lines[index];
|
||||
}
|
||||
|
||||
|
|
@ -319,6 +318,10 @@ namespace Nz
|
|||
glyph.color = m_color;
|
||||
glyph.flipped = fontGlyph.flipped;
|
||||
|
||||
glyph.bounds.Set(fontGlyph.aabb);
|
||||
glyph.bounds.x += m_drawPos.x;
|
||||
glyph.bounds.y += m_drawPos.y;
|
||||
|
||||
if (fontGlyph.requireFauxBold)
|
||||
{
|
||||
// Let's simulate bold by enlarging the glyph (not a neat idea, but should work)
|
||||
|
|
@ -330,16 +333,13 @@ namespace Nz
|
|||
|
||||
// Replace it at the correct height
|
||||
Vector2f offset(glyph.bounds.GetCenter() - center);
|
||||
glyph.bounds.x -= offset.x;
|
||||
glyph.bounds.y -= offset.y;
|
||||
|
||||
// Adjust advance (+10%)
|
||||
advance += advance / 10;
|
||||
}
|
||||
|
||||
glyph.bounds.Set(fontGlyph.aabb);
|
||||
glyph.bounds.x += m_drawPos.x;
|
||||
glyph.bounds.y += m_drawPos.y;
|
||||
|
||||
// We "lean" the glyph to simulate italics style
|
||||
float italic = (fontGlyph.requireFauxItalic) ? 0.208f : 0.f;
|
||||
float italicTop = italic * glyph.bounds.y;
|
||||
|
|
|
|||
Loading…
Reference in New Issue