Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update actor animation tutorial #144

Merged
merged 5 commits into from
Sep 28, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions examples/actor_animation/GlutWindow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ void updatePose(double _time)
// manually update the bone pose
for (auto &v : g_visuals)
{
//! [update pose]
std::map<std::string, ignition::math::Matrix4d> animFrames;
animFrames = g_skelAnim->PoseAt(_time, true);
std::map<std::string, ignition::math::Matrix4d> skinFrames;
Expand All @@ -257,13 +258,11 @@ void updatePose(double _time)
std::string animNodeName = pair.first;
auto animTf = pair.second;

//! [update pose]
std::string skinName =
g_skel->NodeNameAnimToSkin(g_animIdx, animNodeName);
ignition::math::Matrix4d skinTf =
g_skel->AlignTranslation(g_animIdx, animNodeName)
* animTf * g_skel->AlignRotation(g_animIdx, animNodeName);
//! [update pose]

skinFrames[skinName] = skinTf;
}
Expand All @@ -272,6 +271,7 @@ void updatePose(double _time)
ir::MeshPtr mesh =
std::dynamic_pointer_cast<ir::Mesh>(v->GeometryByIndex(0));
mesh->SetSkeletonLocalTransforms(skinFrames);
//! [update pose]
}
}

Expand All @@ -281,11 +281,13 @@ void updateTime(double _time)
// set time to advance animation
for (auto &v : g_visuals)
{
//! [update actor]
ir::MeshPtr mesh =
std::dynamic_pointer_cast<ir::Mesh>(v->GeometryByIndex(0));
mesh->UpdateSkeletonAnimation(
std::chrono::duration_cast<std::chrono::steady_clock::duration>(
std::chrono::duration<double>(_time)));
//! [update actor]
}
}

Expand Down Expand Up @@ -508,17 +510,13 @@ void initContext()
//////////////////////////////////////////////////
void initAnimation()
{
//! [init animation]
if (!g_skel || g_skel->AnimationCount() == 0)
{
std::cerr << "Failed to load animation." << std::endl;
return;
}
//! [init animation]

//! [index animation]
g_skelAnim = g_skel->Animation(g_animIdx);
//! [index animation]

g_startTime = std::chrono::steady_clock::now();
}
Expand Down
14 changes: 8 additions & 6 deletions examples/actor_animation/Main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,16 @@ void buildScene(ScenePtr _scene, std::vector<VisualPtr> &_visuals,
// create a visual for the actor, attach mesh and get skeleton
// Skeleton will be animated by GlutWindow

//! [create mesh]
//! [load mesh]
ignmsg << "Creating mesh with animations..." << std::endl;
MeshDescriptor descriptor;
descriptor.meshName = common::joinPaths(RESOURCE_PATH, "walk.dae");
common::MeshManager *meshManager = common::MeshManager::Instance();
descriptor.mesh = meshManager->Load(descriptor.meshName);
//! [create mesh]
//! [load mesh]

// add bvh animation
//! [add animation]
std::string bvhFile = common::joinPaths(RESOURCE_PATH, "cmu-13_26.bvh");
double scale = 0.055;
_skel = descriptor.mesh->MeshSkeleton();
Expand All @@ -83,6 +84,7 @@ void buildScene(ScenePtr _scene, std::vector<VisualPtr> &_visuals,
ignmsg << "Loaded animations: " << std::endl;
for (unsigned int i = 0; i < _skel->AnimationCount(); ++i)
ignmsg << " * " << _skel->Animation(i)->Name() << std::endl;
//! [add animation]

unsigned int size = 25;
double halfSize = size * 0.5;
Expand All @@ -103,18 +105,18 @@ void buildScene(ScenePtr _scene, std::vector<VisualPtr> &_visuals,
actorVisual->SetLocalRotation(0, 0, 3.14);
//! [create a visual for the actor]

//! [check skeleton]
//! [create mesh]
auto mesh = _scene->CreateMesh(descriptor);
if (!mesh)
{
std::cerr << "Failed to load mesh with animation." << std::endl;
return;
}
//! [check skeleton]
//! [added mesh]
//! [create mesh]
//! [attach mesh]
actorVisual->AddGeometry(mesh);
root->AddChild(actorVisual);
//! [added mesh]
//! [attach mesh]

_visuals.push_back(actorVisual);
}
Expand Down
73 changes: 38 additions & 35 deletions tutorials/10_actor_animation_tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,64 @@

This tutorial will show you how to use the Ignition Rendering library to create an actor animation.

## Code
## Compile and run the example

In this section we will describe the main classes and methods used to create the actor. The basic steps are:
Clone the source code, Create a build directory and use `cmake` and `make` to compile the code:

- Create a visual for the actor
- Attach mesh
- Get skeleton
- The skeleton will be animated by `GlutWindow`
```{.sh}
git clone https://github.com/ignitionrobotics/ign-rendering
cd ign-rendering/examples/actor_animation
mkdir build
cd build
cmake ..
make
```

Create a `Visual` pointer with the scene manager and set the position and rotation of the object:
When the code is compiled you can execute the example with the following command. Using the left and right button of the mouse you can move around the scene and zoom in and out.

\snippet examples/actor_animation/Main.cc create a visual for the actor
```{.sh}
./actor_animation
```

Create a `MeshDescriptor` class with the mesh name of the actor, then using the `MeshManager` Singleton class, load the mesh in the descriptor:
@image html img/actor_animation.png

\snippet examples/actor_animation/Main.cc create mesh
## Code

Finally, attach the mesh to the visual:
In this section we will describe the main classes and methods used to create the actor. The basic steps are:

\snippet examples/actor_animation/Main.cc added mesh
- Load the mesh with animations
- Create the actor visual
- Load the mesh in into the render engine
chapulina marked this conversation as resolved.
Show resolved Hide resolved
- Attach the mesh to the actor visual
- Animate the skeleton

We can check if the mesh has a skeleton. This will allows us to check if we can animate the actor in the scene:
Create a `MeshDescriptor` class with the mesh name of the actor, then using the `MeshManager` Singleton class, load the mesh and its animations using the descriptor:

\snippet examples/actor_animation/Main.cc check skeleton
\snippet examples/actor_animation/Main.cc load mesh

There are two main function in the `GlutWindow.c` file:
The mesh is now loaded with all animations. You can also add additional animations to the mesh:

- **void initAnimation()**: This function will check if the skeleton has an animation. Then it will load the animation using a `bvh` file (an animation file format).
\snippet examples/actor_animation/Main.cc add animation

\snippet examples/actor_animation/GlutWindow.cc init animation
Create a `Visual` pointer with the scene manager and set the position and rotation of the visual:

And finally, the animation will be initialized:
\snippet examples/actor_animation/Main.cc create a visual for the actor

\snippet examples/actor_animation/GlutWindow.cc index animation
Create the mesh in ign-rendering - this loads the animations into the render engine

- **void updatePose()**: This function will update the skeleton over the time to create the animation of the actor.
\snippet examples/actor_animation/GlutWindow.cc update pose
\snippet examples/actor_animation/Main.cc create mesh

Finally, attach the mesh to the visual and add the visual to the scene:

## Compile and run the example
\snippet examples/actor_animation/Main.cc attach mesh

Create a build directory and use `cmake` and `make` to compile the code:
There are two ways to play the animations:

```{.sh}
cd ign-rendering/examples/actor_animation
mkdir build
cd build
cmake ..
make
```
- Update animation time: The first method is to advance the time every iteration and let the render engine handle the animations.

When the code is compiled you can execute the example with the following command. Using the left and right button of the mouse you can move around the scene and even zoom in and out.
\snippet examples/actor_animation/GlutWindow.cc update actor

```{.sh}
./actor_animation
```
- Update bone pose: The second and more involved method is to manually compute and set the bone pose over time.

\snippet examples/actor_animation/GlutWindow.cc update pose

@image html img/actor_animation.png
Binary file modified tutorials/img/actor_animation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.