This is an example of 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; }