Better split between runtime library and editor.

AnimGraphEditor
Martin Felis 2023-03-30 18:11:54 +02:00
parent 9168dec9f9
commit 411aa5ef20
8 changed files with 101 additions and 93 deletions

View File

@ -43,23 +43,11 @@ set(ThirdPartyIncludeDeps
# Shared code by main executable and tests
add_library(AnimTestbedCode OBJECT
src/Camera.c
src/SkinnedMesh.cc
src/SkinnedMesh.h
src/SkinnedMeshResource.cc
src/SkinnedMeshResource.h
src/SyncTrack.cc
src/SyncTrack.h
src/ozzutils.cc
3rdparty/imgui/imgui.cpp
3rdparty/imgui/imgui_draw.cpp
3rdparty/imgui/imgui_widgets.cpp
3rdparty/imgui/misc/cpp/imgui_stdlib.cpp
3rdparty/imnodes/imnodes.cpp
src/AnimGraph/AnimGraphResource.cc
src/AnimGraph/AnimGraphResource.h
src/AnimGraph/AnimGraphEditor.cc
src/AnimGraph/AnimGraphEditor.h
src/AnimGraph/AnimGraph.cc
src/AnimGraph/AnimGraph.h
src/AnimGraph/AnimGraphNodes.cc
@ -87,7 +75,19 @@ target_include_directories(
target_sources(AnimTestbed PRIVATE
src/main.cc
src/SkinnedMeshRenderer.cc
src/AnimGraph/AnimGraphEditor.cc
src/AnimGraph/AnimGraphEditor.h
src/Camera.c
src/SkinnedMesh.cc
src/SkinnedMesh.h
src/SkinnedMeshResource.cc
src/SkinnedMeshResource.h
3rdparty/glfw/deps/glad_gl.c
3rdparty/imgui/imgui.cpp
3rdparty/imgui/imgui_draw.cpp
3rdparty/imgui/imgui_widgets.cpp
3rdparty/imgui/misc/cpp/imgui_stdlib.cpp
3rdparty/imnodes/imnodes.cpp
3rdparty/imgui/imgui_demo.cpp
3rdparty/imgui/backends/imgui_impl_glfw.cpp
3rdparty/imgui/backends/imgui_impl_opengl3.cpp

View File

@ -4,7 +4,10 @@
#include "AnimGraphEditor.h"
#include <sstream>
#include "AnimGraphResource.h"
#include "SkinnedMesh.h"
#include "imgui.h"
#include "imnodes.h"
#include "misc/cpp/imgui_stdlib.h"
@ -63,6 +66,83 @@ void RemoveConnectionsForSocket(
}
}
void SyncTrackEditor(SyncTrack* sync_track) {
ImGui::SliderFloat("duration", &sync_track->m_duration, 0.001f, 10.f);
ImGui::Text("Marker");
ImGui::SameLine();
ImGui::Text("%d", sync_track->m_num_intervals);
ImGui::SameLine();
if (ImGui::Button("+")) {
if (sync_track->m_num_intervals < cSyncTrackMaxIntervals) {
sync_track->m_num_intervals ++;
}
}
ImGui::SameLine();
if (ImGui::Button("-")) {
if (sync_track->m_num_intervals > 0) {
sync_track->m_num_intervals --;
}
}
ImGui::Text("Marker:");
for (int i = 0; i < sync_track->m_num_intervals; i++) {
ImGui::Text("%2d:", i);
ImGui::SameLine();
std::ostringstream marker_stream;
marker_stream << i;
ImGui::SliderFloat(
marker_stream.str().c_str(),
&sync_track->m_sync_markers[i],
0.f,
1.f);
}
if (ImGui::Button ("Update Intervals")) {
sync_track->CalcIntervals();
}
}
void SkinnedMeshWidget(SkinnedMesh* skinned_mesh) {
if (ImGui::TreeNode("Bones")) {
for (int i = 0; i < skinned_mesh->m_skeleton.num_joints(); i++) {
ImGui::Text("%s", skinned_mesh->m_skeleton.joint_names()[i]);
}
ImGui::TreePop();
}
ImGui::Text("Animations");
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();
}
ImGui::Combo("Animation", &selected, items, skinned_mesh->m_animations.size());
ImGui::Text("Sync Track");
if (selected >= 0 && selected < skinned_mesh->m_animations.size()) {
SyncTrackEditor(&skinned_mesh->m_animation_sync_track[selected]);
skinned_mesh->m_override_anim = selected;
ImGui::Checkbox("Override Animation", &skinned_mesh->m_sync_track_override);
if (skinned_mesh->m_sync_track_override) {
ImGui::SliderFloat("Ratio", &skinned_mesh->m_override_ratio, 0.f, 1.f);
ozz::animation::SamplingJob sampling_job;
sampling_job.animation = skinned_mesh->m_animations[selected];
sampling_job.context = &skinned_mesh->m_sampling_context;
sampling_job.ratio = skinned_mesh->m_override_ratio;
sampling_job.output = make_span(skinned_mesh->m_local_matrices);
if (!sampling_job.Run()) {
ozz::log::Err() << "Error sampling animation." << std::endl;
}
}
}
}
void AnimGraphEditorRenderSidebar(
AnimGraphResource& graph_resource,
AnimNodeResource& node_resource) {

View File

@ -7,6 +7,8 @@
#include "AnimGraph.h"
struct SkinnedMesh;
inline int GenerateInputAttributeId(int node_id, int input_index) {
return ((input_index + 1) << 14) + node_id;
}
@ -27,6 +29,10 @@ SplitOutputAttributeId(int attribute_id, int* node_id, int* output_index) {
*output_index = (attribute_id >> 23) - 1;
}
void SyncTrackEditor(SyncTrack* sync_track);
void SkinnedMeshWidget(SkinnedMesh* skinned_mesh);
void AnimGraphEditorUpdate();
void AnimGraphEditorGetRuntimeGraph(AnimGraph& anim_graph);

View File

@ -99,41 +99,3 @@ void SkinnedMesh::CalcModelMatrices() {
void SkinnedMesh::DrawSkeleton() {}
void SkinnedMesh::DrawDebugUi() {
if (ImGui::TreeNode("Bones")) {
for (int i = 0; i < m_skeleton.num_joints(); i++) {
ImGui::Text("%s", m_skeleton.joint_names()[i]);
}
ImGui::TreePop();
}
ImGui::Text("Animations");
const char* items[255] = {0};
static int selected = -1;
for (int i = 0; i < m_animations.size(); i++) {
items[i] = m_animation_names[i].c_str();
}
ImGui::Combo("Animation", &selected, items, m_animations.size());
ImGui::Text("Sync Track");
if (selected >= 0 && selected < m_animations.size()) {
m_animation_sync_track[selected].DrawDebugUi();
m_override_anim = selected;
ImGui::Checkbox("Override Animation", &m_sync_track_override);
if (m_sync_track_override) {
ImGui::SliderFloat("Ratio", &m_override_ratio, 0.f, 1.f);
ozz::animation::SamplingJob sampling_job;
sampling_job.animation = m_animations[selected];
sampling_job.context = &m_sampling_context;
sampling_job.ratio = m_override_ratio;
sampling_job.output = make_span(m_local_matrices);
if (!sampling_job.Run()) {
ozz::log::Err() << "Error sampling animation." << std::endl;
}
}
}
}

View File

@ -40,7 +40,6 @@ struct SkinnedMesh {
void DrawSkeleton();
void DrawJoint(int joint_index, int parent_joint_index);
void DrawDebugUi();
// void DrawSkinnedMesh();
ozz::vector<ozz::animation::Animation*> m_animations;

View File

@ -7,40 +7,3 @@
#include <imgui.h>
#include <sstream>
void SyncTrack::DrawDebugUi() {
ImGui::SliderFloat("duration", &m_duration, 0.001f, 10.f);
ImGui::Text("Marker");
ImGui::SameLine();
ImGui::Text("%d", m_num_intervals);
ImGui::SameLine();
if (ImGui::Button("+")) {
if (m_num_intervals < cSyncTrackMaxIntervals) {
m_num_intervals ++;
}
}
ImGui::SameLine();
if (ImGui::Button("-")) {
if (m_num_intervals > 0) {
m_num_intervals --;
}
}
ImGui::Text("Marker:");
for (int i = 0; i < m_num_intervals; i++) {
ImGui::Text("%2d:", i);
ImGui::SameLine();
std::ostringstream marker_stream;
marker_stream << i;
ImGui::SliderFloat(
marker_stream.str().c_str(),
&m_sync_markers[i],
0.f,
1.f);
}
if (ImGui::Button ("Update Intervals")) {
CalcIntervals();
}
}

View File

@ -150,8 +150,6 @@ struct SyncTrack {
return result;
}
void DrawDebugUi();
};
#endif //ANIMTESTBED_SYNCTRACK_H

View File

@ -669,9 +669,9 @@ int main() {
ImVec2 skinned_mesh_widget_size = ImGui::GetWindowSize();
gApplicationConfig.skinned_mesh_widget.size[0] = skinned_mesh_widget_size.x;
gApplicationConfig.skinned_mesh_widget.size[1] = skinned_mesh_widget_size.y;
skinned_mesh.DrawDebugUi();
SkinnedMeshWidget(&skinned_mesh);
ImGui::End();
}