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.