比較バージョン

キー

  • この行は追加されました。
  • この行は削除されました。
  • 書式設定が変更されました。

You can create custom dependency graph nodes, which carry out custom operations based on their incoming data. Each kind of node you write can be added to the dependency graph of an agent.

This is an example of a node that returns the intersection between a ray and and a height field.受信データに基づいて、カスタム操作を実行するCustom Dependency Graphノードを作成できます。作成した各ノードタイプは、Agent Dependencyグラフに追加できます。
これは、レイとHeightフィールドの交差部分を返すノードの例です。


コード ブロック
languagecpp
#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 deletedeletes 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;
	}
}


...