受信データに基づいて、カスタム操作を実行するCustom Dependency Graphノードを作成できます。作成した各ノードタイプは、Agent Dependencyグラフに追加できます。
これは、レイとHeightフィールドの交差部分を返すノードの例です。
コード ブロック |
---|
|
#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;
};
#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 = heightFieldNamePort->getRef();
// check if the height field exist
AtomsUtils::Mesh* heightField = fields.heightField(heightFieldName);
if (!heightField)
return false;
float param, u, v;
unsigned int faceId = 0;
// compute the intersection
if (heightField->intersect(rayOriginPort->getRef(), m_rayDirectionPort->getRef(), param, faceId, u, v, false))
{
AtomsCore::Vector3 projectedPos = rayOriginPort->getRef() + double(param) * m_rayDirectionPort->getRef();
// compute the normal from the barycentric coords of the intersection
std::vector<AtomsCore::Vector3f> &normals = heightField->normals();
AtomsCore::Vector3 hfNormal = u * normals[faceId * 3] + v * normals[faceId * 3 + 1] + (1.0f - u - v) * normals[faceId * 3 + 2];
hfNormal.normalize();
// set the output ports
m_outPositionPort->set(projectedPos);
m_outNormalPort->set(hfNormal);
}
return true;
}
extern "C"
{
ATOMSPLUGIN_EXPORT bool initializePlugin()
{
AtomsUtils::Logger::info() << "Loading HeighFieldIntersectorNode plugin";
// Register the node to the factory
AtomsGraph::NodeFactory& manager = AtomsGraph::NodeFactory::instance();
manager.registerNode(HeighFieldIntersectorNode::staticTypeStr(), &HeighFieldIntersectorNode::creator);
return true;
}
ATOMSPLUGIN_EXPORT bool unitializePlugin()
{
AtomsUtils::Logger::info() << "Unloading HeighFieldIntersectorNode plugin";
// Deregister the node from the node factory
AtomsGraph::NodeFactory& manager = AtomsGraph::NodeFactory::instance();
manager.deregisterNode(HeighFieldIntersectorNode::staticTypeStr());
return true;
}
}
|