-
Mathias Paulin authoredMathias Paulin authored
Node.hpp 9.25 KiB
#pragma once
#include <RadiumNBR/NodeBasedRendererMacro.hpp>
#include <RadiumNBR/NodeGraph/EditableParameter.hpp>
#include <RadiumNBR/NodeGraph/Port.hpp>
#include <RadiumNBR/externals/json.hpp>
#include <uuid.h>
#include <cstdint>
#include <iostream>
#include <memory>
#include <string>
#include <typeinfo>
#include <vector>
enum class TextureType { COLOR, DEPTH, STENCIL };
template <class T>
constexpr std::string_view type_name() {
#ifdef __clang__
std::string_view p = __PRETTY_FUNCTION__;
return std::string_view( p.data() + 34, p.size() - 34 - 1 );
#elif defined( __GNUC__ )
std::string_view p = __PRETTY_FUNCTION__;
# if __cplusplus < 201402
return std::string_view( p.data() + 36, p.size() - 36 - 1 );
# else
return std::string_view( p.data() + 49, p.find( ';', 49 ) - 49 );
# endif
#elif defined( _MSC_VER )
std::string_view p = __FUNCSIG__;
return std::string_view( p.data() + 84, p.size() - 84 - 7 );
#else
return type_id( T ).type_name();
#endif
}
inline std::size_t
replace_all_in_string( std::string& inout, std::string_view what, std::string_view with ) {
std::size_t count{};
for ( std::string::size_type pos{};
inout.npos != ( pos = inout.find( what.data(), pos, what.length() ) );
pos += with.length(), ++count )
{ inout.replace( pos, what.length(), with.data(), with.length() ); }
return count;
}
inline std::size_t remove_all_in_string( std::string& inout, std::string_view what ) {
return replace_all_in_string( inout, what, "" );
}
#include <Core/Utils/Color.hpp>
#include <Engine/Data/ShaderProgramManager.hpp>
#include <Engine/Data/Texture.hpp>
#include <Engine/Data/ViewingParameters.hpp>
#include <Engine/Rendering/RenderObject.hpp>
#include <Engine/Scene/Light.hpp>
using NodeTypeRenderObject = std::shared_ptr<Ra::Engine::Rendering::RenderObject>;
using NodeTypeLight = const Ra::Engine::Scene::Light*;
using NodeTypeCamera = Ra::Engine::Data::ViewingParameters;
using NodeTypeColor = Ra::Core::Utils::Color;
using NodeTypeTexture = Ra::Engine::Data::Texture;
class NodeBasedRenderer_LIBRARY_API Node
{
public:
/// Constructor.
Node() = delete;
Node( const Node& ) = delete;
Node& operator=( const Node& ) = delete;
virtual ~Node() = default;
/// The init() function is called once at the start of the application.
/// Its goal is to initialize the node's internal data.
virtual void init() = 0;
/// The update() function is called once per frame.
/// Its goal is to update the node's internal data.
virtual void update() = 0;
/// The execute() function is called once per frame.
/// Its goal is to execute a treatment to the output data.
virtual void execute() = 0;
/// The destroy() function is called once at the end of the application.
/// Its goal is to free the internal data that have been allocated.
virtual void destroy() = 0;
/// The resize(uint32_t width, uint32_t height) function is called when the application gets
/// resized. Its goal is to resize the potential internal textures if needed.
/// @param width The new width of the surface.
/// @param height The new height of the surface.
virtual void resize( uint32_t width, uint32_t height ) = 0;
/// TODO : specify the json format for nodes and what is expected from the following ethods
/// return the json representation of the concrete node
void toJson( nlohmann::json& data ) const;
/// Fill the node from its json description
void fromJson( const nlohmann::json& data );
/// Give access to extra json data stored on the node by external application components
nlohmann::json& getExtraJsonData() { return m_extraJsonData; }
/// Build a render technic per material.
/// @param ro The render object to get the material from
/// @param rt The render technic to build
virtual void buildRenderTechnique( const Ra::Engine::Rendering::RenderObject* ro,
Ra::Engine::Rendering::RenderTechnique& rt ) const {}
/// Gets the name of the node.
const std::string& getTypeName() const { return m_typeName; }
/// Gets the instance name of the node.
const std::string& getInstanceName() const { return m_instanceName; }
/// Generates the uuid of the node
void generateUuid();
/// Gets the UUID of the node as a string
std::string getUuid() const;
/// return the deletable status of the node
/// Default is true. If a node must not be deleted (e.g. RenderObjectSource Node in the rendergraph), override this method.
bool isDeletable() { return m_isDeletable;}
// Set the deletable status of the node
void setDeletableStatus( bool deletable = true ) { m_isDeletable = deletable; }
/// Gets the in ports of the node.
std::vector<std::unique_ptr<PortBase>>& getInputs() { return m_inputs; }
/// Gets the out ports of the node.
std::vector<std::unique_ptr<PortBase>>& getOutputs() { return m_outputs; }
/// Gets the editable parameters of the node.
std::vector<std::unique_ptr<EditableParameterBase>>& getEditableParameters() {
return m_editableParameters;
}
/// Sets the filesystem (real or virtual) location for the pass resources
inline void setResourcesDir( std::string resourcesRootDir ) {
m_resourceDir = std::move( resourcesRootDir );
}
/// Sets node index for render technique
void setIndex( const int idx ) { m_idx = idx; }
/// Sets the shader program manager
void setShaderProgramManager( Ra::Engine::Data::ShaderProgramManager* shaderMngr ) {
m_shaderMngr = shaderMngr;
}
/// Flag that checks if the node is already initialized
bool m_initialized{ false };
/// Two nodes are considered equal if there names are the same.
bool operator==( const Node& o_node ) { return m_typeName == o_node.getTypeName(); }
protected:
/// @param instanceName The name of the node
/// @param typeName The type name of the node
Node( const std::string& instanceName, const std::string& typeName );
/// internal json representation of the Node.
/// Must be implemented by inheriting classes.
/// Be careful with template specialization and function member overriding when implementing this method.
virtual void fromJsonInternal( const nlohmann::json& data ) {
std::cout << "virtual void fromJsonInternal : MUST NOT BE CALLED on a " << typeid(*this).name() << "\n";
}//= 0;
/// internal json representation of the Node.
/// Must be implemented by inheriting classes.
/// Be careful with template specialization and function member overriding when implementing this method.
virtual void toJsonInternal( nlohmann::json& data ) const {} //= 0;
/// Adds an in port to the node.
/// This function checks if there is no in port with the same name already associated with this
/// node.
/// @param in The in port to add.
template <typename T>
void addInput( PortIn<T>* in ) {
bool found = false;
for ( auto& input : m_inputs )
{
if ( input->getName() == in->getName() ) { found = true; }
}
if ( !found ) { m_inputs.emplace_back( in ); }
}
/// Adds an out port to the node and the data associated with it.
/// This function checks if there is no out port with the same name already associated with this
/// node.
/// @param out The in port to add.
/// @param data The data associated with the port.
template <typename T>
void addOutput( PortOut<T>* out, T* data ) {
bool found = false;
for ( auto& output : m_outputs )
{
if ( output->getName() == out->getName() ) { found = true; }
}
if ( !found )
{
m_outputs.emplace_back( out );
out->setData( data );
}
}
/// Adds an editable parameter to the node.
/// @param editableParameter The editable parameter to add.
template <typename T>
void addEditableParameter( EditableParameter<T>* editableParameter ) {
m_editableParameters.emplace_back( editableParameter );
}
/// The uuid of the node (TODO, use https://github.com/mariusbancila/stduuid instead of a
/// string)
//std::string m_uuid;
uuids::uuid m_uuid;
/// The deletable status of the node
bool m_isDeletable {true};
/// The type name of the node
std::string m_typeName;
/// The instance name of the node
std::string m_instanceName;
/// The in ports of the node
std::vector<std::unique_ptr<PortBase>> m_inputs;
/// The out ports of the node
std::vector<std::unique_ptr<PortBase>> m_outputs;
/// The editable parameters of the node
std::vector<std::unique_ptr<EditableParameterBase>> m_editableParameters;
/// The index of the node in the render technique description
Ra::Core::Utils::Index m_idx;
/// The base resources directory
std::string m_resourceDir{ "./" };
/// The renderer's shader program manager
Ra::Engine::Data::ShaderProgramManager* m_shaderMngr;
/// Additional data on the node, added by application or gui or ...
nlohmann::json m_extraJsonData;
/// generator for uuid
static bool s_uuidGeneratorInitialized;
static uuids::uuid_random_generator* s_uidGenerator;
static void createUuidGenerator();
};