Atoms Graphノードの書き込み
受信データに基づいて、カスタム操作を実行する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; } }
Copyright © 2017, Toolchefs LTD.