Writing a skeleton loader
If you want use a custom skeleton format you can extend atoms with a new skeleton loader. To add a new skeleton format you must create a new class definition extending the Atoms::BaseSkeletonLoader. Then you must register the new loader class from inside an atoms plugin.
Class definition
#include <Atoms/Globals.h>
#include <AtomsCore/Metadata/MapMetadata.h>
#include <Atoms/Loaders/BaseSkeletonLoader.h>
#define kFooSkeletonLoaderId 101
namespace Atoms
{
class ATOMSPLUGIN_EXPORT FooSkeletonLoader : public BaseSkeletonLoader
{
public:
//! Type string
/*!
\return Class type string
*/
std::string typeStr() const;
//! Class static type string. This is also the file extension of your file format
static std::string const staticTypeStr;
//! Type id
/*!
\return Class type id
*/
unsigned int typeId() const;
//! Class static type id
static const unsigned int staticTypeId;
//! Constructor
FooMeshLoader();
//! Destructor
~FooMeshLoader();
//! Creator function
/*!
\return Return a new AlembicMeshLoader object
*/
static AtomsPtr<BaseMeshLoader> creator();
//! load
/*!
Load an atoms file
*/
AtomsPtr<AtomsCore::MapMetadata> load(const std::string &filePath, const std::string& filter = "*");
};
}
namespace Atoms
{
std::string const FooSkeletonLoader::staticTypeStr = "foo"; // the file extension
std::string FooSkeletonLoader::typeStr() const
{
return FooSkeletonLoader::staticTypeStr;
}
const unsigned int FooSkeletonLoader::staticTypeId = kFooSkeletonLoaderId ;
unsigned int FooSkeletonLoader::typeId() const
{
return FooSkeletonLoader::staticTypeId;
}
FooSkeletonLoader::FooSkeletonLoader() :
BaseMeshLoader()
{
}
FooMeshLoader::~FooMeshLoader()
{
}
AtomsPtr<BaseMeshLoader> FooSkeletonLoader::creator()
{
return std::dynamic_pointer_cast<BaseSkeletonLoader>(std::make_shared<FooSkeletonLoader>());
}
AtomsCore::Skeleton FooSkeletonLoader::load(const std::string &filePath)
{
// This is the actual loader that atoms use to load the atomsskel
// Change it to support your custom format
// If the skeleton is not valid, always return a valid skeleton like in this example
AtomsCore::Skeleton skel(1);
AtomsCore::Archive skinGeoArc;
if (!skinGeoArc.readFromFile(filePath))
{
AtomsUtils::Logger::warning() << "Could not read " << filePath;
AtomsUtils::Logger::warning() << "Creating default skeleton";
skel.addPelvis(0);
skel.setRoot(0);
skel.joint(0).setName("root");
skel.buildIkData();
skel.buildDetachedJointsList();
skel.buildJointNameMap();
return skel;
}
skinGeoArc >> skel;
return std::move(skel);
}
}
Atoms calls the load function to read the new skeleton format. This function must fill and return a Skeleton object.
Register the new loader to atoms
extern "C"
{
ATOMSPLUGIN_EXPORT bool initializePlugin()
{
SkeletonLoaderFactory& factory = SkeletonLoaderFactory::instance();
factory.registerSkeletonLoader(FooSkeletonLoader::staticTypeStr, &FooSkeletonLoader::creator);
}
}
Compile the plugin
Windows:
In visual studio create a dll projects, add the atoms, tbb and openexr includes and add
BUILD_ATOMSPLUGIN,WIN,_CRT_SECURE_NO_WARNINGS,_CRT_NONSTDC_NO_DEPRECATE
to the preprocessor definitions..
Linux:
Compile as a shared object adding the atoms, tbb and opendexr includes and BUILD_ATOMSPLUGIN to the preprocessor definitions.
Use the plugin
Add to the ATOMS_PLUGINS_PATH environment variable the folder where the plugin is located.
Copyright © 2017, Toolchefs LTD.