Started working on the animation player widget.
parent
7152fa74e1
commit
80ea25483b
|
@ -105,7 +105,7 @@ void SkinnedMeshResource::createInstance(SkinnedMesh& skinnedMesh) const {
|
|||
skinnedMesh.LoadSkeleton(m_skeleton_file.c_str());
|
||||
for (int i = 0; i < m_animation_files.size(); i++) {
|
||||
skinnedMesh.LoadAnimation(m_animation_files[i].c_str());
|
||||
skinnedMesh.m_animation_sync_track.push_back(m_sync_tracks[i]);
|
||||
skinnedMesh.m_animation_sync_track.back() = m_sync_tracks[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
113
src/main.cc
113
src/main.cc
|
@ -61,18 +61,12 @@ static void draw_imgui(ImDrawData*);
|
|||
#include "ozz/base/maths/soa_transform.h"
|
||||
#include "ozz/base/maths/vec_float.h"
|
||||
|
||||
// wrapper struct for managed ozz-animation C++ objects, mUST BE DEleted
|
||||
// before shutdown, otherwise ozz-animation will report a memory leak
|
||||
typedef struct {
|
||||
ozz::animation::Skeleton skeleton;
|
||||
ozz::animation::Animation animation;
|
||||
ozz::animation::SamplingJob::Context sampling_context;
|
||||
ozz::vector<ozz::math::SoaTransform> local_matrices;
|
||||
ozz::vector<ozz::math::Float4x4> model_matrices;
|
||||
} ozz_t;
|
||||
|
||||
static struct {
|
||||
std::unique_ptr<ozz_t> ozz;
|
||||
struct {
|
||||
ozz::animation::Animation* animation = nullptr;
|
||||
ozz::animation::SamplingJob sampling_job;
|
||||
ozz::animation::SamplingJob::Context* m_sampling_context = nullptr;
|
||||
} ozz;
|
||||
sg_pass_action pass_action;
|
||||
Camera camera;
|
||||
struct {
|
||||
|
@ -82,7 +76,7 @@ static struct {
|
|||
} loaded;
|
||||
struct {
|
||||
double frame;
|
||||
double absolute;
|
||||
float absolute;
|
||||
uint64_t laptime;
|
||||
float factor;
|
||||
float anim_ratio;
|
||||
|
@ -125,6 +119,13 @@ struct ApplicationConfig {
|
|||
};
|
||||
SkinnedMeshWidget skinned_mesh_widget;
|
||||
|
||||
struct AnimationPlayerWidget {
|
||||
bool visible = false;
|
||||
int position[2] = {20, 20};
|
||||
int size[2] = {800, 500};
|
||||
};
|
||||
AnimationPlayerWidget animation_player_widget;
|
||||
|
||||
bool show_imgui_demo_window = false;
|
||||
bool show_another_window = false;
|
||||
bool show_camera_widget = false;
|
||||
|
@ -152,6 +153,12 @@ void to_json(nlohmann::json& j, const ApplicationConfig& config) {
|
|||
j["skinned_mesh_widget"]["size"][0] = config.skinned_mesh_widget.size[0];
|
||||
j["skinned_mesh_widget"]["size"][1] = config.skinned_mesh_widget.size[1];
|
||||
|
||||
j["animation_player_widget"]["visible"] = config.animation_player_widget.visible;
|
||||
j["animation_player_widget"]["position"][0] = config.animation_player_widget.position[0];
|
||||
j["animation_player_widget"]["position"][1] = config.animation_player_widget.position[1];
|
||||
j["animation_player_widget"]["size"][0] = config.animation_player_widget.size[0];
|
||||
j["animation_player_widget"]["size"][1] = config.animation_player_widget.size[1];
|
||||
|
||||
j["camera_widget"]["visible"] = config.show_camera_widget;
|
||||
}
|
||||
|
||||
|
@ -188,7 +195,6 @@ void from_json(const nlohmann::json& j, ApplicationConfig& config) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (j.contains("skinned_mesh_widget")) {
|
||||
if (j["skinned_mesh_widget"].contains("visible")) {
|
||||
config.skinned_mesh_widget.visible = j["skinned_mesh_widget"]["visible"];
|
||||
|
@ -205,6 +211,22 @@ void from_json(const nlohmann::json& j, ApplicationConfig& config) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (j.contains("animation_player_widget")) {
|
||||
if (j["animation_player_widget"].contains("visible")) {
|
||||
config.animation_player_widget.visible = j["animation_player_widget"]["visible"];
|
||||
}
|
||||
|
||||
if (j["animation_player_widget"].contains("position") and j["animation_player_widget"]["position"].size() == 2) {
|
||||
config.animation_player_widget.position[0] = j["animation_player_widget"]["position"].at(0);
|
||||
config.animation_player_widget.position[1] = j["animation_player_widget"]["position"].at(1);
|
||||
}
|
||||
|
||||
if (j["animation_player_widget"].contains("size") and j["animation_player_widget"]["size"].size() == 2) {
|
||||
config.animation_player_widget.size[0] = j["animation_player_widget"]["size"].at(0);
|
||||
config.animation_player_widget.size[1] = j["animation_player_widget"]["size"].at(1);
|
||||
}
|
||||
}
|
||||
if (j.contains("camera_widget") and j["camera_widget"].contains("visible")) {
|
||||
config.show_camera_widget = j["camera_widget"]["visible"];
|
||||
}
|
||||
|
@ -480,10 +502,16 @@ int main() {
|
|||
&gApplicationConfig.window_size[0],
|
||||
&gApplicationConfig.window_size[1]);
|
||||
|
||||
state.time.frame = stm_sec(
|
||||
stm_round_to_common_refresh_rate(stm_laptime(&state.time.laptime)));
|
||||
if (!state.time.paused) {
|
||||
state.time.frame = stm_sec(
|
||||
stm_round_to_common_refresh_rate(stm_laptime(&state.time.laptime)));
|
||||
|
||||
state.time.absolute += state.time.frame * state.time.factor;
|
||||
state.time.absolute += state.time.frame * state.time.factor;
|
||||
|
||||
if (state.ozz.animation != nullptr) {
|
||||
state.time.absolute = fmodf (state.time.absolute, state.ozz.animation->duration());
|
||||
}
|
||||
}
|
||||
|
||||
int cur_width, cur_height;
|
||||
glfwGetFramebufferSize(w, &cur_width, &cur_height);
|
||||
|
@ -571,6 +599,10 @@ int main() {
|
|||
ImGui::Checkbox(
|
||||
"Skinned Mesh",
|
||||
&gApplicationConfig.skinned_mesh_widget.visible);
|
||||
ImGui::Checkbox(
|
||||
"Animation Player",
|
||||
&gApplicationConfig.animation_player_widget.visible);
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Checkbox(
|
||||
"ImGui Demo",
|
||||
|
@ -621,6 +653,55 @@ int main() {
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
if (gApplicationConfig.animation_player_widget.visible) {
|
||||
ImGui::SetNextWindowPos(ImVec2(gApplicationConfig.animation_player_widget.position[0], gApplicationConfig.skinned_mesh_widget.position[1]), ImGuiCond_FirstUseEver);
|
||||
ImGui::SetNextWindowSize(ImVec2(gApplicationConfig.animation_player_widget.size[0], gApplicationConfig.skinned_mesh_widget.size[1]), ImGuiCond_FirstUseEver);
|
||||
|
||||
ImGui::Begin("Animation Player", &gApplicationConfig.animation_player_widget.visible);
|
||||
|
||||
ImVec2 animation_player_widget_position = ImGui::GetWindowPos();
|
||||
gApplicationConfig.animation_player_widget.position[0] = animation_player_widget_position.x;
|
||||
gApplicationConfig.animation_player_widget.position[1] = animation_player_widget_position.y;
|
||||
|
||||
ImVec2 animation_player_widget_size = ImGui::GetWindowSize();
|
||||
gApplicationConfig.animation_player_widget.size[0] = animation_player_widget_size.x;
|
||||
gApplicationConfig.animation_player_widget.size[1] = animation_player_widget_size.y;
|
||||
|
||||
ImGui::Text("Animation");
|
||||
|
||||
const char* items[255] = {0};
|
||||
static int selected = -1;
|
||||
for (int i = 0; i < skinned_mesh.m_animations.size(); i++) {
|
||||
items[i] = skinned_mesh.m_animation_names[i].c_str();
|
||||
}
|
||||
|
||||
if (ImGui::Combo("Animation", &selected, items, skinned_mesh.m_animations.size())) {
|
||||
state.ozz.animation = skinned_mesh.m_animations[selected];
|
||||
}
|
||||
|
||||
if (state.time.paused) {
|
||||
if (ImGui::Button("Play")) {
|
||||
state.time.paused = false;
|
||||
}
|
||||
} else {
|
||||
if (ImGui::Button("Pause")) {
|
||||
state.time.paused = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (state.ozz.animation != nullptr) {
|
||||
ImGui::SliderFloat(
|
||||
"Time",
|
||||
&state.time.absolute,
|
||||
0,
|
||||
state.ozz.animation->duration(),
|
||||
"%.3f",
|
||||
0);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// TODO: add AnimGraph to calculate pose
|
||||
// skinned_mesh.CalcModelMatrices();
|
||||
|
||||
|
|
Loading…
Reference in New Issue