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());
|
skinnedMesh.LoadSkeleton(m_skeleton_file.c_str());
|
||||||
for (int i = 0; i < m_animation_files.size(); i++) {
|
for (int i = 0; i < m_animation_files.size(); i++) {
|
||||||
skinnedMesh.LoadAnimation(m_animation_files[i].c_str());
|
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/soa_transform.h"
|
||||||
#include "ozz/base/maths/vec_float.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 {
|
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;
|
sg_pass_action pass_action;
|
||||||
Camera camera;
|
Camera camera;
|
||||||
struct {
|
struct {
|
||||||
|
@ -82,7 +76,7 @@ static struct {
|
||||||
} loaded;
|
} loaded;
|
||||||
struct {
|
struct {
|
||||||
double frame;
|
double frame;
|
||||||
double absolute;
|
float absolute;
|
||||||
uint64_t laptime;
|
uint64_t laptime;
|
||||||
float factor;
|
float factor;
|
||||||
float anim_ratio;
|
float anim_ratio;
|
||||||
|
@ -125,6 +119,13 @@ struct ApplicationConfig {
|
||||||
};
|
};
|
||||||
SkinnedMeshWidget skinned_mesh_widget;
|
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_imgui_demo_window = false;
|
||||||
bool show_another_window = false;
|
bool show_another_window = false;
|
||||||
bool show_camera_widget = 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"][0] = config.skinned_mesh_widget.size[0];
|
||||||
j["skinned_mesh_widget"]["size"][1] = config.skinned_mesh_widget.size[1];
|
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;
|
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.contains("skinned_mesh_widget")) {
|
||||||
if (j["skinned_mesh_widget"].contains("visible")) {
|
if (j["skinned_mesh_widget"].contains("visible")) {
|
||||||
config.skinned_mesh_widget.visible = j["skinned_mesh_widget"]["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")) {
|
if (j.contains("camera_widget") and j["camera_widget"].contains("visible")) {
|
||||||
config.show_camera_widget = j["camera_widget"]["visible"];
|
config.show_camera_widget = j["camera_widget"]["visible"];
|
||||||
}
|
}
|
||||||
|
@ -480,10 +502,16 @@ int main() {
|
||||||
&gApplicationConfig.window_size[0],
|
&gApplicationConfig.window_size[0],
|
||||||
&gApplicationConfig.window_size[1]);
|
&gApplicationConfig.window_size[1]);
|
||||||
|
|
||||||
state.time.frame = stm_sec(
|
if (!state.time.paused) {
|
||||||
stm_round_to_common_refresh_rate(stm_laptime(&state.time.laptime)));
|
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;
|
int cur_width, cur_height;
|
||||||
glfwGetFramebufferSize(w, &cur_width, &cur_height);
|
glfwGetFramebufferSize(w, &cur_width, &cur_height);
|
||||||
|
@ -571,6 +599,10 @@ int main() {
|
||||||
ImGui::Checkbox(
|
ImGui::Checkbox(
|
||||||
"Skinned Mesh",
|
"Skinned Mesh",
|
||||||
&gApplicationConfig.skinned_mesh_widget.visible);
|
&gApplicationConfig.skinned_mesh_widget.visible);
|
||||||
|
ImGui::Checkbox(
|
||||||
|
"Animation Player",
|
||||||
|
&gApplicationConfig.animation_player_widget.visible);
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Checkbox(
|
ImGui::Checkbox(
|
||||||
"ImGui Demo",
|
"ImGui Demo",
|
||||||
|
@ -621,6 +653,55 @@ int main() {
|
||||||
ImGui::End();
|
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
|
// TODO: add AnimGraph to calculate pose
|
||||||
// skinned_mesh.CalcModelMatrices();
|
// skinned_mesh.CalcModelMatrices();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue