/
Writing an Atoms graph node (AtomsUnreal)
Writing an Atoms graph node (AtomsUnreal)
You can create custom dependency graph nodes, which carry out custom operations based on their incoming data. Each node type you write can be added to the agent dependency graph.
This is an example of a node that returns the intersection between a ray and an height field.
#include <AtomsGraph/Globals.h>
#include <Atoms/Globals.h>
#include <AtomsGraph/Ports.h>
#include <AtomsGraph/NodeFactory.h>
#include <Atoms/HeightFields.h>
#include <Atoms/HeightField.h>
class HeighFieldIntersectorNode :
public AtomsGraph::Node
{
public:
NODE_STANDARD_MEMBERS
HeighFieldIntersectorNode();
virtual ~HeighFieldIntersectorNode();
virtual bool compute();
private:
AtomsGraph::StringPort *m_heightFieldNamePort;
AtomsGraph::VectorPort *m_rayOriginPort;
AtomsGraph::VectorPort *m_rayDirectionPort;
AtomsGraph::VectorPort *m_outPositionPort;
AtomsGraph::VectorPort *m_outNormalPort;
};
#include "HeighFieldIntersectorNode.h"
#include <Atoms/MeshHeightField.h>
#define HEIGHTFIELDINTERSECTOR_NODE_ID 999999 // this must be unique
NODE_STANDARD_MEMBERS_IMPL(HeighFieldIntersectorNode)
unsigned int HeighFieldIntersectorNode::staticTypeId() { return HEIGHTFIELDINTERSECTOR_NODE_ID; }
std::string HeighFieldIntersectorNode::staticTypeStr() { return std::string("HeighFieldIntersectorNode"); }
HeighFieldIntersectorNode::HeighFieldIntersectorNode()
{
m_heightFieldNamePort = new AtomsGraph::StringPort("heightField");
m_rayOriginPort = new AtomsGraph::VectorPort("rayOrigin");
m_rayDirectionPort = new AtomsGraph::VectorPort("rayDirection");
m_outPositionPort = new AtomsGraph::VectorPort("outPosition");
m_outNormalPort = new AtomsGraph::VectorPort("outNormal");
// add input and output ports
addInputPort(m_heightFieldNamePort);
addInputPort(m_rayOriginPort);
addInputPort(m_rayDirectionPort);
addOutputPort(m_outPositionPort);
addOutputPort(m_outNormalPort);
}
HeighFieldIntersectorNode::~HeighFieldIntersectorNode()
{
// the parent destructor automatically deletes all the ports so we don't need to delete them here
}
bool HeighFieldIntersectorNode::compute()
{
Atoms::HeightFields& fields = Atoms::HeightFields::instance();
// get the height field name from the input port
const std::string& heightFieldName = m_heightFieldNamePort->getRef();
// check if the height field exist
auto heightField = fields.heightField(heightFieldName);
Atoms::MeshHeightField* meshHf = nullptr;
if (heightField && heightField->typeId() == Atoms::MeshHeightField::staticTypeId())
{
meshHf = static_cast<Atoms::MeshHeightField*>(heightField.get());
}
if (!meshHf)
return false;
// compute the intersection
Atoms::HeightField::HitResult hitResult;
if (meshHf->intersect(m_rayOriginPort->getRef(), m_rayDirectionPort->getRef(), hitResult, false))
{
AtomsCore::Vector3 projectedPos = m_rayOriginPort->getRef() + double(hitResult.t) * m_rayDirectionPort->getRef();
// compute the normal from the barycentric coords of the intersection
std::vector<AtomsCore::Vector3f> &normals = meshHf->mesh().normals();
AtomsCore::Vector3 hfNormal = hitResult.uv.x * normals[hitResult.faceId * 3] + hitResult.uv.y * normals[hitResult.faceId * 3 + 1] + (1.0f - hitResult.uv.x - hitResult.uv.y) * normals[hitResult.faceId * 3 + 2];
hfNormal.normalize();
// set the output ports
m_outPositionPort->set(projectedPos);
m_outNormalPort->set(hfNormal);
}
return true;
}
Register the new node to the factory
#include "HeighFieldIntersectorNode.h"
void FAtomsUnrealTestGameModule::StartupModule()
{
AtomsGraph::NodeFactory& manager = AtomsGraph::NodeFactory::instance();
manager.registerNode(HeighFieldIntersectorNode::staticTypeStr(), &HeighFieldIntersectorNode::creator);
}
void FAtomsUnrealTestGameModule::ShutdownModule()
{
AtomsGraph::NodeFactory& manager = AtomsGraph::NodeFactory::instance();
manager.deregisterNode(HeighFieldIntersectorNode::staticTypeStr());
}
, multiple selections available,
Related content
Writing an Atoms graph node
Writing an Atoms graph node
More like this
Writing an Atoms operator (AtomsUnreal)
Writing an Atoms operator (AtomsUnreal)
More like this
Writing an Atoms operator
Writing an Atoms operator
More like this
SOP Solver
SOP Solver
More like this
Access agent data (AtomsUnreal)
Access agent data (AtomsUnreal)
More like this
Scene initialization - Houdini
Scene initialization - Houdini
More like this
Copyright © 2017, Toolchefs LTD.