比較バージョン

キー

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

An Atoms Cache is composed by a cache header file, a folder containing all the agent types used by the agents and for each frame an header, frame, meta, pose file.

Cache header

The cache header is a MapMetadata cointaining the following key-value pairs:

  • agentIds: It's an IntArrayMetadata containing all the agents ids
  • cacheType: It's a StringMetadata. It's for internal use only and it must store the value "dynamic"
  • endFrame: It's an IntMetadata containing the end frame
  • startFrame: It's an IntMetadata containing the start frame

This file must have the following name extension: atoms (ex: tast_cache.atoms)

Agent types

To make the caches more portable, all the agent type files should be saved in a "agentTypes" subfolder next to the cache files.

The agent type can be serialized in a binary format:Atomsは、Agent Cacheのための独自の内部フォーマットを保有しています。どのファイルが作成されているかについての詳細を確認する場合は、Referenceをチェックしてください。


Cache Header

Cache Headerは、次のキーと値のペアを含むMapMetadataです。

  • agentIds:すべてのエージェントを含むIntArrayMetadata ID
  • cacheType:内部使用のみを目的としたStringMetadata。Value"dynamic"を格納する必要があります。
  • endFrame:終了フレームを含むIntMetadata
  • startFrame:開始フレームを含むIntMetadata

このファイルは、次の名前拡張子を持つ必要があります。

atoms(すなわちtest_cache.atoms)


Agent Types

キャッシュの移植性を高めるために、すべてのAgent TypeファイルはCacheファイルの横にある "agentTypes"サブフォルダに保存されています。
エージェントタイプは、バイナリ形式でシリアル化されています。

コード ブロック
languagecpp
Atoms::AgentTypePtr agentType = agent->agentType();
AtomsCore::Archive agentTypeArchive(agentType->memSize());
agentType->serialize(agentTypeArchive);
agentTypeArchive->writeToFile("myAgentType.agentType")

 

エージェントタイプをAtoms UI内で表示可能にするために、Event Simulationのpythonラッパースクリプトが同じフォルダーにエクスポートされます。

コード ブロック
languagecpp
Atomsstd::AgentTypePtrstring agentTypecachePath = agent->agentType();
"/atomsDemo/cache/";
std::string agentType = agent->agentType().name();

Atoms::AgentTypePtr agentTypePtr = agent->agentType();
AtomsCore::Archive agentTypeArchive(agentTypeagentTypePtr->memSize());
agentTypeagentTypePtr->serialize(agentTypeArchive);
agentTypeArchive->writeToFile("myAgentTypecachePath + "/agentTypes/"  + agentType + ".agentType")

 

To make an agent type visible inside the Atoms UI, an event simulation python wrapper script must be exported in the same folder.

コード ブロック
languagecpp



//store the python event wrapper
	const std::string cachePathpythonEvent =	
"/atomsDemo/cache/";
std::string agentType = agent->agentType().name();

Atoms::AgentTypePtr agentTypePtr = agent->agentType();
AtomsCore::Archive agentTypeArchive(agentTypePtr->memSize());
agentTypePtr->serialize(agentTypeArchive);
agentTypeArchive->writeToFile(cachePath + "/agentTypes/" 	"import AtomsCore\n"
	"import Atoms\n"
	"import imath\n"
	"\n"
	"class "+ agentType +"Cached(Atoms.SimulationEvent):\n"
	"\tagentTypeFile = r'" + agentTypePath + "'\n"
	"\teventName = '" + agentType + ".agentType")


//store the python event wrapper
	const std::string pythonEvent =	
	"import AtomsCoreCached'\n"
	"\tagentTypeName = '+ agentType + '\n"
	"\tgeoPath = ''\n"
	"import Atoms\tskinPath = ''\n"
	"import imath\tstateMachine = ''\n"
	"\n"
	"class "+ agentType +"Cached(Atoms.SimulationEvent\tdef __init__(self):\n"
	"\tagentTypeFile = r'" + agentTypePath + "'\t\tAtoms.SimulationEvent.__init__(self)\n"
	"\t\tself.setName(self.eventName)\n"
	"\teventName = '" + agentType + "Cached'n"
	"\tdef load(self):\n"
	"\t\tagentTypeNametaType = '+ agentType + 'Atoms.AgentType()\n"
	"\tgeoPatht\taTypeArchive = ''AtomsCore.Archive()\n"
	"\t\tskinPath = ''tif aTypeArchive.readFromFile(self.agentTypeFile):\n"
	"\tstateMachine = ''\t\t\taType.deserialise(aTypeArchive)\n"
	"\t\telse:\n"
	"\tdef __init__(self):\t\t\treturn\n"
	"\t\tAtoms.SimulationEvent.__init__(self)\n"
	"\t\tself.setName(tif self.eventName)geoPath:\n"
	"\n"
	"\tdef load(self):\n"
	"t\t\taTypetmeshMap = AtomsAtomsCore.AgentTypeMapMetadata()\n"
	"\t\t\taTypeArchivettypeArchive = AtomsCore.Archive()\n"
	"\t\t\tif aTypeArchivetypeArchive.readFromFile(self.agentTypeFilegeoPath):\n"
	"\t\t\taTypet\tmeshMap.deserialise(aTypeArchivetypeArchive)\n"
	"\t\telse:\n"
	"\t\t\treturntaType.metadata()["lowGeo"] = meshMap\n"
	"\n"
	"\t\tif self.geoPathskinPath:\n"
	"\t\t\tmeshMaptskinMap = AtomsCore.MapMetadata()\n"
	"\t\t\ttypeArchivetskinArchive = AtomsCore.Archive()\n"
	"\t\t\tif typeArchiveskinArchive.readFromFile(self.geoPathskinPath):\n"
	"\t\t\t\tmeshMaptskinMap.deserialise(typeArchiveskinArchive)\n"
	"\t\t\t\taType.metadata()["lowGeoskinGeo"] = meshMapskinMap\n"
	"\n"
	"\t\tif self.skinPath:\n"
	"\t\t\tskinMaptaType.metadata()["stateMachine"] = AtomsCore.MapMetadataStringMetadata(self.stateMachine)\n"
	"\t\t\tskinArchive = AtomsCore.Archive()\n"
	"\t\t\tif skinArchive.readFromFiletAtoms.AgentTypes.instance().addAgentType(self.skinPathagentTypeName, aType):\n";

	"\t\t\t\tskinMap.deserialise(skinArchive)\n"
	"\t\t\t\taType.metadata()["skinGeo"] = skinMap\n"
	"\n"
	"\t\taType.metadata()["stateMachine"] = AtomsCore.StringMetadata(self.stateMachine)\n"
	"\n"
	"\t\tAtoms.AgentTypes.instance().addAgentType(self.agentTypeName, aType)\n";

	std::string agentTypeWrapperPath = cachePath  + "/agenTypes/" + agentType + ".py";
	std::ofstream out(agentTypeWrapperPath);
    out << pythonEvent;
    out.close();std::string agentTypeWrapperPath = cachePath  + "/agenTypes/" + agentType + ".py";
	std::ofstream out(agentTypeWrapperPath);
    out << pythonEvent;
    out.close();


コード ブロック
languagepy
CACHED_AGENT_TYPE_SCRIPT = '''
import AtomsCore
import Atoms

class AgentTypeEvent$(Atoms.SimulationEvent):
\tagentTypeFile = r'agentTypeFile$'
\teventName = 'agentType$'
\tagentTypeName = 'agentTypeName$'
\tgeoPath = ''
\tskinPath = ''
\tstateMachine = ''

\tdef __init__(self):
\t\tAtoms.SimulationEvent.__init__(self)
\t\tself.setName(self.eventName)

\tdef load(self):
\t\taType = Atoms.AgentType()
\t\taTypeArchive = AtomsCore.Archive()
\t\tif aTypeArchive.readFromFile(self.agentTypeFile):
\t\t\taType.deserialise(aTypeArchive)
\t\telse:
\t\t\treturn

\t\tif self.geoPath:
\t\t\tmeshMap = AtomsCore.MapMetadata()
\t\t\ttypeArchive = AtomsCore.Archive()
\t\t\tif typeArchive.readFromFile(self.geoPath):
\t\t\t\tmeshMap.deserialise(typeArchive)
\t\t\t\taType.metadata()["lowGeo"] = meshMap

\t\tif self.skinPath:
\t\t\tskinMap = AtomsCore.MapMetadata()
\t\t\tskinArchive = AtomsCore.Archive()
\t\t\tif skinArchive.readFromFile(self.skinPath):
\t\t\t\tskinMap.deserialise(skinArchive)
\t\t\t\taType.metadata()["skinGeo"] = skinMap

\t\taType.metadata()["stateMachine"] = AtomsCore.StringMetadata(self.stateMachine)

\t\tAtoms.AgentTypes.instance().addAgentType(self.agentTypeName, aType)
'''

agentType = "atomsRobot"

# This serialize the agent type in python
aType = Atoms.AgentTypes.instance().agentType(agentType)
if aType:
  atArchive = AtomsCore.Archive(aType.memSize())
  aType.serialise(atArchive)
  atArchive.writeToFile(os.path.join(agentTypesPath, "%s.agentType" %
                                               (agentType)))

agentTypesPath = "/atomsDemo/cache/test_cache/agentTypes/"

agentTypeScript = CACHED_AGENT_TYPE_SCRIPT

af = os.path.normpath(os.path.join(agentTypesPath, "%s.agentType" %
                                               (agentType)))

agentTypeScript = agentTypeScript.replace("agentTypeFile$", af)
agentTypeScript = agentTypeScript.replace("agentType$","%sCached" %
                                                      agentType)
agentTypeScript = agentTypeScript.replace("agentTypeName$",
                                                      agentType)
agentTypeScript = agentTypeScript.replace("AgentTypeEvent$",
                                                      "%sCached" % (agentType))

with open(os.path.join(agentTypesPath, "%s.py" % (agentType)), "w") as pyFile:
	pyFile.write(agentTypeScript)
	pyFile.close()

Frame files

For each frame must have these four files:

  • header: basic info such as number of agents at the current frame, number of created agents and number of deleted agents
  • frame: agent data such as agent type, position, velocity, bbox and variation
  • meta: agents metadata
  • pose: agent skeleton data
Header file

The cache frame header is a MapMetadata cointaining the following key-value pairs:

  • agents: It's an IntArrayMetadata containing all the agents ids
  • agentsCreated: It's an IntArrayMetadata containing the id of the agents created at this frame.
  • agentsDeleted: It's an IntArrayMetadata containing the id of the agents deleted at this frame.
  • box: It's an BoxMetadata containing the bounding box at the current frame

This file must have the following extension: .$FRAME.header.atoms (ex: tast_cache.0010.header.atoms)

Frame file

The cache frame is a MapMetadata. Each entry in this map use the agent id as key while the value is another MapMetadata containing the following key-value pairs:

  • agentType: StringMetadata containing the agent type name
  • box: BoxMetadata containing the agent bounding box
  • position: Vector3Metadata containing the agent position
  • variation: StringMetadata containing the agent variation
  • velocity: Vector3Metadata containing the agent velocity
This is an example of frame data:
" % (agentType))

with open(os.path.join(agentTypesPath, "%s.py" % (agentType)), "w") as pyFile:
	pyFile.write(agentTypeScript)
	pyFile.close()

Frame files

キャッシュには、フレームごとに次の4つのファイルがあります。

  • header:現在のフレームのエージェント数、作成されたエージェントの数、削除されたエージェントの数などの基本情報
  • frame:エージェントの種類、位置、速度、bbox、バリエーションなどのエージェントデータ
  • meta:agents metadata
  • pose:agent skeleton data

Header file

Cache Frame Headerは、次のキーと値のペアを含むMapMetadataです。

  • agents:すべてのエージェントIDを含むIntArrayMetadata
  • agentsCreated:このフレームで作成されたエージェントのIDを含むIntArrayMetadata
  • agentsDeleted:このフレームで削除されたエージェントのIDを含むIntArrayMetadata
  • box:現在のフレームのバウンディングボックスを含むBoxMetadata


このファイルの拡張子は次のとおりです。

$ FRAME.header.atoms(つまりtest_cache.0010.header.atoms)


Frame file

CacheフレームはMapMetadataです。このマップの各エントリは、エージェントIDをキーとして使用し、値は次のキーと値のペアを含む別のMapMetadataです。

  • agentType:エージェントタイプ名を含むStringMetadata
  • box:エージェントバウンディングボックスを含むBoxMetadata
  • position:エージェントの位置を含むVector3Metadata
  • variation:エージェントバリエーションを含むStringMetadata
  • velocity:エージェントの速度を含むVector3Metadata

これは、フレームデータの例です。

  • "0":

- "agentType": StringMetadata("atomsRobot")

- "box": BoxMetadata(AtomsCore::Box(AtomsCore::Vector3(-10,-10,-10),AtomsCore::Vector3( 10, 10, 10)))

- "position": Vector3Metadata(AtomsCore::Vector3(0,0,0))

-

 

"velocity": Vector3Metadata(AtomsCore::Vector3(1.4354,0.234,0.54433))

  • "1":

- "agentType": StringMetadata("atomsRobot")

- "box": BoxMetadata(AtomsCore::Box(AtomsCore::Vector3(-50,-10,-50),AtomsCore::Vector3(-40, 10, -40)))

- "position": Vector3Metadata(AtomsCore::Vector3(-45,0,0))

- "velocity": Vector3Metadata(AtomsCore::Vector3(1.5464,0.124,0.76433))

  • "5":

- "agentType": StringMetadata("atomsRobot")

- "box": BoxMetadata(...)

- "position": Vector3Metadata(...)

- "velocity": Vector3Metadata(...)

  • ...

This file must have the following extension: .$FRAME.frame.atoms (ex: tast_cache.0010.frame.atoms)

Metafile

The cache meta file is a MapMetadata. Each entry in this map use the agent id as key while the value is another MapMetadata containing all the metadatas of the agent

This is an example:

このファイルの拡張子は以下のとおりです。

$ FRAME.frame.atoms(つまりtest_cache.0010.frame.atoms)


Metafile

Cache MetaファイルはMapMetadataです。このマップの各エントリは、エージェントIDをキーとして使用し、値はエージェントのすべてのメタデータを含む別のMapMetadataです。

これは一例です。

  • "0":
    - "position": Vector3Metadata(...)
    - "direction": Vector3Metadata(...)
    - "state": IntMetadata(...)
    - ...
  • "1":

    - "position": Vector3Metadata(...)
    - "direction": Vector3Metadata(...)
    - "state": IntMetadata(...)
    - ...

  • "1":

    - "position": Vector3Metadata(...)
    - "direction": Vector3Metadata(...)
    - "state": IntMetadata(...)
    - ...

  • ...

This file must have the following extension: .$FRAME.meta.atoms (ex: tast_cache.0010.meta.atoms)

Pose file

The cache pose file is a MapMetadata. Each entry in this map use the agent id as key while the value is a PoseMetadata that store the agent pose.

This file must have the following extension: .$FRAME.pose.atoms (ex: tast
  • ": IntMetadata(...)
    - ...

  • ...

このファイルの拡張子は次のとおりです。

$ FRAME.meta.atoms(つまりtest_cache.0010.pose.atoms)

Writing an Atoms cache

An atoms cache can be exported using the AtomsCache::exportCacheFrame() function. This function export only the frame files, the header and the agents type must be exported separately.

meta.atoms)


Pose file

Cache Pose fileは、MapMetadataです。このマップの各エントリは、エージェントIDをキーとして使用し、値はエージェントのポーズを格納するPoseMetadataです。
このファイルの拡張子は以下のとおりです。

$ FRAME.pose.atoms(つまりtest_cache.0010.pose.atoms)


Atoms Cacheの書き込み

AtomsCache :: exportCacheFrame()関数を使用して、Atoms Cacheをエクスポートできます。この関数は、フレームファイルだけをエクスポートします。HeaderとAgent Typeは、別々にエクスポートする必要があります。

コード ブロック
languagecpp
#include <Atoms/AtomsCache

std::string cachePath = "/atomsDemo/cache/";
std::string cacheName = "cache_test";
int startFrame = 1;
int endFrame = 2;

// list of agents groups to export
std::vector<AtomsPtr<Atoms::AgentGroup>> agentGroups;

// if you are in maya or houdini you can get the agent groups from the agents simulation
auto sims = Atoms::AgentsSimulations::instance()
auto sim = sims.begin().second;
for(unsigned int i=0; i < sim.numAgentGroups(); i++)
{
	agentGroups.push_back(sim.agentGroup(i));
}

// This maps the agent global id with the cache id 
std::unordered_map<size_t, size_t> cacheIdMap;

std::set<std::string> agentTypes;

// Add compression and use multithread 
size_t tags = AtomsCore::Archive::kRandomAccessCompress | AtomsCore::Archive::kMultithread;


for (unsigned int frame = startFrame; frame < endFrame; frame++)
{
	AtomsCache::exportCacheFrame(cachePath, cacheName, frame, agentGroups, cacheIdMap, agentTypes, tags);
}

// save the agent types
Atoms::AgentTypes& agentTypes = Atoms::AgentTypes::instance();
for(const std::string agentType: agentTypes)
{
	auto agentTypePtr = agentTypes->agentType(agentType);
	if (!agentTypePtr)
		continue;
	AtomsCore::Archive agentTypeArchive(agentTypePtr->memSize());
	agentType->serialize(agentTypeArchive);
	std::string agentTypePath = cachePath  + "/agenTypes/" + agentType + ".agentType";
	agentTypeArchive->writeToFile(agentTypePath);

	//store the python event wrapper
	const std::string pythonEvent =	
	"import AtomsCore\n"
	"import Atoms\n"
	"import imath\n"
	"\n"
	"class "+ agentType +"Cached(Atoms.SimulationEvent):\n"
	"\tagentTypeFile = r'" + agentTypePath + "'\n"
	"\teventName = '" + agentType + "Cached'\n"
	"\tagentTypeName = '+ agentType + '\n"
	"\tgeoPath = ''\n"
	"\tskinPath = ''\n"
	"\tstateMachine = ''\n"
	"\n"
	"\tdef __init__(self):\n"
	"\t\tAtoms.SimulationEvent.__init__(self)\n"
	"\t\tself.setName(self.eventName)\n"
	"\n"
	"\tdef load(self):\n"
	"\t\taType = Atoms.AgentType()\n"
	"\t\taTypeArchive = AtomsCore.Archive()\n"
	"\t\tif aTypeArchive.readFromFile(self.agentTypeFile):\n"
	"\t\t\taType.deserialise(aTypeArchive)\n"
	"\t\telse:\n"
	"\t\t\treturn\n"
	"\n"
	"\t\tif self.geoPath:\n"
	"\t\t\tmeshMap = AtomsCore.MapMetadata()\n"
	"\t\t\ttypeArchive = AtomsCore.Archive()\n"
	"\t\t\tif typeArchive.readFromFile(self.geoPath):\n"
	"\t\t\t\tmeshMap.deserialise(typeArchive)\n"
	"\t\t\t\taType.metadata()["lowGeo"] = meshMap\n"
	"\n"
	"\t\tif self.skinPath:\n"
	"\t\t\tskinMap = AtomsCore.MapMetadata()\n"
	"\t\t\tskinArchive = AtomsCore.Archive()\n"
	"\t\t\tif skinArchive.readFromFile(self.skinPath):\n"
	"\t\t\t\tskinMap.deserialise(skinArchive)\n"
	"\t\t\t\taType.metadata()["skinGeo"] = skinMap\n"
	"\n"
	"\t\taType.metadata()["stateMachine"] = AtomsCore.StringMetadata(self.stateMachine)\n"
	"\n"
	"\t\tAtoms.AgentTypes.instance().addAgentType(self.agentTypeName, aType)\n";

	std::string agentTypeWrapperPath = cachePath  + "/agenTypes/" + agentType + ".py";
	std::ofstream out(agentTypeWrapperPath);
    out << pythonEvent;
    out.close();
}


// write the cache header
AtomsCore::IntArrayMetadata agentIdsMeta;
std::vector<int>& agentIdsVec = agentIdsMeta.get();
agentIdsVec.reserve(cacheIdMap.size());
for (auto it=cacheIdMap.begin(); it != cacheIdMap.end(); it++)
{
	agentIdsVec.pushBack(it->second);
}

std::sort(agentIdsVec.begin(), agentIdsVec.end());

AtomsCore::MapMetadata cacheHeader;
cacheHeader.addEntry("startFrame", &AtomsCore::IntMetadata(startFrame));
cacheHeader.addEntry("endFrame", &AtomsCore::IntMetadata(endFrame));
cacheHeader.addEntry("cacheType", &AtomsCore::StringMetadata("dynamic"));
cacheHeader.addEntry("agentIds", &agentIdsMeta);

Reading an


Atoms

cache

Cacheの読み込み

Since the Atoms cache is composed by different MapMetadata serialized you can read them using the atoms serialization system.

If you are going to query multiple times some cache frames during a simulation, you can use the cache manager to increase the performance.Atoms Cacheは、様々なシリアル化されたMapMetadataで構成されているため、Atoms Serialization Systemを使用してそれらを読み取ることができます。
シミュレーション中に、異なるキャッシュフレームを複数回Queryする場合は、Cache Managerを使用して、パフォーマンスを向上させることができます。