Skip to content

Commit

Permalink
[Tydra] Changing Animation struct to provide AnimationChannel per joint
Browse files Browse the repository at this point in the history
  • Loading branch information
syoyo committed Apr 19, 2024
1 parent 1161aef commit 1101bd8
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 14 deletions.
11 changes: 8 additions & 3 deletions src/tydra/render-data.hh
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,9 @@ struct AnimationSampler {
Interpolation interpolation{Interpolation::Linear};
};

// TODO: Supprot more data types(e.g. float2)
// We store animation data in AoS(array of structure) approach(glTF-like), i.e. animation channel is provided per joint, instead of
// SoA(structure of array) approach(USD SkelAnimation)
// TODO: Use VertexAttribute-like data structure
struct AnimationChannel {
enum class ChannelType { Transform, Translation, Rotation, Scale, Weight };

Expand All @@ -677,15 +679,18 @@ struct AnimationChannel {
AnimationSampler<std::vector<vec3>> scales; // half-types are upcasted to float precision
AnimationSampler<std::vector<float>> weights;

int64_t taget_node{-1}; // array index to RenderScene::nodes
//std::string joint_name; // joint name(UsdSkel::joints)
//int64_t joint_id{-1}; // joint index in SkelHierarchy
};

// USD SkelAnimation
struct Animation {
std::string prim_name; // Prim name(element name)
std::string abs_path; // Target USD Prim path
std::string display_name; // `displayName` prim meta
std::vector<AnimationChannel> channels;

// key = joint, value = channels(Usually 3(trans, rots and scales))
std::map<std::string, std::vector<AnimationChannel>> channels_map;
};

struct Node {
Expand Down
54 changes: 43 additions & 11 deletions src/tydra/usd-export.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,54 @@ static bool ExportBlendShape(const ShapeTarget &target, BlendShape *dst, std::st
}

// TODO: Support BlendShapes target
static bool ExportSkelAnimation(const Animation &anim, const std::vector<std::string> &jointNames, SkelAnimation *dst, std::string *err) {
static bool ExportSkelAnimation(const Animation &anim, SkelAnimation *dst, std::string *err) {
(void)err;
dst->name = anim.prim_name;
if (anim.display_name.size()) {
dst->metas().displayName = anim.display_name;
}

if (anim.channels_map.empty()) {
// TODO: Warn message
return true;
}

StringAndIdMap joint_idMap;
for (const auto &channels : anim.channels_map)
{
std::vector<value::token> joints(jointNames.size());
for (size_t i = 0; i < jointNames.size(); i++) {
joints[i] = value::token(jointNames[i]);
}
dst->joints = joints;
uint64_t joint_id = uint64_t(joint_idMap.size());
joint_idMap.add(channels.first, uint64_t(joint_id));
}

for (size_t i = 0; i < anim.channels.size(); i++) {
std::vector<value::token> joints(joint_idMap.size());
for (const auto &channels : anim.channels_map) {
joints[joint_idMap.at(channels.first)] = value::token(channels.first);
}

for (const auto &channels : anim.channels_map) {
size_t tx_id{~0u};
size_t rot_id{~0u};
size_t scale_id{~0u};

for (size_t i = 0; i < channels.second.size(); i++) {
if (channels.second[i].type == AnimationChannel::ChannelType::Translation) {
tx_id = i;
} else if (channels.second[i].type == AnimationChannel::ChannelType::Rotation) {
rot_id = i;
} else if (channels.second[i].type == AnimationChannel::ChannelType::Scale) {
scale_id = i;
}
}

// TODO: Provide dummy value when missing.
if ((tx_id == ~0u) || (rot_id == ~0u) || (scale_id == ~0u)) {
PUSH_ERROR_AND_RETURN(fmt::format("translation, rotation and scale AnimationChannel must be all provided. translation {}, rotation {}, scale {}",
(tx_id == ~0u) ? "missing" : "provided",
(rot_id == ~0u) ? "missing" : "provided",
(scale_id == ~0u) ? "missing" : "provided"));
}

#if 0 // TODO
const AnimationChannel &channel = anim.channels[i];

if (channel.rotations.samples.size()) {
Expand Down Expand Up @@ -110,6 +142,7 @@ static bool ExportSkelAnimation(const Animation &anim, const std::vector<std::st
}
dst->scales.set_value(scales);
}
#endif
}
return false;
}
Expand Down Expand Up @@ -202,7 +235,7 @@ static bool ToGeomMesh(const RenderMesh &rmesh, GeomMesh *dst, std::string *err)
}

// TODO: GeomSubset, Material assignment, skel binding, ...

return true;
}

Expand All @@ -222,7 +255,7 @@ bool export_to_usda(const RenderScene &scene,
stage.metas().upAxis = Axis::Y;
} else if (scene.meta.upAxis == "Z") {
stage.metas().upAxis = Axis::Z;
}
}

// TODO: Construct Node hierarchy

Expand Down Expand Up @@ -271,8 +304,7 @@ bool export_to_usda(const RenderScene &scene,

for (size_t i = 0; i < scene.animations.size(); i++) {
SkelAnimation skelAnim;
std::vector<std::string> jointNames; // TODO: Read jointNames from SkelHierarchy.
if (!detail::ExportSkelAnimation(scene.animations[i], jointNames, &skelAnim, err)) {
if (!detail::ExportSkelAnimation(scene.animations[i], &skelAnim, err)) {
return false;
}

Expand Down

0 comments on commit 1101bd8

Please sign in to comment.