🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

C++/Assimp how to implement skeleton animations?

Started by
1 comment, last by SeanReid 1 month ago

I'm making a game in C++ and I'm using assimp for loading models and I want to move onto animations and to simply put it I'm confused on the animation pipeline(?) or overall process of loading an animation and playing it on a mesh/skeleton.

From what I've gathered the general gist of it seems to be load a mesh (loadMesh("path/to/mesh")) and create its bones/joints which would make up its skeleton and the mesh would probably reference this skeleton:

struct Mesh {
// buffers...
Skeleton skeleton;
}

Then an animation/animation clip (loadAnimation("path/to/animation")) is simply is just the duration and how the bones should move(?) and then in the end you just supply this clip to the skeleton:

myMesh.skeleton.playAnimation(myAnimationClip, ...);

That's where I'm at curious if I'm close or far off lol.

Advertisement

Hi, I am new to this forum, so this will be my first post.

I am working on a project called ogalib (https://github.com/NineTalesDigital/ogalib)

Inside the project, I have started working on an open-source version of my original game engine called Prime Engine. I make use of Assimp to load models and the animations contained inside them. If you download the ogalib project from GitHub, you can run the PrimeDemo project.

The PrimeDemo project is a simple program that loads and displays three types of assets: a static image, a 2D animated character, and finally a 3D model. The 3D model of a rhinoceros is what you would be interested in. The Prime Engine allows you to load a GLTF/GLB file from the raw source file and then use that content to be set on the Model object called "rhino".

refptr rhino = new Model();
GetContent("data/Asset/Rhino.glb", [=](Content* content) {
  rhino->SetContent(content);
});

Then at the bottom of the main method is the code to calculate it per-frame (to progress its animation), and then query some vertex ranges so that the model can be drawn.

if(rhino) {
  rhino->Calc(dt);
  ...
  rhino->Draw();
}

All of the code is in the Prime Engine if you are feeling adventurous in seeing how I use the parsed file provided from Assimp and TinyGLTF. At a high level for starters, you can add this code to the loading of the GLB file to print out the available animations detected in the GLB file:

refptr rhino = new Model();
GetContent("data/Asset/Rhino.glb", [=](Content* content) {
  rhino->SetContent(content);

  auto modelContent = content->GetAs<ModelContent>();
  size_t actionCount = modelContent->GetActionCount();
  for(size_t i = 0; i < actionCount; i++) {
    dbgprintf("action %zu: %s\n", i, modelContent->GetAction(i).name.c_str());
  }

  rhino->SetAction("Talking");
});

This added code will get the content as ModelContent (since the GLB produces a ModelContent object, a sub-class of Content), and from there you can get the number of actions and then print-out each action's name. You can use the string name of the action to change the animation, such as “Talking”.

This version of Prime Engine is a work-in-progress, and it only covers a small fraction of what my full-blown version can do. It was used in many games over the past decade including Mecho Wars, War Theatre, Mecho Tales, Plague Road, Bunny Raiders, and more.

None

This topic is closed to new replies.

Advertisement