メタデータの末尾にスキップ
メタデータの先頭に移動

このページの古いバージョンを表示しています。現在のバージョンを表示します。

現在のバージョンとの相違点 ページ履歴を表示

« 前のバージョン バージョン 4 次のバージョン »

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.


#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");

	addInputPort(m_heightFieldNamePort);
	addInputPort(m_rayOriginPort);
	addInputPort(m_rayDirectionPort);
	addOutputPort(m_outPositionPort);
	addOutputPort(m_outNormalPort);
}

HeighFieldIntersectorNode::~HeighFieldIntersectorNode()
{
	// the parent destructor automatically delete all the ports so don't need to delete them here
}

bool HeighFieldIntersectorNode::compute()
{
	Atoms::HeightFields& fields = Atoms::HeightFields::instance();
	const std::string& heightFieldName = heightFieldNamePort->getRef();

	AtomsUtils::Mesh* heightField = fields.heightField(heightFieldName);
	if (!heightField)
		return false;

	float param, u, v;
	unsigned int faceId = 0;
	if (heightField->intersect(rayOriginPort->getRef(), m_rayDirectionPort->getRef(), param, faceId, u, v, false))
	{
		AtomsCore::Vector3 projectedPos = rayOriginPort->getRef() + double(param) * m_rayDirectionPort->getRef();
		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();
		m_outPositionPort->set(projectedPos);
		m_outNormalPort->set(hfNormal);
	}
		
	return true;
}

extern "C"
{
	ATOMSPLUGIN_EXPORT bool initializePlugin()
	{
		AtomsUtils::Logger::info() << "Loading HeighFieldIntersectorNode plugin";
		AtomsGraph::NodeFactory& manager = AtomsGraph::NodeFactory::instance();
		manager.registerNode(HeighFieldIntersectorNode::staticTypeStr(), &HeighFieldIntersectorNode::creator);
		return true;
	}

	ATOMSPLUGIN_EXPORT bool unitializePlugin()
	{
		AtomsUtils::Logger::info() << "Unloading HeighFieldIntersectorNode plugin";
		AtomsGraph::NodeFactory& manager = AtomsGraph::NodeFactory::instance();
		manager.deregisterNode(HeighFieldIntersectorNode::staticTypeStr());
		return true;
	}
}


  • ラベルがありません