Merge branch 'master' into gui

Former-commit-id: 4219b882862695f5855081ea997d64bec14a7ec7 [formerly 00d365bfa5c84b97f410e5cc3dd6cfbea0be179f] [formerly fdb4829bc4371afc415aeb0c31bc5f96046cb865 [formerly 346917aade13eb3ae2562cc7490244e338878b41]]
Former-commit-id: 9610a43f6de50988aad9008c45c65ca5f3ba4d84 [formerly aabaeeec873c5595e784d30e24f6f6c5add38889]
Former-commit-id: 98193fb1c618cc6ecc4af809089161c7a9bab95f
This commit is contained in:
Lynix 2016-09-06 13:57:25 +02:00
commit f9d7dbba57
217 changed files with 5658 additions and 4089 deletions

3
.gitignore vendored
View File

@ -10,6 +10,9 @@ tests/*.dll
tests/*.so
lib/*
# Example generated files
examples/bin/HardwareInfo.txt
# Feature page
build/scripts/features/index.html

View File

@ -776,7 +776,9 @@ WARN_LOGFILE =
# Note: If this tag is empty the current directory is searched.
INPUT = include \
src
src \
SDK/include \
SDK/src
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

View File

@ -6,7 +6,15 @@
namespace Ndk
{
///TODO: constexpr avec le C++14
/*!
* \ingroup NDK
* \brief Builds a component id based on a name
* \return Identifier for the component
*
* \param name Name to generate id from
*/
///TODO: constexpr with the C++14
template<unsigned int N>
ComponentId BuildComponentId(const char (&name)[N])
{
@ -19,18 +27,38 @@ namespace Ndk
return componentId;
}
/*!
* \ingroup NDK
* \brief Gets the component id of a component
* \return Identifier for the component
*/
template<typename ComponentType>
ComponentIndex GetComponentIndex()
{
return ComponentType::componentIndex;
}
/*!
* \ingroup NDK
* \brief Gets the system id of a system
* \return Identifier for the system
*/
template<typename SystemType>
SystemIndex GetSystemIndex()
{
return SystemType::systemIndex;
}
/*!
* \ingroup NDK
* \brief Initializes the a component
* \return Identifier for the component
*
* \param name Name to generate id from
*/
template<typename ComponentType, unsigned int N>
ComponentIndex InitializeComponent(const char (&name)[N])
{
@ -38,6 +66,12 @@ namespace Ndk
return ComponentType::componentIndex;
}
/*!
* \ingroup NDK
* \brief Initializes the a system
* \return Identifier for the system
*/
template<typename SystemType>
SystemIndex InitializeSystem()
{
@ -45,12 +79,26 @@ namespace Ndk
return SystemType::systemIndex;
}
/*!
* \brief Checks whether the parameter is a component
* \return true If it is the case
*
* \param component Component to check
*/
template<typename ComponentType, typename C>
bool IsComponent(C& component)
{
return component.GetIndex() == GetComponentIndex<ComponentType>();
}
/*!
* \brief Checks whether the parameter is a system
* \return true If it is the case
*
* \param system System to check
*/
template<typename SystemType, typename S>
bool IsSystem(S& system)
{

View File

@ -8,18 +8,35 @@
#define NDK_APPLICATION_HPP
#include <NDK/Prerequesites.hpp>
#include <NDK/EntityOwner.hpp>
#include <NDK/World.hpp>
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Utility/Window.hpp>
#include <map>
#include <list>
#include <set>
#include <vector>
#ifndef NDK_SERVER
#include <NDK/Console.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Lua/LuaInstance.hpp>
#include <Nazara/Graphics/TextSprite.hpp>
#include <Nazara/Renderer/RenderTarget.hpp>
#include <Nazara/Utility/Window.hpp>
#endif
namespace Ndk
{
class NDK_API Application
{
public:
#ifndef NDK_SERVER
struct ConsoleOverlay;
struct FPSCounterOverlay;
#endif
inline Application();
Application(int argc, char* argv[]);
Application(const Application&) = delete;
Application(Application&&) = delete;
inline ~Application();
@ -29,8 +46,27 @@ namespace Ndk
#endif
template<typename... Args> World& AddWorld(Args&&... args);
#ifndef NDK_SERVER
inline void EnableConsole(bool enable);
inline void EnableFPSCounter(bool enable);
inline ConsoleOverlay& GetConsoleOverlay(std::size_t windowIndex = 0U);
inline FPSCounterOverlay& GetFPSCounterOverlay(std::size_t windowIndex = 0U);
#endif
inline const std::set<Nz::String>& GetOptions() const;
inline const std::map<Nz::String, Nz::String>& GetParameters() const;
inline float GetUpdateTime() const;
inline bool HasOption(const Nz::String& option) const;
inline bool HasParameter(const Nz::String& key, Nz::String* value) const;
#ifndef NDK_SERVER
inline bool IsConsoleEnabled() const;
inline bool IsFPSCounterEnabled() const;
#endif
bool Run();
#ifndef NDK_SERVER
@ -44,13 +80,63 @@ namespace Ndk
inline static Application* Instance();
#ifndef NDK_SERVER
struct ConsoleOverlay
{
std::unique_ptr<Console> console;
Nz::LuaInstance lua;
NazaraSlot(Nz::EventHandler, OnEvent, eventSlot);
NazaraSlot(Nz::EventHandler, OnKeyPressed, keyPressedSlot);
NazaraSlot(Nz::RenderTarget, OnRenderTargetSizeChange, resizedSlot);
NazaraSlot(Nz::Log, OnLogWrite, logSlot);
};
struct FPSCounterOverlay
{
Nz::TextSpriteRef sprite;
EntityOwner entity;
float elapsedTime = 0.f;
unsigned int frameCount = 0;
};
#endif
private:
#ifndef NDK_SERVER
std::vector<std::unique_ptr<Nz::Window>> m_windows;
enum OverlayFlags
{
OverlayFlags_Console = 0x1,
OverlayFlags_FPSCounter = 0x2
};
struct WindowInfo
{
inline WindowInfo(std::unique_ptr<Nz::Window>&& window);
Nz::RenderTarget* renderTarget;
std::unique_ptr<Nz::Window> window;
std::unique_ptr<ConsoleOverlay> console;
std::unique_ptr<FPSCounterOverlay> fpsCounter;
std::unique_ptr<World> overlayWorld;
};
void SetupConsole(WindowInfo& info);
void SetupFPSCounter(WindowInfo& info);
void SetupOverlay(WindowInfo& info);
template<typename T> void SetupWindow(WindowInfo& info, T* renderTarget, std::true_type /*isRenderTarget*/);
template<typename T> void SetupWindow(WindowInfo& /*info*/, T* /*renderTarget*/, std::false_type /*isNotRenderTarget*/);
std::vector<WindowInfo> m_windows;
#endif
std::map<Nz::String, Nz::String> m_parameters;
std::set<Nz::String> m_options;
std::list<World> m_worlds;
Nz::Clock m_updateClock;
#ifndef NDK_SERVER
Nz::UInt32 m_overlayFlags;
bool m_exitOnClosedWindows;
#endif
bool m_shouldQuit;

View File

@ -2,14 +2,23 @@
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <NDK/Application.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <type_traits>
#include <NDK/Sdk.hpp>
namespace Ndk
{
/*!
* \brief Constructs an Application object without passing command-line arguments
*
* This calls Sdk::Initialize()
*
* \remark Only one Application instance can exist at a time
*/
inline Application::Application() :
#ifndef NDK_SERVER
m_overlayFlags(0U),
m_exitOnClosedWindows(true),
#endif
m_shouldQuit(false),
@ -24,6 +33,11 @@ namespace Ndk
Sdk::Initialize();
}
/*!
* \brief Destructs the application object
*
* This destroy all worlds and windows and then calls Sdk::Uninitialize
*/
inline Application::~Application()
{
m_worlds.clear();
@ -31,24 +45,43 @@ namespace Ndk
m_windows.clear();
#endif
// Libération du SDK
// Free of SDK
Sdk::Uninitialize();
// Libération automatique des modules
// Automatic free of modules
s_application = nullptr;
}
/*!
* \brief Adds a window to the application
* \return A reference to the newly created windows
*
* \param args Arguments used to create the window
*/
#ifndef NDK_SERVER
template<typename T, typename... Args>
T& Application::AddWindow(Args&&... args)
{
static_assert(std::is_base_of<Nz::Window, T>::value, "Type must inherit Window");
m_windows.emplace_back(new T(std::forward<Args>(args)...));
return static_cast<T&>(*m_windows.back().get());
m_windows.emplace_back(std::make_unique<T>(std::forward<Args>(args)...));
WindowInfo& info = m_windows.back();
T& window = static_cast<T&>(*info.window.get()); //< Warning: ugly
SetupWindow(info, &window, std::is_base_of<Nz::RenderTarget, T>());
return window;
}
#endif
/*!
* \brief Adds a world to the application
* \return A reference to the newly created world
*
* \param args Arguments used to create the world
*/
template<typename... Args>
World& Application::AddWorld(Args&&... args)
{
@ -56,11 +89,241 @@ namespace Ndk
return m_worlds.back();
}
/*!
* \brief Enable/disable debug console
*
* \param enable Should the console overlay be enabled
*/
#ifndef NDK_SERVER
inline void Application::EnableConsole(bool enable)
{
if (enable != ((m_overlayFlags & OverlayFlags_Console) != 0))
{
if (enable)
{
if (m_overlayFlags == 0)
{
for (WindowInfo& info : m_windows)
SetupOverlay(info);
}
for (WindowInfo& info : m_windows)
{
if (info.renderTarget)
SetupConsole(info);
}
m_overlayFlags |= OverlayFlags_Console;
}
else
{
for (WindowInfo& info : m_windows)
info.console.reset();
m_overlayFlags &= ~OverlayFlags_Console;
if (m_overlayFlags == 0)
{
for (WindowInfo& info : m_windows)
info.overlayWorld.reset();
}
}
}
}
#endif
/*!
* \brief Enable/disable debug FPS counter
*
* \param enable Should the FPS counter be displayed
*/
#ifndef NDK_SERVER
inline void Application::EnableFPSCounter(bool enable)
{
if (enable != ((m_overlayFlags & OverlayFlags_FPSCounter) != 0))
{
if (enable)
{
if (m_overlayFlags == 0)
{
for (WindowInfo& info : m_windows)
SetupOverlay(info);
}
for (WindowInfo& info : m_windows)
{
if (info.renderTarget)
SetupFPSCounter(info);
}
m_overlayFlags |= OverlayFlags_FPSCounter;
}
else
{
for (WindowInfo& info : m_windows)
info.fpsCounter.reset();
m_overlayFlags &= ~OverlayFlags_FPSCounter;
if (m_overlayFlags == 0)
{
for (WindowInfo& info : m_windows)
info.overlayWorld.reset();
}
}
}
}
#endif
/*!
* \brief Gets the console overlay for a specific window
*
* \param windowIndex Index of the window to get
*
* \remark The console overlay must be enabled
*
* \return A reference to the console overlay of the window
*
* \see IsConsoleOverlayEnabled
*/
#ifndef NDK_SERVER
inline Application::ConsoleOverlay& Application::GetConsoleOverlay(std::size_t windowIndex)
{
NazaraAssert(m_overlayFlags & OverlayFlags_Console, "Console overlay is not enabled");
NazaraAssert(windowIndex <= m_windows.size(), "Window index is out of range");
return *m_windows[windowIndex].console;
}
#endif
/*!
* \brief Gets the console overlay for a specific window
*
* \param windowIndex Index of the window to get
*
* \remark The console overlay must be enabled
*
* \return A reference to the console overlay of the window
*
* \see IsFPSCounterEnabled
*/
#ifndef NDK_SERVER
inline Application::FPSCounterOverlay& Application::GetFPSCounterOverlay(std::size_t windowIndex)
{
NazaraAssert(m_overlayFlags & OverlayFlags_FPSCounter, "FPS counter overlay is not enabled");
NazaraAssert(windowIndex <= m_windows.size(), "Window index is out of range");
return *m_windows[windowIndex].fpsCounter;
}
#endif
/*!
* \brief Gets the options used to start the application
*
* Options are defined as "-optionName" in command-line and are always lower-case
*
* \return Command-line options
*/
inline const std::set<Nz::String>& Application::GetOptions() const
{
return m_options;
}
/*!
* \brief Gets the parameters used to start the application
*
* Parameters are defined as "-key=value" in command-line, their key is lower-case but value capitals are kept.
*
* \return Command-line parameters
*/
inline const std::map<Nz::String, Nz::String>& Application::GetParameters() const
{
return m_parameters;
}
/*!
* \brief Gets the update time of the application
* \return Update rate
*/
inline float Application::GetUpdateTime() const
{
return m_updateTime;
}
/*!
* \brief Query for a command-line option
*
* \param option Option name
*
* \remark option must be lower-case
*
* \return True if option is present
*
* \see GetOptions
*/
inline bool Application::HasOption(const Nz::String& option) const
{
return m_options.count(option) != 0;
}
/*!
* \brief Query for a command-line option
*
* \param key Parameter name
* \param value Optional string to receive the parameter value
*
* \remark key must be lower-case
*
* \return True if parameter is present
*
* \see GetParameters
*/
inline bool Application::HasParameter(const Nz::String& key, Nz::String* value) const
{
auto it = m_parameters.find(key);
if (it == m_parameters.end())
return false;
if (value)
*value = it->second;
return true;
}
/*!
* \brief Checks if the console overlay is enabled
*
* \remark This has nothing to do with the visibility state of the console
*
* \return True if the console overlay is enabled
*
* \see GetConsoleOverlay
*/
#ifndef NDK_SERVER
inline bool Application::IsConsoleEnabled() const
{
return (m_overlayFlags & OverlayFlags_Console) != 0;
}
#endif
/*!
* \brief Checks if the FPS counter overlay is enabled
* \return True if the FPS counter overlay is enabled
*
* \see GetFPSCounterOverlay
*/
#ifndef NDK_SERVER
inline bool Application::IsFPSCounterEnabled() const
{
return (m_overlayFlags & OverlayFlags_FPSCounter) != 0;
}
#endif
/*!
* \brief Makes the application exit when there's no more open window
*
* \param exitOnClosedWindows Should exit be called when no more window is open
*/
#ifndef NDK_SERVER
inline void Application::MakeExitOnLastWindowClosed(bool exitOnClosedWindows)
{
@ -68,13 +331,52 @@ namespace Ndk
}
#endif
/*!
* \brief Quits the application
*/
inline void Application::Quit()
{
m_shouldQuit = true;
}
/*!
* \brief Gets the singleton instance of the application
* \return Singleton application
*/
inline Application* Application::Instance()
{
return s_application;
}
#ifndef NDK_SERVER
template<typename T>
inline void Application::SetupWindow(WindowInfo& info, T* renderTarget, std::true_type)
{
info.renderTarget = renderTarget;
if (m_overlayFlags)
{
SetupOverlay(info);
if (m_overlayFlags & OverlayFlags_Console)
SetupConsole(info);
if (m_overlayFlags & OverlayFlags_FPSCounter)
SetupFPSCounter(info);
}
}
template<typename T>
inline void Application::SetupWindow(WindowInfo&, T*, std::false_type)
{
}
inline Application::WindowInfo::WindowInfo(std::unique_ptr<Nz::Window>&& window) :
window(std::move(window)),
renderTarget(nullptr)
{
}
#endif
}

View File

@ -27,7 +27,7 @@ namespace Ndk
BaseComponent(BaseComponent&&) = default;
virtual ~BaseComponent();
virtual BaseComponent* Clone() const = 0;
virtual std::unique_ptr<BaseComponent> Clone() const = 0;
ComponentIndex GetIndex() const;

View File

@ -7,34 +7,60 @@
namespace Ndk
{
/*!
* \brief Constructs a BaseComponent object with an index
*
* \param index Index of the component
*/
inline BaseComponent::BaseComponent(ComponentIndex index) :
m_componentIndex(index),
m_entity(nullptr)
{
}
/*!
* \brief Gets the index of the component
* \return Index of the component
*/
inline ComponentIndex BaseComponent::GetIndex() const
{
return m_componentIndex;
}
/*!
* \brief Gets the maximal index of the components
* \return Index of the maximal component
*/
inline ComponentIndex BaseComponent::GetMaxComponentIndex()
{
return static_cast<ComponentIndex>(s_entries.size());
}
/*!
* \brief Registers a component
* \return Index of the registered component
*
* \param id Index of the component
* \param factory Factory to create the component
*
* \remark Produces a NazaraAssert if the identifier is already in use
*/
inline ComponentIndex BaseComponent::RegisterComponent(ComponentId id, Factory factoryFunc)
{
// Nous allons rajouter notre composant à la fin
// We add our component to the end
ComponentIndex index = static_cast<ComponentIndex>(s_entries.size());
s_entries.resize(index + 1);
// On récupère et on affecte
// We retrieve it and affect it
ComponentEntry& entry = s_entries.back();
entry.factory = factoryFunc;
entry.id = id;
// Une petite assertion pour s'assurer que l'identifiant n'est pas déjà utilisé
// We ensure that id is not already in use
NazaraAssert(s_idToIndex.find(id) == s_idToIndex.end(), "This id is already in use");
s_idToIndex[id] = index;
@ -42,6 +68,10 @@ namespace Ndk
return index;
}
/*!
* \brief Sets the entity on which the component operates
*/
inline void BaseComponent::SetEntity(Entity* entity)
{
if (m_entity != entity)
@ -55,12 +85,21 @@ namespace Ndk
}
}
/*!
* \brief Initializes the BaseComponent
* \return true
*/
inline bool BaseComponent::Initialize()
{
// Rien à faire
// Nothing to do
return true;
}
/*!
* \brief Uninitializes the BaseComponent
*/
inline void BaseComponent::Uninitialize()
{
s_entries.clear();

View File

@ -27,7 +27,9 @@ namespace Ndk
BaseSystem(BaseSystem&&) noexcept = default;
virtual ~BaseSystem();
virtual BaseSystem* Clone() const = 0;
inline void Enable(bool enable = true);
virtual std::unique_ptr<BaseSystem> Clone() const = 0;
bool Filters(const Entity* entity) const;
@ -36,6 +38,8 @@ namespace Ndk
inline float GetUpdateRate() const;
inline World& GetWorld() const;
inline bool IsEnabled() const;
inline bool HasEntity(const Entity* entity) const;
inline void SetUpdateRate(float updatePerSecond);
@ -86,6 +90,7 @@ namespace Ndk
Nz::Bitset<> m_requiredComponents;
SystemIndex m_systemIndex;
World* m_world;
bool m_updateEnabled;
float m_updateCounter;
float m_updateRate;

View File

@ -2,46 +2,109 @@
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <NDK/BaseSystem.hpp>
#include <Nazara/Core/Error.hpp>
#include <type_traits>
namespace Ndk
{
/*!
* \brief Constructs a BaseSystem object with an index
*
* \param systemId Index of the system
*/
inline BaseSystem::BaseSystem(SystemIndex systemId) :
m_updateEnabled(true),
m_systemIndex(systemId)
{
SetUpdateRate(30);
}
/*!
* \brief Constructs a BaseSystem object by copy semantic
*
* \param system System to copy
*/
inline BaseSystem::BaseSystem(const BaseSystem& system) :
m_excludedComponents(system.m_excludedComponents),
m_requiredComponents(system.m_requiredComponents),
m_systemIndex(system.m_systemIndex),
m_updateEnabled(system.m_updateEnabled),
m_updateCounter(0.f),
m_updateRate(system.m_updateRate)
{
}
/*!
* \brief Enables the system
*
* \param enable Should the system be enabled
*/
inline void BaseSystem::Enable(bool enable)
{
m_updateEnabled = enable;
}
/*!
* \brief Gets every entities that system handle
* \return A constant reference to the list of entities
*/
inline const std::vector<EntityHandle>& BaseSystem::GetEntities() const
{
return m_entities;
}
/*!
* \brief Gets the index of the system
* \return Index of the system
*/
inline SystemIndex BaseSystem::GetIndex() const
{
return m_systemIndex;
}
/*!
* \brief Gets the rate of update for the system
* \return Update rate
*/
inline float BaseSystem::GetUpdateRate() const
{
return (m_updateRate > 0.f) ? 1.f / m_updateRate : 0.f;
}
/*!
* \brief Gets the world on which the system operate
* \return World in which the system is
*/
inline World& BaseSystem::GetWorld() const
{
return *m_world;
}
/*!
* \brief Checks whether or not the system is enabled
* \return true If it is the case
*/
inline bool BaseSystem::IsEnabled() const
{
return m_updateEnabled;
}
/*!
* \brief Checks whether or not the system has the entity
* \return true If it is the case
*
* \param entity Pointer to the entity
*/
inline bool BaseSystem::HasEntity(const Entity* entity) const
{
if (!entity)
@ -50,14 +113,29 @@ namespace Ndk
return m_entityBits.UnboundedTest(entity->GetId());
}
/*!
* \brief Sets the rate of update for the system
*
* \param updatePerSecond Update rate, 0 means as much as possible
*/
inline void BaseSystem::SetUpdateRate(float updatePerSecond)
{
m_updateCounter = 0.f;
m_updateRate = (updatePerSecond > 0.f) ? 1.f / updatePerSecond : 0.f; // 0.f means no limit
}
/*!
* \brief Updates the system
*
* \param elapsedTime Delta time used for the update
*/
inline void BaseSystem::Update(float elapsedTime)
{
if (!IsEnabled())
return;
if (m_updateRate > 0.f)
{
m_updateCounter += elapsedTime;
@ -72,6 +150,10 @@ namespace Ndk
OnUpdate(elapsedTime);
}
/*!
* \brief Excludes some component from the system
*/
template<typename ComponentType>
void BaseSystem::Excludes()
{
@ -80,6 +162,10 @@ namespace Ndk
ExcludesComponent(GetComponentIndex<ComponentType>());
}
/*!
* \brief Excludes some components from the system
*/
template<typename ComponentType1, typename ComponentType2, typename... Rest>
void BaseSystem::Excludes()
{
@ -87,16 +173,31 @@ namespace Ndk
Excludes<ComponentType2, Rest...>();
}
/*!
* \brief Excludes some component from the system by index
*
* \param index Index of the component
*/
inline void BaseSystem::ExcludesComponent(ComponentIndex index)
{
m_excludedComponents.UnboundedSet(index);
}
/*!
* \brief Gets the next index for the system
* \return Next unique index for the system
*/
inline SystemIndex BaseSystem::GetNextIndex()
{
return s_nextIndex++;
}
/*!
* \brief Requires some component from the system
*/
template<typename ComponentType>
void BaseSystem::Requires()
{
@ -105,6 +206,10 @@ namespace Ndk
RequiresComponent(GetComponentIndex<ComponentType>());
}
/*!
* \brief Requires some components from the system
*/
template<typename ComponentType1, typename ComponentType2, typename... Rest>
void BaseSystem::Requires()
{
@ -112,11 +217,21 @@ namespace Ndk
Requires<ComponentType2, Rest...>();
}
/*!
* \brief Requires some component for the system by index
*
* \param index Index of the component
*/
inline void BaseSystem::RequiresComponent(ComponentIndex index)
{
m_requiredComponents.UnboundedSet(index);
}
/*!
* \brief Requires any component from the system
*/
template<typename ComponentType>
void BaseSystem::RequiresAny()
{
@ -125,6 +240,10 @@ namespace Ndk
RequiresAnyComponent(GetComponentIndex<ComponentType>());
}
/*!
* \brief Requires any components from the system
*/
template<typename ComponentType1, typename ComponentType2, typename... Rest>
void BaseSystem::RequiresAny()
{
@ -132,11 +251,25 @@ namespace Ndk
RequiresAny<ComponentType2, Rest...>();
}
/*!
* \brief Requires any component for the system by index
*
* \param index Index of the component
*/
inline void BaseSystem::RequiresAnyComponent(ComponentIndex index)
{
m_requiredAnyComponents.UnboundedSet(index);
}
/*!
* \brief Adds an entity to a system
*
* \param entity Pointer to the entity
*
* \remark Produces a NazaraAssert if entity is invalid
*/
inline void BaseSystem::AddEntity(Entity* entity)
{
NazaraAssert(entity, "Invalid entity");
@ -149,6 +282,14 @@ namespace Ndk
OnEntityAdded(entity);
}
/*!
* \brief Removes an entity to a system
*
* \param entity Pointer to the entity
*
* \remark Produces a NazaraAssert if entity is invalid
*/
inline void BaseSystem::RemoveEntity(Entity* entity)
{
NazaraAssert(entity, "Invalid entity");
@ -156,16 +297,25 @@ namespace Ndk
auto it = std::find(m_entities.begin(), m_entities.end(), *entity);
NazaraAssert(it != m_entities.end(), "Entity is not part of this system");
// Pour éviter de déplacer beaucoup de handles, on swap le dernier avec celui à supprimer
// To avoid moving a lot of handles, we swap and pop
std::swap(*it, m_entities.back());
m_entities.pop_back(); // On le sort du vector
m_entities.pop_back(); // We get it out of the vector
m_entityBits.Reset(entity->GetId());
entity->UnregisterSystem(m_systemIndex);
OnEntityRemoved(entity); // Et on appelle le callback
OnEntityRemoved(entity); // And we alert our callback
}
/*!
* \brief Validates an entity to a system
*
* \param entity Pointer to the entity
* \param justAdded Is the entity newly added
*
* \remark Produces a NazaraAssert if entity is invalid or if system does not hold this entity
*/
inline void BaseSystem::ValidateEntity(Entity* entity, bool justAdded)
{
NazaraAssert(entity, "Invalid entity");
@ -174,11 +324,20 @@ namespace Ndk
OnEntityValidation(entity, justAdded);
}
/*!
* \brief Sets the world on which the system operates
*/
inline void BaseSystem::SetWorld(World* world) noexcept
{
m_world = world;
}
/*!
* \brief Initializes the BaseSystem
* \return true
*/
inline bool BaseSystem::Initialize()
{
s_nextIndex = 0;
@ -186,6 +345,10 @@ namespace Ndk
return true;
}
/*!
* \brief Uninitializes the BaseSystem
*/
inline void BaseSystem::Uninitialize()
{
// Nothing to do

View File

@ -18,7 +18,7 @@ namespace Ndk
Component();
virtual ~Component();
BaseComponent* Clone() const override;
std::unique_ptr<BaseComponent> Clone() const override;
static ComponentIndex RegisterComponent(ComponentId id);

View File

@ -7,6 +7,18 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::Component<ComponentType>
* \brief NDK class that represents a component for an entity which interacts with a system
*
* \remark This class is meant to be derived as CRTP: "Component<Subtype>"
*/
/*!
* \brief Constructs a Component object by default
*/
template<typename ComponentType>
Component<ComponentType>::Component() :
BaseComponent(GetComponentIndex<ComponentType>())
@ -16,19 +28,30 @@ namespace Ndk
template<typename ComponentType>
Component<ComponentType>::~Component() = default;
/*!
* \brief Clones the component
* \return The clone newly created
*
* \remark The component to clone should be trivially copy constructible
*/
template<typename ComponentType>
BaseComponent* Component<ComponentType>::Clone() const
std::unique_ptr<BaseComponent> Component<ComponentType>::Clone() const
{
///FIXME: Pas encore supporté par GCC (4.9.2)
//static_assert(std::is_trivially_copy_constructible<ComponentType>::value, "ComponentType must be copy-constructible");
return new ComponentType(static_cast<const ComponentType&>(*this));
return std::make_unique<ComponentType>(static_cast<const ComponentType&>(*this));
}
/*!
* \brief Registers the component by assigning it an index
*/
template<typename ComponentType>
ComponentIndex Component<ComponentType>::RegisterComponent(ComponentId id)
{
// On utilise les lambda pour créer une fonction factory
//We use the lambda to create a factory function
auto factory = []() -> BaseComponent*
{
return nullptr; //< Temporary workaround to allow non-default-constructed components, will be updated for serialization
@ -38,11 +61,15 @@ namespace Ndk
return BaseComponent::RegisterComponent(id, factory);
}
/*!
* \brief Registers the component by assigning it an index based on the name
*/
template<typename ComponentType>
template<unsigned int N>
ComponentIndex Component<ComponentType>::RegisterComponent(const char (&name)[N])
{
// On récupère la chaîne de caractère sous la forme d'un nombre qui servira d'identifiant unique
// We convert the string to a number which will be used as unique identifier
ComponentId id = BuildComponentId(name);
return RegisterComponent(id);
}

View File

@ -8,6 +8,10 @@
namespace Ndk
{
/*!
* \brief Constructs an CameraComponent object by default
*/
inline CameraComponent::CameraComponent() :
m_projectionType(Nz::ProjectionType_Perspective),
m_targetRegion(0.f, 0.f, 1.f, 1.f),
@ -25,6 +29,12 @@ namespace Ndk
{
}
/*!
* \brief Constructs a CameraComponent object by copy semantic
*
* \param camera CameraComponent to copy
*/
inline CameraComponent::CameraComponent(const CameraComponent& camera) :
Component(camera),
AbstractViewer(camera),
@ -45,30 +55,51 @@ namespace Ndk
SetTarget(camera.m_target);
}
/*!
* \brief Ensures the frustum is up to date
*/
inline void CameraComponent::EnsureFrustumUpdate() const
{
if (!m_frustumUpdated)
UpdateFrustum();
}
/*!
* \brief Ensures the projection matrix is up to date
*/
inline void CameraComponent::EnsureProjectionMatrixUpdate() const
{
if (!m_projectionMatrixUpdated)
UpdateProjectionMatrix();
}
/*!
* \brief Ensures the view matrix is up to date
*/
inline void CameraComponent::EnsureViewMatrixUpdate() const
{
if (!m_viewMatrixUpdated)
UpdateViewMatrix();
}
/*!
* \brief Ensures the view port is up to date
*/
inline void CameraComponent::EnsureViewportUpdate() const
{
if (!m_viewportUpdated)
UpdateViewport();
}
/*!
* \brief Gets the aspect ratio of the camera
* \return Aspect ratio of the camera
*/
inline float CameraComponent::GetAspectRatio() const
{
EnsureViewportUpdate();
@ -76,11 +107,21 @@ namespace Ndk
return m_aspectRatio;
}
/*!
* \brief Gets the field of view of the camera
* \return Field of view of the camera
*/
inline float CameraComponent::GetFOV() const
{
return m_fov;
}
/*!
* \brief Gets the frutum of the camera
* \return A constant reference to the frustum of the camera
*/
inline const Nz::Frustumf& CameraComponent::GetFrustum() const
{
EnsureFrustumUpdate();
@ -88,11 +129,21 @@ namespace Ndk
return m_frustum;
}
/*!
* \brief Gets the layer of the camera
* \return Layer of the camera
*/
inline unsigned int CameraComponent::GetLayer() const
{
return m_layer;
}
/*!
* \brief Gets the projection matrix of the camera
* \return A constant reference to the projection matrix of the camera
*/
inline const Nz::Matrix4f& CameraComponent::GetProjectionMatrix() const
{
EnsureProjectionMatrixUpdate();
@ -100,26 +151,51 @@ namespace Ndk
return m_projectionMatrix;
}
/*!
* \brief Gets the projection type of the camera
* \return Projection type of the camera
*/
inline Nz::ProjectionType CameraComponent::GetProjectionType() const
{
return m_projectionType;
}
/*!
* \brief Gets the size of the camera
* \return Size of the camera
*/
inline const Nz::Vector2f & CameraComponent::GetSize() const
{
return m_size;
}
/*!
* \brief Gets the target of the camera
* \return A constant reference to the render target of the camera
*/
inline const Nz::RenderTarget* CameraComponent::GetTarget() const
{
return m_target;
}
/*!
* \brief Gets the target region of the camera
* \return A constant reference to the target region of the camera
*/
inline const Nz::Rectf& CameraComponent::GetTargetRegion() const
{
return m_targetRegion;
}
/*!
* \brief Gets the view matrix of the camera
* \return A constant reference to the view matrix of the camera
*/
inline const Nz::Matrix4f& CameraComponent::GetViewMatrix() const
{
EnsureViewMatrixUpdate();
@ -127,6 +203,11 @@ namespace Ndk
return m_viewMatrix;
}
/*!
* \brief Gets the view port of the camera
* \return A constant reference to the view port of the camera
*/
inline const Nz::Recti& CameraComponent::GetViewport() const
{
EnsureViewportUpdate();
@ -134,16 +215,34 @@ namespace Ndk
return m_viewport;
}
/*!
* \brief Gets the Z far distance of the camera
* \return Z far distance of the camera
*/
inline float CameraComponent::GetZFar() const
{
return m_zFar;
}
/*!
* \brief Gets the Z near distance of the camera
* \return Z near distance of the camera
*/
inline float CameraComponent::GetZNear() const
{
return m_zNear;
}
/*!
* \brief Sets the field of view of the camera
*
* \param fov Field of view of the camera
*
* \remark Produces a NazaraAssert if angle is zero
*/
inline void CameraComponent::SetFOV(float fov)
{
NazaraAssert(!Nz::NumberEquals(fov, 0.f), "FOV must be different from zero");
@ -152,6 +251,12 @@ namespace Ndk
InvalidateProjectionMatrix();
}
/*!
* \brief Sets the projection type of the camera
*
* \param projectionType Projection type of the camera
*/
inline void CameraComponent::SetProjectionType(Nz::ProjectionType projectionType)
{
m_projectionType = projectionType;
@ -159,6 +264,12 @@ namespace Ndk
InvalidateProjectionMatrix();
}
/*!
* \brief Sets the size of the camera
*
* \param size Size of the camera
*/
inline void CameraComponent::SetSize(const Nz::Vector2f& size)
{
m_size = size;
@ -166,11 +277,24 @@ namespace Ndk
InvalidateProjectionMatrix();
}
/*!
* \brief Sets the size of the camera
*
* \param width Size in X of the camera
* \param height Size in Y of the camera
*/
inline void CameraComponent::SetSize(float width, float height)
{
SetSize({width, height});
}
/*!
* \brief Sets the target of the camera
*
* \param renderTarget A constant reference to the render target of the camera
*/
inline void CameraComponent::SetTarget(const Nz::RenderTarget* renderTarget)
{
m_target = renderTarget;
@ -186,6 +310,12 @@ namespace Ndk
}
}
/*!
* \brief Sets the target region of the camera
*
* \param region A constant reference to the target region of the camera
*/
inline void CameraComponent::SetTargetRegion(const Nz::Rectf& region)
{
m_targetRegion = region;
@ -193,17 +323,31 @@ namespace Ndk
InvalidateViewport();
}
/*!
* \brief Sets the view port of the camera
*
* \param viewport A constant reference to the view port of the camera
*
* \remark Produces a NazaraAssert if the camera has no target
*/
inline void CameraComponent::SetViewport(const Nz::Recti& viewport)
{
NazaraAssert(m_target, "Component has no render target");
// On calcule la région nécessaire pour produire ce viewport avec la taille actuelle de la cible
float invWidth = 1.f/m_target->GetWidth();
float invHeight = 1.f/m_target->GetHeight();
// We compute the region necessary to make this view port with the actual size of the target
float invWidth = 1.f / m_target->GetWidth();
float invHeight = 1.f / m_target->GetHeight();
SetTargetRegion(Nz::Rectf(invWidth * viewport.x, invHeight * viewport.y, invWidth * viewport.width, invHeight * viewport.height));
}
/*!
* \brief Sets the Z far distance of the camera
*
* \param zFar Z far distance of the camera
*/
inline void CameraComponent::SetZFar(float zFar)
{
m_zFar = zFar;
@ -211,6 +355,14 @@ namespace Ndk
InvalidateProjectionMatrix();
}
/*!
* \brief Sets the Z near distance of the camera
*
* \param zNear Z near distance of the camera
*
* \remark Produces a NazaraAssert if zNear is zero
*/
inline void CameraComponent::SetZNear(float zNear)
{
NazaraAssert(!Nz::NumberEquals(zNear, 0.f), "zNear cannot be zero");
@ -219,23 +371,39 @@ namespace Ndk
InvalidateProjectionMatrix();
}
/*!
* \brief Invalidates the frustum
*/
inline void CameraComponent::InvalidateFrustum() const
{
m_frustumUpdated = false;
}
/*!
* \brief Invalidates the projection matrix
*/
inline void CameraComponent::InvalidateProjectionMatrix() const
{
m_frustumUpdated = false;
m_projectionMatrixUpdated = false;
}
/*!
* \brief Invalidates the view matrix
*/
inline void CameraComponent::InvalidateViewMatrix() const
{
m_frustumUpdated = false;
m_viewMatrixUpdated = false;
}
/*!
* \brief Invalidates the view port
*/
inline void CameraComponent::InvalidateViewport() const
{
m_frustumUpdated = false;

View File

@ -9,23 +9,47 @@
namespace Ndk
{
/*!
* \brief Constructs a CollisionComponent object with a geometry
*
* \param geom Reference to a geometry symbolizing the entity
*/
inline CollisionComponent::CollisionComponent(Nz::PhysGeomRef geom) :
m_geom(std::move(geom)),
m_bodyUpdated(false)
{
}
/*!
* \brief Constructs a CollisionComponent object by copy semantic
*
* \param collision CollisionComponent to copy
*/
inline CollisionComponent::CollisionComponent(const CollisionComponent& collision) :
m_geom(collision.m_geom),
m_bodyUpdated(false)
{
}
/*!
* \brief Gets the geometry representing the entity
* \return A constant reference to the physics geometry
*/
inline const Nz::PhysGeomRef& CollisionComponent::GetGeom() const
{
return m_geom;
}
/*!
* \brief Assigns the geometry to this component
* \return A reference to this
*
* \param geom Reference to a geometry symbolizing the entity
*/
inline CollisionComponent& CollisionComponent::operator=(Nz::PhysGeomRef geom)
{
SetGeom(geom);
@ -33,6 +57,11 @@ namespace Ndk
return *this;
}
/*!
* \brief Gets the static body used by the entity
* \return A pointer to the entity
*/
inline Nz::PhysObject* CollisionComponent::GetStaticBody()
{
return m_staticBody.get();

View File

@ -32,10 +32,11 @@ namespace Ndk
inline void AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const;
inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0);
inline void Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder = 0);
inline void Clear();
inline void Detach(const Nz::InstancedRenderableRef& renderable);
inline void Detach(const Nz::InstancedRenderable* renderable);
inline void EnsureBoundingVolumeUpdate() const;
inline void EnsureTransformMatrixUpdate() const;
@ -75,20 +76,31 @@ namespace Ndk
Renderable(Renderable&& renderable) noexcept :
data(std::move(renderable.data)),
renderable(std::move(renderable.renderable)),
dataUpdated(renderable.dataUpdated)
dataUpdated(renderable.dataUpdated),
renderableInvalidationSlot(std::move(renderable.renderableInvalidationSlot)),
renderableReleaseSlot(std::move(renderable.renderableReleaseSlot))
{
}
~Renderable()
{
// Disconnect release slot before releasing instanced renderable reference
renderableReleaseSlot.Disconnect();
}
Renderable& operator=(Renderable&& r) noexcept
{
data = std::move(r.data);
dataUpdated = r.dataUpdated;
renderable = std::move(r.renderable);
renderableInvalidationSlot = std::move(r.renderableInvalidationSlot);
renderableReleaseSlot = std::move(r.renderableReleaseSlot);
return *this;
}
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateData, renderableInvalidationSlot);
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableRelease, renderableReleaseSlot);
mutable Nz::InstancedRenderable::InstanceData data;
Nz::InstancedRenderableRef renderable;

View File

@ -2,11 +2,19 @@
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <NDK/Components/GraphicsComponent.hpp>
#include <NDK/World.hpp>
#include <NDK/Systems/RenderSystem.hpp>
#include <algorithm>
#include "GraphicsComponent.hpp"
namespace Ndk
{
/*!
* \brief Constructs a GraphicsComponent object by copy semantic
*
* \param graphicsComponent GraphicsComponent to copy
*/
inline GraphicsComponent::GraphicsComponent(const GraphicsComponent& graphicsComponent) :
Component(graphicsComponent),
HandledObject(graphicsComponent),
@ -20,14 +28,23 @@ namespace Ndk
Attach(r.renderable, r.data.renderOrder);
}
/*!
* \brief Adds the renderable elements to the render queue
*
* \param renderQueue Queue to be added
*/
inline void GraphicsComponent::AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const
{
EnsureTransformMatrixUpdate();
Ndk::RenderSystem& renderSystem = m_entity->GetWorld()->GetSystem<Ndk::RenderSystem>();
for (const Renderable& object : m_renderables)
{
if (!object.dataUpdated)
{
object.data.transformMatrix = Nz::Matrix4f::ConcatenateAffine(renderSystem.GetCoordinateSystemMatrix(), Nz::Matrix4f::ConcatenateAffine(object.data.localMatrix, m_transformMatrix));
object.renderable->UpdateData(&object.data);
object.dataUpdated = true;
}
@ -36,17 +53,35 @@ namespace Ndk
}
}
/*!
* \brief Attaches a renderable to the entity
*
* \param renderable Reference to a renderable element
* \param renderOrder Render order of the element
*/
inline void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable, int renderOrder)
{
return Attach(renderable, Nz::Matrix4f::Identity(), renderOrder);
}
inline void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder)
{
m_renderables.emplace_back(m_transformMatrix);
Renderable& r = m_renderables.back();
r.data.localMatrix = localMatrix;
r.data.renderOrder = renderOrder;
r.renderable = std::move(renderable);
r.renderableInvalidationSlot.Connect(r.renderable->OnInstancedRenderableInvalidateData, std::bind(&GraphicsComponent::InvalidateRenderableData, this, std::placeholders::_1, std::placeholders::_2, m_renderables.size()-1));
r.renderableInvalidationSlot.Connect(r.renderable->OnInstancedRenderableInvalidateData, std::bind(&GraphicsComponent::InvalidateRenderableData, this, std::placeholders::_1, std::placeholders::_2, m_renderables.size() - 1));
r.renderableReleaseSlot.Connect(r.renderable->OnInstancedRenderableRelease, this, &GraphicsComponent::Detach);
InvalidateBoundingVolume();
}
/*!
* \brief Clears every renderable elements
*/
inline void GraphicsComponent::Clear()
{
m_renderables.clear();
@ -54,7 +89,13 @@ namespace Ndk
InvalidateBoundingVolume();
}
inline void GraphicsComponent::Detach(const Nz::InstancedRenderableRef& renderable)
/*!
* \brief Detaches a renderable to the entity
*
* \param renderable Reference to a renderable element
*/
inline void GraphicsComponent::Detach(const Nz::InstancedRenderable* renderable)
{
for (auto it = m_renderables.begin(); it != m_renderables.end(); ++it)
{
@ -67,18 +108,34 @@ namespace Ndk
}
}
/*!
* \brief Ensures the bounding volume is up to date
*/
inline void GraphicsComponent::EnsureBoundingVolumeUpdate() const
{
if (!m_boundingVolumeUpdated)
UpdateBoundingVolume();
}
/*!
* \brief Ensures the transformation matrix is up to date
*/
inline void GraphicsComponent::EnsureTransformMatrixUpdate() const
{
if (!m_transformMatrixUpdated)
UpdateTransformMatrix();
}
/*!
* \brief Gets the set of renderable elements
*
* \param renderables Pointer to the list of renderables
*
* \remark Produces a NazaraAssert if renderables is invalid
*/
inline void GraphicsComponent::GetAttachedRenderables(RenderableList* renderables) const
{
NazaraAssert(renderables, "Invalid renderable list");
@ -88,11 +145,21 @@ namespace Ndk
renderables->push_back(r.renderable);
}
/*!
* \brief Gets the number of renderable elements attached to the entity
* \return Number of renderable elements
*/
inline std::size_t GraphicsComponent::GetAttachedRenderableCount() const
{
return m_renderables.size();
}
/*!
* \brief Gets the bouding volume of the entity
* \return A constant reference to the bounding volume
*/
inline const Nz::BoundingVolumef& GraphicsComponent::GetBoundingVolume() const
{
EnsureBoundingVolumeUpdate();
@ -100,17 +167,29 @@ namespace Ndk
return m_boundingVolume;
}
/*!
* \brief Invalidates the bounding volume
*/
inline void GraphicsComponent::InvalidateBoundingVolume()
{
m_boundingVolumeUpdated = false;
}
/*!
* \brief Invalidates every renderable elements
*/
inline void GraphicsComponent::InvalidateRenderables()
{
for (Renderable& r : m_renderables)
r.dataUpdated = false;
}
/*!
* \brief Invalidates the transformation matrix
*/
inline void GraphicsComponent::InvalidateTransformMatrix()
{
m_boundingVolumeUpdated = false;

View File

@ -4,6 +4,10 @@
namespace Ndk
{
/*!
* \brief Constructs an LightComponent object with a light type
*/
inline LightComponent::LightComponent(Nz::LightType lightType) :
Nz::Light(lightType)
{

View File

@ -4,16 +4,31 @@
namespace Ndk
{
/*!
* \brief Constructs an ListenerComponent object by default
*/
inline ListenerComponent::ListenerComponent() :
m_isActive(true)
{
}
/*!
* \brief Checks whether the listener is activated
* \param true If it is the case
*/
inline bool ListenerComponent::IsActive() const
{
return m_isActive;
}
/*!
* \brief Enables the listener
*
* \param active Should the listener be active
*/
inline void ListenerComponent::SetActive(bool active)
{
m_isActive = active;

View File

@ -7,6 +7,15 @@
namespace Ndk
{
/*!
* \brief Sets the parent node of the entity
*
* \param entity Pointer to the entity considered as parent
* \param keepDerived Should this component considered as a derived
*
* \remark Produces a NazaraAssert if entity has no component NodeComponent
*/
inline void NodeComponent::SetParent(Entity* entity, bool keepDerived)
{
if (entity)

View File

@ -6,21 +6,42 @@
namespace Ndk
{
/*!
* \brief Constructs an ParticleEmitterComponent object by default
*/
inline ParticleEmitterComponent::ParticleEmitterComponent() :
m_isActive(true)
{
}
/*!
* \brief Enables the emission of particles
*
* \param active Should the emitter be active
*/
inline void Ndk::ParticleEmitterComponent::Enable(bool active)
{
m_isActive = active;
}
/*!
* \brief Checks whether the emission of particles is activated
* \param true If it is the case
*/
inline bool ParticleEmitterComponent::IsActive() const
{
return m_isActive;
}
/*!
* \brief Sets the function use for setting up particles
*
* \param func Function to set up particles
*/
inline void Ndk::ParticleEmitterComponent::SetSetupFunc(SetupFunc func)
{
m_setupFunc = std::move(func);

View File

@ -17,7 +17,7 @@ namespace Ndk
using ParticleGroupComponentHandle = Nz::ObjectHandle<ParticleGroupComponent>;
class NDK_API ParticleGroupComponent : public Component<ParticleGroupComponent>, public Nz::ParticleGroup
class NDK_API ParticleGroupComponent : public Component<ParticleGroupComponent>, public Nz::ParticleGroup, public Nz::HandledObject<ParticleGroupComponent>
{
public:
inline ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleLayout layout);
@ -25,6 +25,12 @@ namespace Ndk
ParticleGroupComponent(const ParticleGroupComponent&) = default;
~ParticleGroupComponent() = default;
void AddEmitter(Entity* emitter);
using ParticleGroup::AddEmitter;
void RemoveEmitter(Entity* emitter);
using ParticleGroup::RemoveEmitter;
static ComponentIndex componentIndex;
};
}

View File

@ -1,17 +1,77 @@
#include "ParticleGroupComponent.hpp"
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <NDK/Components/ParticleGroupComponent.hpp>
#include <NDK/Components/ParticleEmitterComponent.hpp>
#include <Nazara/Core/Error.hpp>
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::ParticleGroupComponent
* \brief NDK class that represents the component for a group of particles
*/
/*!
* \brief Constructs a ParticleGroupComponent object with a maximal number of particles and a layout
*
* \param maxParticleCount Maximum number of particles to generate
* \param layout Enumeration for the layout of data information for the particles
*/
inline ParticleGroupComponent::ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleLayout layout) :
ParticleGroup(maxParticleCount, layout)
{
}
/*!
* \brief Constructs a ParticleGroupComponent object with a maximal number of particles and a particle declaration
*
* \param maxParticleCount Maximum number of particles to generate
* \param declaration Data information for the particles
*/
inline ParticleGroupComponent::ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleDeclarationConstRef declaration) :
ParticleGroup(maxParticleCount, std::move(declaration))
{
}
/*!
* \brief Adds an emitter to the particles
*
* \param emitter Emitter for the particles
*
* \remark Produces a NazaraAssert if emitter is invalid
* \remark Produces a NazaraAssert if entity has no component of type ParticleEmitterComponent
*/
inline void ParticleGroupComponent::AddEmitter(Entity* emitter)
{
NazaraAssert(emitter && emitter->IsValid(), "Invalid entity");
NazaraAssert(emitter->HasComponent<ParticleEmitterComponent>(), "Entity must have a NodeComponent");
auto& emitterComponent = emitter->GetComponent<ParticleEmitterComponent>();
ParticleGroup::AddEmitter(&emitterComponent);
}
/*!
* \brief Removes an emitter to the particles
*
* \param emitter Emitter for the particles to remove
*
* \remark Produces a NazaraAssert if emitter is invalid
* \remark Produces a NazaraAssert if entity has no component of type ParticleEmitterComponent
*/
inline void ParticleGroupComponent::RemoveEmitter(Entity* emitter)
{
NazaraAssert(emitter && emitter->IsValid(), "Invalid entity");
NazaraAssert(emitter->HasComponent<ParticleEmitterComponent>(), "Entity must have a NodeComponent");
auto& emitterComponent = emitter->GetComponent<ParticleEmitterComponent>();
ParticleGroup::RemoveEmitter(&emitterComponent);
}
}

View File

@ -6,12 +6,27 @@
namespace Ndk
{
/*!
* \brief Constructs a PhysicsComponent object by copy semantic
*
* \param physics PhysicsComponent to copy
*/
inline PhysicsComponent::PhysicsComponent(const PhysicsComponent& physics)
{
// Pas de copie de l'objet physique (étant donné que nous n'allons le créer qu'une fois attaché à une entité)
// No copy of physical object (because we only create it when attached to an entity)
NazaraUnused(physics);
}
/*!
* \brief Applies a force to the entity
*
* \param force Force to apply on the entity
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::AddForce(const Nz::Vector3f& force, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
@ -19,6 +34,16 @@ namespace Ndk
m_object->AddForce(force, coordSys);
}
/*!
* \brief Applies a force to the entity
*
* \param force Force to apply on the entity
* \param point Point where to apply the force
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::AddForce(const Nz::Vector3f& force, const Nz::Vector3f& point, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
@ -26,13 +51,30 @@ namespace Ndk
m_object->AddForce(force, point, coordSys);
}
/*!
* \brief Applies a torque to the entity
*
* \param torque Torque to apply on the entity
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::AddTorque(const Nz::Vector3f& torque, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->AddForce(torque, coordSys);
m_object->AddTorque(torque, coordSys);
}
/*!
* \brief Enables auto sleep of physics object
*
* \param autoSleep Should the physics of the object be disabled when too far from others
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::EnableAutoSleep(bool autoSleep)
{
NazaraAssert(m_object, "Invalid physics object");
@ -40,6 +82,13 @@ namespace Ndk
m_object->EnableAutoSleep(autoSleep);
}
/*!
* \brief Gets the AABB of the physics object
* \return AABB of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Boxf PhysicsComponent::GetAABB() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -47,6 +96,13 @@ namespace Ndk
return m_object->GetAABB();
}
/*!
* \brief Gets the angular velocity of the physics object
* \return Angular velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector3f PhysicsComponent::GetAngularVelocity() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -54,6 +110,13 @@ namespace Ndk
return m_object->GetAngularVelocity();
}
/*!
* \brief Gets the gravity factor of the physics object
* \return Gravity factor of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline float PhysicsComponent::GetGravityFactor() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -61,6 +124,13 @@ namespace Ndk
return m_object->GetGravityFactor();
}
/*!
* \brief Gets the mass of the physics object
* \return Mass of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline float PhysicsComponent::GetMass() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -68,6 +138,15 @@ namespace Ndk
return m_object->GetMass();
}
/*!
* \brief Gets the gravity center of the physics object
* \return Gravity center of the object
*
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector3f PhysicsComponent::GetMassCenter(Nz::CoordSys coordSys) const
{
NazaraAssert(m_object, "Invalid physics object");
@ -75,6 +154,13 @@ namespace Ndk
return m_object->GetMassCenter(coordSys);
}
/*!
* \brief Gets the matrix of the physics object
* \return Matrix of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline const Nz::Matrix4f& PhysicsComponent::GetMatrix() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -82,6 +168,13 @@ namespace Ndk
return m_object->GetMatrix();
}
/*!
* \brief Gets the position of the physics object
* \return Position of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector3f PhysicsComponent::GetPosition() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -89,6 +182,13 @@ namespace Ndk
return m_object->GetPosition();
}
/*!
* \brief Gets the rotation of the physics object
* \return Rotation of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Quaternionf PhysicsComponent::GetRotation() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -96,6 +196,13 @@ namespace Ndk
return m_object->GetRotation();
}
/*!
* \brief Gets the velocity of the physics object
* \return Velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector3f PhysicsComponent::GetVelocity() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -103,6 +210,13 @@ namespace Ndk
return m_object->GetVelocity();
}
/*!
* \brief Checks whether the auto sleep is enabled
* \return true If it is the case
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline bool PhysicsComponent::IsAutoSleepEnabled() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -110,6 +224,13 @@ namespace Ndk
return m_object->IsAutoSleepEnabled();
}
/*!
* \brief Checks whether the entity is currently sleeping
* \return true If it is the case
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline bool PhysicsComponent::IsSleeping() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -117,6 +238,14 @@ namespace Ndk
return m_object->IsSleeping();
}
/*!
* \brief Sets the angular velocity of the physics object
*
* \param angularVelocity Angular velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::SetAngularVelocity(const Nz::Vector3f& angularVelocity)
{
NazaraAssert(m_object, "Invalid physics object");
@ -124,6 +253,14 @@ namespace Ndk
m_object->SetAngularVelocity(angularVelocity);
}
/*!
* \brief Sets the gravity factor of the physics object
*
* \param gravityFactor Gravity factor of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::SetGravityFactor(float gravityFactor)
{
NazaraAssert(m_object, "Invalid physics object");
@ -131,6 +268,15 @@ namespace Ndk
m_object->SetGravityFactor(gravityFactor);
}
/*!
* \brief Sets the mass of the physics object
*
* \param mass Mass of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
* \remark Produces a NazaraAssert if the mass is negative
*/
inline void PhysicsComponent::SetMass(float mass)
{
NazaraAssert(m_object, "Invalid physics object");
@ -139,6 +285,14 @@ namespace Ndk
m_object->SetMass(mass);
}
/*!
* \brief Sets the gravity center of the physics object
*
* \param center Gravity center of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::SetMassCenter(const Nz::Vector3f& center)
{
NazaraAssert(m_object, "Invalid physics object");
@ -146,6 +300,14 @@ namespace Ndk
m_object->SetMassCenter(center);
}
/*!
* \brief Sets the position of the physics object
*
* \param position Position of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::SetPosition(const Nz::Vector3f& position)
{
NazaraAssert(m_object, "Invalid physics object");
@ -153,6 +315,14 @@ namespace Ndk
m_object->SetPosition(position);
}
/*!
* \brief Sets the rotation of the physics object
*
* \param rotation Rotation of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::SetRotation(const Nz::Quaternionf& rotation)
{
NazaraAssert(m_object, "Invalid physics object");
@ -160,6 +330,14 @@ namespace Ndk
m_object->SetRotation(rotation);
}
/*!
* \brief Sets the velocity of the physics object
*
* \param velocity Velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::SetVelocity(const Nz::Vector3f& velocity)
{
NazaraAssert(m_object, "Invalid physics object");
@ -167,6 +345,11 @@ namespace Ndk
m_object->SetVelocity(velocity);
}
/*!
* \brief Gets the underlying physics object
* \return A reference to the physics object
*/
inline Nz::PhysObject& PhysicsComponent::GetPhysObject()
{
return *m_object.get();

View File

@ -7,11 +7,30 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::VelocityComponent
* \brief NDK class that represents the component for velocity
*/
/*!
* \brief Constructs a VelocityComponent object with a velocity
*
* \param velocity Linear velocity
*/
inline VelocityComponent::VelocityComponent(const Nz::Vector3f& velocity) :
linearVelocity(velocity)
{
}
/*!
* \brief Assigns the velocity to this component
* \return A reference to this
*
* \param vel Linear velocity
*/
inline VelocityComponent& VelocityComponent::operator=(const Nz::Vector3f& vel)
{
linearVelocity = vel;

View File

@ -7,41 +7,81 @@
namespace Ndk
{
/*!
* \brief Gets the character size
* \return Height of the character
*/
inline unsigned int Console::GetCharacterSize() const
{
return m_characterSize;
}
/*!
* \brief Gets the entity representing the history of the console
* \return History of the console
*/
inline const EntityHandle& Console::GetHistory() const
{
return m_history;
}
/*!
* \brief Gets the entity representing the background of the console's history
* \return Background history of the console
*/
inline const EntityHandle& Console::GetHistoryBackground() const
{
return m_historyBackground;
}
/*!
* \brief Gets the entity representing the input of the console
* \return Input of the console
*/
inline const EntityHandle& Console::GetInput() const
{
return m_input;
}
/*!
* \brief Gets the entity representing the background of the console's input
* \return Background input of the console
*/
inline const EntityHandle& Console::GetInputBackground() const
{
return m_inputBackground;
}
/*!
* \brief Gets the size of the console
* \return Size (Width, Height) of the console
*/
inline const Nz::Vector2f& Console::GetSize() const
{
return m_size;
}
/*!
* \brief Gets the font used by the console
* \return A reference to the font currenty used
*/
inline const Nz::FontRef& Console::GetTextFont() const
{
return m_defaultFont;
}
/*!
* \brief Checks whether the console is visible
* \return true If it is the case
*/
inline bool Console::IsVisible() const
{
return m_opened;

View File

@ -34,10 +34,14 @@ namespace Ndk
BaseComponent& AddComponent(std::unique_ptr<BaseComponent>&& component);
template<typename ComponentType, typename... Args> ComponentType& AddComponent(Args&&... args);
inline void Enable(bool enable);
const EntityHandle& Clone() const;
inline void Enable(bool enable = true);
inline BaseComponent& GetComponent(ComponentIndex index);
template<typename ComponentType> ComponentType& GetComponent();
inline const BaseComponent& GetComponent(ComponentIndex index) const;
template<typename ComponentType> const ComponentType& GetComponent() const;
inline const Nz::Bitset<>& GetComponentBits() const;
inline EntityId GetId() const;
inline const Nz::Bitset<>& GetSystemBits() const;
@ -52,8 +56,8 @@ namespace Ndk
inline bool IsEnabled() const;
inline bool IsValid() const;
void RemoveAllComponents();
void RemoveComponent(ComponentIndex index);
inline void RemoveAllComponents();
inline void RemoveComponent(ComponentIndex index);
template<typename ComponentType> void RemoveComponent();
inline Nz::String ToString() const;
@ -67,6 +71,10 @@ namespace Ndk
void Create();
void Destroy();
void DestroyComponent(ComponentIndex index);
inline Nz::Bitset<>& GetRemovedComponentBits();
inline void RegisterSystem(SystemIndex index);
inline void SetWorld(World* world) noexcept;
@ -75,6 +83,7 @@ namespace Ndk
std::vector<std::unique_ptr<BaseComponent>> m_components;
Nz::Bitset<> m_componentBits;
Nz::Bitset<> m_removedComponentBits;
Nz::Bitset<> m_systemBits;
EntityId m_id;
World* m_world;

View File

@ -2,6 +2,7 @@
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <NDK/Entity.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <algorithm>
@ -10,16 +11,29 @@
namespace Ndk
{
/*!
* \brief Adds a component to the entity
* \return A reference to the newly added component
*
* \param args Arguments to create in place the component to add to the entity
*/
template<typename ComponentType, typename... Args>
ComponentType& Entity::AddComponent(Args&&... args)
{
static_assert(std::is_base_of<BaseComponent, ComponentType>::value, "ComponentType is not a component");
// Allocation et affectation du component
// Affectation and return of the component
std::unique_ptr<ComponentType> ptr(new ComponentType(std::forward<Args>(args)...));
return static_cast<ComponentType&>(AddComponent(std::move(ptr)));
}
/*!
* \brief Enables the entity
*
* \param enable Should the entity be enabled
*/
inline void Entity::Enable(bool enable)
{
if (m_enabled != enable)
@ -29,9 +43,17 @@ namespace Ndk
}
}
/*!
* \brief Gets a component in the entity by index
* \return A reference to the component
*
* \param index Index of the component
*
* \remark Produces a NazaraAssert if component is not available in this entity or is invalid
*/
inline BaseComponent& Entity::GetComponent(ComponentIndex index)
{
///DOC: Le component doit être présent
NazaraAssert(HasComponent(index), "This component is not part of the entity");
BaseComponent* component = m_components[index].get();
@ -40,41 +62,114 @@ namespace Ndk
return *component;
}
/*!
* \brief Gets a component in the entity by type
* \return A reference to the component
*
* \remark Produces a NazaraAssert if component is not available in this entity
*/
template<typename ComponentType>
ComponentType& Entity::GetComponent()
{
///DOC: Le component doit être présent
static_assert(std::is_base_of<BaseComponent, ComponentType>::value, "ComponentType is not a component");
ComponentIndex index = GetComponentIndex<ComponentType>();
return static_cast<ComponentType&>(GetComponent(index));
}
/*!
* \brief Gets a component in the entity by index
* \return A constant reference to the component
*
* \param index Index of the component
*
* \remark Produces a NazaraAssert if component is not available in this entity or is invalid
*/
inline const BaseComponent& Entity::GetComponent(ComponentIndex index) const
{
NazaraAssert(HasComponent(index), "This component is not part of the entity");
BaseComponent* component = m_components[index].get();
NazaraAssert(component, "Invalid component pointer");
return *component;
}
/*!
* \brief Gets a component in the entity by type
* \return A constant reference to the component
*
* \remark Produces a NazaraAssert if component is not available in this entity
*/
template<typename ComponentType>
const ComponentType& Entity::GetComponent() const
{
static_assert(std::is_base_of<BaseComponent, ComponentType>::value, "ComponentType is not a component");
ComponentIndex index = GetComponentIndex<ComponentType>();
return static_cast<ComponentType&>(GetComponent(index));
}
/*!
* \brief Gets the bits representing the components in the entiy
* \return A constant reference to the set of component's bits
*/
inline const Nz::Bitset<>& Entity::GetComponentBits() const
{
return m_componentBits;
}
/*!
* \brief Gets the identifier of the entity
* \return Identifier of the entity
*/
inline EntityId Entity::GetId() const
{
return m_id;
}
/*!
* \brief Gets the bits representing the systems in the entiy
* \return A constant reference to the set of system's bits
*/
inline const Nz::Bitset<>& Entity::GetSystemBits() const
{
return m_systemBits;
}
/*!
* \brief Gets the world in which the entity is
* \return Pointer to the world
*/
inline World* Entity::GetWorld() const
{
return m_world;
}
/*!
* \brief Checks whether or not a component is present in the entity by index
* \return true If it is the case
*
* \param index Index of the component
*/
inline bool Entity::HasComponent(ComponentIndex index) const
{
return m_componentBits.UnboundedTest(index);
}
/*!
* \brief Checks whether or not a component is present in the entity by type
* \return true If it is the case
*/
template<typename ComponentType>
bool Entity::HasComponent() const
{
@ -84,16 +179,54 @@ namespace Ndk
return HasComponent(index);
}
/*!
* \brief Checks whether or not the entity is enabled
* \return true If it is the case
*/
inline bool Entity::IsEnabled() const
{
return m_enabled;
}
/*!
* \brief Checks whether or not the entity is valid
* \return true If it is the case
*/
inline bool Entity::IsValid() const
{
return m_valid;
}
/*!
* \brief Removes every components
*/
inline void Entity::RemoveAllComponents()
{
m_removedComponentBits = m_componentBits;
Invalidate();
}
/*!
* \brief Removes a component in the entity by index
*
* \param index Index of the component
*/
inline void Entity::RemoveComponent(ComponentIndex index)
{
m_removedComponentBits.UnboundedSet(index);
Invalidate();
}
/*!
* \brief Removes a component in the entity by type
*/
template<typename ComponentType>
void Entity::RemoveComponent()
{
@ -103,17 +236,46 @@ namespace Ndk
RemoveComponent(index);
}
/*!
* \brief Gives a string representation
* \return A string representation of the object: "Entity(GetId())"
*/
inline Nz::String Entity::ToString() const
{
Nz::StringStream ss;
return ss << "Entity(" << GetId() << ')';
}
/*!
* \brief Gets the bits representing the removed components in the entiy
* \return A constant reference to the set of remove component's bits
*/
inline Nz::Bitset<>& Entity::GetRemovedComponentBits()
{
return m_removedComponentBits;
}
/*!
* \brief Registers a system for the entity
*
* \param index Index of the system
*/
inline void Entity::RegisterSystem(SystemIndex index)
{
m_systemBits.UnboundedSet(index);
}
/*!
* \brief Sets the world of the entity
*
* \param world World in which the entity will be
*
* \remark Produces a NazaraAssert if world is invalid
*/
inline void Entity::SetWorld(World* world) noexcept
{
NazaraAssert(world, "An entity must be attached to a world at any time");
@ -121,6 +283,12 @@ namespace Ndk
m_world = world;
}
/*!
* \brief Unregisters a system for the entity
*
* \param index Index of the system
*/
inline void Entity::UnregisterSystem(SystemIndex index)
{
m_systemBits.UnboundedReset(index);
@ -132,10 +300,16 @@ namespace std
template<>
struct hash<Ndk::EntityHandle>
{
/*!
* \brief Specialisation of std to hash
* \return Result of the hash
*
* \param handle Entity to hash
*/
size_t operator()(const Ndk::EntityHandle& handle) const
{
// Hasher le pointeur fonctionnerait jusqu'à ce que l'entité soit mise à jour et déplacée
// pour cette raison, nous devons hasher l'ID de l'entité (qui reste constante)
// Hash the pointer will work until the entity is updated and moved
// so, we have to hash the ID of the entity (which is constant)
Ndk::EntityId id = (handle.IsValid()) ? handle->GetId() : std::numeric_limits<Ndk::EntityId>::max();
return hash<Ndk::EntityId>()(id);

View File

@ -7,22 +7,54 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::EntityList
* \brief NDK class that represents a set of entities to help performing batch operations
*/
/*!
* \brief Clears the set from every entities
*/
inline void EntityList::Clear()
{
m_entities.clear();
m_entityBits.Clear();
}
/*!
* \brief Checks whether or not the set contains the entity
* \return true If it is the case
*
* \param entity Pointer to the entity
*/
inline bool EntityList::Has(const Entity* entity)
{
return entity && entity->IsValid() && Has(entity->GetId());
}
/*!
* \brief Checks whether or not the set contains the entity by id
* \return true If it is the case
*
* \param id Identifier of the entity
*/
inline bool EntityList::Has(EntityId entity)
{
return m_entityBits.UnboundedTest(entity);
}
/*!
* \brief Inserts the entity into the set
*
* \param entity Pointer to the entity
*
* \remark If entity is already contained, no action is performed
*/
inline void EntityList::Insert(Entity* entity)
{
if (!Has(entity))
@ -32,6 +64,14 @@ namespace Ndk
}
}
/*!
* \brief Removes the entity from the set
*
* \param entity Pointer to the entity
*
* \remark If entity is not contained, no action is performed
*/
inline void EntityList::Remove(Entity* entity)
{
if (Has(entity))
@ -40,7 +80,7 @@ namespace Ndk
NazaraAssert(it != m_entities.end(), "Entity should be part of the vector");
std::swap(*it, m_entities.back());
m_entities.pop_back(); // On le sort du vector
m_entities.pop_back(); // We get it out of the vector
m_entityBits.UnboundedSet(entity->GetId(), false);
}
}

View File

@ -8,17 +8,41 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::EntityOwner
* \brief NDK class that represents the owner of the entity and so its lifetime
*/
/*!
* \brief Constructs a EntityOwner object
*
* \param entity Entity to own
*/
inline EntityOwner::EntityOwner(Entity* entity) :
EntityOwner()
{
Reset(entity);
}
/*!
* \brief Destructs the object and calls Reset
*
* \see Reset
*/
inline EntityOwner::~EntityOwner()
{
Reset(nullptr);
}
/*!
* \brief Resets the ownership of the entity, previous is killed
*
* \param entity Entity to own
*/
inline void EntityOwner::Reset(Entity* entity)
{
if (m_object)
@ -27,12 +51,24 @@ namespace Ndk
EntityHandle::Reset(entity);
}
/*!
* \brief Resets the ownership of the entity by move semantic
*
* \param handle EntityOwner to move into this
*/
inline void EntityOwner::Reset(EntityOwner&& handle)
{
Reset(handle.GetObject());
handle.m_object = nullptr;
}
/*!
* \brief Resets the ownership of the entity to the affected one
*
* \param entity Entity to own
*/
inline EntityOwner& EntityOwner::operator=(Entity* entity)
{
Reset(entity);

View File

@ -26,6 +26,11 @@
namespace Ndk
{
/*!
* \brief Gets the internal binding for Lua
* \return A pointer to the binding
*/
inline LuaBinding* LuaAPI::GetBinding()
{
return s_binding;
@ -34,6 +39,15 @@ namespace Ndk
namespace Nz
{
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param color Resulting color
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Color* color, TypeTag<Color>)
{
instance.CheckType(index, Nz::LuaType_Table);
@ -46,6 +60,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param angles Resulting euler angles
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, EulerAnglesd* angles, TypeTag<EulerAnglesd>)
{
switch (instance.GetType(index))
@ -66,6 +89,15 @@ namespace Nz
}
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param angles Resulting euler angles
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, EulerAnglesf* angles, TypeTag<EulerAnglesf>)
{
EulerAnglesd anglesDouble;
@ -75,6 +107,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param fontRef Resulting reference to a font
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, FontRef* fontRef, TypeTag<FontRef>)
{
*fontRef = *static_cast<FontRef*>(instance.CheckUserdata(index, "Font"));
@ -82,6 +123,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param params Resulting parameters for a font
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, FontParams* params, TypeTag<FontParams>)
{
NazaraUnused(params);
@ -93,6 +143,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param params Resulting parameters for a mesh
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MeshParams* params, TypeTag<MeshParams>)
{
instance.CheckType(index, Nz::LuaType_Table);
@ -106,6 +165,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param rect Resulting rectangle
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Rectd* rect, TypeTag<Rectd>)
{
instance.CheckType(index, LuaType_Table);
@ -118,6 +186,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param rect Resulting rectangle
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Rectf* rect, TypeTag<Rectf>)
{
Rectd rectDouble;
@ -127,6 +204,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param rect Resulting rectangle
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Rectui* rect, TypeTag<Rectui>)
{
Rectd rectDouble;
@ -136,6 +222,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param quat Resulting quaternion
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Quaterniond* quat, TypeTag<Quaterniond>)
{
switch (instance.GetType(index))
@ -156,6 +251,15 @@ namespace Nz
}
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param quat Resulting quaternion
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Quaternionf* quat, TypeTag<Quaternionf>)
{
Quaterniond quatDouble;
@ -165,6 +269,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param address Resulting IP address
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, IpAddress* address, TypeTag<IpAddress>)
{
switch (instance.GetType(index))
@ -179,6 +292,15 @@ namespace Nz
}
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param vec Resulting vector2D
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2d* vec, TypeTag<Vector2d>)
{
switch (instance.GetType(index))
@ -200,6 +322,15 @@ namespace Nz
}
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param vec Resulting vector2D
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2f* vec, TypeTag<Vector2f>)
{
Vector2d vecDouble;
@ -209,6 +340,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param vec Resulting vector2D
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2ui* vec, TypeTag<Vector2ui>)
{
Vector2d vecDouble;
@ -218,6 +358,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param vec Resulting vector3D
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3d* vec, TypeTag<Vector3d>)
{
switch (instance.GetType(index))
@ -239,6 +388,15 @@ namespace Nz
}
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param vec Resulting vector3D
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3f* vec, TypeTag<Vector3f>)
{
Vector3d vecDouble;
@ -248,6 +406,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param vec Resulting vector3D
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3ui* vec, TypeTag<Vector3ui>)
{
Vector3d vecDouble;
@ -257,6 +424,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param handle Resulting entity
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::EntityHandle* handle, TypeTag<Ndk::EntityHandle>)
{
*handle = *static_cast<Ndk::EntityHandle*>(instance.CheckUserdata(index, "Entity"));
@ -264,6 +440,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param handle Resulting world
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::WorldHandle* handle, TypeTag<Ndk::WorldHandle>)
{
*handle = *static_cast<Ndk::WorldHandle*>(instance.CheckUserdata(index, "World"));
@ -272,6 +457,16 @@ namespace Nz
}
#ifndef NDK_SERVER
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param renderable Resulting reference to a instanced renderable
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, InstancedRenderableRef* renderable, TypeTag<InstancedRenderableRef>)
{
if (instance.IsOfType(index, "InstancedRenderable"))
@ -281,6 +476,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param params Resulting parameters for a material
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MaterialParams* params, TypeTag<MaterialParams>)
{
instance.CheckType(index, Nz::LuaType_Table);
@ -295,6 +499,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param params Resulting parameters for a model
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, ModelParameters* params, TypeTag<ModelParameters>)
{
instance.CheckType(index, Nz::LuaType_Table);
@ -307,6 +520,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param params Resulting parameters for a music
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MusicParams* params, TypeTag<MusicParams>)
{
instance.CheckType(index, Nz::LuaType_Table);
@ -316,6 +538,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param params Resulting parameters for a sound buffer
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, SoundBufferParams* params, TypeTag<SoundBufferParams>)
{
instance.CheckType(index, Nz::LuaType_Table);
@ -324,9 +555,16 @@ namespace Nz
return 1;
}
#endif
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting euler angles
*/
inline int LuaImplReplyVal(const LuaInstance& instance, EulerAnglesd&& val, TypeTag<EulerAnglesd>)
{
@ -334,18 +572,42 @@ namespace Nz
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting euler angles
*/
inline int LuaImplReplyVal(const LuaInstance& instance, EulerAnglesf&& val, TypeTag<EulerAnglesf>)
{
instance.PushInstance<EulerAnglesd>("EulerAngles", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting reference to a font
*/
inline int LuaImplReplyVal(const LuaInstance& instance, FontRef&& val, TypeTag<FontRef>)
{
instance.PushInstance<FontRef>("Font", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting size information for a font
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Font::SizeInfo&& val, TypeTag<Font::SizeInfo>)
{
instance.PushTable();
@ -357,114 +619,266 @@ namespace Nz
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting quaternion
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Quaterniond&& val, TypeTag<Quaterniond>)
{
instance.PushInstance<Quaterniond>("Quaternion", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting quaternion
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Quaternionf&& val, TypeTag<Quaternionf>)
{
instance.PushInstance<Quaterniond>("Quaternion", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting IP address
*/
inline int LuaImplReplyVal(const LuaInstance& instance, IpAddress&& val, TypeTag<IpAddress>)
{
instance.PushInstance<IpAddress>("IpAddress", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting rectangle
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Rectd&& val, TypeTag<Rectf>)
{
instance.PushInstance<Rectd>("Rect", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting rectangle
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Rectf&& val, TypeTag<Rectf>)
{
instance.PushInstance<Rectd>("Rect", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting rectangle
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Rectui&& val, TypeTag<Rectui>)
{
instance.PushInstance<Rectd>("Rect", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting vector2D
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Vector2d&& val, TypeTag<Vector2d>)
{
instance.PushInstance<Vector2d>("Vector2", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting vector2D
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Vector2f&& val, TypeTag<Vector2f>)
{
instance.PushInstance<Vector2d>("Vector2", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting vector2D
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Vector2ui&& val, TypeTag<Vector2ui>)
{
instance.PushInstance<Vector2d>("Vector2", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting vector3D
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Vector3d&& val, TypeTag<Vector3d>)
{
instance.PushInstance<Vector3d>("Vector3", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting vector3D
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Vector3f&& val, TypeTag<Vector3f>)
{
instance.PushInstance<Vector3d>("Vector3", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting vector3D
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Vector3ui&& val, TypeTag<Vector3ui>)
{
instance.PushInstance<Vector3d>("Vector3", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param ptr Resulting entity
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::Entity* ptr, TypeTag<Ndk::Entity*>)
{
instance.PushInstance<Ndk::EntityHandle>("Entity", ptr);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param ptr Resulting application
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::Application* ptr, TypeTag<Ndk::Application*>)
{
instance.PushInstance<Ndk::Application*>("Application", ptr);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param handle Resulting entity
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::EntityHandle&& handle, TypeTag<Ndk::EntityHandle>)
{
instance.PushInstance<Ndk::EntityHandle>("Entity", handle);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param handle Resulting node component
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::NodeComponentHandle&& handle, TypeTag<Ndk::NodeComponentHandle>)
{
instance.PushInstance<Ndk::NodeComponentHandle>("NodeComponent", handle);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param handle Resulting velocity component
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::VelocityComponentHandle&& handle, TypeTag<Ndk::VelocityComponentHandle>)
{
instance.PushInstance<Ndk::VelocityComponentHandle>("VelocityComponent", handle);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param ptr Resulting world
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::World* ptr, TypeTag<Ndk::World*>)
{
instance.PushInstance<Ndk::WorldHandle>("World", ptr);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param ptr Resulting world
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::WorldHandle&& handle, TypeTag<Ndk::WorldHandle>)
{
instance.PushInstance<Ndk::WorldHandle>("World", handle);
@ -472,22 +886,49 @@ namespace Nz
}
#ifndef NDK_SERVER
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param handle Resulting console
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::ConsoleHandle&& handle, TypeTag<Ndk::ConsoleHandle>)
{
instance.PushInstance<Ndk::ConsoleHandle>("Console", handle);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param handle Resulting graphics component
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::GraphicsComponentHandle&& handle, TypeTag<Ndk::GraphicsComponentHandle>)
{
instance.PushInstance<Ndk::GraphicsComponentHandle>("GraphicsComponent", handle);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting sound buffer
*/
inline int LuaImplReplyVal(const LuaInstance& instance, const SoundBuffer* val, TypeTag<const SoundBuffer*>)
{
instance.PushInstance<SoundBufferConstRef>("SoundBuffer", val);
return 1;
}
#endif
}

View File

@ -6,6 +6,14 @@
namespace Ndk
{
/*!
* \brief Binds a component to a name
*
* \param name Name used to retrieve the component
*
* \remark Produces a NazaraAssert if name is empty
*/
template<typename T>
void LuaBinding::BindComponent(const Nz::String& name)
{
@ -24,6 +32,16 @@ namespace Ndk
m_componentBindingByName[name] = T::componentIndex;
}
/*!
* \brief Adds a component to an entity
* \return 1 in case of success
*
* \param instance Lua instance that will interact with the component
* \param handle Entity which component will be added to
*
* \remark T must be a subtype of BaseComponent
*/
template<typename T>
int AddComponentOfType(Nz::LuaInstance& lua, EntityHandle& handle)
{
@ -34,6 +52,16 @@ namespace Ndk
return 1;
}
/*!
* \brief Pushes a component
* \return 1 in case of success
*
* \param instance Lua instance that will interact with the component
* \param component Component that will be pushed
*
* \remark T must be a subtype of BaseComponent
*/
template<typename T>
int PushComponentOfType(Nz::LuaInstance& lua, BaseComponent& component)
{

View File

@ -27,11 +27,11 @@
#include <Nazara/Prerequesites.hpp>
// Version du SDK
// Version of SDK
#define NDK_VERSION_MAJOR 0
#define NDK_VERSION_MINOR 1
// Importation/Exportation de l'API
// Importation/Exportation of the API
#if defined(NAZARA_PLATFORM_WINDOWS)
#if !defined(NDK_STATIC)
#ifdef NDK_BUILD
@ -49,7 +49,7 @@
#define NDK_API
#endif
#else
// À commenter pour tenter quand même une compilation
// To comment to force a compilation
#error This operating system is not fully supported by the Nazara Development Kit
#define NDK_API

View File

@ -4,6 +4,11 @@
namespace Ndk
{
/*!
* \brief Checks whether the module is initialized
* \return true if module is initialized
*/
inline bool Sdk::IsInitialized()
{
return s_referenceCounter != 0;

View File

@ -8,6 +8,21 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::StateMachine
* \brief NDK class that represents a state machine, to represent the multiple states of your program
*/
/*!
* \brief Constructs a StateMachine object with an original state
*
* \param originalState State which is the entry point of the application
*
* \remark Calls "Enter" on the state
* \remark Produces a NazaraAssert if nullptr is given
*/
inline StateMachine::StateMachine(std::shared_ptr<State> originalState) :
m_currentState(std::move(originalState))
{
@ -15,22 +30,45 @@ namespace Ndk
m_currentState->Enter(*this);
}
/*!
* \brief Destructs the object
*
* \remark Calls "Leave" on the state
*/
inline StateMachine::~StateMachine()
{
m_currentState->Leave(*this);
}
/*!
* \brief Changes the current state of the machine
*
* \param state Next state to represent
*/
inline void StateMachine::ChangeState(std::shared_ptr<State> state)
{
m_nextState = std::move(state);
}
/*!
* \brief Gets the current state of the machine
* \return A constant reference to the state
*/
inline const std::shared_ptr<State>& StateMachine::GetCurrentState() const
{
return m_currentState;
}
/*!
* \brief Updates the state
* \return True if update is successful
*
* \param elapsedTime Delta time used for the update
*/
inline bool StateMachine::Update(float elapsedTime)
{
if (m_nextState)

View File

@ -11,7 +11,7 @@
namespace Ndk
{
template<typename ComponentType>
template<typename SystemType>
class System : public BaseSystem
{
public:
@ -20,7 +20,7 @@ namespace Ndk
System(System&&) = default;
virtual ~System();
BaseSystem* Clone() const override;
std::unique_ptr<BaseSystem> Clone() const override;
System& operator=(const System&) = delete;
System& operator=(System&&) = default;

View File

@ -7,6 +7,18 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::System<SystemType>
* \brief NDK class that represents a system which interacts on a world
*
* \remark This class is meant to be derived as CRTP: "System<Subtype>"
*/
/*!
* \brief Constructs a System object by default
*/
template<typename SystemType>
System<SystemType>::System() :
BaseSystem(GetSystemIndex<SystemType>())
@ -16,15 +28,26 @@ namespace Ndk
template<typename SystemType>
System<SystemType>::~System() = default;
/*!
* \brief Clones the system
* \return The clone newly created
*
* \remark The system to clone should be trivially copy constructible
*/
template<typename SystemType>
BaseSystem* System<SystemType>::Clone() const
std::unique_ptr<BaseSystem> System<SystemType>::Clone() const
{
///FIXME: Pas encore supporté par GCC (4.9.2)
///FIXME: Not fully supported in GCC (4.9.2)
//static_assert(std::is_trivially_copy_constructible<SystemType>::value, "SystemType should be copy-constructible");
return new SystemType(static_cast<const SystemType&>(*this));
return std::make_unique<SystemType>(static_cast<const SystemType&>(*this));
}
/*!
* \brief Registers the system by assigning it an index
*/
template<typename SystemType>
SystemIndex System<SystemType>::RegisterSystem()
{

View File

@ -4,6 +4,7 @@
#pragma once
#ifndef NDK_SERVER
#ifndef NDK_SYSTEMS_PARTICLESYSTEM_HPP
#define NDK_SYSTEMS_PARTICLESYSTEM_HPP
@ -27,3 +28,4 @@ namespace Ndk
#include <NDK/Systems/ParticleSystem.inl>
#endif // NDK_SYSTEMS_PARTICLESYSTEM_HPP
#endif // NDK_SERVER

View File

@ -4,11 +4,21 @@
namespace Ndk
{
/*!
* \brief Gets the physical world
* \return A reference to the physical world
*/
inline Nz::PhysWorld& PhysicsSystem::GetWorld()
{
return m_world;
}
/*!
* \brief Gets the physical world
* \return A constant reference to the physical world
*/
inline const Nz::PhysWorld& PhysicsSystem::GetWorld() const
{
return m_world;

View File

@ -28,8 +28,8 @@ namespace Ndk
inline RenderSystem(const RenderSystem& renderSystem);
~RenderSystem() = default;
template<typename T> void ChangeRenderTechnique();
inline void ChangeRenderTechnique(std::unique_ptr<Nz::AbstractRenderTechnique>&& renderTechnique);
template<typename T> T& ChangeRenderTechnique();
inline Nz::AbstractRenderTechnique& ChangeRenderTechnique(std::unique_ptr<Nz::AbstractRenderTechnique>&& renderTechnique);
inline const Nz::BackgroundRef& GetDefaultBackground() const;
inline const Nz::Matrix4f& GetCoordinateSystemMatrix() const;

View File

@ -4,57 +4,119 @@
namespace Ndk
{
/*!
* \brief Constructs a RenderSystem object by copy semantic
*
* \param renderSystem RenderSystem to copy
*/
inline RenderSystem::RenderSystem(const RenderSystem& renderSystem) :
System(renderSystem)
{
}
/*!
* \brief Changes the render technique used for the system
* \return A reference to the render technique type
*/
template<typename T>
inline void RenderSystem::ChangeRenderTechnique()
inline T& RenderSystem::ChangeRenderTechnique()
{
ChangeRenderTechnique(std::make_unique<T>());
static_assert(std::is_base_of<Nz::AbstractRenderTechnique, T>::value, "RenderTechnique is not a subtype of AbstractRenderTechnique");
return static_cast<T&>(ChangeRenderTechnique(std::make_unique<T>()));
}
inline void RenderSystem::ChangeRenderTechnique(std::unique_ptr<Nz::AbstractRenderTechnique>&& renderTechnique)
/*!
* \brief Changes the render technique used for the system
* \return A reference to the abstract render technique
*
* \param renderTechnique Render technique to use
*/
inline Nz::AbstractRenderTechnique& RenderSystem::ChangeRenderTechnique(std::unique_ptr<Nz::AbstractRenderTechnique>&& renderTechnique)
{
m_renderTechnique = std::move(renderTechnique);
return *m_renderTechnique.get();
}
/*!
* \brief Gets the background used for rendering
* \return A reference to the background
*/
inline const Nz::BackgroundRef& RenderSystem::GetDefaultBackground() const
{
return m_background;
}
/*!
* \brief Gets the coordinates matrix used for rendering
* \return A constant reference to the matrix of coordinates
*/
inline const Nz::Matrix4f& RenderSystem::GetCoordinateSystemMatrix() const
{
return m_coordinateSystemMatrix;
}
/*!
* \brief Gets the "forward" global direction
* \return The forward direction, by default, it's -UnitZ() (Right hand coordinates)
*/
inline Nz::Vector3f RenderSystem::GetGlobalForward() const
{
return Nz::Vector3f(-m_coordinateSystemMatrix.m13, -m_coordinateSystemMatrix.m23, -m_coordinateSystemMatrix.m33);
}
/*!
* \brief Gets the "right" global direction
* \return The right direction, by default, it's UnitX() (Right hand coordinates)
*/
inline Nz::Vector3f RenderSystem::GetGlobalRight() const
{
return Nz::Vector3f(m_coordinateSystemMatrix.m11, m_coordinateSystemMatrix.m21, m_coordinateSystemMatrix.m31);
}
/*!
* \brief Gets the "up" global direction
* \return The up direction, by default, it's UnitY() (Right hand coordinates)
*/
inline Nz::Vector3f RenderSystem::GetGlobalUp() const
{
return Nz::Vector3f(m_coordinateSystemMatrix.m12, m_coordinateSystemMatrix.m22, m_coordinateSystemMatrix.m32);
}
/*!
* \brief Gets the render technique used for rendering
* \return A reference to the abstract render technique being used
*/
inline Nz::AbstractRenderTechnique& RenderSystem::GetRenderTechnique() const
{
return *m_renderTechnique.get();
}
/*!
* \brief Sets the background used for rendering
*
* \param background A reference to the background
*/
inline void RenderSystem::SetDefaultBackground(Nz::BackgroundRef background)
{
m_background = std::move(background);
}
/*!
* \brief Sets the "forward" global direction
*
* \param direction The new forward direction
*/
inline void RenderSystem::SetGlobalForward(const Nz::Vector3f& direction)
{
m_coordinateSystemMatrix.m13 = -direction.x;
@ -64,6 +126,12 @@ namespace Ndk
InvalidateCoordinateSystem();
}
/*!
* \brief Sets the "right" global direction
*
* \param direction The new right direction
*/
inline void RenderSystem::SetGlobalRight(const Nz::Vector3f& direction)
{
m_coordinateSystemMatrix.m11 = direction.x;
@ -73,6 +141,12 @@ namespace Ndk
InvalidateCoordinateSystem();
}
/*!
* \brief Sets the "up" global direction
*
* \param direction The new up direction
*/
inline void RenderSystem::SetGlobalUp(const Nz::Vector3f& direction)
{
m_coordinateSystemMatrix.m12 = direction.x;
@ -82,6 +156,10 @@ namespace Ndk
InvalidateCoordinateSystem();
}
/*!
* \brief Invalidates the matrix of coordinates for the system
*/
inline void RenderSystem::InvalidateCoordinateSystem()
{
m_coordinateSystemInvalidated = true;

View File

@ -43,6 +43,7 @@ namespace Ndk
inline EntityList CreateEntities(unsigned int count);
void Clear() noexcept;
const EntityHandle& CloneEntity(EntityId id);
const EntityHandle& GetEntity(EntityId id);
inline const EntityList& GetEntities();

View File

@ -7,47 +7,80 @@
namespace Ndk
{
/*!
* \brief Constructs a World object
*
* \param addDefaultSystems Should default provided systems be used
*/
inline World::World(bool addDefaultSystems)
{
if (addDefaultSystems)
AddDefaultSystems();
}
/*!
* \brief Constructs a World object by move semantic
*
* \param world World to move into this
*/
inline World::World(World&& world) noexcept :
HandledObject(std::move(world))
{
operator=(std::move(world));
}
/*!
* \brief Adds a system to the world
* \return A reference to the newly created system
*
* \param system System to add to the world
*/
inline BaseSystem& World::AddSystem(std::unique_ptr<BaseSystem>&& system)
{
NazaraAssert(system, "System must be valid");
SystemIndex index = system->GetIndex();
// Nous nous assurons que le vecteur de component est suffisamment grand pour contenir le nouveau component
// We must ensure that the vector is big enough to hold the new system
if (index >= m_systems.size())
m_systems.resize(index + 1);
// Affectation et retour du système
// Affectation and return of system
m_systems[index] = std::move(system);
m_systems[index]->SetWorld(this);
Invalidate(); // On force une mise à jour de toutes les entités
Invalidate(); // We force an update for every entities
return *m_systems[index].get();
}
/*!
* \brief Adds a system to the world
* \return A reference to the newly created system
*
* \param args Arguments used to create the system
*/
template<typename SystemType, typename... Args>
SystemType& World::AddSystem(Args&&... args)
{
static_assert(std::is_base_of<BaseSystem, SystemType>::value, "SystemType is not a component");
// Allocation et affectation du component
// Allocation and affectation of the system
std::unique_ptr<SystemType> ptr(new SystemType(std::forward<Args>(args)...));
return static_cast<SystemType&>(AddSystem(std::move(ptr)));
}
/*!
* \brief Creates multiple entities in the world
* \return The set of entities created
*
* \param count Number of entities to create
*/
inline World::EntityList World::CreateEntities(unsigned int count)
{
EntityList list;
@ -59,14 +92,27 @@ namespace Ndk
return list;
}
/*!
* \brief Gets every entities in the world
* \return A constant reference to the entities
*/
inline const World::EntityList& World::GetEntities()
{
return m_aliveEntities;
}
/*!
* \brief Gets a system in the world by index
* \return A reference to the system
*
* \param index Index of the system
*
* \remark Produces a NazaraAssert if system is not available in this world
*/
inline BaseSystem& World::GetSystem(SystemIndex index)
{
///DOC: Le système doit être présent
NazaraAssert(HasSystem(index), "This system is not part of the world");
BaseSystem* system = m_systems[index].get();
@ -75,21 +121,39 @@ namespace Ndk
return *system;
}
/*!
* \brief Gets a system in the world by type
* \return A reference to the system
*
* \remark Produces a NazaraAssert if system is not available in this world
*/
template<typename SystemType>
SystemType& World::GetSystem()
{
///DOC: Le système doit être présent
static_assert(std::is_base_of<BaseSystem, SystemType>::value, "SystemType is not a system");
SystemIndex index = GetSystemIndex<SystemType>();
return static_cast<SystemType&>(GetSystem(index));
}
/*!
* \brief Checks whether or not a system is present in the world by index
* \return true If it is the case
*
* \param index Index of the system
*/
inline bool World::HasSystem(SystemIndex index) const
{
return index < m_systems.size() && m_systems[index];
}
/*!
* \brief Checks whether or not a system is present in the world by type
* \return true If it is the case
*/
template<typename SystemType>
bool World::HasSystem() const
{
@ -99,34 +163,69 @@ namespace Ndk
return HasSystem(index);
}
/*!
* \brief Kills a set of entities
*
* \param list Set of entities to kill
*/
inline void World::KillEntities(const EntityList& list)
{
for (const EntityHandle& entity : list)
KillEntity(entity);
}
/*!
* \brief Checks whether or not an entity is valid
* \return true If it is the case
*
* \param entity Pointer to the entity
*/
inline bool World::IsEntityValid(const Entity* entity) const
{
return entity && entity->GetWorld() == this && IsEntityIdValid(entity->GetId());
}
/*!
* \brief Checks whether or not an entity is valid
* \return true If it is the case
*
* \param id Identifier of the entity
*/
inline bool World::IsEntityIdValid(EntityId id) const
{
return id < m_entities.size() && m_entities[id].entity.IsValid();
}
/*!
* \brief Removes each system from the world
*/
inline void World::RemoveAllSystems()
{
m_systems.clear();
}
/*!
* \brief Removes a system from the world by index
*
* \param index Index of the system
*
* \remark No change is done if system is not present
*/
inline void World::RemoveSystem(SystemIndex index)
{
///DOC: N'a aucun effet si le système n'est pas présent
if (HasSystem(index))
m_systems[index].reset();
}
/*!
* \brief Removes a system from the world by type
*/
template<typename SystemType>
void World::RemoveSystem()
{
@ -136,6 +235,12 @@ namespace Ndk
RemoveSystem(index);
}
/*!
* \brief Updates the world
*
* \param elapsedTime Delta time used for the update
*/
inline void World::Update(float elapsedTime)
{
Update(); //< Update entities
@ -148,17 +253,32 @@ namespace Ndk
}
}
/*!
* \brief Invalidates each entity in the world
*/
inline void World::Invalidate()
{
m_dirtyEntities.Resize(m_entities.size(), false);
m_dirtyEntities.Set(true); // Activation de tous les bits
m_dirtyEntities.Set(true); // Activation of all bits
}
/*!
* \brief Invalidates an entity in the world
*
* \param id Identifier of the entity
*/
inline void World::Invalidate(EntityId id)
{
m_dirtyEntities.UnboundedSet(id, true);
}
/*!
* \brief Moves a world into another world object
* \return A reference to the object
*/
inline World& World::operator=(World&& world) noexcept
{
m_aliveEntities = std::move(world.m_aliveEntities);

View File

@ -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;
}

View File

@ -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()
{
}

View File

@ -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);

View File

@ -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");

View File

@ -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();

View File

@ -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;
}

View File

@ -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)

View File

@ -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();

View File

@ -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();

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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)
{
}

View File

@ -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))

View File

@ -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);

View File

@ -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)

View File

@ -6,5 +6,11 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::State
* \brief NDK class that represents a state of your application
*/
State::~State() = default;
}

View File

@ -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>();

View File

@ -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())

View File

@ -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);

View File

@ -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())

View File

@ -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())

View File

@ -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

View File

@ -270,7 +270,6 @@ function NazaraBuild:Execute()
project(prefix .. toolTable.Name)
location(_ACTION .. "/tools")
targetdir(toolTable.TargetDirectory)
if (toolTable.Kind == "plugin" or toolTable.Kind == "library") then
kind("SharedLib")
@ -279,6 +278,7 @@ function NazaraBuild:Execute()
self:MakeInstallCommands(toolTable)
elseif (toolTable.Kind == "application") then
debugdir(toolTable.TargetDirectory)
targetdir(toolTable.TargetDirectory)
if (toolTable.EnableConsole) then
kind("ConsoleApp")
else
@ -307,7 +307,7 @@ function NazaraBuild:Execute()
libdirs("../extlibs/lib/" .. makeLibDir .. "/x86")
libdirs("../lib/" .. makeLibDir .. "/x86")
if (toolTable.Kind == "library") then
targetdir("../lib/" .. makeLibDir .. "/x86")
targetdir(toolTable.TargetDirectory .. "/" .. makeLibDir .. "/x86")
elseif (toolTable.Kind == "plugin") then
targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x86")
end
@ -316,7 +316,7 @@ function NazaraBuild:Execute()
libdirs("../extlibs/lib/" .. makeLibDir .. "/x64")
libdirs("../lib/" .. makeLibDir .. "/x64")
if (toolTable.Kind == "library") then
targetdir("../lib/" .. makeLibDir .. "/x64")
targetdir(toolTable.TargetDirectory .. "/" .. makeLibDir .. "/x64")
elseif (toolTable.Kind == "plugin") then
targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x64")
end
@ -325,7 +325,7 @@ function NazaraBuild:Execute()
libdirs("../extlibs/lib/msvc/x86")
libdirs("../lib/msvc/x86")
if (toolTable.Kind == "library") then
targetdir("../lib/msvc/x86")
targetdir(toolTable.TargetDirectory .. "/msvc/x86")
elseif (toolTable.Kind == "plugin") then
targetdir("../plugins/" .. toolTable.Name .. "/lib/msvc/x86")
end
@ -334,7 +334,7 @@ function NazaraBuild:Execute()
libdirs("../extlibs/lib/msvc/x64")
libdirs("../lib/msvc/x64")
if (toolTable.Kind == "library") then
targetdir("../lib/msvc/x64")
targetdir(toolTable.TargetDirectory .. "/msvc/x64")
elseif (toolTable.Kind == "plugin") then
targetdir("../plugins/" .. toolTable.Name .. "/lib/msvc/x64")
end
@ -343,7 +343,7 @@ function NazaraBuild:Execute()
libdirs("../extlibs/lib/xcode/x86")
libdirs("../lib/xcode/x86")
if (toolTable.Kind == "library") then
targetdir("../lib/xcode/x86")
targetdir(toolTable.TargetDirectory .. "/xcode/x86")
elseif (toolTable.Kind == "plugin") then
targetdir("../plugins/" .. toolTable.Name .. "/lib/xcode/x86")
end
@ -352,7 +352,7 @@ function NazaraBuild:Execute()
libdirs("../extlibs/lib/xcode/x64")
libdirs("../lib/xcode/x64")
if (toolTable.Kind == "library") then
targetdir("../lib/xcode/x64")
targetdir(toolTable.TargetDirectory .. "/xcode/x64")
elseif (toolTable.Kind == "plugin") then
targetdir("../plugins/" .. toolTable.Name .. "/lib/xcode/x64")
end
@ -576,10 +576,10 @@ function NazaraBuild:Initialize()
local succeed, err = self:RegisterTool(TOOL)
if (not succeed) then
print("Unable to register tool: " .. err)
print("Unable to register tool " .. tostring(TOOL.Name) .. ": " .. err)
end
else
print("Unable to load tool file: " .. err)
print("Unable to load tool file " .. v .. ": " .. err)
end
end
TOOL = nil
@ -990,10 +990,6 @@ function NazaraBuild:RegisterTool(toolTable)
return false, "This tool name is already in use"
end
if (toolTable.TargetDirectory == nil or type(toolTable.TargetDirectory) ~= "string" or string.len(toolTable.TargetDirectory) == 0) then
return false, "Invalid tool directory"
end
if (toolTable.Kind == nil or type(toolTable.Kind) ~= "string" or string.len(toolTable.Kind) == 0) then
return false, "Invalid tool type"
end
@ -1005,6 +1001,10 @@ function NazaraBuild:RegisterTool(toolTable)
return false, "Invalid tool type"
end
if (lowerCaseKind ~= "plugin" and (toolTable.TargetDirectory == nil or type(toolTable.TargetDirectory) ~= "string" or string.len(toolTable.TargetDirectory) == 0)) then
return false, "Invalid tool directory"
end
toolTable.Type = "Tool"
self.Tools[lowerCaseName] = toolTable
return true
@ -1084,4 +1084,4 @@ function NazaraBuild:SetupModuleTable(infoTable)
table.insert(infoTable.LibraryPaths.x64, "../extlibs/lib/common/x64")
end
NazaraBuild.SetupToolTable = NazaraBuild.SetupInfoTable
NazaraBuild.SetupToolTable = NazaraBuild.SetupInfoTable

View File

@ -1,71 +1,71 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Avancement de Nazara</title>
</head>
<body>
<div id="englob">
<img style="display: block;margin-left: auto;margin-right: auto;" src="https://github.com/DigitalPulseSoftware/NazaraEngine/raw/master/Logo.png" alt="Nazara Engine" />
<hr>
Retrouvez le moteur sur GitHub !<br>
<a href="https://github.com/DigitalPulseSoftware/NazaraEngine">Dépôt GitHub</a><br><br>
Venez vous renseigner sur les topics dédiés à Nazara présents sur plusieurs sites web :<br>
<a href="https://openclassrooms.com/forum/sujet/moteur-de-jeu-nazara-engine-69732">OpenClassrooms</a>, <a href="http://pdp.microjoe.org/forums/sujet/354/projet-nazara-engine-moteur-de-jeu">Progdupeupl</a> ou <a href="https://zestedesavoir.com/forums/sujet/1039/nazara-engine/">ZesteDeSavoir</a>
<br><br>
... ou pourquoi ne pas venir faire un tour sur <a href="http://forum.digitalpulsesoftware.net">le forum dédié au moteur</a> ?
<hr>
<h1>Fonctionnalités de Nazara</h1>
<div>Dernière mise à jour : <span class="lastupdate">
%DATE%
</span></div>
<h2>Important:</h2>
<p>Afin de faciliter la mise à jour, la page que vous voyez ici a été générée automatiquement par un <i>script Lua</i>, ce qui m'oblige néanmoins à encoder les fonctionnalités de chaque module dans un premier temps.
C'est un travail assez long (pour vous donner une idée, les données du noyau représentent un fichier de 200 lignes), et il n'est pas encore complet, c'est pourquoi des modules manquent sur cette page.<br>
Gardez donc à l'esprit que le moteur possède plus de fonctionnalités que ce qui est décrit actuellement sur cette page.</p>
<p>Oh et bien sûr je ne suis pas concepteur de site web, c'est pourquoi cette page est moche (j'ai <u>essayé</u> de minimiser les dégâts).<br>
Si vous sentez en vous l'irrésistible envie d'améliorer cette page, sachez que votre aide serait grandement appréciée (vous pouvez me contacter via le lien de votre choix plus haut).</p>
<p>Le pourcentage indiqué est calculé automatiquement en fonction des <u>fonctionnalités</u>, cela signifie qu'une fonctionnalité présente sera comptée à 100% à partir du moment où son implémentation de base est considérée fonctionnelle, <u>cela n'est donc pas une assurance qu'aucun bug n'existe concernant cette fonctionnalité</u> (cependant cela signifie que la fonctionnalité est utilisable).<br>
Et bien entendu, un module ou une fonctionnalité ayant atteint les 100% peut toujours évoluer par la suite.</p>
<hr>
<table>
<caption>Sommaire</caption>
<thead>
<tr>
<th>Module</th>
<th>Avancement</th>
</tr>
</thead>
<tbody>
%MODULELIST%
</tbody>
</table>
%MODULEDESCRIPTION%
<hr>
<table>
<caption>Sommaire</caption>
<thead>
<tr>
<th>Module</th>
<th>Pourcentage</th>
</tr>
</thead>
<tbody>
%MODULELIST%
</tbody>
</table>
</div>
</body>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Avancement de Nazara</title>
</head>
<body>
<div id="englob">
<img style="display: block;margin-left: auto;margin-right: auto;" src="https://github.com/DigitalPulseSoftware/NazaraEngine/raw/master/Logo.png" alt="Nazara Engine" />
<hr>
Retrouvez le moteur sur GitHub !<br>
<a href="https://github.com/DigitalPulseSoftware/NazaraEngine">Dépôt GitHub</a><br><br>
Venez vous renseigner sur les topics dédiés à Nazara présents sur plusieurs sites web :<br>
<a href="https://openclassrooms.com/forum/sujet/moteur-de-jeu-nazara-engine-69732">OpenClassrooms</a>, <a href="http://pdp.microjoe.org/forums/sujet/354/projet-nazara-engine-moteur-de-jeu">Progdupeupl</a> ou <a href="https://zestedesavoir.com/forums/sujet/1039/nazara-engine/">ZesteDeSavoir</a>
<br><br>
... ou pourquoi ne pas venir faire un tour sur <a href="http://forum.digitalpulsesoftware.net">le forum dédié au moteur</a> ?
<hr>
<h1>Fonctionnalités de Nazara</h1>
<div>Dernière mise à jour : <span class="lastupdate">
%DATE%
</span></div>
<h2>Important:</h2>
<p>Afin de faciliter la mise à jour, la page que vous voyez ici a été générée automatiquement par un <i>script Lua</i>, ce qui m'oblige néanmoins à encoder les fonctionnalités de chaque module dans un premier temps.
C'est un travail assez long (pour vous donner une idée, les données du noyau représentent un fichier de 200 lignes), et il n'est pas encore complet, c'est pourquoi des modules manquent sur cette page.<br>
Gardez donc à l'esprit que le moteur possède plus de fonctionnalités que ce qui est décrit actuellement sur cette page.</p>
<p>Oh et bien sûr je ne suis pas concepteur de site web, c'est pourquoi cette page est moche (j'ai <u>essayé</u> de minimiser les dégâts).<br>
Si vous sentez en vous l'irrésistible envie d'améliorer cette page, sachez que votre aide serait grandement appréciée (vous pouvez me contacter via le lien de votre choix plus haut).</p>
<p>Le pourcentage indiqué est calculé automatiquement en fonction des <u>fonctionnalités</u>, cela signifie qu'une fonctionnalité présente sera comptée à 100% à partir du moment où son implémentation de base est considérée fonctionnelle, <u>cela n'est donc pas une assurance qu'aucun bug n'existe concernant cette fonctionnalité</u> (cependant cela signifie que la fonctionnalité est utilisable).<br>
Et bien entendu, un module ou une fonctionnalité ayant atteint les 100% peut toujours évoluer par la suite.</p>
<hr>
<table>
<caption>Sommaire</caption>
<thead>
<tr>
<th>Module</th>
<th>Avancement</th>
</tr>
</thead>
<tbody>
%MODULELIST%
</tbody>
</table>
%MODULEDESCRIPTION%
<hr>
<table>
<caption>Sommaire</caption>
<thead>
<tr>
<th>Module</th>
<th>Pourcentage</th>
</tr>
</thead>
<tbody>
%MODULELIST%
</tbody>
</table>
</div>
</body>
</html>

View File

@ -1,121 +1,121 @@
/* Je ne suis pas développeur HTML/CSS, je dois y toucher une fois l'an, désolé pour les quelques atrocités que vous pourrez trouver ici */
body
{
font-family: sans-serif;
text-align: center;
margin: 0;
background-color: #f1f1f1;
}
#englob {
display: block;
margin-left: auto;
margin-right: auto;
background-color: white;
width: 50%;
min-width: 765px;
padding: 0 20px;
}
hr {
height: 0;
border: 0;
border-top: 1px solid #eee;
}
a
{
color: #007ACC;
}
a:hover
{
color: lightblue;
}
h1
{
display: inline;
}
h2
{
display: inline;
text-decoration: underline;
}
h4
{
text-decoration: underline;
}
p {
text-align: justify;
}
ol
{
list-style-type: none;
}
table
{
border-collapse: collapse;
text-align: center;
display: inline-block;
border: white groove;
border-radius: 10px;
box-shadow: 0px 0px 10px lightblue;
}
th
{
text-shadow: 2px 2px 4px black;
}
tr
{
border: 1px solid white;
}
tbody tr:hover
{
text-shadow: 0px 0px 4px white;
}
.description
{
margin-left: 20px;
}
.lastupdate
{
font-size: x-large;
font-weight: bold;
color: #f1c40f;
}
.modulename
{
font-size: x-large;
font-weight: bold;
text-shadow: 2px 2px 10px #007ACC;
}
.note
{
margin-left: 20px;
color: #007ACC;
}
.notedesc
{
color: rgb(200, 200, 255);
}
.portability
{
margin-left: 20px;
color: red;
/* Je ne suis pas développeur HTML/CSS, je dois y toucher une fois l'an, désolé pour les quelques atrocités que vous pourrez trouver ici */
body
{
font-family: sans-serif;
text-align: center;
margin: 0;
background-color: #f1f1f1;
}
#englob {
display: block;
margin-left: auto;
margin-right: auto;
background-color: white;
width: 50%;
min-width: 765px;
padding: 0 20px;
}
hr {
height: 0;
border: 0;
border-top: 1px solid #eee;
}
a
{
color: #007ACC;
}
a:hover
{
color: lightblue;
}
h1
{
display: inline;
}
h2
{
display: inline;
text-decoration: underline;
}
h4
{
text-decoration: underline;
}
p {
text-align: justify;
}
ol
{
list-style-type: none;
}
table
{
border-collapse: collapse;
text-align: center;
display: inline-block;
border: white groove;
border-radius: 10px;
box-shadow: 0px 0px 10px lightblue;
}
th
{
text-shadow: 2px 2px 4px black;
}
tr
{
border: 1px solid white;
}
tbody tr:hover
{
text-shadow: 0px 0px 4px white;
}
.description
{
margin-left: 20px;
}
.lastupdate
{
font-size: x-large;
font-weight: bold;
color: #f1c40f;
}
.modulename
{
font-size: x-large;
font-weight: bold;
text-shadow: 2px 2px 10px #007ACC;
}
.note
{
margin-left: 20px;
color: #007ACC;
}
.notedesc
{
color: rgb(200, 200, 255);
}
.portability
{
margin-left: 20px;
color: red;
}

View File

@ -1,31 +0,0 @@
MODULE.Name = "Vulkan"
MODULE.ClientOnly = true
MODULE.Defines = {
"VK_NO_PROTOTYPES"
}
MODULE.Libraries = {
"NazaraCore",
"NazaraUtility"
}
MODULE.OsDefines.Linux = {
-- "VK_USE_PLATFORM_MIR_KHR",
"VK_USE_PLATFORM_XCB_KHR"
-- "VK_USE_PLATFORM_XLIB_KHR",
-- "VK_USE_PLATFORM_WAYLAND_KHR"
}
MODULE.OsDefines.BSD = MODULE.OsDefines.Linux
MODULE.OsDefines.Solaris = MODULE.OsDefines.Linux
MODULE.OsDefines.Windows = {
"VK_USE_PLATFORM_WIN32_KHR"
}
MODULE.OsFiles.Windows = {
"../src/Nazara/Vulkan/Win32/**.hpp",
"../src/Nazara/Vulkan/Win32/**.cpp"
}

View File

@ -2,7 +2,6 @@ TOOL.Name = "Assimp"
TOOL.Directory = "../plugins/Assimp"
TOOL.Kind = "Plugin"
TOOL.TargetDirectory = "../SDK/lib"
TOOL.Includes = {
"../extlibs/include",

View File

@ -2,7 +2,7 @@ TOOL.Name = "SDK"
TOOL.Directory = "../SDK"
TOOL.Kind = "Library"
TOOL.TargetDirectory = "../SDK/lib"
TOOL.TargetDirectory = "../lib"
TOOL.Defines = {
"NDK_BUILD"

View File

@ -2,7 +2,7 @@ TOOL.Name = "SDKServer"
TOOL.Directory = "../SDK"
TOOL.Kind = "Library"
TOOL.TargetDirectory = "../SDK/lib"
TOOL.TargetDirectory = "../lib"
TOOL.Defines = {
"NDK_BUILD",
@ -30,6 +30,8 @@ TOOL.FilesExcluded = {
"../SDK/**/LightComponent.*",
"../SDK/**/ListenerComponent.*",
"../SDK/**/ListenerSystem.*",
"../SDK/**/Particle*Component.*",
"../SDK/**/ParticleSystem.*",
"../SDK/**/RenderSystem.*",
"../SDK/**/LuaBinding_Audio.*",
"../SDK/**/LuaBinding_Graphics.*",

View File

@ -14,17 +14,10 @@ TOOL.Includes = {
TOOL.Files = {
"../tests/main.cpp",
"../tests/Engine/**.cpp"
"../tests/Engine/**.cpp",
"../tests/SDK/**.cpp"
}
TOOL.Libraries = {
"NazaraCore",
"NazaraAudio",
"NazaraLua",
"NazaraGraphics",
"NazaraRenderer",
"NazaraNetwork",
"NazaraNoise",
"NazaraPhysics",
"NazaraUtility"
"NazaraSDK"
}

View File

@ -256,78 +256,22 @@ int main()
// On lie la caméra à la fenêtre
cameraComp.SetTarget(&window);
// Et on créé deux horloges pour gérer le temps
Nz::Clock secondClock, updateClock;
// Et on créé une horloge pour gérer le temps
Nz::Clock updateClock;
Nz::UInt64 updateAccumulator = 0;
// Ainsi qu'un compteur de FPS improvisé
unsigned int fps = 0;
// Quelques variables de plus pour notre caméra
bool smoothMovement = true;
Nz::Vector3f targetPos = cameraNode.GetPosition();
// Pour ajouter une console à notre application, nous avons besoin d'un monde 2D pour gérer ces rendus
Ndk::WorldHandle world2D = application.AddWorld().CreateHandle();
world2D->GetSystem<Ndk::RenderSystem>().SetDefaultBackground(nullptr);
world2D->GetSystem<Ndk::RenderSystem>().SetGlobalUp(Nz::Vector3f::Down());
window.EnableEventPolling(true); // Déprécié
// Nous ajoutons une caméra comme précédement
Ndk::EntityHandle viewEntity = world2D->CreateEntity();
viewEntity->AddComponent<Ndk::NodeComponent>();
application.EnableConsole(true);
application.EnableFPSCounter(true);
// À la différence que celui-ci effectuera une projection orthogonale
Ndk::CameraComponent& viewer = viewEntity->AddComponent<Ndk::CameraComponent>();
viewer.SetTarget(&window);
viewer.SetProjectionType(Nz::ProjectionType_Orthogonal);
// Nous créons un environnement Lua pour gérer nos scripts
Nz::LuaInstance lua;
// Faisons en sorte d'enregistrer les classes du moteur dans cet environnement
Ndk::LuaAPI::RegisterClasses(lua);
// Ensuite nous créons la console en elle-même
Ndk::Console console(*world2D, Nz::Vector2f(window.GetWidth(), window.GetHeight() / 4), lua);
// Nous redirigeons les logs vers cette console
Nz::Log::OnLogWriteType::ConnectionGuard logGuard = Nz::Log::OnLogWrite.Connect([&console] (const Nz::String& str)
{
console.AddLine(str);
});
// Nous réécrivons la fonction "print" du Lua pour la rediriger vers la console
lua.PushFunction([&console] (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
instance.PushValue(i); // Arg
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);
}
console.AddLine(stream);
return 0;
});
lua.SetGlobal("print");
// Définissons quelques variables de base
lua.PushGlobal("Application", Ndk::Application::Instance());
lua.PushGlobal("Console", console.CreateHandle());
lua.PushGlobal("Spaceship", spaceship->CreateHandle());
lua.PushGlobal("World", world->CreateHandle());
Ndk::Application::ConsoleOverlay& consoleOverlay = application.GetConsoleOverlay();
consoleOverlay.lua.PushGlobal("Spaceship", spaceship->CreateHandle());
consoleOverlay.lua.PushGlobal("World", world->CreateHandle());
// Début de la boucle de rendu du programme (s'occupant par exemple de mettre à jour le monde)
while (application.Run())
@ -340,8 +284,12 @@ int main()
{
case Nz::WindowEventType_MouseMoved: // La souris a bougé
{
if (console.IsVisible())
break;
if (application.IsConsoleEnabled())
{
Ndk::Application::ConsoleOverlay& consoleOverlay = application.GetConsoleOverlay();
if (consoleOverlay.console->IsVisible())
break;
}
// Gestion de la caméra free-fly (Rotation)
float sensitivity = 0.3f; // Sensibilité de la souris
@ -366,9 +314,6 @@ int main()
break;
case Nz::WindowEventType_KeyPressed: // Une touche a été pressée !
if (console.IsVisible())
console.SendEvent(event);
if (event.key.code == Nz::Keyboard::Key::Escape)
window.Close();
else if (event.key.code == Nz::Keyboard::F1)
@ -381,19 +326,6 @@ int main()
else
smoothMovement = true;
}
else if (event.key.code == Nz::Keyboard::F9)
console.Show(!console.IsVisible());
break;
case Nz::WindowEventType_TextEntered:
{
if (console.IsVisible())
console.SendCharacter(event.text.character);
break;
}
case Nz::WindowEventType_Resized:
console.SetSize({float(event.size.width), event.size.height / 4.f});
break;
default:
@ -417,7 +349,16 @@ int main()
// Vitesse de déplacement de la caméra
float cameraSpeed = 3.f * elapsedTime; // Trois mètres par seconde
if (!console.IsVisible())
bool move = true;
if (application.IsConsoleEnabled())
{
Ndk::Application::ConsoleOverlay& consoleOverlay = application.GetConsoleOverlay();
if (consoleOverlay.console->IsVisible())
move = false;
}
if (move)
{
// Si la touche espace est enfoncée, notre vitesse de déplacement est multipliée par deux
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Space))
@ -458,28 +399,6 @@ int main()
// Après avoir dessiné sur la fenêtre, il faut s'assurer qu'elle affiche cela
// Cet appel ne fait rien d'autre qu'échanger les buffers de rendu (Double Buffering)
window.Display();
// On incrémente le compteur de FPS improvisé
fps++;
if (secondClock.GetMilliseconds() >= 1000) // Toutes les secondes
{
// Et on insère ces données dans le titre de la fenêtre
window.SetTitle(windowTitle + " - " + Nz::String::Number(fps) + " FPS");
/*
Note: En C++11 il est possible d'insérer de l'Unicode de façon standard, quel que soit l'encodage du fichier,
via quelque chose de similaire à u8"Cha\u00CEne de caract\u00E8res".
Cependant, si le code source est encodé en UTF-8 (Comme c'est le cas dans ce fichier),
cela fonctionnera aussi comme ceci : "Chaîne de caractères".
*/
// Et on réinitialise le compteur de FPS
fps = 0;
// Et on relance l'horloge pour refaire ça dans une seconde
secondClock.Restart();
}
}
return EXIT_SUCCESS;

View File

@ -94,7 +94,7 @@ int main()
std::cout << oss.str() << std::endl;
Nz::File reportFile("RapportNz::HardwareInfo.txt");
Nz::File reportFile("HardwareInfo.txt");
if (reportFile.Open(Nz::OpenMode_Text | Nz::OpenMode_Truncate | Nz::OpenMode_WriteOnly))
{
reportFile.Write(oss.str()); // Conversion implicite en Nz::String

View File

@ -9,16 +9,14 @@
#include <Nazara/Utility.hpp>
#include <NDK/Application.hpp>
#include <iostream>
#include <vector>
#include <unordered_map>
int main()
int main(int argc, char* argv[])
{
// This "example" has only one purpose: Giving an empty project for you to test whatever you want
// If you wish to have multiple test projects, you only have to copy/paste this directory and change the name in the build.lua
Ndk::Application app;
// This "example" has only one purpose: Giving an empty project for you to test whatever you want
// If you wish to have multiple test projects, you only have to copy/paste this directory and change the name in the build.lua
Ndk::Application application(argc, argv);
// Do what you want here
return EXIT_SUCCESS;
// Do what you want here
return EXIT_SUCCESS;
}

View File

@ -9,16 +9,17 @@
#include <NDK/World.hpp>
#include <iostream>
int main()
int main(int argc, char* argv[])
{
Ndk::Application application;
Ndk::Application application(argc, argv);
Nz::RenderWindow& mainWindow = application.AddWindow<Nz::RenderWindow>();
mainWindow.Create(Nz::VideoMode(800, 600, 32), "Test");
Ndk::World& world = application.AddWorld();
world.GetSystem<Ndk::RenderSystem>().SetGlobalUp(Nz::Vector3f::Down());
world.GetSystem<Ndk::RenderSystem>().SetDefaultBackground(Nz::ColorBackground::New(Nz::Color(192, 100, 100)));
world.GetSystem<Ndk::RenderSystem>().SetDefaultBackground(Nz::ColorBackground::New(Nz::Color(117, 122, 214)));
Ndk::EntityHandle viewEntity = world.CreateEntity();
@ -43,13 +44,6 @@ int main()
while (application.Run())
{
Nz::WindowEvent event;
while (mainWindow.PollEvent(&event))
{
if (event.type == Nz::WindowEventType_Quit)
application.Quit();
}
mainWindow.Display();
}

View File

@ -11,7 +11,7 @@
namespace Nz
{
template<typename T> void MixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount);
template<typename T> void MixToMono(T* input, T* output, UInt32 channelCount, UInt64 frameCount);
}
#include <Nazara/Audio/Algorithm.inl>

View File

@ -19,16 +19,16 @@ namespace Nz
* \remark The input buffer may be the same as the output one
*/
template<typename T>
void MixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount)
void MixToMono(T* input, T* output, UInt32 channelCount, UInt64 frameCount)
{
// To avoid overflow, we use, as an accumulator, a type which is large enough: (u)int 64 bits for integers, double for floatings
typedef typename std::conditional<std::is_unsigned<T>::value, UInt64, Int64>::type BiggestInt;
typedef typename std::conditional<std::is_integral<T>::value, BiggestInt, double>::type Biggest;
for (unsigned int i = 0; i < frameCount; ++i)
for (UInt64 i = 0; i < frameCount; ++i)
{
Biggest acc = Biggest(0);
for (unsigned int j = 0; j < channelCount; ++j)
for (UInt32 j = 0; j < channelCount; ++j)
acc += input[i * channelCount + j];
output[i] = static_cast<T>(acc / channelCount);

View File

@ -48,7 +48,7 @@ namespace Nz
UInt32 GetDuration() const;
AudioFormat GetFormat() const;
UInt32 GetPlayingOffset() const;
UInt32 GetSampleCount() const;
UInt64 GetSampleCount() const;
UInt32 GetSampleRate() const;
SoundStatus GetStatus() const;

View File

@ -50,18 +50,18 @@ namespace Nz
public:
SoundBuffer() = default;
SoundBuffer(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples);
SoundBuffer(AudioFormat format, UInt64 sampleCount, UInt32 sampleRate, const Int16* samples);
SoundBuffer(const SoundBuffer&) = delete;
SoundBuffer(SoundBuffer&&) = delete;
~SoundBuffer();
bool Create(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples);
bool Create(AudioFormat format, UInt64 sampleCount, UInt32 sampleRate, const Int16* samples);
void Destroy();
UInt32 GetDuration() const;
AudioFormat GetFormat() const;
const Int16* GetSamples() const;
UInt32 GetSampleCount() const;
UInt64 GetSampleCount() const;
UInt32 GetSampleRate() const;
bool IsValid() const;

View File

@ -21,11 +21,11 @@ namespace Nz
virtual UInt32 GetDuration() const = 0;
virtual AudioFormat GetFormat() const = 0;
virtual UInt32 GetSampleCount() const = 0;
virtual UInt64 GetSampleCount() const = 0;
virtual UInt32 GetSampleRate() const = 0;
virtual unsigned int Read(void* buffer, unsigned int sampleCount) = 0;
virtual void Seek(UInt32 offset) = 0;
virtual UInt64 Read(void* buffer, UInt64 sampleCount) = 0;
virtual void Seek(UInt64 offset) = 0;
};
}

View File

@ -124,7 +124,7 @@ namespace Nz
template<typename T, std::size_t N>
constexpr std::size_t CountOf(T(&name)[N]) noexcept
{
NazaraUnused(name);
// NazaraUnused(name); //< Because "body of function is not a return-statement" >.>
return N;
}

View File

@ -121,7 +121,7 @@ namespace Nz
if (sizeof(T) <= sizeof(Block))
{
m_bitCount = std::numeric_limits<T>::digits;
m_blocks.push_back(value);
m_blocks.push_back(static_cast<Block>(value));
}
else
{

View File

@ -2,6 +2,7 @@
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Signal.hpp>
#include <Nazara/Core/Error.hpp>
#include <utility>
#include <Nazara/Core/Debug.hpp>

View File

@ -47,9 +47,9 @@ namespace Nz
Vector2ui m_dimensions;
DeferredRenderTechnique* m_deferredTechnique;
DeferredRenderQueue* m_renderQueue;
RenderBuffer* m_depthStencilBuffer;
RenderTexture* m_GBufferRTT;
RenderTexture* m_workRTT;
Texture* m_depthStencilTexture;
Texture* m_GBuffer[4];
Texture* m_workTextures[2];

View File

@ -37,7 +37,7 @@ namespace Nz
void EnablePass(RenderPassType renderPass, int position, bool enable);
RenderBuffer* GetDepthStencilBuffer() const;
Texture* GetDepthStencilTexture() const;
Texture* GetGBuffer(unsigned int i) const;
RenderTexture* GetGBufferRTT() const;
const ForwardRenderTechnique* GetForwardTechnique() const;
@ -69,14 +69,14 @@ namespace Nz
std::map<RenderPassType, std::map<int, std::unique_ptr<DeferredRenderPass>>, RenderPassComparator> m_passes;
ForwardRenderTechnique m_forwardTechnique; // Must be initialized before the RenderQueue
DeferredRenderQueue m_renderQueue;
mutable RenderBufferRef m_depthStencilBuffer;
mutable TextureRef m_depthStencilTexture;
mutable RenderTexture m_GBufferRTT;
mutable RenderTexture m_workRTT;
mutable TextureRef m_GBuffer[4];
mutable TextureRef m_workTextures[2];
mutable Vector2ui m_GBufferSize;
const RenderTarget* m_viewerTarget;
};
};
}
#endif // NAZARA_FORWARDRENDERTECHNIQUE_HPP

View File

@ -54,8 +54,8 @@ namespace Nz
struct InstanceData
{
InstanceData(const Matrix4f& referenceMatrix) :
transformMatrix(&referenceMatrix),
InstanceData(const Matrix4f& transformationMatrix) :
localMatrix(transformationMatrix),
flags(0)
{
}
@ -67,6 +67,7 @@ namespace Nz
data = std::move(instanceData.data);
flags = instanceData.flags;
renderOrder = instanceData.renderOrder;
localMatrix = instanceData.localMatrix;
transformMatrix = instanceData.transformMatrix;
volume = instanceData.volume;
@ -75,7 +76,8 @@ namespace Nz
std::vector<UInt8> data;
BoundingVolumef volume;
const Matrix4f* transformMatrix;
Matrix4f localMatrix;
mutable Matrix4f transformMatrix;
UInt32 flags;
int renderOrder;
};

View File

@ -61,7 +61,7 @@ namespace Nz
if (!operator==(static_cast<const RenderStates&>(lhs), static_cast<const RenderStates&>(rhs)))
return false;
#define NazaraPipelineMember(field) if (lhs.##field != rhs.##field) return false
#define NazaraPipelineMember(field) if (lhs.field != rhs.field) return false
#define NazaraPipelineBoolMember NazaraPipelineMember
NazaraPipelineBoolMember(alphaTest);
@ -97,6 +97,7 @@ namespace Nz
MaterialPipelineRef MaterialPipeline::New(Args&&... args)
{
std::unique_ptr<MaterialPipeline> object(new MaterialPipeline(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
}
@ -115,8 +116,8 @@ namespace std
Nz::UInt16 parameterHash = 0;
Nz::UInt16 parameterIndex = 0;
#define NazaraPipelineMember(member) Nz::HashCombine(seed, pipelineInfo.##member)
#define NazaraPipelineBoolMember(member) parameterHash |= ((pipelineInfo.##member) ? 1U : 0U) << (parameterIndex++)
#define NazaraPipelineMember(member) Nz::HashCombine(seed, pipelineInfo.member)
#define NazaraPipelineBoolMember(member) parameterHash |= ((pipelineInfo.member) ? 1U : 0U) << (parameterIndex++)
NazaraPipelineBoolMember(alphaTest);
NazaraPipelineBoolMember(depthSorting);

View File

@ -18,8 +18,9 @@ namespace Nz
*/
inline void Model::AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix, unsigned int renderOrder)
{
InstanceData instanceData(transformMatrix);
InstanceData instanceData(Nz::Matrix4f::Identity());
instanceData.renderOrder = renderOrder;
instanceData.transformMatrix = transformMatrix;
return AddToRenderQueue(renderQueue, instanceData);
}

View File

@ -11,6 +11,8 @@ namespace Nz
ParticleDeclarationRef ParticleDeclaration::New(Args&&... args)
{
std::unique_ptr<ParticleDeclaration> object(new ParticleDeclaration(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
}

View File

@ -0,0 +1,45 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_PARTICLEFUNCTIONCONTROLLER_HPP
#define NAZARA_PARTICLEFUNCTIONCONTROLLER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Graphics/ParticleController.hpp>
#include <functional>
namespace Nz
{
class ParticleFunctionController;
using ParticleFunctionControllerConstRef = ObjectRef<const ParticleFunctionController>;
using ParticleFunctionControllerRef = ObjectRef<ParticleFunctionController>;
class NAZARA_GRAPHICS_API ParticleFunctionController : public ParticleController
{
public:
using Controller = std::function<void(ParticleGroup& /*group*/, ParticleMapper& /*mapper*/, unsigned int /*startId*/, unsigned int /*endId*/, float /*elapsedTime*/)>;
inline ParticleFunctionController(Controller controller);
ParticleFunctionController(const ParticleFunctionController&) = default;
~ParticleFunctionController() = default;
void Apply(ParticleGroup& group, ParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) override final;
inline const Controller& GetController() const;
inline void SetController(Controller controller);
template<typename... Args> static ParticleFunctionControllerRef New(Args&&... args);
private:
Controller m_controller;
};
}
#include <Nazara/Graphics/ParticleFunctionController.inl>
#endif // NAZARA_PARTICLEFUNCTIONCONTROLLER_HPP

View File

@ -0,0 +1,46 @@
// Copyright (C) 2016 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/ParticleFunctionController.hpp>
#include <memory>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline ParticleFunctionController::ParticleFunctionController(Controller controller) :
m_controller(std::move(controller))
{
}
/*!
* \brief Gets the controller function
*
* \return Controller function responsible for particle update
*/
inline const ParticleFunctionController::Controller& ParticleFunctionController::GetController() const
{
return m_controller;
}
/*!
* \brief Sets the controller function
*
* \remark The controller function must be valid
*/
inline void ParticleFunctionController::SetController(Controller controller)
{
m_controller = std::move(controller);
}
template<typename... Args>
ParticleFunctionControllerRef ParticleFunctionController::New(Args&&... args)
{
std::unique_ptr<ParticleFunctionController> object(new ParticleFunctionController(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -0,0 +1,45 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_PARTICLEFUNCTIONGENERATOR_HPP
#define NAZARA_PARTICLEFUNCTIONGENERATOR_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Graphics/ParticleGenerator.hpp>
#include <functional>
namespace Nz
{
class ParticleFunctionGenerator;
using ParticleFunctionGeneratorConstRef = ObjectRef<const ParticleFunctionGenerator>;
using ParticleFunctionGeneratorRef = ObjectRef<ParticleFunctionGenerator>;
class NAZARA_GRAPHICS_API ParticleFunctionGenerator : public ParticleGenerator
{
public:
using Generator = std::function<void(ParticleGroup& /*group*/, ParticleMapper& /*mapper*/, unsigned int /*startId*/, unsigned int /*endId*/)>;
inline ParticleFunctionGenerator(Generator controller);
ParticleFunctionGenerator(const ParticleFunctionGenerator&) = default;
~ParticleFunctionGenerator() = default;
void Generate(ParticleGroup& group, ParticleMapper& mapper, unsigned int startId, unsigned int endId) override final;
inline const Generator& GetGenerator() const;
inline void SetGenerator(Generator generator);
template<typename... Args> static ParticleFunctionGeneratorRef New(Args&&... args);
private:
Generator m_generator;
};
}
#include <Nazara/Graphics/ParticleFunctionGenerator.inl>
#endif // NAZARA_PARTICLEFUNCTIONGENERATOR_HPP

View File

@ -0,0 +1,46 @@
// Copyright (C) 2016 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/ParticleFunctionGenerator.hpp>
#include <memory>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline ParticleFunctionGenerator::ParticleFunctionGenerator(Generator generator) :
m_generator(std::move(generator))
{
}
/*!
* \brief Gets the generator function
*
* \return Generator function responsible for particle creation
*/
inline const ParticleFunctionGenerator::Generator& ParticleFunctionGenerator::GetGenerator() const
{
return m_generator;
}
/*!
* \brief Sets the generator function
*
* \remark The generator function must be valid
*/
inline void ParticleFunctionGenerator::SetGenerator(Generator generator)
{
m_generator = std::move(generator);
}
template<typename... Args>
ParticleFunctionGeneratorRef ParticleFunctionGenerator::New(Args&&... args)
{
std::unique_ptr<ParticleFunctionGenerator> object(new ParticleFunctionGenerator(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -0,0 +1,45 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_PARTICLEFUNCTIONRENDERER_HPP
#define NAZARA_PARTICLEFUNCTIONRENDERER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Graphics/ParticleRenderer.hpp>
#include <functional>
namespace Nz
{
class ParticleFunctionRenderer;
using ParticleFunctionRendererConstRef = ObjectRef<const ParticleFunctionRenderer>;
using ParticleFunctionRendererRef = ObjectRef<ParticleFunctionRenderer>;
class NAZARA_GRAPHICS_API ParticleFunctionRenderer : public ParticleRenderer
{
public:
using Renderer = std::function<void(const ParticleGroup& /*group*/, const ParticleMapper& /*mapper*/, unsigned int /*startId*/, unsigned int /*endId*/, AbstractRenderQueue* /*renderQueue*/)>;
inline ParticleFunctionRenderer(Renderer renderer);
ParticleFunctionRenderer(const ParticleFunctionRenderer&) = default;
~ParticleFunctionRenderer() = default;
void Render(const ParticleGroup& group, const ParticleMapper& mapper, unsigned int startId, unsigned int endId, AbstractRenderQueue* renderQueue) override final;
inline const Renderer& GetRenderer() const;
inline void SetRenderer(Renderer renderer);
template<typename... Args> static ParticleFunctionRendererRef New(Args&&... args);
private:
Renderer m_renderer;
};
}
#include <Nazara/Graphics/ParticleFunctionRenderer.inl>
#endif // NAZARA_PARTICLEFUNCTIONRENDERER_HPP

Some files were not shown because too many files have changed in this diff Show More