Merge branch 'master' into gui
Former-commit-id: ab617839e9da6d7576bb2ee260aa5a53691042a0 [formerly 0b7b354ef529ca3b9795f8042772890125942701] [formerly 1390383adba6cfc347d513cc290927a6d254d733 [formerly 6a6a1a4f56d26a6601d8a5e53a6fc99dbcc187be]] Former-commit-id: 1b19d5fda60c06437b1c874c424258a83dad0f77 [formerly 2423a7b5c83f99d5097c3cf5dc647033161ad78a] Former-commit-id: 744ec2d55571319ba6266ac69b6a51ba8deb0b4a
This commit is contained in:
@@ -3,9 +3,79 @@
|
||||
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
|
||||
|
||||
#include <NDK/Application.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <regex>
|
||||
|
||||
#ifndef NDK_SERVER
|
||||
#include <NDK/Components/CameraComponent.hpp>
|
||||
#include <NDK/Components/GraphicsComponent.hpp>
|
||||
#include <NDK/Components/NodeComponent.hpp>
|
||||
#include <NDK/Systems/RenderSystem.hpp>
|
||||
#include <NDK/LuaAPI.hpp>
|
||||
#include <Nazara/Utility/SimpleTextDrawer.hpp>
|
||||
#endif
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::Application
|
||||
* \brief NDK class that represents the application, it offers a set of tools to ease the development
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs an Application object with command-line arguments
|
||||
*
|
||||
* Pass the argc and argv arguments from the main function.
|
||||
*
|
||||
* Command-line arguments can be retrieved by application methods
|
||||
*
|
||||
* This calls Sdk::Initialize()
|
||||
*
|
||||
* \remark Only one Application instance can exist at a time
|
||||
*/
|
||||
inline Application::Application(int argc, char* argv[]) :
|
||||
Application()
|
||||
{
|
||||
std::regex optionRegex(R"(-(\w+))");
|
||||
std::regex valueRegex(R"(-(\w+)\s*=\s*(.+))");
|
||||
|
||||
std::smatch results;
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
std::string argument(argv[i]);
|
||||
if (std::regex_match(argument, results, valueRegex))
|
||||
{
|
||||
Nz::String key(results[1].str());
|
||||
Nz::String value(results[2].str());
|
||||
|
||||
m_parameters[key.ToLower()] = value;
|
||||
NazaraDebug("Registred parameter from command-line: " + key.ToLower() + "=" + value);
|
||||
}
|
||||
else if (std::regex_match(argument, results, optionRegex))
|
||||
{
|
||||
Nz::String option(results[1].str());
|
||||
|
||||
m_options.insert(option);
|
||||
NazaraDebug("Registred option from command-line: " + option);
|
||||
}
|
||||
else
|
||||
NazaraWarning("Ignored command-line argument #" + Nz::String::Number(i) + " \"" + argument + '"');
|
||||
}
|
||||
|
||||
#ifndef NDK_SERVER
|
||||
if (HasOption("console"))
|
||||
EnableConsole(true);
|
||||
|
||||
if (HasOption("fpscounter"))
|
||||
EnableFPSCounter(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Runs the application by updating worlds, taking care about windows, ...
|
||||
*/
|
||||
bool Application::Run()
|
||||
{
|
||||
#ifndef NDK_SERVER
|
||||
@@ -14,7 +84,9 @@ namespace Ndk
|
||||
auto it = m_windows.begin();
|
||||
while (it != m_windows.end())
|
||||
{
|
||||
Nz::Window& window = **it;
|
||||
Nz::Window& window = *it->window;
|
||||
|
||||
window.ProcessEvents();
|
||||
|
||||
if (!window.IsOpen(true))
|
||||
{
|
||||
@@ -42,8 +114,140 @@ namespace Ndk
|
||||
for (World& world : m_worlds)
|
||||
world.Update(m_updateTime);
|
||||
|
||||
#ifndef NDK_SERVER
|
||||
for (WindowInfo& info : m_windows)
|
||||
{
|
||||
if (!info.overlayWorld)
|
||||
continue;
|
||||
|
||||
if (info.fpsCounter)
|
||||
{
|
||||
FPSCounterOverlay& fpsCounter = *info.fpsCounter;
|
||||
|
||||
fpsCounter.frameCount++;
|
||||
|
||||
fpsCounter.elapsedTime += m_updateTime;
|
||||
if (fpsCounter.elapsedTime >= 1.f)
|
||||
{
|
||||
fpsCounter.sprite->Update(Nz::SimpleTextDrawer::Draw("FPS: " + Nz::String::Number(fpsCounter.frameCount), 36));
|
||||
fpsCounter.frameCount = 0;
|
||||
fpsCounter.elapsedTime = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
info.overlayWorld->Update(m_updateTime);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef NDK_SERVER
|
||||
void Application::SetupConsole(WindowInfo& info)
|
||||
{
|
||||
std::unique_ptr<ConsoleOverlay> overlay = std::make_unique<ConsoleOverlay>();
|
||||
|
||||
Nz::Vector2ui windowDimensions;
|
||||
if (info.window->IsValid())
|
||||
windowDimensions.Set(info.window->GetWidth(), info.window->GetHeight() / 4);
|
||||
else
|
||||
windowDimensions.MakeZero();
|
||||
|
||||
overlay->console = std::make_unique<Console>(*info.overlayWorld, Nz::Vector2f(windowDimensions), overlay->lua);
|
||||
|
||||
Console& consoleRef = *overlay->console;
|
||||
|
||||
// Redirect logs toward the console
|
||||
overlay->logSlot.Connect(Nz::Log::OnLogWrite, [&consoleRef] (const Nz::String& str)
|
||||
{
|
||||
consoleRef.AddLine(str);
|
||||
});
|
||||
|
||||
LuaAPI::RegisterClasses(overlay->lua);
|
||||
|
||||
// Override "print" function to add a line in the console
|
||||
overlay->lua.PushFunction([&consoleRef] (Nz::LuaInstance& instance)
|
||||
{
|
||||
Nz::StringStream stream;
|
||||
|
||||
unsigned int argCount = instance.GetStackTop();
|
||||
instance.GetGlobal("tostring");
|
||||
for (unsigned int i = 1; i <= argCount; ++i)
|
||||
{
|
||||
instance.PushValue(-1); // tostring function
|
||||
instance.PushValue(i); // argument
|
||||
instance.Call(1, 1);
|
||||
|
||||
std::size_t length;
|
||||
const char* str = instance.CheckString(-1, &length);
|
||||
if (i > 1)
|
||||
stream << '\t';
|
||||
|
||||
stream << Nz::String(str, length);
|
||||
instance.Pop(1);
|
||||
}
|
||||
|
||||
consoleRef.AddLine(stream);
|
||||
return 0;
|
||||
});
|
||||
overlay->lua.SetGlobal("print");
|
||||
|
||||
// Define a few base variables to allow our interface to interact with the application
|
||||
overlay->lua.PushGlobal("Application", Ndk::Application::Instance());
|
||||
overlay->lua.PushGlobal("Console", consoleRef.CreateHandle());
|
||||
|
||||
// Setup a few event callback to handle the console
|
||||
Nz::EventHandler& eventHandler = info.window->GetEventHandler();
|
||||
|
||||
overlay->eventSlot.Connect(eventHandler.OnEvent, [&consoleRef] (const Nz::EventHandler*, const Nz::WindowEvent& event)
|
||||
{
|
||||
if (consoleRef.IsVisible())
|
||||
consoleRef.SendEvent(event);
|
||||
});
|
||||
|
||||
overlay->keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&consoleRef] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& event)
|
||||
{
|
||||
if (event.code == Nz::Keyboard::F9)
|
||||
consoleRef.Show(!consoleRef.IsVisible());
|
||||
});
|
||||
|
||||
overlay->resizedSlot.Connect(info.renderTarget->OnRenderTargetSizeChange, [&consoleRef] (const Nz::RenderTarget* renderTarget)
|
||||
{
|
||||
consoleRef.SetSize({float(renderTarget->GetWidth()), renderTarget->GetHeight() / 4.f});
|
||||
});
|
||||
|
||||
info.console = std::move(overlay);
|
||||
}
|
||||
|
||||
void Application::SetupFPSCounter(WindowInfo& info)
|
||||
{
|
||||
std::unique_ptr<FPSCounterOverlay> fpsCounter = std::make_unique<FPSCounterOverlay>();
|
||||
fpsCounter->sprite = Nz::TextSprite::New();
|
||||
|
||||
fpsCounter->entity = info.overlayWorld->CreateEntity();
|
||||
fpsCounter->entity->AddComponent<NodeComponent>();
|
||||
fpsCounter->entity->AddComponent<GraphicsComponent>().Attach(fpsCounter->sprite);
|
||||
|
||||
info.fpsCounter = std::move(fpsCounter);
|
||||
}
|
||||
|
||||
void Application::SetupOverlay(WindowInfo& info)
|
||||
{
|
||||
info.overlayWorld = std::make_unique<World>(false); //< No default system
|
||||
|
||||
RenderSystem& renderSystem = info.overlayWorld->AddSystem<RenderSystem>();
|
||||
renderSystem.ChangeRenderTechnique<Nz::ForwardRenderTechnique>();
|
||||
renderSystem.SetDefaultBackground(nullptr);
|
||||
renderSystem.SetGlobalUp(Nz::Vector3f::Down());
|
||||
|
||||
EntityHandle viewer = info.overlayWorld->CreateEntity();
|
||||
CameraComponent& camComponent = viewer->AddComponent<CameraComponent>();
|
||||
viewer->AddComponent<NodeComponent>();
|
||||
|
||||
camComponent.SetProjectionType(Nz::ProjectionType_Orthogonal);
|
||||
camComponent.SetTarget(info.renderTarget);
|
||||
}
|
||||
#endif
|
||||
|
||||
Application* Application::s_application = nullptr;
|
||||
}
|
||||
@@ -6,22 +6,50 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::BaseComponent
|
||||
* \brief NDK class that represents the common base of all components
|
||||
*
|
||||
* \remark This class is meant to be purely abstract, for type erasure
|
||||
*/
|
||||
|
||||
BaseComponent::~BaseComponent() = default;
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is attached to an entity
|
||||
*/
|
||||
|
||||
void BaseComponent::OnAttached()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is attached to this component
|
||||
*
|
||||
* \param component Component being attached
|
||||
*/
|
||||
|
||||
void BaseComponent::OnComponentAttached(BaseComponent& component)
|
||||
{
|
||||
NazaraUnused(component);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is detached from this component
|
||||
*
|
||||
* \param component Component being detached
|
||||
*/
|
||||
|
||||
void BaseComponent::OnComponentDetached(BaseComponent& component)
|
||||
{
|
||||
NazaraUnused(component);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is detached from an entity
|
||||
*/
|
||||
|
||||
void BaseComponent::OnDetached()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -6,12 +6,31 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::BaseSystem
|
||||
* \brief NDK class that represents the common base of all systems
|
||||
*
|
||||
* \remark This class is meant to be purely abstract, for type erasure
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Destructs the object and unregisters it-self on every entities
|
||||
*/
|
||||
|
||||
BaseSystem::~BaseSystem()
|
||||
{
|
||||
for (const EntityHandle& entity : m_entities)
|
||||
entity->UnregisterSystem(m_systemIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the key of the entity matches the lock of the system
|
||||
* \return true If it is the case
|
||||
*
|
||||
* \param Pointer to the entity
|
||||
*/
|
||||
|
||||
bool BaseSystem::Filters(const Entity* entity) const
|
||||
{
|
||||
if (!entity)
|
||||
@@ -21,13 +40,13 @@ namespace Ndk
|
||||
|
||||
m_filterResult.PerformsAND(m_requiredComponents, components);
|
||||
if (m_filterResult != m_requiredComponents)
|
||||
return false; // Au moins un component requis n'est pas présent
|
||||
return false; // At least one required component is not available
|
||||
|
||||
m_filterResult.PerformsAND(m_excludedComponents, components);
|
||||
if (m_filterResult.TestAny())
|
||||
return false; // Au moins un component exclu est présent
|
||||
return false; // At least one excluded component is available
|
||||
|
||||
// Si nous avons une liste de composants nécessaires
|
||||
// If we have a list of needed components
|
||||
if (m_requiredAnyComponents.TestAny())
|
||||
{
|
||||
if (!m_requiredAnyComponents.Intersects(components))
|
||||
@@ -37,16 +56,35 @@ namespace Ndk
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when entity is added to the system
|
||||
*
|
||||
* \param Pointer to the entity
|
||||
*/
|
||||
|
||||
void BaseSystem::OnEntityAdded(Entity* entity)
|
||||
{
|
||||
NazaraUnused(entity);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when entity is removed to the system
|
||||
*
|
||||
* \param Pointer to the entity
|
||||
*/
|
||||
|
||||
void BaseSystem::OnEntityRemoved(Entity* entity)
|
||||
{
|
||||
NazaraUnused(entity);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when entity is validated for the system
|
||||
*
|
||||
* \param entity Pointer to the entity
|
||||
* \param justAdded Is the entity newly added
|
||||
*/
|
||||
|
||||
void BaseSystem::OnEntityValidation(Entity* entity, bool justAdded)
|
||||
{
|
||||
NazaraUnused(entity);
|
||||
|
||||
@@ -9,6 +9,18 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::CameraComponent
|
||||
* \brief NDK class that represents the component for camera
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Applys the view of the camera
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the camera has no target
|
||||
*/
|
||||
|
||||
void CameraComponent::ApplyView() const
|
||||
{
|
||||
NazaraAssert(m_target, "CameraComponent has no target");
|
||||
@@ -23,6 +35,12 @@ namespace Ndk
|
||||
Nz::Renderer::SetViewport(m_viewport);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the eye position of the camera
|
||||
*
|
||||
* \remark Produces a NazaraAssert if entity is invalid or has no NodeComponent
|
||||
*/
|
||||
|
||||
Nz::Vector3f CameraComponent::GetEyePosition() const
|
||||
{
|
||||
NazaraAssert(m_entity && m_entity->HasComponent<NodeComponent>(), "CameraComponent requires NodeComponent");
|
||||
@@ -30,6 +48,12 @@ namespace Ndk
|
||||
return m_entity->GetComponent<NodeComponent>().GetPosition();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the forward direction of the camera
|
||||
*
|
||||
* \remark Produces a NazaraAssert if entity is invalid or has no NodeComponent
|
||||
*/
|
||||
|
||||
Nz::Vector3f CameraComponent::GetForward() const
|
||||
{
|
||||
NazaraAssert(m_entity && m_entity->HasComponent<NodeComponent>(), "CameraComponent requires NodeComponent");
|
||||
@@ -37,6 +61,12 @@ namespace Ndk
|
||||
return m_entity->GetComponent<NodeComponent>().GetForward();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the layer of the camera in case of multiples fields
|
||||
*
|
||||
* \param layer Layer of the camera
|
||||
*/
|
||||
|
||||
void CameraComponent::SetLayer(unsigned int layer)
|
||||
{
|
||||
m_layer = layer;
|
||||
@@ -44,6 +74,10 @@ namespace Ndk
|
||||
m_entity->Invalidate(); // Invalidate the entity to make it passes through RenderSystem validation
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is attached to an entity
|
||||
*/
|
||||
|
||||
void CameraComponent::OnAttached()
|
||||
{
|
||||
if (m_entity->HasComponent<NodeComponent>())
|
||||
@@ -52,6 +86,12 @@ namespace Ndk
|
||||
InvalidateViewMatrix();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is attached to this component
|
||||
*
|
||||
* \param component Component being attached
|
||||
*/
|
||||
|
||||
void CameraComponent::OnComponentAttached(BaseComponent& component)
|
||||
{
|
||||
if (IsComponent<NodeComponent>(component))
|
||||
@@ -63,6 +103,12 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is detached from this component
|
||||
*
|
||||
* \param component Component being detached
|
||||
*/
|
||||
|
||||
void CameraComponent::OnComponentDetached(BaseComponent& component)
|
||||
{
|
||||
if (IsComponent<NodeComponent>(component))
|
||||
@@ -73,6 +119,10 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is detached from an entity
|
||||
*/
|
||||
|
||||
void CameraComponent::OnDetached()
|
||||
{
|
||||
m_nodeInvalidationSlot.Disconnect();
|
||||
@@ -80,6 +130,12 @@ namespace Ndk
|
||||
InvalidateViewMatrix();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when the node is invalidated
|
||||
*
|
||||
* \param node Pointer to the node
|
||||
*/
|
||||
|
||||
void CameraComponent::OnNodeInvalidated(const Nz::Node* node)
|
||||
{
|
||||
NazaraUnused(node);
|
||||
@@ -88,6 +144,12 @@ namespace Ndk
|
||||
InvalidateViewMatrix();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when the render target is released
|
||||
*
|
||||
* \param renderTarget Pointer to the RenderTarget
|
||||
*/
|
||||
|
||||
void CameraComponent::OnRenderTargetRelease(const Nz::RenderTarget* renderTarget)
|
||||
{
|
||||
if (renderTarget == m_target)
|
||||
@@ -96,6 +158,12 @@ namespace Ndk
|
||||
NazaraInternalError("Not listening to " + Nz::String::Pointer(renderTarget));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when the render target has its size changed
|
||||
*
|
||||
* \param renderTarget Pointer to the RenderTarget
|
||||
*/
|
||||
|
||||
void CameraComponent::OnRenderTargetSizeChange(const Nz::RenderTarget* renderTarget)
|
||||
{
|
||||
if (renderTarget == m_target)
|
||||
@@ -104,6 +172,10 @@ namespace Ndk
|
||||
NazaraInternalError("Not listening to " + Nz::String::Pointer(renderTarget));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates the frustum of the camera
|
||||
*/
|
||||
|
||||
void CameraComponent::UpdateFrustum() const
|
||||
{
|
||||
EnsureProjectionMatrixUpdate();
|
||||
@@ -114,6 +186,10 @@ namespace Ndk
|
||||
m_frustumUpdated = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates the project matrix of the camera
|
||||
*/
|
||||
|
||||
void CameraComponent::UpdateProjectionMatrix() const
|
||||
{
|
||||
switch (m_projectionType)
|
||||
@@ -139,6 +215,12 @@ namespace Ndk
|
||||
m_projectionMatrixUpdated = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates the view matrix of the camera
|
||||
*
|
||||
* \remark Produces a NazaraAssert if entity is invalid or has no NodeComponent
|
||||
*/
|
||||
|
||||
void CameraComponent::UpdateViewMatrix() const
|
||||
{
|
||||
NazaraAssert(m_entity && m_entity->HasComponent<NodeComponent>(), "CameraComponent requires NodeComponent");
|
||||
@@ -150,6 +232,12 @@ namespace Ndk
|
||||
m_viewMatrixUpdated = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates the view port of the camera
|
||||
*
|
||||
* \remark Produces a NazaraAssert if entity has no target
|
||||
*/
|
||||
|
||||
void CameraComponent::UpdateViewport() const
|
||||
{
|
||||
NazaraAssert(m_target, "CameraComponent has no target");
|
||||
|
||||
@@ -11,13 +11,27 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::CollisionComponent
|
||||
* \brief NDK class that represents the component for collision (meant for static objects)
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Sets geometry for the entity
|
||||
*
|
||||
* \param geom Geometry used for collisions
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the entity has no physics component and has no static body
|
||||
*/
|
||||
|
||||
void CollisionComponent::SetGeom(Nz::PhysGeomRef geom)
|
||||
{
|
||||
m_geom = std::move(geom);
|
||||
|
||||
if (m_entity->HasComponent<PhysicsComponent>())
|
||||
{
|
||||
// On met à jour la géométrie du PhysObject associé au PhysicsComponent
|
||||
// We update the geometry of the PhysiscsObject linked to the PhysicsComponent
|
||||
PhysicsComponent& physComponent = m_entity->GetComponent<PhysicsComponent>();
|
||||
physComponent.GetPhysObject().SetGeom(m_geom);
|
||||
}
|
||||
@@ -28,6 +42,13 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Initializes the static body
|
||||
*
|
||||
* \remark Produces a NazaraAssert if entity is invalid
|
||||
* \remark Produces a NazaraAssert if entity is not linked to a world, or the world has no physics system
|
||||
*/
|
||||
|
||||
void CollisionComponent::InitializeStaticBody()
|
||||
{
|
||||
NazaraAssert(m_entity, "Invalid entity");
|
||||
@@ -41,24 +62,44 @@ namespace Ndk
|
||||
m_staticBody->EnableAutoSleep(false);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is attached to an entity
|
||||
*/
|
||||
|
||||
void CollisionComponent::OnAttached()
|
||||
{
|
||||
if (!m_entity->HasComponent<PhysicsComponent>())
|
||||
InitializeStaticBody();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is attached to this component
|
||||
*
|
||||
* \param component Component being attached
|
||||
*/
|
||||
|
||||
void CollisionComponent::OnComponentAttached(BaseComponent& component)
|
||||
{
|
||||
if (IsComponent<PhysicsComponent>(component))
|
||||
m_staticBody.reset();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is detached from this component
|
||||
*
|
||||
* \param component Component being detached
|
||||
*/
|
||||
|
||||
void CollisionComponent::OnComponentDetached(BaseComponent& component)
|
||||
{
|
||||
if (IsComponent<PhysicsComponent>(component))
|
||||
InitializeStaticBody();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is detached from an entity
|
||||
*/
|
||||
|
||||
void CollisionComponent::OnDetached()
|
||||
{
|
||||
m_staticBody.reset();
|
||||
|
||||
@@ -9,7 +9,23 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
void GraphicsComponent::InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, std::size_t index)
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::GraphicsComponent
|
||||
* \brief NDK class that represents the component for graphics
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Invalidates the data for renderable
|
||||
*
|
||||
* \param renderable Renderable to invalidate
|
||||
* \param flags Flags for the instance
|
||||
* \param index Index of the renderable to invalidate
|
||||
*
|
||||
* \remark Produces a NazaraAssert if index is out of bound
|
||||
*/
|
||||
|
||||
void GraphicsComponent::InvalidateRenderableData(const Nz::InstancedRenderable* renderable , Nz::UInt32 flags, std::size_t index)
|
||||
{
|
||||
NazaraAssert(index < m_renderables.size(), "Invalid renderable index");
|
||||
NazaraUnused(renderable);
|
||||
@@ -19,6 +35,10 @@ namespace Ndk
|
||||
r.renderable->InvalidateData(&r.data, flags);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is attached to an entity
|
||||
*/
|
||||
|
||||
void GraphicsComponent::OnAttached()
|
||||
{
|
||||
if (m_entity->HasComponent<NodeComponent>())
|
||||
@@ -27,6 +47,12 @@ namespace Ndk
|
||||
InvalidateTransformMatrix();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is attached to this component
|
||||
*
|
||||
* \param component Component being attached
|
||||
*/
|
||||
|
||||
void GraphicsComponent::OnComponentAttached(BaseComponent& component)
|
||||
{
|
||||
if (IsComponent<NodeComponent>(component))
|
||||
@@ -38,6 +64,12 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is detached from this component
|
||||
*
|
||||
* \param component Component being detached
|
||||
*/
|
||||
|
||||
void GraphicsComponent::OnComponentDetached(BaseComponent& component)
|
||||
{
|
||||
if (IsComponent<NodeComponent>(component))
|
||||
@@ -48,6 +80,10 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is detached from an entity
|
||||
*/
|
||||
|
||||
void GraphicsComponent::OnDetached()
|
||||
{
|
||||
m_nodeInvalidationSlot.Disconnect();
|
||||
@@ -55,6 +91,12 @@ namespace Ndk
|
||||
InvalidateTransformMatrix();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when the node is invalidated
|
||||
*
|
||||
* \param node Pointer to the node
|
||||
*/
|
||||
|
||||
void GraphicsComponent::OnNodeInvalidated(const Nz::Node* node)
|
||||
{
|
||||
NazaraUnused(node);
|
||||
@@ -63,6 +105,10 @@ namespace Ndk
|
||||
InvalidateTransformMatrix();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates the bounding volume
|
||||
*/
|
||||
|
||||
void GraphicsComponent::UpdateBoundingVolume() const
|
||||
{
|
||||
EnsureTransformMatrixUpdate();
|
||||
@@ -75,13 +121,19 @@ namespace Ndk
|
||||
m_boundingVolumeUpdated = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates the transform matrix of the renderable
|
||||
*
|
||||
* \remark Produces a NazaraAssert if entity is invalid or has no NodeComponent
|
||||
*/
|
||||
|
||||
void GraphicsComponent::UpdateTransformMatrix() const
|
||||
{
|
||||
NazaraAssert(m_entity && m_entity->HasComponent<NodeComponent>(), "GraphicsComponent requires NodeComponent");
|
||||
|
||||
Ndk::RenderSystem& renderSystem = m_entity->GetWorld()->GetSystem<Ndk::RenderSystem>();
|
||||
|
||||
m_transformMatrix = Nz::Matrix4f::ConcatenateAffine(renderSystem.GetCoordinateSystemMatrix(), m_entity->GetComponent<NodeComponent>().GetTransformMatrix());
|
||||
m_transformMatrix = m_entity->GetComponent<NodeComponent>().GetTransformMatrix();
|
||||
m_transformMatrixUpdated = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,19 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::ParticleEmitterComponent
|
||||
* \brief NDK class that represents the component emitter of particles
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Sets up the particles
|
||||
*
|
||||
* \param mapper Mapper containing layout information of each particle
|
||||
* \param count Number of particles
|
||||
*/
|
||||
|
||||
void ParticleEmitterComponent::SetupParticles(Nz::ParticleMapper& mapper, unsigned int count) const
|
||||
{
|
||||
if (m_isActive && m_setupFunc)
|
||||
|
||||
@@ -12,6 +12,18 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::PhysicsComponent
|
||||
* \brief NDK class that represents the component for physics (meant for dynamic objects)
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is attached to an entity
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the world does not have a physics system
|
||||
*/
|
||||
|
||||
void PhysicsComponent::OnAttached()
|
||||
{
|
||||
World* entityWorld = m_entity->GetWorld();
|
||||
@@ -33,6 +45,14 @@ namespace Ndk
|
||||
m_object->SetMass(1.f);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is attached to this component
|
||||
*
|
||||
* \param component Component being attached
|
||||
*
|
||||
* \remark Produces a NazaraAssert if physical object is invalid
|
||||
*/
|
||||
|
||||
void PhysicsComponent::OnComponentAttached(BaseComponent& component)
|
||||
{
|
||||
if (IsComponent<CollisionComponent>(component))
|
||||
@@ -42,6 +62,14 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is detached from this component
|
||||
*
|
||||
* \param component Component being detached
|
||||
*
|
||||
* \remark Produces a NazaraAssert if physical object is invalid
|
||||
*/
|
||||
|
||||
void PhysicsComponent::OnComponentDetached(BaseComponent& component)
|
||||
{
|
||||
if (IsComponent<CollisionComponent>(component))
|
||||
@@ -51,6 +79,10 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when component is detached from an entity
|
||||
*/
|
||||
|
||||
void PhysicsComponent::OnDetached()
|
||||
{
|
||||
m_object.reset();
|
||||
|
||||
@@ -19,6 +19,20 @@ namespace Ndk
|
||||
constexpr std::size_t s_inputPrefixSize = Nz::CountOf(s_inputPrefix) - 1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::Console
|
||||
* \brief NDK class that represents a console to help development with Lua scripting
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Console object with a world to interact with
|
||||
*
|
||||
* \param world World to interact with
|
||||
* \param size (Width, Height) of the console
|
||||
* \param instance Lua instance that will interact with the world
|
||||
*/
|
||||
|
||||
Console::Console(World& world, const Nz::Vector2f& size, Nz::LuaInstance& instance) :
|
||||
m_historyPosition(0),
|
||||
m_defaultFont(Nz::Font::GetDefault()),
|
||||
@@ -86,18 +100,35 @@ namespace Ndk
|
||||
Layout();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds a line to the console
|
||||
*
|
||||
* \param text New line of text
|
||||
* \param color Color for the text
|
||||
*/
|
||||
|
||||
void Console::AddLine(const Nz::String& text, const Nz::Color& color)
|
||||
{
|
||||
AddLineInternal(text, color);
|
||||
RefreshHistory();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Clears the console
|
||||
*/
|
||||
|
||||
void Console::Clear()
|
||||
{
|
||||
m_historyLines.clear();
|
||||
RefreshHistory();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sends a character to the console
|
||||
*
|
||||
* \param character Character that will be added to the console
|
||||
*/
|
||||
|
||||
void Console::SendCharacter(char32_t character)
|
||||
{
|
||||
switch (character)
|
||||
@@ -131,6 +162,12 @@ namespace Ndk
|
||||
m_inputTextSprite->Update(m_inputDrawer);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sends an event to the console
|
||||
*
|
||||
* \param event Event to be takin into consideration by the console
|
||||
*/
|
||||
|
||||
void Console::SendEvent(Nz::WindowEvent event)
|
||||
{
|
||||
switch (event.type)
|
||||
@@ -170,6 +207,12 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the character size
|
||||
*
|
||||
* \param size Size of the font
|
||||
*/
|
||||
|
||||
void Console::SetCharacterSize(unsigned int size)
|
||||
{
|
||||
m_characterSize = size;
|
||||
@@ -182,6 +225,12 @@ namespace Ndk
|
||||
Layout();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the console size
|
||||
*
|
||||
* \param size (Width, Height) of the console
|
||||
*/
|
||||
|
||||
void Console::SetSize(const Nz::Vector2f& size)
|
||||
{
|
||||
m_size = size;
|
||||
@@ -189,6 +238,14 @@ namespace Ndk
|
||||
Layout();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the text font
|
||||
*
|
||||
* \param font Reference to a valid font
|
||||
*
|
||||
* \remark Produces a NazaraAssert if font is invalid or null
|
||||
*/
|
||||
|
||||
void Console::SetTextFont(Nz::FontRef font)
|
||||
{
|
||||
NazaraAssert(font && font->IsValid(), "Invalid font");
|
||||
@@ -200,6 +257,12 @@ namespace Ndk
|
||||
Layout();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shows the console
|
||||
*
|
||||
* \param show Should the console be showed
|
||||
*/
|
||||
|
||||
void Console::Show(bool show)
|
||||
{
|
||||
if (m_opened != show)
|
||||
@@ -213,11 +276,22 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds a line to the history of the console
|
||||
*
|
||||
* \param text New line of text
|
||||
* \param color Color for the text
|
||||
*/
|
||||
|
||||
void Console::AddLineInternal(const Nz::String& text, const Nz::Color& color)
|
||||
{
|
||||
m_historyLines.emplace_back(Line{color, text});
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Performs this action when an input is added to the console
|
||||
*/
|
||||
|
||||
void Console::ExecuteInput()
|
||||
{
|
||||
Nz::String input = m_inputDrawer.GetText();
|
||||
@@ -237,6 +311,10 @@ namespace Ndk
|
||||
RefreshHistory();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Places the console according to its layout
|
||||
*/
|
||||
|
||||
void Console::Layout()
|
||||
{
|
||||
unsigned int lineHeight = m_defaultFont->GetSizeInfo(m_characterSize).lineHeight;
|
||||
@@ -258,6 +336,10 @@ namespace Ndk
|
||||
m_inputBackgroundSprite->SetSize(m_size.x, m_size.y - historyHeight);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Refreshes the history of the console
|
||||
*/
|
||||
|
||||
void Console::RefreshHistory()
|
||||
{
|
||||
m_historyDrawer.Clear();
|
||||
|
||||
@@ -8,6 +8,18 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::Entity
|
||||
* \brief NDK class that represents an entity in a world
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Entity object by move semantic
|
||||
*
|
||||
* \param entity Entity to move into this
|
||||
*/
|
||||
|
||||
Entity::Entity(Entity&& entity) :
|
||||
HandledObject(std::move(entity)),
|
||||
m_components(std::move(entity.m_components)),
|
||||
@@ -20,34 +32,57 @@ namespace Ndk
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Entity object linked to a world and with an id
|
||||
*
|
||||
* \param world World in which the entity interact
|
||||
* \param id Identifier of the entity
|
||||
*/
|
||||
|
||||
Entity::Entity(World* world, EntityId id) :
|
||||
m_id(id),
|
||||
m_world(world)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destructs the object and calls Destroy
|
||||
*
|
||||
* \see Destroy
|
||||
*/
|
||||
|
||||
Entity::~Entity()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds a component to the entity
|
||||
* \return A reference to the newly added component
|
||||
*
|
||||
* \param componentPtr Component to add to the entity
|
||||
*
|
||||
* \remark Produces a NazaraAssert if component is nullptr
|
||||
*/
|
||||
|
||||
BaseComponent& Entity::AddComponent(std::unique_ptr<BaseComponent>&& componentPtr)
|
||||
{
|
||||
NazaraAssert(componentPtr, "Component must be valid");
|
||||
|
||||
ComponentIndex index = componentPtr->GetIndex();
|
||||
|
||||
// Nous nous assurons que le vecteur de component est suffisamment grand pour contenir le nouveau component
|
||||
// We ensure that the vector has enough space
|
||||
if (index >= m_components.size())
|
||||
m_components.resize(index + 1);
|
||||
|
||||
// Affectation et retour du component
|
||||
// Affectation and return of the component
|
||||
m_components[index] = std::move(componentPtr);
|
||||
m_componentBits.UnboundedSet(index);
|
||||
m_removedComponentBits.UnboundedReset(index);
|
||||
|
||||
Invalidate();
|
||||
|
||||
// On récupère le component et on informe les composants existants du nouvel arrivant
|
||||
// We get the new component and we alert other existing components of the new one
|
||||
BaseComponent& component = *m_components[index].get();
|
||||
component.SetEntity(this);
|
||||
|
||||
@@ -60,50 +95,43 @@ namespace Ndk
|
||||
return component;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Clones the entity
|
||||
* \return The clone newly created
|
||||
*
|
||||
* \remark The close is enable by default, even if the original is disabled
|
||||
* \remark Produces a NazaraAssert if the entity is not valid
|
||||
*/
|
||||
|
||||
const EntityHandle& Entity::Clone() const
|
||||
{
|
||||
NazaraAssert(IsValid(), "Invalid entity");
|
||||
|
||||
return m_world->CloneEntity(m_id);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Kills the entity
|
||||
*/
|
||||
|
||||
void Entity::Kill()
|
||||
{
|
||||
m_world->KillEntity(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Invalidates the entity
|
||||
*/
|
||||
|
||||
void Entity::Invalidate()
|
||||
{
|
||||
// On informe le monde que nous avons besoin d'une mise à jour
|
||||
// We alert everyone that we have been updated
|
||||
m_world->Invalidate(m_id);
|
||||
}
|
||||
|
||||
void Entity::RemoveAllComponents()
|
||||
{
|
||||
for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i))
|
||||
RemoveComponent(static_cast<ComponentIndex>(i));
|
||||
|
||||
NazaraAssert(m_componentBits.TestNone(), "All components should be gone");
|
||||
|
||||
m_components.clear();
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void Entity::RemoveComponent(ComponentIndex index)
|
||||
{
|
||||
///DOC: N'a aucun effet si le component n'est pas présent
|
||||
if (HasComponent(index))
|
||||
{
|
||||
// On récupère le component et on informe les composants du détachement
|
||||
BaseComponent& component = *m_components[index].get();
|
||||
for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i))
|
||||
{
|
||||
if (i != index)
|
||||
m_components[i]->OnComponentDetached(component);
|
||||
}
|
||||
|
||||
component.SetEntity(nullptr);
|
||||
|
||||
m_components[index].reset();
|
||||
m_componentBits.Reset(index);
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
/*!
|
||||
* \brief Creates the entity
|
||||
*/
|
||||
|
||||
void Entity::Create()
|
||||
{
|
||||
@@ -111,9 +139,13 @@ namespace Ndk
|
||||
m_valid = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destroys the entity
|
||||
*/
|
||||
|
||||
void Entity::Destroy()
|
||||
{
|
||||
// On informe chaque système
|
||||
// We alert each system
|
||||
for (std::size_t index = m_systemBits.FindFirst(); index != m_systemBits.npos; index = m_systemBits.FindNext(index))
|
||||
{
|
||||
if (m_world->HasSystem(index))
|
||||
@@ -128,4 +160,32 @@ namespace Ndk
|
||||
|
||||
m_valid = false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destroys a component by index
|
||||
*
|
||||
* \param index Index of the component
|
||||
*
|
||||
* \remark If component is not available, no action is performed
|
||||
*/
|
||||
|
||||
void Entity::DestroyComponent(ComponentIndex index)
|
||||
{
|
||||
if (HasComponent(index))
|
||||
{
|
||||
// We get the component and we alert existing components of the deleted one
|
||||
BaseComponent& component = *m_components[index].get();
|
||||
for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i))
|
||||
{
|
||||
if (i != index)
|
||||
m_components[i]->OnComponentDetached(component);
|
||||
}
|
||||
|
||||
component.SetEntity(nullptr);
|
||||
|
||||
m_components[index].reset();
|
||||
m_componentBits.Reset(index);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,12 +5,29 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::LuaAPI
|
||||
* \brief NDK class that represents the api used for Lua
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Initializes the LuaAPI module
|
||||
* \return true if initialization is successful
|
||||
*/
|
||||
|
||||
bool LuaAPI::Initialize()
|
||||
{
|
||||
s_binding = new LuaBinding;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Registers the classes that will be used by the Lua instance
|
||||
*
|
||||
* \param instance Lua instance that will interact with the engine & SDK
|
||||
*/
|
||||
|
||||
void LuaAPI::RegisterClasses(Nz::LuaInstance& instance)
|
||||
{
|
||||
if (!s_binding && !Initialize())
|
||||
@@ -22,6 +39,10 @@ namespace Ndk
|
||||
s_binding->RegisterClasses(instance);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Uninitializes the LuaAPI module
|
||||
*/
|
||||
|
||||
void LuaAPI::Uninitialize()
|
||||
{
|
||||
delete s_binding;
|
||||
|
||||
@@ -4,6 +4,16 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::LuaBinding
|
||||
* \brief NDK class that represents the binding between the engine & the SDK with the Lua scripting
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Binds modules to Lua
|
||||
*/
|
||||
|
||||
LuaBinding::LuaBinding() :
|
||||
// Core
|
||||
clockClass("Clock"),
|
||||
@@ -65,6 +75,12 @@ namespace Ndk
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Registers the classes that will be used by the Lua instance
|
||||
*
|
||||
* \param instance Lua instance that will interact with the engine & SDK
|
||||
*/
|
||||
|
||||
void LuaBinding::RegisterClasses(Nz::LuaInstance& instance)
|
||||
{
|
||||
RegisterCore(instance);
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \brief Binds Audio module to Lua
|
||||
*/
|
||||
|
||||
void LuaBinding::BindAudio()
|
||||
{
|
||||
/*********************************** Nz::Music **********************************/
|
||||
@@ -164,6 +168,12 @@ namespace Ndk
|
||||
soundEmitter.BindMethod("Stop", &Nz::SoundEmitter::Stop);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Registers the classes that will be used by the Lua instance
|
||||
*
|
||||
* \param instance Lua instance that will interact with the Audio classes
|
||||
*/
|
||||
|
||||
void LuaBinding::RegisterAudio(Nz::LuaInstance& instance)
|
||||
{
|
||||
musicClass.Register(instance);
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \brief Binds Core module to Lua
|
||||
*/
|
||||
|
||||
void LuaBinding::BindCore()
|
||||
{
|
||||
/*********************************** Nz::Clock **********************************/
|
||||
@@ -254,6 +258,12 @@ namespace Ndk
|
||||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Registers the classes that will be used by the Lua instance
|
||||
*
|
||||
* \param instance Lua instance that will interact with the Core classes
|
||||
*/
|
||||
|
||||
void LuaBinding::RegisterCore(Nz::LuaInstance& instance)
|
||||
{
|
||||
// Classes
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \brief Binds Graphics module to Lua
|
||||
*/
|
||||
|
||||
void LuaBinding::BindGraphics()
|
||||
{
|
||||
/*********************************** Nz::InstancedRenderable ***********************************/
|
||||
@@ -40,6 +44,12 @@ namespace Ndk
|
||||
modelClass.BindMethod("SetSkinCount", &Nz::Model::SetSkinCount);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Registers the classes that will be used by the Lua instance
|
||||
*
|
||||
* \param instance Lua instance that will interact with the Graphics classes
|
||||
*/
|
||||
|
||||
void LuaBinding::RegisterGraphics(Nz::LuaInstance& instance)
|
||||
{
|
||||
instancedRenderable.Register(instance);
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \brief Binds Math module to Lua
|
||||
*/
|
||||
|
||||
void LuaBinding::BindMath()
|
||||
{
|
||||
/*********************************** Nz::EulerAngles **********************************/
|
||||
@@ -673,6 +677,12 @@ namespace Ndk
|
||||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Registers the classes that will be used by the Lua instance
|
||||
*
|
||||
* \param instance Lua instance that will interact with the Math classes
|
||||
*/
|
||||
|
||||
void LuaBinding::RegisterMath(Nz::LuaInstance& instance)
|
||||
{
|
||||
eulerAnglesClass.Register(instance);
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \brief Binds Network module to Lua
|
||||
*/
|
||||
|
||||
void LuaBinding::BindNetwork()
|
||||
{
|
||||
/*********************************** Nz::AbstractSocket **********************************/
|
||||
@@ -132,6 +136,12 @@ namespace Ndk
|
||||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Registers the classes that will be used by the Lua instance
|
||||
*
|
||||
* \param instance Lua instance that will interact with the Network classes
|
||||
*/
|
||||
|
||||
void LuaBinding::RegisterNetwork(Nz::LuaInstance& instance)
|
||||
{
|
||||
// Classes
|
||||
|
||||
@@ -7,10 +7,20 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \brief Binds Renderer module to Lua
|
||||
*/
|
||||
|
||||
void LuaBinding::BindRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Registers the classes that will be used by the Lua instance
|
||||
*
|
||||
* \param instance Lua instance that will interact with the Renderer classes
|
||||
*/
|
||||
|
||||
void LuaBinding::RegisterRenderer(Nz::LuaInstance& instance)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -7,13 +7,24 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \brief Binds SDK module to Lua
|
||||
*/
|
||||
|
||||
void LuaBinding::BindSDK()
|
||||
{
|
||||
/*********************************** Ndk::Application **********************************/
|
||||
|
||||
#ifndef NDK_SERVER
|
||||
//application.SetMethod("AddWindow", &Application::AddWindow);
|
||||
|
||||
application.BindMethod("EnableConsole", &Application::EnableConsole);
|
||||
application.BindMethod("EnableFPSCounter", &Application::EnableFPSCounter);
|
||||
|
||||
application.BindMethod("IsConsoleEnabled", &Application::IsConsoleEnabled);
|
||||
application.BindMethod("IsFPSCounterEnabled", &Application::IsFPSCounterEnabled);
|
||||
#endif
|
||||
|
||||
application.BindMethod("AddWorld", [] (Nz::LuaInstance& instance, Application* application) -> int
|
||||
{
|
||||
instance.Push(application->AddWorld().CreateHandle());
|
||||
@@ -53,7 +64,7 @@ namespace Ndk
|
||||
#endif
|
||||
|
||||
/*********************************** Ndk::Entity **********************************/
|
||||
entityClass.BindMethod("Enable", &Entity::Enable);
|
||||
entityClass.BindMethod("Enable", &Entity::Enable, true);
|
||||
entityClass.BindMethod("GetId", &Entity::GetId);
|
||||
entityClass.BindMethod("GetWorld", &Entity::GetWorld);
|
||||
entityClass.BindMethod("Kill", &Entity::Kill);
|
||||
@@ -128,7 +139,7 @@ namespace Ndk
|
||||
|
||||
#ifndef NDK_SERVER
|
||||
/*********************************** Ndk::GraphicsComponent **********************************/
|
||||
graphicsComponent.BindMethod("Attach", &GraphicsComponent::Attach, 0);
|
||||
graphicsComponent.BindMethod("Attach", (void(Ndk::GraphicsComponent::*)(Nz::InstancedRenderableRef, int)) &GraphicsComponent::Attach, 0);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -143,6 +154,12 @@ namespace Ndk
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Registers the classes that will be used by the Lua instance
|
||||
*
|
||||
* \param instance Lua instance that will interact with the SDK classes
|
||||
*/
|
||||
|
||||
void LuaBinding::RegisterSDK(Nz::LuaInstance& instance)
|
||||
{
|
||||
// Classes
|
||||
@@ -173,6 +190,14 @@ namespace Ndk
|
||||
instance.SetGlobal("ComponentType");
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the index of the component
|
||||
* \return A pointer to the binding linked to a component
|
||||
*
|
||||
* \param instance Lua instance that will interact with the component
|
||||
* \param argIndex Index of the component
|
||||
*/
|
||||
|
||||
LuaBinding::ComponentBinding* LuaBinding::QueryComponentIndex(Nz::LuaInstance& instance, int argIndex)
|
||||
{
|
||||
switch (instance.GetType(argIndex))
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \brief Binds Utility module to Lua
|
||||
*/
|
||||
|
||||
void LuaBinding::BindUtility()
|
||||
{
|
||||
/*********************************** Nz::AbstractImage **********************************/
|
||||
@@ -308,6 +312,12 @@ namespace Ndk
|
||||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Registers the classes that will be used by the Lua instance
|
||||
*
|
||||
* \param instance Lua instance that will interact with the Utility classes
|
||||
*/
|
||||
|
||||
void LuaBinding::RegisterUtility(Nz::LuaInstance& instance)
|
||||
{
|
||||
abstractImage.Register(instance);
|
||||
|
||||
@@ -34,6 +34,19 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::Sdk
|
||||
* \brief NDK class that represents the software development kit, a set of tools made to ease the conception of application
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Initializes the Sdk module
|
||||
* \return true if initialization is successful
|
||||
*
|
||||
* \remark Produces a NazaraNotice
|
||||
*/
|
||||
|
||||
bool Sdk::Initialize()
|
||||
{
|
||||
if (s_referenceCounter++ > 0)
|
||||
@@ -104,6 +117,12 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Uninitializes the Sdk module
|
||||
*
|
||||
* \remark Produces a NazaraNotice
|
||||
*/
|
||||
|
||||
void Sdk::Uninitialize()
|
||||
{
|
||||
if (s_referenceCounter != 1)
|
||||
|
||||
@@ -6,5 +6,11 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::State
|
||||
* \brief NDK class that represents a state of your application
|
||||
*/
|
||||
|
||||
State::~State() = default;
|
||||
}
|
||||
|
||||
@@ -10,11 +10,29 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::ListenerSystem
|
||||
* \brief NDK class that represents the audio system
|
||||
*
|
||||
* \remark This system is enabled if the entity owns the trait: ListenerComponent and NodeComponent
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs an ListenerSystem object by default
|
||||
*/
|
||||
|
||||
ListenerSystem::ListenerSystem()
|
||||
{
|
||||
Requires<ListenerComponent, NodeComponent>();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when system is updated
|
||||
*
|
||||
* \param elapsedTime Delta time used for the update
|
||||
*/
|
||||
|
||||
void ListenerSystem::OnUpdate(float elapsedTime)
|
||||
{
|
||||
NazaraUnused(elapsedTime);
|
||||
@@ -23,18 +41,18 @@ namespace Ndk
|
||||
|
||||
for (const Ndk::EntityHandle& entity : GetEntities())
|
||||
{
|
||||
// Le listener est-il actif ?
|
||||
// Is the listener actif ?
|
||||
const ListenerComponent& listener = entity->GetComponent<ListenerComponent>();
|
||||
if (!listener.IsActive())
|
||||
continue;
|
||||
|
||||
// On récupère la position et la rotation pour les affecter au listener
|
||||
// We get the position and the rotation to affect these to the listener
|
||||
const NodeComponent& node = entity->GetComponent<NodeComponent>();
|
||||
Nz::Audio::SetListenerPosition(node.GetPosition(Nz::CoordSys_Global));
|
||||
Nz::Audio::SetListenerRotation(node.GetRotation(Nz::CoordSys_Global));
|
||||
|
||||
// On vérifie la présence d'une donnée de vitesse, et on l'affecte
|
||||
// (La vitesse du listener Audio ne le fait pas se déplacer, mais affecte par exemple l'effet Doppler)
|
||||
// We verify the presence of a component of velocity
|
||||
// (The listener'speed does not move it, but disturbs the sound like Doppler effect)
|
||||
if (entity->HasComponent<VelocityComponent>())
|
||||
{
|
||||
const VelocityComponent& velocity = entity->GetComponent<VelocityComponent>();
|
||||
|
||||
@@ -7,11 +7,29 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::ParticleSystem
|
||||
* \brief NDK class that represents the particle system
|
||||
*
|
||||
* \remark This system is enabled if the entity has the trait: NodeComponent and any of these two: ParticleGroupComponent
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs an ParticleSystem object by default
|
||||
*/
|
||||
|
||||
ParticleSystem::ParticleSystem()
|
||||
{
|
||||
Requires<ParticleGroupComponent>();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when system is updated
|
||||
*
|
||||
* \param elapsedTime Delta time used for the update
|
||||
*/
|
||||
|
||||
void ParticleSystem::OnUpdate(float elapsedTime)
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : GetEntities())
|
||||
|
||||
@@ -10,24 +10,50 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::PhysicsSystem
|
||||
* \brief NDK class that represents the physics system
|
||||
*
|
||||
* \remark This system is enabled if the entity has the trait: NodeComponent and any of these two: CollisionComponent or PhysicsComponent
|
||||
* \remark Static objects do not have a velocity specified by the physical engine
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs an PhysicsSystem object by default
|
||||
*/
|
||||
|
||||
PhysicsSystem::PhysicsSystem()
|
||||
{
|
||||
Requires<NodeComponent>();
|
||||
RequiresAny<CollisionComponent, PhysicsComponent>();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a PhysicsSystem object by copy semantic
|
||||
*
|
||||
* \param system PhysicsSystem to copy
|
||||
*/
|
||||
|
||||
PhysicsSystem::PhysicsSystem(const PhysicsSystem& system) :
|
||||
System(system),
|
||||
m_world()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when entity is validated for the system
|
||||
*
|
||||
* \param entity Pointer to the entity
|
||||
* \param justAdded Is the entity newly added
|
||||
*/
|
||||
|
||||
void PhysicsSystem::OnEntityValidation(Entity* entity, bool justAdded)
|
||||
{
|
||||
// Si l'entité ne vient pas d'être ajoutée au système, il est possible qu'elle fasse partie du mauvais tableau
|
||||
// If entity has not been just added to the system, it is possible that it does not own to the right array
|
||||
if (!justAdded)
|
||||
{
|
||||
// On prend le tableau inverse de celui dont l'entité devrait faire partie
|
||||
// We take the inverted array from which the entity should belong to
|
||||
auto& entities = (entity->HasComponent<PhysicsComponent>()) ? m_staticObjects : m_dynamicObjects;
|
||||
entities.Remove(entity);
|
||||
}
|
||||
@@ -36,6 +62,12 @@ namespace Ndk
|
||||
entities.Insert(entity);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when system is updated
|
||||
*
|
||||
* \param elapsedTime Delta time used for the update
|
||||
*/
|
||||
|
||||
void PhysicsSystem::OnUpdate(float elapsedTime)
|
||||
{
|
||||
m_world.Step(elapsedTime);
|
||||
@@ -63,8 +95,8 @@ namespace Ndk
|
||||
Nz::Quaternionf newRotation = node.GetRotation(Nz::CoordSys_Global);
|
||||
Nz::Vector3f newPosition = node.GetPosition(Nz::CoordSys_Global);
|
||||
|
||||
// Pour déplacer des objets statiques et assurer les collisions, il faut leur définir une vitesse
|
||||
// (note importante: le moteur physique n'applique pas la vitesse sur les objets statiques)
|
||||
// To move static objects and ensure their collisions, we have to specify them a velocity
|
||||
// (/!\: the physical motor does not apply the speed on static objects)
|
||||
if (newPosition != oldPosition)
|
||||
{
|
||||
physObj->SetPosition(newPosition);
|
||||
|
||||
@@ -14,6 +14,21 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::RenderSystem
|
||||
* \brief NDK class that represents the rendering system
|
||||
*
|
||||
* \remark This system is enabled if the entity is a 'camera' with the trait: CameraComponent and NodeComponent
|
||||
* or a drawable element with trait: GraphicsComponent and NodeComponent
|
||||
* or a light element with trait: LightComponent and NodeComponent
|
||||
* or a set of particles with trait: ParticleGroupComponent
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs an RenderSystem object by default
|
||||
*/
|
||||
|
||||
RenderSystem::RenderSystem() :
|
||||
m_coordinateSystemMatrix(Nz::Matrix4f::Identity()),
|
||||
m_coordinateSystemInvalidated(true)
|
||||
@@ -23,6 +38,12 @@ namespace Ndk
|
||||
SetUpdateRate(0.f);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when an entity is removed
|
||||
*
|
||||
* \param entity Pointer to the entity
|
||||
*/
|
||||
|
||||
void RenderSystem::OnEntityRemoved(Entity* entity)
|
||||
{
|
||||
m_cameras.Remove(entity);
|
||||
@@ -33,6 +54,13 @@ namespace Ndk
|
||||
m_pointSpotLights.Remove(entity);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when entity is validated for the system
|
||||
*
|
||||
* \param entity Pointer to the entity
|
||||
* \param justAdded Is the entity newly added
|
||||
*/
|
||||
|
||||
void RenderSystem::OnEntityValidation(Entity* entity, bool justAdded)
|
||||
{
|
||||
NazaraUnused(justAdded);
|
||||
@@ -82,6 +110,12 @@ namespace Ndk
|
||||
m_particleGroups.Remove(entity);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when system is updated
|
||||
*
|
||||
* \param elapsedTime Delta time used for the update
|
||||
*/
|
||||
|
||||
void RenderSystem::OnUpdate(float elapsedTime)
|
||||
{
|
||||
NazaraUnused(elapsedTime);
|
||||
@@ -146,6 +180,12 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates the directional shadow maps according to the position of the viewer
|
||||
*
|
||||
* \param viewer Viewer of the scene
|
||||
*/
|
||||
|
||||
void RenderSystem::UpdateDirectionalShadowMaps(const Nz::AbstractViewer& viewer)
|
||||
{
|
||||
if (!m_shadowRT.IsValid())
|
||||
@@ -191,6 +231,10 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates the point spot shadow maps
|
||||
*/
|
||||
|
||||
void RenderSystem::UpdatePointSpotShadowMaps()
|
||||
{
|
||||
if (!m_shadowRT.IsValid())
|
||||
|
||||
@@ -9,12 +9,31 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::VelocitySystem
|
||||
* \brief NDK class that represents the velocity system
|
||||
*
|
||||
* \remark This system is enabled if the entity owns the trait: NodeComponent and VelocityComponent
|
||||
* but it's disabled with the trait: PhysicsComponent
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs an VelocitySystem object by default
|
||||
*/
|
||||
|
||||
VelocitySystem::VelocitySystem()
|
||||
{
|
||||
Requires<NodeComponent, VelocityComponent>();
|
||||
Excludes<PhysicsComponent>();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when system is updated
|
||||
*
|
||||
* \param elapsedTime Delta time used for the update
|
||||
*/
|
||||
|
||||
void VelocitySystem::OnUpdate(float elapsedTime)
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : GetEntities())
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <NDK/World.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <NDK/BaseComponent.hpp>
|
||||
#include <NDK/Systems/PhysicsSystem.hpp>
|
||||
#include <NDK/Systems/VelocitySystem.hpp>
|
||||
|
||||
@@ -15,12 +16,28 @@
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::World
|
||||
* \brief NDK class that represents a world
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Destructs the object and calls Clear
|
||||
*
|
||||
* \see Clear
|
||||
*/
|
||||
|
||||
World::~World() noexcept
|
||||
{
|
||||
// La destruction doit se faire dans un ordre précis
|
||||
// The destruct must be done in an ordered way
|
||||
Clear();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds default systems to the world
|
||||
*/
|
||||
|
||||
void World::AddDefaultSystems()
|
||||
{
|
||||
AddSystem<PhysicsSystem>();
|
||||
@@ -33,40 +50,49 @@ namespace Ndk
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Creates an entity in the world
|
||||
* \return The entity created
|
||||
*/
|
||||
|
||||
const EntityHandle& World::CreateEntity()
|
||||
{
|
||||
EntityId id;
|
||||
if (!m_freeIdList.empty())
|
||||
{
|
||||
// On récupère un identifiant
|
||||
// We get an identifier
|
||||
id = m_freeIdList.back();
|
||||
m_freeIdList.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
// On alloue une nouvelle entité
|
||||
// We allocate a new entity
|
||||
id = m_entities.size();
|
||||
|
||||
// Impossible d'utiliser emplace_back à cause de la portée
|
||||
// We can't use emplace_back due to the scope
|
||||
m_entities.push_back(Entity(this, id));
|
||||
}
|
||||
|
||||
// On initialise l'entité et on l'ajoute à la liste des entités vivantes
|
||||
// We initialise the entity and we add it to the list of alive entities
|
||||
Entity& entity = m_entities[id].entity;
|
||||
entity.Create();
|
||||
|
||||
m_aliveEntities.emplace_back(&entity);
|
||||
m_entities[id].aliveIndex = m_aliveEntities.size()-1;
|
||||
m_entities[id].aliveIndex = m_aliveEntities.size() - 1;
|
||||
|
||||
return m_aliveEntities.back();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Clears the world from every entities
|
||||
*
|
||||
* \remark Every handles are correctly invalidated, entities are immediately invalidated
|
||||
*/
|
||||
|
||||
void World::Clear() noexcept
|
||||
{
|
||||
///DOC: Tous les handles sont correctement invalidés, les entités sont immédiatement invalidées
|
||||
|
||||
// Destruction des entités d'abord, et des handles ensuite
|
||||
// ceci pour éviter que les handles n'informent les entités inutilement lors de leur destruction
|
||||
// First, destruction of entities, then handles
|
||||
// This is made to avoid that handle warn uselessly entities before their destruction
|
||||
m_entities.clear();
|
||||
|
||||
m_aliveEntities.clear();
|
||||
@@ -74,14 +100,59 @@ namespace Ndk
|
||||
m_killedEntities.Clear();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Clones the entity
|
||||
* \return The clone newly created
|
||||
*
|
||||
* \param id Identifier of the entity
|
||||
*
|
||||
* \remark Produces a NazaraError if the entity to clone does not exist
|
||||
*/
|
||||
|
||||
const EntityHandle& World::CloneEntity(EntityId id)
|
||||
{
|
||||
EntityHandle original = GetEntity(id);
|
||||
if (!original)
|
||||
{
|
||||
NazaraError("Invalid entity ID");
|
||||
return EntityHandle::InvalidHandle;
|
||||
}
|
||||
|
||||
EntityHandle clone = CreateEntity();
|
||||
|
||||
const Nz::Bitset<>& componentBits = original->GetComponentBits();
|
||||
for (std::size_t i = componentBits.FindFirst(); i != componentBits.npos; i = componentBits.FindNext(i))
|
||||
{
|
||||
std::unique_ptr<BaseComponent> component(original->GetComponent(ComponentIndex(i)).Clone());
|
||||
clone->AddComponent(std::move(component));
|
||||
}
|
||||
|
||||
return GetEntity(clone->GetId());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Kills an entity
|
||||
*
|
||||
* \param Pointer to the entity
|
||||
*
|
||||
* \remark No change is done if entity is invalid
|
||||
*/
|
||||
|
||||
void World::KillEntity(Entity* entity)
|
||||
{
|
||||
///DOC: Ignoré si l'entité est invalide
|
||||
|
||||
if (IsEntityValid(entity))
|
||||
m_killedEntities.UnboundedSet(entity->GetId(), true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets an entity
|
||||
* \return A constant reference to the modified entity
|
||||
*
|
||||
* \param id Identifier of the entity
|
||||
*
|
||||
* \remark Produces a NazaraError if entity identifier is not valid
|
||||
*/
|
||||
|
||||
const EntityHandle& World::GetEntity(EntityId id)
|
||||
{
|
||||
if (IsEntityIdValid(id))
|
||||
@@ -93,9 +164,15 @@ namespace Ndk
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates the world
|
||||
*
|
||||
* \remark Produces a NazaraAssert if an entity is invalid
|
||||
*/
|
||||
|
||||
void World::Update()
|
||||
{
|
||||
// Gestion des entités tuées depuis le dernier appel
|
||||
// Handle killed entities before last call
|
||||
for (std::size_t i = m_killedEntities.FindFirst(); i != m_killedEntities.npos; i = m_killedEntities.FindNext(i))
|
||||
{
|
||||
EntityBlock& block = m_entities[i];
|
||||
@@ -103,32 +180,32 @@ namespace Ndk
|
||||
|
||||
NazaraAssert(entity.IsValid(), "Entity must be valid");
|
||||
|
||||
// Remise en file d'attente de l'identifiant d'entité
|
||||
// Send back the identifier of the entity to the free queue
|
||||
m_freeIdList.push_back(entity.GetId());
|
||||
|
||||
// Destruction de l'entité (invalidation du handle par la même occasion)
|
||||
// Destruction of the entity (invalidation of handle by the same way)
|
||||
entity.Destroy();
|
||||
|
||||
// Nous allons sortir le handle de la liste des entités vivantes
|
||||
// en swappant le handle avec le dernier handle, avant de pop
|
||||
// We take out the handle from the list of alive entities
|
||||
// With the idiom swap and pop
|
||||
|
||||
NazaraAssert(block.aliveIndex < m_aliveEntities.size(), "Alive index out of range");
|
||||
|
||||
if (block.aliveIndex < m_aliveEntities.size()-1) // S'il ne s'agit pas du dernier handle
|
||||
if (block.aliveIndex < m_aliveEntities.size() - 1) // If it's not the last handle
|
||||
{
|
||||
EntityHandle& lastHandle = m_aliveEntities.back();
|
||||
EntityHandle& myHandle = m_aliveEntities[block.aliveIndex];
|
||||
|
||||
myHandle = std::move(lastHandle);
|
||||
|
||||
// On n'oublie pas de corriger l'indice associé à l'entité
|
||||
// We don't forget to update the index associated to the entity
|
||||
m_entities[myHandle->GetId()].aliveIndex = block.aliveIndex;
|
||||
}
|
||||
m_aliveEntities.pop_back();
|
||||
}
|
||||
m_killedEntities.Reset();
|
||||
|
||||
// Gestion des entités nécessitant une mise à jour de leurs systèmes
|
||||
// Handle of entities which need an update from the systems
|
||||
for (std::size_t i = m_dirtyEntities.FindFirst(); i != m_dirtyEntities.npos; i = m_dirtyEntities.FindNext(i))
|
||||
{
|
||||
NazaraAssert(i < m_entities.size(), "Entity index out of range");
|
||||
@@ -139,6 +216,11 @@ namespace Ndk
|
||||
if (!entity->IsValid())
|
||||
continue;
|
||||
|
||||
Nz::Bitset<>& removedComponents = entity->GetRemovedComponentBits();
|
||||
for (std::size_t j = removedComponents.FindFirst(); j != m_dirtyEntities.npos; j = removedComponents.FindNext(j))
|
||||
entity->DestroyComponent(j);
|
||||
removedComponents.Reset();
|
||||
|
||||
for (auto& system : m_systems)
|
||||
{
|
||||
// Ignore non-existent systems
|
||||
|
||||
Reference in New Issue
Block a user