
[ad_1]
I’m making an attempt to animate a skeletal mesh utilizing opengl and assimp and I’m having bother understanding what transforms I would like to use for it to work. From what I perceive, every vertices have bone indices and bone weights which might be static buffers. Theses vertex attribute factors to a bone array uniform that adjustments on each body, relying on the animation time. However, I’m undecided tips on how to receive the bone array uniform.
More exactly, I would really like extra info on aiBone::mOffsetMatrix
and aiNodeAnim
on tips on how to mix them to acquire the bone remodel uniform to ship to the GPU.
Right now, I’ve code that appears like this:
// Loading bone information
for (uint32 index_bone = 0; index_bone < ai_mesh.mNumBones; ++index_bone)
{
const aiBone& ai_bone = *ai_mesh.mBones[index_bone];
bone bone = {
.title = ai_bone.mName.C_Str(),
.bone_id = ai_bone_id,
.remodel = to_mat4(ai_bone.mOffsetMatrix),
};
bones.emplace_back(std::transfer(bone));
for (uint32 index_weight = 0; index_weight < ai_bone.mNumWeights; ++index_weight)
{
const aiVertexWeight& ai_bone_weight = ai_bone.mWeights[index_weight];
vertex& vertex = vertices.at(ai_bone_weight.mVertexId);
vertex.add_bone_weight(index_bone, ai_bone_weight.mWeight);
}
}
// Loading animation
animation to_animation(const asset_metadata& metadata, const aiScene& ai_scene, const aiAnimation& ai_animation) const
{
animation animation;
animation.title = ai_animation.mName.C_Str();
animation.length = static_cast<float32>(ai_animation.mDuration);
animation.fps = static_cast<float32>(ai_animation.mTicksPerSecond);
const auto add_frames = [&](uint32 bone_id, uint32 ai_frame_num, const auto* ai_frames, auto&& func) {
for (uint32 index = 0; index < ai_frame_num; ++index)
{
const auto& ai_frame = ai_frames[index];
animation_frame body {
.key = animation_frame_key {
.bone_id = bone_id,
.time = static_cast<float32>(ai_frame.mTime),
},
};
func(ai_frame, body);
animation.add_frame(std::transfer(body));
}
};
const auto add_frame_translation = [&](const auto& ai_frame, animation_frame& body) {
body.remodel.translation = to_vec3(ai_frame.mValue);
};
const auto add_frame_rotation = [&](const auto& ai_frame, animation_frame& body) {
body.remodel.rotation = to_quat(ai_frame.mValue);
};
const auto add_frame_scaling = [&](const auto& ai_frame, animation_frame& body) {
body.remodel.scale = to_vec3(ai_frame.mValue);
};
for (uint32 index = 0; index < ai_animation.mNumChannels; ++index)
{
const aiNodeAnim* ai_node_anim = ai_animation.mChannels[index];
add_frames(index, ai_node_anim->mNumPositionKeys, ai_node_anim->mPositionKeys, add_frame_translation);
add_frames(index, ai_node_anim->mNumRotationKeys, ai_node_anim->mRotationKeys, add_frame_rotation);
add_frames(index, ai_node_anim->mNumScalingKeys, ai_node_anim->mScalingKeys, add_frame_scaling);
const auto predicate = [&](const aiNode& ai_node) {
return ai_node.mName == ai_node_anim->mNodeName;
};
const aiNode* ai_node = find_node(ai_scene.mRootNode, predicate);
if (ai_node == nullptr)
{
SPDLOG_WARN("animation node not discovered, scene={} animation={} node={}", metadata.title, animation.title.get(), ai_node_anim->mNodeName.C_Str());
proceed;
}
const auto to_scene_transform = [&](animation_frame& body) {
for (const aiNode* ai_node_parent = ai_node; ai_node_parent != nullptr; ai_node_parent = ai_node_parent->mParent)
{
body.remodel += to_transform(ai_node_parent->mTransformation);
}
};
animation.for_each_frames_of(index, to_scene_transform);
}
return animation;
}
// Binding uniform
const auto update_bones = [&](const animation_frame& body) {
mesh_instance.bone_transforms[frame.key.bone_id] = body.remodel.to_mat();
};
float32 animation_time = std::fmod(time, animation.length);
animation.for_each_frames_in(animation_time, animation_time + 16.6666f, update_bones);
if (uniform_bones != spore::opengl::invalid_id)
{
glProgramUniformMatrix4fv(shader_program.program_id, uniform_bones, mesh_instance.bone_transforms.dimension(), GL_FALSE, &mesh_instance.bone_transforms[0][0][0]);
}
This shouldn’t be everything of the code, however it’s the gist of it. Thank for the assistance!
[ad_2]