比較バージョン

キー

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

Atoms has several layout modules but you can create new modules with c++.  This example shows how create a layout module for generating agents along a input curve.

This example is made of two parts:

  • the layout generator responsible for creating the agents
  • a behaviour module responsible for creating the layout generator and attaching it to the agent group

Image Removed

Writing the curve layout generator

The layout generator object generates the description of new agents created at every frame. A generator can be static or dynamic. A static generator creates the agent descriptions only at the first frame, while a dynamic one can generate new agents at every frame. In this example our generator is static, since the agents are created only at the first frame along the curve. If you want to create a dynamic generator just use the setAsStaticgenerator(false) function inside the constructor.

The generate function creates a vector of AgentInitData objects. This object defines the position, direction, agent type, groupId of the new agents. The agent group uses this information to create thee new agents.Atomsには、いくつかのLayoutモジュールがありますが、C ++を使用して、新しいモジュールを作成できます。こちらの例では、入力カーブに沿ってエージェントを生成するためのLayoutモジュールを作成する方法を説明しています。

こちらの例は、2つの部分から構成されています。


  • エージェントの作成を担当するLayoutジェネレータ、レイアウトの作成を担当するBehaviourモジュール
  • ジェネレータとそれをエージェントグループにアタッチを実施

Image Added

Curve Layoutジェネレータを書く

Layoutジェネレータオブジェクトは、すべてのフレームで作成された新しいエージェントの描写を生成します。ジェネレータは、StaticでもDynamicのどちらでも構いません。Staticジェネレータは、最初のフレームでのみ、エージェントの描写を作成しますが、Dynamicジェネレータは、すべてのフレームで新しいエージェントを生成できます。この例では、エージェントはカーブに沿った最初のフレームでのみ作成されるので、ジェネレータはStaticです。Dynamicジェネレータを作成したい場合は、コンストラクタ内でsetAsStaticgenerator(false)関数を使用するだけです。


generate関数は、AgentInitDataオブジェクトのベクトルを作成します。このオブジェクトは、新しいエージェントの位置、方向、エージェントタイプ、グループIDを定義します。エージェントグループは、この情報を使用して新しいエージェントを作成します。

コード ブロック
languagecpp
#include <Atoms/LayoutGenerators/LayoutGenerator.h>
#include <AtomsUtils/Curve.h>
#include <Atoms/AgentTypes.h>

class CurveLayoutGenerator : public LayoutGenerator
{
public:

	CurveLayoutGenerator();

	virtual ~CurveLayoutGenerator();

	// the generator function
	virtual std::vector<AgentInitData> generate(double time);

	inline void setCurve(AtomsUtils::Curve& curve) { m_curve = curve; }

	inline void setDirection(AtomsCore::Vector3& dir) { m_direction = dir; }

	inline void setUpVector(AtomsCore::Vector3& dir) { m_upVector = dir; }

	inline void setNumberOfAgents(size_t value) { m_numberOfAgents = value; }

	inline void setDirectionType(short value) { m_directionType = value; }

	inline void setInvertDirection(short value) { m_invertDirection = value; }

	inline void setAgentTypeOverride(const std::map<int, std::string>& value) { m_agentTypeOverride = value; }

	inline void setDirectionOverride(const std::map<int, AtomsCore::Vector3>& value) { m_directionOverride = value; }

private:

	// Input curve
	AtomsUtils::Curve m_curve;

	// Agent direction
	AtomsCore::Vector3 m_direction;

	// Up vector
	AtomsCore::Vector3 m_upVector;

	// Agent direction override
	std::map<int, AtomsCore::Vector3> m_directionOverride;

	// Agent type override
	std::map<int, std::string> m_agentTypeOverride;

	// Number of agents along the curve
	size_t m_numberOfAgents;

	// Direction type: 0 - tangent, 1 - normal, 2 - custom
	short m_directionType;

	// Invert the direction
	bool m_invertDirection;
};

CurveLayoutGenerator::CurveLayoutGenerator(): LayoutGenerator(),
	m_direction(1.0,0.0,0.0),
	m_upVector(0.0,1.0,0.0),
	m_numberOfAgents(0),
	m_directionType(0),
	m_invertDirection(false)
{
	setAsStaticGenerator(true);
}

CurveLayoutGenerator::~CurveLayoutGenerator()
{

}

// the generator function since is a static generator this function is called once
std::vector<AgentInitData> CurveLayoutGenerator::generate(double time)
{
	// Check if the curve is a valid
curve

	if ((m_curve.cvs().size() < 2) || (m_numberOfAgents < 1))
		return std::vector<AgentInitData>();

	Atoms::AgentTypes &agTypes = Atoms::AgentTypes::instance();

	// initialize the vector
	std::vector<AgentInitData> data(m_numberOfAgents);

	// curve parameter step
	float curveStep = m_curve.maxU() / static_cast<float>(std::max(static_cast<size_t>(1), m_numberOfAgents - 1));
	for (size_t i = 0; i < m_numberOfAgents; i++)
	{
		float param = static_cast<float>(i) * curveStep;

		AgentInitData& agentData = data[i];

		// set the agent position
		agentData.position = m_curve.pointOnCurve(param);
		
		// set the agent group id, this must be unique
		agentData.groupId = i;
		
		// set the agent type checking if there is any override
		auto atIt = m_agentTypeOverride.find(i);
		if (atIt != m_agentTypeOverride.end())
		{
			agentData.agentType = agTypes.agentType(atIt->second);
		}
		else
		{
			agentData.agentType = agentType();
		}

		// set the agent direction checking if there is any override
		auto dIt = m_directionOverride.find(i);
		if (dIt != m_directionOverride.end())
		{
			agentData.direction = dIt->second;
		}
		else
		{
			switch (m_directionType)
			{
				case 0: // use the 
tanget
tangent
				{
					agentData.direction = m_curve.tangentOnCurve(param);
					break;
				}
				case 1: // use the normal
				{
					agentData.direction = m_curve.tangentOnCurve(param);
					agentData.direction = agentData.direction.cross(m_upVector);
					break;
				}
				default:
				{
					agentData.direction = m_direction;
					break;
				}
			}
		}

		if (m_invertDirection)
		{
			agentData.direction *= -1.0;
	
}
	}
return std::move(data); }

Writing the curve layout module

To use the curve layout generator a new behaviour modules is needed. This behaviour module exposes the generator attributes to the user and sends all the data to the generator itself.

	}

	return std::move(data);
}

Curve Layout モジュールを書く

Curve Layoutジェネレータを使用する場合は、新規のBehaviourモジュールが必要です。このBehaviourモジュールは、ジェネレータのアトリビュートをユーザーに公開し、すべてのデータをジェネレータ自体に送信します。

コード ブロック
languagecpp
#include <Atoms/BehaviourModule.h>
#include <Atoms/AgentTypes.h>
#include <Atoms/AgentGroup.h>
#include <AtomsCore/Metadata/IntMetadata.h>
#include <AtomsCore/Metadata/Vector3ArrayMetadata.h>
#include <AtomsCore/Metadata/StringMetadata.h>
#include <AtomsCore/Metadata/CurveMetadata.h>
#include <AtomsCore/Metadata/BoolMetadata.h>

class CurveGeneratorModule : public Atoms::BehaviourModule
{
	public:

	CurveGeneratorModule();

	~CurveGeneratorModule();

	virtual void initSimulation(Atoms::AgentGroup* agentGroup = nullptr);

	static Atoms::BehaviourModule* creator(const std::string& parameter);
};

CurveGeneratorModule::CurveGeneratorModule() :
	Atoms::BehaviourModule()
{
	AtomsCore::MapMetadata& metadata = attributes();
	AtomsCore::StringMetadata atype("atomsRobot");
	addAttribute("agentType", &atype, true);

	AtomsCore::CurveMetadata curve;
	metadata.addEntry("curve", &curve);

	AtomsCore::IntMetadata numAgents(10);
	metadata.addEntry("numAgents", &numAgents);

	AtomsCore::IntMetadata dirType(0);
	metadata.addEntry("directionType", &dirType);

	AtomsCore::BoolMetadata invDir(false);
	metadata.addEntry("invertDirection", &invDir);

	AtomsCore::Vector3Metadata dir(AtomsCore::Vector3(1.0, 0.0, 0.0));
	addAttribute("direction", &dir, true);

	AtomsCore::Vector3Metadata up(AtomsCore::Vector3(
0.
0
, 1
.0,
0.0)); //metadata.addEntry("direction", &dir
 1.0, 0.0));
	addAttribute("upVector", &up, false);
}

CurveGeneratorModule::~CurveGeneratorModule()
{}

void CurveGeneratorModule::initSimulation(Atoms::AgentGroup* agentGroup)
{
	// Get the module attributes
	AtomsCore::MapMetadata& metadata = attributes();

	AtomsPtr<AtomsCore::CurveMetadata> curvePtr = metadata.getTypedEntry<AtomsCore::CurveMetadata>("curve");
	AtomsPtr<AtomsCore::IntMetadata> numAgentsPtr = metadata.getTypedEntry<AtomsCore::IntMetadata>("numAgents");
	AtomsPtr<AtomsCore::IntMetadata> directionTypePtr = metadata.getTypedEntry<AtomsCore::IntMetadata>("directionType");
	AtomsPtr<AtomsCore::BoolMetadata> invertDirectionPtr = metadata.getTypedEntry<AtomsCore::BoolMetadata>("invertDirection");
	AtomsPtr<AtomsCore::Vector3Metadata> directionPtr = metadata.getTypedEntry<AtomsCore::Vector3Metadata>("direction");
	AtomsPtr<AtomsCore::Vector3Metadata> upPtr = metadata.getTypedEntry<AtomsCore::Vector3Metadata>("upVector");
	AtomsPtr<AtomsCore::StringMetadata> agentTypePtr = metadata.getTypedEntry<AtomsCore::StringMetadata>("agentType");

	// Check if the agent type is valid
	Atoms::AgentTypePtr aType = Atoms::AgentTypes::instance().agentType(agentTypePtr->value());
	if (!aType)
	{
		return;
	}

	// Get all agent type overrides
	AtomsPtr<AtomsCore::MapMetadata> atypeOverride = metadata.getTypedEntry<AtomsCore::MapMetadata>("agentType_override");

	std::map<int, std::string> aTypesOverride;
	for (auto it = atypeOverride->begin(); it != atypeOverride->end(); it++)
	{
		if (!it->second)
			continue;

		if (it->second->typeId() != AtomsCore::StringMetadata::staticTypeId())
			continue;

		auto value = std::static_pointer_cast<AtomsCore::StringMetadata>(it->second);
		if (!value)
			continue;

		Atoms::AgentTypePtr aType = Atoms::AgentTypes::instance().agentType(value->get());
		if (!aType)
		{
			continue;
		}

		aTypesOverride[std::stoi(it->first)] = value->get();
	}

	// Get all agent direction overrides
	AtomsPtr<AtomsCore::MapMetadata> directionOverride = metadata.getTypedEntry<AtomsCore::MapMetadata>("direction_override");

	std::map<int, AtomsCore::Vector3> dirOverride;
	for (auto it = directionOverride->begin(); it != directionOverride->end(); it++)
	{
		if (!it->second)
			continue;

		if (it->second->typeId() != AtomsCore::Vector3Metadata::staticTypeId())
			continue;

		auto value = std::static_pointer_cast<AtomsCore::Vector3Metadata>(it->second);
		if (value)
			dirOverride[std::stoi(it->first)] = value->get();
	}

	// Create the layout 
generato
generator and set all the attributes
	Atoms::CurveLayoutGenerator* curveLayout = new Atoms::CurveLayoutGenerator();
	curveLayout->setCurve(curvePtr->get());
	curveLayout->setNumberOfAgents(numAgentsPtr->value());
	curveLayout->setDirectionType(directionTypePtr->value());
	curveLayout-
>setCurve
>setInvertDirection(
curvePtr
invertDirectionPtr-
>get
>value());
	curveLayout-
>setNumberOfAgents
>setDirection(
numAgentsPtr
directionPtr->value());
	curveLayout-
>setDirectionType
>setUpVector(
directionTypePtr->value()
upPtr->value());
	curveLayout->setAgentTypeOverride(aTypesOverride);
	curveLayout->setDirectionOverride(dirOverride);

	Atoms::LayoutGeneratorPtr generator(curveLayout);

	generator->setAgentType(aType);
	
curveLayout
agentGroup-
>setInvertDirection(invertDirectionPtr->value()); curveLayout->setDirection(directionPtr->value()); curveLayout->setUpVector(upPtr->value()); curveLayout->setAgentTypeOverride(aTypesOverride); curveLayout->setDirectionOverride(dirOverride); Atoms::LayoutGeneratorPtr generator(curveLayout); generator->setAgentType(aType); agentGroup->setLayoutGenerator(generator); } Atoms::BehaviourModule* CurveGeneratorModule::creator(const std::string& parameter)
>setLayoutGenerator(generator);
}

Atoms::BehaviourModule* CurveGeneratorModule::creator(const std::string& parameter)
{
	return new CurveGeneratorModule();
}

extern "C"
{
    ATOMSPLUGIN_EXPORT bool initializePlugin() 
    {
	return true;
    }

    ATOMSPLUGIN_EXPORT bool unitializePlugin() 
    {
	return 
new CurveGeneratorModule(); }
true;
   
extern
 
"C"
}
{

    ATOMSPLUGIN_EXPORT bool 
initializePlugin
initializeScene()
    {
        Atoms::BehaviourModules& moduleManager = Atoms::BehaviourModules::instance();
	moduleManager.registerBehaviourModule("SimpleCurveLayout", &CurveGeneratorModule::creator, 	Atoms::BehaviourModules::kNative);
        return true;
    }
 
    ATOMSPLUGIN_EXPORT bool 
unitializePlugin
unitializeScene()
    {
Atoms::BehaviourModules& moduleManager = Atoms::BehaviourModules::instance();

moduleManager.deregisterBehaviourModule("SimpleCurveLayout");

        return true;
    }
}