Fixed SpeedScale node not properly propagating time.

AnimGraphEditor
Martin Felis 2023-04-02 21:24:12 +02:00
parent abf44a875a
commit 7c8b44247b
5 changed files with 50 additions and 10 deletions

View File

@ -188,6 +188,31 @@ struct Socket {
m_value_string = value; m_value_string = value;
} }
} }
template <typename T>
T GetValue() const {
if constexpr (std::is_same<T, bool>::value) {
return m_value.flag;
}
if constexpr (std::is_same<T, float>::value) {
return m_value.float_value;
}
if constexpr (std::is_same<T, Vec3>::value) {
return m_value.vec3;
}
if constexpr (std::is_same<T, Quat>::value) {
return m_value.quat;
}
if constexpr (std::is_same<T, std::string>::value) {
return m_value_string;
}
return T();
}
}; };
template <typename T> template <typename T>
@ -356,6 +381,13 @@ struct NodeDescriptorBase {
return *static_cast<T*>(socket->m_reference.ptr); return *static_cast<T*>(socket->m_reference.ptr);
} }
template <typename T>
T GetPropertyValue(const char* name) {
Socket* socket = FindSocket(name, m_properties);
assert(GetSocketType<T>() == socket->m_type);
return socket->GetValue<T>();
}
virtual void UpdateFlags(){}; virtual void UpdateFlags(){};
protected: protected:

View File

@ -172,9 +172,12 @@ void AnimGraphEditorRenderSidebar(
-100.f, -100.f,
100.f); 100.f);
} else if (property.m_type == SocketType::SocketTypeBool) { } else if (property.m_type == SocketType::SocketTypeBool) {
ImGui::Checkbox( bool flag_value = property.GetValue<bool>();
if (ImGui::Checkbox(
property.m_name.c_str(), property.m_name.c_str(),
reinterpret_cast<bool*>(property.m_reference.ptr)); &flag_value)) {
property.SetValue(flag_value);
}
} else if (property.m_type == SocketType::SocketTypeString) { } else if (property.m_type == SocketType::SocketTypeString) {
char string_buf[1024]; char string_buf[1024];
memset(string_buf, '\0', sizeof(string_buf)); memset(string_buf, '\0', sizeof(string_buf));

View File

@ -82,7 +82,7 @@ void AnimSamplerNode::Evaluate(AnimGraphContext& context) {
ozz::animation::SamplingJob sampling_job; ozz::animation::SamplingJob sampling_job;
sampling_job.animation = m_animation; sampling_job.animation = m_animation;
sampling_job.context = &m_sampling_context; sampling_job.context = &m_sampling_context;
sampling_job.ratio = m_time_now; sampling_job.ratio = fmodf(m_time_now, m_animation->duration());
sampling_job.output = make_span(o_output->m_local_matrices); sampling_job.output = make_span(o_output->m_local_matrices);
if (!sampling_job.Run()) { if (!sampling_job.Run()) {

View File

@ -138,7 +138,7 @@ struct NodeDescriptor<Blend2Node> : public NodeDescriptorBase {
Socket* weight_input_socket = FindSocket("Weight", m_inputs); Socket* weight_input_socket = FindSocket("Weight", m_inputs);
assert(weight_input_socket != nullptr); assert(weight_input_socket != nullptr);
if (GetProperty<bool>("Sync") == true) { if (GetPropertyValue<bool>("Sync") == true) {
weight_input_socket->m_flags = SocketFlags::SocketFlagAffectsTime; weight_input_socket->m_flags = SocketFlags::SocketFlagAffectsTime;
} else { } else {
weight_input_socket->m_flags = SocketFlags::SocketFlagNone; weight_input_socket->m_flags = SocketFlags::SocketFlagNone;
@ -156,8 +156,8 @@ struct SpeedScaleNode : public AnimNode {
float* i_speed_scale = nullptr; float* i_speed_scale = nullptr;
void UpdateTime(float time_last, float time_now) override { void UpdateTime(float time_last, float time_now) override {
m_time_last = time_last; m_time_last = m_time_now;
m_time_now = time_last + (time_now - time_last) * (*i_speed_scale); m_time_now = m_time_last + (time_now - time_last) * (*i_speed_scale);
m_state = AnimNodeEvalState::TimeUpdated; m_state = AnimNodeEvalState::TimeUpdated;
} }
@ -196,7 +196,7 @@ struct AnimSamplerNode : public AnimNode {
virtual bool Init(AnimGraphContext& context) override; virtual bool Init(AnimGraphContext& context) override;
void UpdateTime(float time_last, float time_now) override { void UpdateTime(float time_last, float time_now) override {
m_time_last = time_last; m_time_last = time_last;
m_time_now = fmodf(time_last + (time_now - time_last), m_animation->duration()); m_time_now = time_now;
m_state = AnimNodeEvalState::TimeUpdated; m_state = AnimNodeEvalState::TimeUpdated;
} }
virtual void Evaluate(AnimGraphContext& context) override; virtual void Evaluate(AnimGraphContext& context) override;

View File

@ -76,6 +76,7 @@ static struct {
} loaded; } loaded;
struct { struct {
double frame; double frame;
double anim_update_time;
float absolute; float absolute;
uint64_t laptime; uint64_t laptime;
float factor; float factor;
@ -511,7 +512,10 @@ int main() {
stm_round_to_common_refresh_rate(stm_laptime(&state.time.laptime))); stm_round_to_common_refresh_rate(stm_laptime(&state.time.laptime)));
if (!state.time.paused) { if (!state.time.paused) {
state.time.anim_update_time = state.time.frame;
state.time.absolute += state.time.frame * state.time.factor; state.time.absolute += state.time.frame * state.time.factor;
} else {
state.time.anim_update_time = 0.;
} }
if (state.ozz.animation != nullptr) { if (state.ozz.animation != nullptr) {
@ -725,7 +729,8 @@ int main() {
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Step")) { if (ImGui::Button("Step")) {
state.time.absolute += state.time.frame; state.time.anim_update_time = 1. / 30.f;
state.time.absolute += state.time.anim_update_time;
} }
if (state.ozz.animation != nullptr) { if (state.ozz.animation != nullptr) {
@ -758,9 +763,9 @@ int main() {
skinned_mesh.CalcModelMatrices(); skinned_mesh.CalcModelMatrices();
} }
if (state.time.use_graph && anim_graph.m_nodes.size() > 0) { if (state.time.use_graph && anim_graph.m_nodes.size() > 0 && state.time.anim_update_time > 0.) {
anim_graph.markActiveNodes(); anim_graph.markActiveNodes();
anim_graph.updateTime(state.time.frame); anim_graph.updateTime(state.time.anim_update_time);
anim_graph.evaluate(anim_graph_context); anim_graph.evaluate(anim_graph_context);
skinned_mesh.m_local_matrices = anim_graph_output.m_local_matrices; skinned_mesh.m_local_matrices = anim_graph_output.m_local_matrices;