/
C ++ Standalone Simulationの作成

C ++ Standalone Simulationの作成


#include <iostream>
#include <Atoms/Initialize.h>
#include <Atoms/AgentsSimulation.h>
#include <Atoms/AgentsSimulations.h>
#include <Atoms/SimulationTime.h>
#include <Atoms/AgentGroup.h>
#include <AtomsModules/Initialize.h>
#include <Atoms/BehaviourModules.h>
#include <chrono>
#include <Atoms/AnimationClip.h>
#include <Atoms/AnimationClips.h>
#include <Atoms/SimulationEvents.h>
#include <Atoms/GlobalNames.h>
#include <Atoms/SimulationEvent.h>
#include <AtomsCore/Metadata/Vector3Metadata.h>
#include <AtomsCore/Metadata/IntMetadata.h>
#include <AtomsCore/Metadata/BoolMetadata.h>
#include <AtomsCore/Metadata/DoubleMetadata.h>
#include <AtomsCore/Metadata/MapMetadata.h>
#include <AtomsCore/Metadata/StringMetadata.h>

/////////////////////////
// REGISTER CLIPS
/////////////////////////

template<const char* NAME, const char* CLIPNAME, int START, int END, int LOOP_BLEND, bool LOOP, bool IDLE>
class AtomsRobotClip : public Atoms::SimulationEvent
{
public:
	AtomsRobotClip() : Atoms::SimulationEvent()
	{
		setName(NAME);
	}

	virtual ~AtomsRobotClip()
	{

	}

	void load()
	{
		//CLIP = GLOBAL_NAMES.CLIP
		const char* eventName = NAME;
		const char* clipNameFile = CLIPNAME;
		const int blendFramesAfterFootUp = 4;
		const bool loop = LOOP;
		const int loopStart = START;
		const int loopEnd = END;
		const int loopBlend = 4;
		const bool idle = IDLE;
		const double direction[3] = { 1.0, 0.0, 0.0 };
		const int directionType = 1;
		const int directionFromJoints[2] = { 0, 1 };

		std::string clipPath = "";
		if (getenv("ATOMS_DATA"))
		{
			std::string dataPath = getenv("ATOMS_DATA");
			clipPath = dataPath + "/" + clipNameFile;
		}

		Atoms::AnimationClips& aClips = Atoms::AnimationClips::instance();
		aClips.addAnimationClip(eventName, clipPath, true);
		Atoms::AnimationClipPtr acPtr = aClips.animationClip(eventName);
		if (!acPtr)
			return;

		AtomsCore::MapMetadata& metadataMap = acPtr->metadata();

		metadataMap.addEntry(ATOMS_CLIP_BLEND_FRAMES_AFTER_FOOT_UP, &AtomsCore::IntMetadata(blendFramesAfterFootUp));
		metadataMap.addEntry(ATOMS_CLIP_LOOP, &AtomsCore::BoolMetadata(loop));
		metadataMap.addEntry(ATOMS_CLIP_LOOP_START, &AtomsCore::IntMetadata(loopStart));
		metadataMap.addEntry(ATOMS_CLIP_LOOP_END, &AtomsCore::IntMetadata(loopEnd));
		metadataMap.addEntry(ATOMS_CLIP_LOOP_NUM_BLEND_FRAMES, &AtomsCore::IntMetadata(loopBlend));

		if (directionType)
		{
			acPtr->setDirectionType(Atoms::AnimationClip::DirectionType::kStatic);
		}
		else if (directionType == 0)
		{
			acPtr->setDirectionType(Atoms::AnimationClip::DirectionType::kPelvis);
		}
		else
		{
			acPtr->setDirectionType(Atoms::AnimationClip::DirectionType::kJoints);
		}
		acPtr->setDirection(AtomsCore::Vector3(direction[0], direction[1], direction[2]));
		acPtr->setDirectionFromJoints(directionFromJoints[0], directionFromJoints[1]);
		acPtr->setIdle(idle);
	}

	static Atoms::SimulationEvent* creator(const std::string& parameter)
	{
		return new AtomsRobotClip();
	}
};

extern const char robotIdleName[] = "atomsRobotIdle";
extern const char robotIdleClip[] = "atomsRobot_idle.fbx";
typedef AtomsRobotClip<robotIdleName, robotIdleClip, 0, 1, 0, true, false> AtomsRobotIdleClip;

extern const char robotWalkName[] = "atomsRobotWalk";
extern const char robotWalkClip[] = "atomsRobot_walk.fbx";
typedef AtomsRobotClip<robotWalkName, robotWalkClip, 21, 50, 4, true, false> AtomsRobotWalkClip;

extern const char robotRunName[] = "atomsRobotRun";
extern const char robotRunClip[] = "atomsRobot_run.fbx";
typedef AtomsRobotClip<robotRunName, robotRunClip, 6, 26, 4, true, false> AtomsRobotRunClip;

extern const char robotIdleToWalkName[] = "atomsRobotIdleToWalk";
extern const char robotIdleToWalkClip[] = "atomsRobot_idleToWalk.fbx";
typedef AtomsRobotClip<robotIdleToWalkName, robotIdleToWalkClip, 17, 66, 6, false, false> AtomsRobotIdleToWalkClip;

extern const char robotWalkToRunName[] = "atomsRobotWalkToRun";
extern const char robotWalkToRunClip[] = "atomsRobot_walkToRun.fbx";
typedef AtomsRobotClip<robotWalkToRunName, robotWalkToRunClip, 0, 45, 3, false, false> AtomsRobotWalkToRunClip;

void registerAtomsClips(Atoms::AgentsSimulation& sim)
{
	Atoms::SimulationEvents& events = Atoms::SimulationEvents::instance();
	events.registerSimulationEvent(robotIdleName, AtomsRobotIdleClip::creator, Atoms::SimulationEvent::kAnimClipNative);
	events.registerSimulationEvent(robotWalkName, AtomsRobotWalkClip::creator, Atoms::SimulationEvent::kAnimClipNative);
	events.registerSimulationEvent(robotRunName, AtomsRobotRunClip::creator, Atoms::SimulationEvent::kAnimClipNative);
	events.registerSimulationEvent(robotIdleToWalkName, AtomsRobotIdleToWalkClip::creator, Atoms::SimulationEvent::kAnimClipNative);
	events.registerSimulationEvent(robotWalkToRunName, AtomsRobotWalkToRunClip::creator, Atoms::SimulationEvent::kAnimClipNative);
	
	sim.addAnimationClipEvent(events.createSimulationEvent(robotIdleName));
	sim.addAnimationClipEvent(events.createSimulationEvent(robotWalkName));
	sim.addAnimationClipEvent(events.createSimulationEvent(robotRunName));
	sim.addAnimationClipEvent(events.createSimulationEvent(robotIdleToWalkName));
	sim.addAnimationClipEvent(events.createSimulationEvent(robotWalkToRunName));
}

/////////////////////////
// REGISTER AGENT TYPE
/////////////////////////

template<
	const char* NAME,
	const char* SKEL_PATH,
	const char* GEO_PATH,
	const char* SKIN_PATH,
	const char* STATE_MACHINE>
class SimTestAgentType : public Atoms::SimulationEvent
{
public:
	

	SimTestAgentType() : Atoms::SimulationEvent()
	{
		setName(NAME);
	}

	virtual ~SimTestAgentType()
	{

	}

	void load()
	{
		const char* stateMachine = STATE_MACHINE;
		const double scaleMultiplier = 1.0;

		std::string skeletonPath = "";
		std::string geoPath = "";
		std::string skinPath = "";
		if (getenv("ATOMS_DATA"))
		{
			std::string dataPath = getenv("ATOMS_DATA");
			skeletonPath = dataPath + "/" + SKEL_PATH;
			geoPath = dataPath + "/" + GEO_PATH;
			skinPath = dataPath + "/" + SKIN_PATH;
		}

		AtomsCore::Skeleton skel(1);
		AtomsCore::Archive	skeletonArchive;
		if (skeletonArchive.readFromFile(skeletonPath))
		{
			skeletonArchive >> skel;
		}
		else
		{
			return;
		}

		Atoms::AgentType aType;
		aType.setSkeleton(skel);

		AtomsCore::MapMetadata meshMap;
		AtomsCore::Archive typeArchive;
		if (typeArchive.readFromFile(geoPath))
		{
			meshMap.deserialise(typeArchive);
			aType.metadata().addEntry(ATOMS_AGENT_TYPE_LOW_GEO, &meshMap);
		}

		AtomsCore::MapMetadata skinMap;
		AtomsCore::Archive skinArchive;
		if (skinArchive.readFromFile(skinPath))
		{
			skinMap.deserialise(skinArchive);
			aType.metadata().addEntry(ATOMS_AGENT_TYPE_SKIN_GEO, &skinMap);
		}


		aType.metadata().addEntry(ATOMS_AGENT_TYPE_STATE_MACHINE, &AtomsCore::StringMetadata(stateMachine));
		aType.metadata().addEntry(ATOMS_AGENT_TYPE_SCALE_MULTIPLIER, &AtomsCore::DoubleMetadata(scaleMultiplier));

		Atoms::AgentTypes::instance().addAgentType(NAME, aType);
	}

	void unload()
	{
		Atoms::AgentTypes::instance().removeAgentType(NAME);
	}

	static Atoms::SimulationEvent* creator(const std::string& parameter)
	{
		return new SimTestAgentType();
	}
};

extern const char atomsRobotName[] = "atomsRobot";
extern const char atomsRobotSkel[] = "atomsRobot.atomsskel";
extern const char atomsRobotGeo[] = "atomsRobot.geos";
extern const char atomsRobotSkin[] = "atomsRobot_skin.geos";
extern const char atomsRobotStateMachineName[] = "atomsRobotStateMachine";
typedef SimTestAgentType<atomsRobotName, atomsRobotSkel, atomsRobotGeo, atomsRobotSkin, atomsRobotStateMachineName> AtomsRobotAgentType;

void registerAgentType(Atoms::AgentsSimulation& sim)
{
	Atoms::SimulationEvents& events = Atoms::SimulationEvents::instance();
	events.registerSimulationEvent(atomsRobotName, AtomsRobotAgentType::creator, Atoms::SimulationEvent::kAgentTypeNative);
	sim.addAgentTypeEvent(events.createSimulationEvent(atomsRobotName));
}

/////////////////////////////////
// Register state machine
/////////////////////////////////

void registerStateMachine(Atoms::AgentsSimulation& sim)
{
	Atoms::StateMachines& stateMachineManager = Atoms::StateMachines::instance();
	Atoms::StateMachine stateMachine;
	Atoms::AnimationState currentAnimState("idle", 0, AtomsCore::Vector3(0.200000, 0.200000, 0.200000), 3, 3);
	currentAnimState.addClip(Atoms::AnimationStateClip("atomsRobotIdle", 0, 0, 0.000000, 0.000000));
	stateMachine.addAnimationState(currentAnimState);
	currentAnimState = Atoms::AnimationState("walk", 1, AtomsCore::Vector3(0.200000, 0.200000, 0.200000), 3, 3);
	currentAnimState.addClip(Atoms::AnimationStateClip("atomsRobotWalk", 0, 0, 0.000000, 0.000000));
	stateMachine.addAnimationState(currentAnimState);
	currentAnimState = Atoms::AnimationState("run", 2, AtomsCore::Vector3(0.200000, 0.200000, 0.200000), 3, 3);
	currentAnimState.addClip(Atoms::AnimationStateClip("atomsRobotRun", 0, 0, 0.000000, 0.000000));
	stateMachine.addAnimationState(currentAnimState);
	currentAnimState = Atoms::AnimationState("idleToWalk", -1, AtomsCore::Vector3(0.200000, 0.200000, 0.200000), 3, 3);
	currentAnimState.addClip(Atoms::AnimationStateClip("atomsRobotIdleToWalk", 0, 0, 0.000000, 0.000000));
	stateMachine.connect("idle", "walk", currentAnimState);
	currentAnimState = Atoms::AnimationState("walkToRun", -1, AtomsCore::Vector3(0.200000, 0.200000, 0.200000), 3, 3);
	currentAnimState.addClip(Atoms::AnimationStateClip("atomsRobotWalkToRun", 0, 0, 0.000000, 0.000000));
	stateMachine.connect("walk", "run", currentAnimState);
	stateMachineManager.addStateMachine("atomsRobotStateMachine", stateMachine, true);
}

//////////////////////////////////
// Main simulation
//////////////////////////////////

int main()
{
	Atoms::initAtoms();
	AtomsModules::initAtomsModules();
	

	Atoms::AgentsSimulation simulation;
	Atoms::AgentsSimulations::instance().addAgentsSimulation("main", &simulation);

	registerAtomsClips(simulation);
	registerStateMachine(simulation);
	registerAgentType(simulation);


	Atoms::BehaviourModules& modulesFactory = Atoms::BehaviourModules::instance();
	AtomsPtr<Atoms::AgentGroup> agGroup(new Atoms::AgentGroup());
	agGroup->setMultithread(true);
	simulation.addAgentGroup(agGroup);

	auto gridLayout = modulesFactory.createBehaviourModule("gridLayout");
	gridLayout->attributes().getTypedEntry<AtomsCore::StringMetadata>("agentType")->set("atomsRobot");
	gridLayout->attributes().getTypedEntry<AtomsCore::Vector3Metadata>("size")->set(AtomsCore::Vector3(50,0,50));
	auto stateMachine = modulesFactory.createBehaviourModule("stateMachine");
	stateMachine->attributes().getTypedEntry<AtomsCore::IntMetadata>("state")->set(1);
	agGroup->addBehaviourModule("gridLayout", gridLayout);
	agGroup->addBehaviourModule("stateMachine", stateMachine);
	
	Atoms::SimulationTime& atomsTime = Atoms::SimulationTime::instance();
	atomsTime.set(0);
	atomsTime.setFps(24.0);

	
	simulation.initSimulation();

	for (unsigned int i = 0; i < 50; i++)
	{
		atomsTime.set(i);
		auto start = std::chrono::high_resolution_clock::now();
		simulation.initFrame();
		simulation.computeFrame();
		simulation.endFrame();
		auto end = std::chrono::high_resolution_clock::now();
		auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
		std::cout << "Frame " << i << " " << elapsed <<"ms " << 1.0 /(static_cast<double>(elapsed)*0.001) <<"fps" << std::endl;
	}

	simulation.endSimulation();
	return 0;
}

Related content

Atomsオブジェクトの解析
Atomsオブジェクトの解析
More like this
Agent Aim
More like this
Agent Groupを作成する
Agent Groupを作成する
More like this
Animation Clipの作成
Animation Clipの作成
More like this
アニメーションのエクスポート
アニメーションのエクスポート
More like this
Agent Typeの作成
Agent Typeの作成
More like this

Copyright © 2017, Toolchefs LTD.