Atoms Crowd  7.0.0
Creating a 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;
}
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)
{
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::Archive skeletonArchive;
if (skeletonArchive.readFromFile(skeletonPath))
{
skeletonArchive >> skel;
}
else
{
return;
}
aType.setSkeleton(skel);
AtomsCore::Archive typeArchive;
if (typeArchive.readFromFile(geoPath))
{
meshMap.deserialise(typeArchive);
aType.metadata().addEntry(ATOMS_AGENT_TYPE_LOW_GEO, &meshMap);
}
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));
}
void unload()
{
}
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)
{
events.registerSimulationEvent(atomsRobotName, AtomsRobotAgentType::creator, Atoms::SimulationEvent::kAgentTypeNative);
sim.addAgentTypeEvent(events.createSimulationEvent(atomsRobotName));
}
// Register state machine
void registerStateMachine(Atoms::AgentsSimulation& sim)
{
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()
{
AtomsModules::initAtomsModules();
registerAtomsClips(simulation);
registerStateMachine(simulation);
registerAgentType(simulation);
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);
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;
}
Agent group.
Definition: AgentGroup.h:36
Agent type.
Definition: AgentType.h:30
void setSkeleton(const AtomsCore::Skeleton &skeleton)
Sets the agent type skeleton.
AtomsCore::MapMetadata & metadata()
Gets the metadata map.
Definition: AgentType.impl.h:21
void addAgentType(const std::string &name, const AgentType &agentType, bool replace=true)
Adds an agent type to the map.
static AgentTypes & instance()
Singleton access for global data.
void removeAgentType(const std::string &name)
Removes an agent type from the map.
Agent simulation.
Definition: AgentsSimulation.h:24
void addAgentTypeEvent(AtomsPtr< SimulationEvent > &simEvent, bool replace=true)
Adds a simulation event.
void endFrame()
End frame.
void endSimulation()
End simulation.
void computeFrame()
Compute frame.
void initSimulation()
Init simulation.
void addAnimationClipEvent(AtomsPtr< SimulationEvent > &simEvent, bool replace=true)
Adds a simulation event.
void initFrame()
Init Frame.
void addAgentGroup(AtomsPtr< AgentGroup > &aGroup)
Adds an agent group.
static AgentsSimulations & instance()
Singleton access.
void addAgentsSimulation(const std::string &name, AtomsPtr< AgentsSimulation > &agentSim, bool replace=true)
Adds an agent simulation.
Animation clips manager.
Definition: AnimationClips.h:23
AnimationClipPtr addAnimationClip(const std::string &name, const std::string &filePath, bool replace=true)
Add an animation clip to the map.
AnimationClipCPtr animationClip(const std::string &name) const
Return an animation clips.
static AnimationClips & instance()
Singleton access.
Animation State clip.
Definition: AnimationStateClip.h:23
Animation State.
Definition: AnimationState.h:25
Behaviour module factory.
Definition: BehaviourModules.h:22
AtomsPtr< BehaviourModule > createBehaviourModule(const std::string &name)
Creates a behaviour module.
static BehaviourModules & instance()
Singleton access.
Simiation Event.
Definition: SimulationEvent.h:22
virtual void setName(const std::string &name)
Sets the name.
Definition: SimulationEvent.impl.h:16
virtual void unload()
Unload fuction.
virtual void load()
Load fuction.
Simulation event factory.
Definition: SimulationEvents.h:24
static SimulationEvents & instance()
Singleton access.
bool registerSimulationEvent(const std::string &eventName, creatorFn func, unsigned int moduleType=SimulationEvent::kNative, bool replace=false)
Registers a behaviour module in the factory.
AtomsPtr< SimulationEvent > createSimulationEvent(const std::string &name)
Creates a SimulationEvent.
Global simulation time.
Definition: SimulationTime.h:21
void setFps(double fps)
Sets the fps.
Definition: SimulationTime.impl.h:32
static SimulationTime & instance()
Singleton access.
void set(double value)
Sets the time.
Definition: SimulationTime.impl.h:27
State machine.
Definition: StateMachine.h:27
void connect(const std::string &fromState, const std::string &toState, AnimationState &transition)
Connects two states.
void addAnimationState(const AnimationState &state)
Adds animation state.
Definition: StateMachine.impl.h:11
Container for all state machines.
Definition: StateMachines.h:21
void addStateMachine(const std::string &name, const StateMachine &stateMachine, bool replace=true)
Add a state machine to the map.
static StateMachines & instance()
Singleton access.
Archive class.
Definition: Serialiser.h:29
bool readFromFile(const std::string &fileName)
Reads a file and store inside the binary stream.
MapMetadata class.
Definition: MapMetadata.h:24
void addEntry(const Key &key, AtomsPtr< Metadata > &data, bool cloneData=true)
Add an entry.
bool deserialise(Archive &inStream)
Deserialise.
Skeleton class.
Definition: Skeleton.h:68
AtomsMath::Vector3 Vector3
Vector3 class.
Definition: AtomsMath.h:57
Atoms namespace.
Definition: Agent.h:29
AtomsPtr< AnimationClip > AnimationClipPtr
animation clip pointer
Definition: AnimationClip.h:28
ATOMS_EXPORT void initAtoms()
Initialize atoms core.