Skip to content

Commit

Permalink
[Tydra] Change Animation data structure
Browse files Browse the repository at this point in the history
[Tydra] USD export with SkelAnimation(w.i.p.)
  • Loading branch information
syoyo committed Apr 17, 2024
1 parent bdedcc0 commit 269901d
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 9 deletions.
17 changes: 10 additions & 7 deletions src/tydra/render-data.hh
Original file line number Diff line number Diff line change
Expand Up @@ -659,22 +659,25 @@ struct AnimationSampler {
struct AnimationChannel {
enum class ChannelType { Transform, Translation, Rotation, Scale, Weight };

// Matrix precision is recuded to float-precision
// Matrix precision is reduced to float-precision
// NOTE: transform is not supported in glTF(you need to decompose transform
// matrix into TRS)
AnimationSampler<mat4> transforms;
AnimationSampler<std::vector<mat4>> transforms;

// half-types are upcasted to float precision
AnimationSampler<vec3> translations;
AnimationSampler<quat> rotations; // Rotation is converted to quaternions
AnimationSampler<vec3> scales;
AnimationSampler<float> weights;
AnimationSampler<std::vector<vec3>> translations;
AnimationSampler<std::vector<quat>> rotations; // Rotation is represented as quaternions
AnimationSampler<std::vector<vec3>> scales;
AnimationSampler<std::vector<float>> weights;

int64_t taget_node{-1}; // array index to RenderScene::nodes
};

// USD SkelAnimation
struct Animation {
std::string target_path; // Target USD Prim path
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;
};

Expand Down
71 changes: 69 additions & 2 deletions src/tydra/usd-export.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,61 @@ namespace tydra {

namespace detail {

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

{
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;
}

for (size_t i = 0; i < anim.channels.size(); i++) {
const AnimationChannel &channel = anim.channels[i];

if (channel.rotations.samples.size()) {
Animatable<std::vector<value::quatf>> rots;
for (const auto &sample : channel.rotations.samples) {
std::vector<value::quatf> ts(sample.value.size());
for (size_t k = 0; k < sample.value.size(); k++) {
ts[k][0] = sample.value[k][0];
ts[k][1] = sample.value[k][1];
ts[k][2] = sample.value[k][2];
ts[k][3] = sample.value[k][3];
}
rots.add_sample(double(sample.t), ts);
}
dst->rotations.set_value(rots);
} else if (channel.translations.samples.size()) {
Animatable<std::vector<value::float3>> txs;
for (const auto &sample : channel.translations.samples) {
txs.add_sample(double(sample.t), sample.value);
}
dst->translations.set_value(txs);
} else if (channel.scales.samples.size()) {
Animatable<std::vector<value::half3>> scales;
for (const auto &sample : channel.scales.samples) {
std::vector<value::half3> ts(sample.value.size());
for (size_t k = 0; k < sample.value.size(); k++) {
ts[k][0] = tinyusdz::value::float_to_half_full(sample.value[k][0]);
ts[k][1] = tinyusdz::value::float_to_half_full(sample.value[k][1]);
ts[k][2] = tinyusdz::value::float_to_half_full(sample.value[k][2]);
}
scales.add_sample(double(sample.t), ts);
}
dst->scales.set_value(scales);
}
}
return false;
}

static bool ToGeomMesh(const RenderMesh &rmesh, GeomMesh *dst, std::string *err) {
std::vector<int> fvCounts(rmesh.faceVertexCounts().size());
for (size_t i = 0; i < rmesh.faceVertexCounts().size(); i++) {
Expand Down Expand Up @@ -107,7 +162,7 @@ static bool ToGeomMesh(const RenderMesh &rmesh, GeomMesh *dst, std::string *err)
dst->set_primvar(uvPvar);
}

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

return true;
}
Expand All @@ -130,7 +185,7 @@ bool export_to_usda(const RenderScene &scene,
stage.metas().upAxis = Axis::Z;
}

// TODO: Node hierarchy
// TODO: Construct Node hierarchy

for (size_t i = 0; i < scene.meshes.size(); i++) {
GeomMesh mesh;
Expand All @@ -141,6 +196,18 @@ bool export_to_usda(const RenderScene &scene,
stage.add_root_prim(std::move(prim));
}

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)) {
return false;
}

// TODO: Put SkelAnimation under SkelRoot
Prim prim(skelAnim);
stage.add_root_prim(std::move(prim));
}

usda_str =stage.ExportToString();

return true;
Expand Down

0 comments on commit 269901d

Please sign in to comment.