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

Fix animation processing interpolation bug, crash on no merc material #3794

Merged
merged 1 commit into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 4 additions & 3 deletions goalc/build_actor/common/MercExtract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ void extract(const std::string& name,
out.new_model.max_draws = 0;

auto process_normal_draw = [&](tfrag3::MercEffect& eff, int mat_idx, const tfrag3::MercDraw& d_) {
const auto& mat = model.materials[mat_idx];
eff.all_draws.push_back(d_);
auto& draw = eff.all_draws.back();
draw.mode = gltf_util::make_default_draw_mode();
Expand All @@ -107,6 +106,8 @@ void extract(const std::string& name,
draw.tree_tex_id = 0;
return;
}
const auto& mat = model.materials[mat_idx];

int tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index;
if (tex_idx == -1) {
lg::warn("Material {} has no texture, using default texture.", mat.name);
Expand Down Expand Up @@ -172,8 +173,8 @@ void extract(const std::string& name,
};

for (const auto& [mat_idx, d_] : draw_by_material) {
const auto& mat = model.materials[mat_idx];
if (!gltf_util::material_has_envmap(mat) || !gltf_util::envmap_is_valid(mat)) {
if (mat_idx < 0 || !gltf_util::material_has_envmap(model.materials[mat_idx]) ||
!gltf_util::envmap_is_valid(model.materials[mat_idx])) {
process_normal_draw(e, mat_idx, d_);
} else {
envmap_eff.has_envmap = true;
Expand Down
25 changes: 17 additions & 8 deletions goalc/build_actor/common/animation_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ int find_max_joint(const tinygltf::Animation& anim, const std::map<int, int>& no
template <typename T>
std::vector<T> compute_keyframes(const std::vector<float>& times,
const std::vector<T>& values,
float framerate) {
float framerate,
bool quaternion_interp) {
std::vector<T> ret;
ASSERT(!times.empty());
ASSERT(times.size() == values.size());
Expand All @@ -36,8 +37,15 @@ std::vector<T> compute_keyframes(const std::vector<float>& times,
}

const float fraction = (t - times.at(i)) / (times.at(i + 1) - times.at(i));
ret.push_back(values.at(i) * (1.f - fraction) + values.at(i + 1) * fraction);
// lg::info("{} + {:.3f}, {}", i, fraction, ret.back().to_string_aligned());
if (quaternion_interp) {
float multiplier = 1;
if (values.at(i).dot(values.at(i + 1)) < 0) {
multiplier = -1;
}
ret.push_back(values.at(i) * (1.f - fraction) + values.at(i + 1) * fraction * multiplier);
} else {
ret.push_back(values.at(i) * (1.f - fraction) + values.at(i + 1) * fraction);
}
t += 1.f / framerate;
}
return ret;
Expand All @@ -47,12 +55,13 @@ template <int n>
std::vector<math::Vector<float, n>> extract_keyframed_gltf_vecn(
const tinygltf::Model& model,
const tinygltf::AnimationSampler& sampler,
float framerate) {
float framerate,
bool quaternion_interp) {
std::vector<float> times = gltf_util::extract_floats(model, sampler.input);
std::vector<math::Vector<float, n>> values =
gltf_util::extract_vec<float, n>(model, sampler.output, TINYGLTF_COMPONENT_TYPE_FLOAT);
ASSERT(times.size() == values.size());
return compute_keyframes(times, values, framerate);
return compute_keyframes(times, values, framerate, quaternion_interp);
}
} // namespace

Expand All @@ -75,13 +84,13 @@ UncompressedJointAnim extract_anim_from_gltf(const tinygltf::Model& model,
const auto& sampler = anim.samplers.at(channel.sampler);
if (channel.target_path == "translation") {
out.joints.at(channel_joint).trans_frames =
extract_keyframed_gltf_vecn<3>(model, sampler, framerate);
extract_keyframed_gltf_vecn<3>(model, sampler, framerate, false);
} else if (channel.target_path == "rotation") {
out.joints.at(channel_joint).quat_frames =
extract_keyframed_gltf_vecn<4>(model, sampler, framerate);
extract_keyframed_gltf_vecn<4>(model, sampler, framerate, true);
} else if (channel.target_path == "scale") {
out.joints.at(channel_joint).scale_frames =
extract_keyframed_gltf_vecn<3>(model, sampler, framerate);
extract_keyframed_gltf_vecn<3>(model, sampler, framerate, false);
} else {
lg::die("unknown target_path {}", channel.target_path);
}
Expand Down
Loading