Skip to content

Commit

Permalink
Merge pull request #1193 from reinago/anim-editor
Browse files Browse the repository at this point in the history
Fixes to Animation Editor and others
  • Loading branch information
moritz-h authored Apr 18, 2024
2 parents 235a5f7 + f48d2bb commit 2749f63
Show file tree
Hide file tree
Showing 78 changed files with 2,300 additions and 778 deletions.
4 changes: 2 additions & 2 deletions core/include/mmcore/Call.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ class Call : public std::enable_shared_from_this<Call> {
// and thereby linking the frontend service headers into the core
// so make the perf queries public when profiling is active...
public:
frontend_resources::PerformanceManager* perf_man = nullptr;
frontend_resources::PerformanceManager::handle_vector cpu_queries, gl_queries;
frontend_resources::performance::PerformanceManager* perf_man = nullptr;
frontend_resources::performance::handle_vector cpu_queries, gl_queries;
#endif // MEGAMOL_USE_PROFILING
#ifdef MEGAMOL_USE_OPENGL_DEBUGGROUPS
public:
Expand Down
55 changes: 54 additions & 1 deletion core/include/mmcore/utility/animation/AnimationData.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <imgui.h>
#include <sol/sol.hpp>

#include "mmcore/MegaMolGraph.h"

Expand All @@ -20,10 +21,30 @@ using KeyTimeType = int32_t;

enum class InterpolationType : int32_t { Step = 0, Linear = 1, Hermite = 2, CubicBezier = 3, SLERP = 4 };

class ExpressionInterpreter {
public:
static ExpressionInterpreter& getInstance() {
static ExpressionInterpreter instance;
return instance;
}
ExpressionInterpreter(ExpressionInterpreter const&) = delete;
void operator=(ExpressionInterpreter const&) = delete;

float EvaluateFloat(const std::string& script, KeyTimeType t);

std::string EvaluateString(const std::string& script, KeyTimeType t);

private:
ExpressionInterpreter() {
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string);
}
sol::state lua;
};

struct FloatKey {
using ValueType = float;
KeyTimeType time;
ValueType value;
ValueType value = ValueType();
InterpolationType interpolation = InterpolationType::Linear;
bool tangents_linked = true;
ImVec2 in_tangent{-1.0f, 0.0f};
Expand Down Expand Up @@ -61,6 +82,20 @@ struct StringKey {
ValueType value;
};

struct ScriptedStringKey {
using ValueType = std::string;
KeyTimeType time;
ValueType value;
std::string script;
};

struct ScriptedFloatKey {
using ValueType = float;
KeyTimeType time;
ValueType value;
std::string script;
};

template<class KeyType>
class GenericAnimation {
public:
Expand Down Expand Up @@ -98,6 +133,9 @@ class GenericAnimation {
const std::string& GetName() const {
return param_name;
}
void SetName(std::string param) {
param_name = param;
}
typename KeyMap::size_type GetSize() const {
return keys.size();
}
Expand Down Expand Up @@ -218,6 +256,21 @@ float GenericAnimation<FloatKey>::GetMinValue() const;
template<>
float GenericAnimation<FloatKey>::GetMaxValue() const;

using ScriptedStringAnimation = GenericAnimation<ScriptedStringKey>;

// Scripted Strings do everything differently
template<>
GenericAnimation<ScriptedStringKey>::ValueType::ValueType GenericAnimation<ScriptedStringKey>::GetValue(
KeyTimeType time) const;

using ScriptedFloatAnimation = GenericAnimation<ScriptedFloatKey>;

// Scripted Floats as well
template<>
GenericAnimation<ScriptedFloatKey>::ValueType::ValueType GenericAnimation<ScriptedFloatKey>::GetValue(
KeyTimeType time) const;


// same goes for vec keys, plus some more specialization
template<class C>
class VectorAnimation : public GenericAnimation<VectorKey<C>> {
Expand Down
10 changes: 9 additions & 1 deletion core/include/mmcore/utility/animation/AnimationUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,22 @@ void to_json(nlohmann::json& j, const StringKey& k);
void from_json(const nlohmann::json& j, StringKey& k);
void to_json(nlohmann::json& j, const VectorKey<FloatKey>& k);
void from_json(const nlohmann::json& j, VectorKey<FloatKey>& k);
void to_json(nlohmann::json& j, const ScriptedFloatKey& k);
void from_json(const nlohmann::json& j, ScriptedFloatKey& k);
void to_json(nlohmann::json& j, const ScriptedStringKey& k);
void from_json(const nlohmann::json& j, ScriptedStringKey& k);

void to_json(nlohmann::json& j, const FloatAnimation& f);
void from_json(const nlohmann::json& j, FloatAnimation& f);
void to_json(nlohmann::json& j, const StringAnimation& s);
void from_json(const nlohmann::json& j, StringAnimation& s);
void to_json(nlohmann::json& j, const FloatVectorAnimation& v);
void from_json(const nlohmann::json& j, FloatVectorAnimation& s);
void from_json(const nlohmann::json& j, FloatVectorAnimation& v);

void to_json(nlohmann::json& j, const ScriptedFloatAnimation& f);
void from_json(const nlohmann::json& j, ScriptedFloatAnimation& f);
void to_json(nlohmann::json& j, const ScriptedStringAnimation& s);
void from_json(const nlohmann::json& j, ScriptedStringAnimation& s);

// this does not seem okay
// PD code from https://github.com/ocornut/imgui/issues/1496#issuecomment-1287772456
Expand Down
9 changes: 5 additions & 4 deletions core/src/Call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,18 @@ bool Call::operator()(unsigned int func) {
}
#endif
#ifdef MEGAMOL_USE_PROFILING
perf_man->start_timer(cpu_queries[func]);
auto& cpu_region = perf_man->start_timer(cpu_queries[func]);
frontend_resources::performance::timer_region* gpu_region = nullptr;
if (caps.OpenGLRequired()) {
perf_man->start_timer(gl_queries[func]);
gpu_region = &perf_man->start_timer(gl_queries[func]);
}
#endif
res = this->callee->InCall(this->funcMap[func], *this);
#ifdef MEGAMOL_USE_PROFILING
if (caps.OpenGLRequired()) {
perf_man->stop_timer(gl_queries[func]);
gpu_region->end_region();
}
perf_man->stop_timer(cpu_queries[func]);
cpu_region.end_region();
#endif
#ifdef MEGAMOL_USE_OPENGL_DEBUGGROUPS
if (caps.OpenGLRequired()) {
Expand Down
51 changes: 45 additions & 6 deletions core/src/utility/animation/AnimationData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,33 @@ std::ostream& megamol::core::utility::operator<<(
return outs << ss.str();
}

float ExpressionInterpreter::EvaluateFloat(const std::string& script, KeyTimeType t) {
lua.set("time", t);
// I think this makes it too complicated
//sol::table in_t = lua["in_tangent"];
//in_t.clear();
//in_t.add(in_tangent[0], in_tangent[1]);
//sol::table out_t = lua["out_tangent"];
//out_t.clear();
//out_t.add(in_tangent[0], in_tangent[1]);
try {
const float res = lua.script(script);
return res;
} catch (sol::error& e) {
return 0.0f;
}
}

std::string ExpressionInterpreter::EvaluateString(const std::string& script, KeyTimeType t) {
lua.set("time", t);
try {
std::string res = lua.script(script);
return res;
} catch (sol::error& e) {
return "";
}
}

FloatKey::ValueType FloatKey::InterpolateForTime(FloatKey first, FloatKey second, KeyTimeType time) {
FloatKey my_first = first;
FloatKey my_second = second;
Expand Down Expand Up @@ -264,13 +291,13 @@ GenericAnimation<FloatKey>::ValueType::ValueType GenericAnimation<FloatKey>::Get
if (keys.empty()) {
return ValueType::ValueType();
}
return keys.begin()->second.value;
return FloatKey::InterpolateForTime(keys.begin()->second, keys.begin()->second, time);
}
FloatKey before_key = keys.begin()->second, after_key = keys.begin()->second;
bool ok = false;
for (auto it = keys.begin(); it != keys.end(); ++it) {
if (it->second.time == time) {
return it->second.value;
return FloatKey::InterpolateForTime(it->second, it->second, time);
}
if (it->second.time < time) {
before_key = it->second;
Expand All @@ -284,7 +311,7 @@ GenericAnimation<FloatKey>::ValueType::ValueType GenericAnimation<FloatKey>::Get
if (ok) {
return FloatKey::InterpolateForTime(before_key, after_key, time);
} else {
return before_key.value;
return FloatKey::InterpolateForTime(before_key, before_key, time);
}
}

Expand All @@ -293,7 +320,7 @@ template<>
ImVec2 GenericAnimation<FloatKey>::GetTangent(KeyTimeType time) const {
if (keys.size() < 2) {
if (keys.empty()) {
return ImVec2();
return ImVec2(1.0, 0.0);
}
return keys.begin()->second.out_tangent;
}
Expand Down Expand Up @@ -339,7 +366,7 @@ InterpolationType GenericAnimation<FloatKey>::GetInterpolation(KeyTimeType time)


template<>
float GenericAnimation<FloatKey>::GetMinValue() const {
GenericAnimation<FloatKey>::ValueType::ValueType GenericAnimation<FloatKey>::GetMinValue() const {
if (!keys.empty()) {
auto min = std::numeric_limits<float>::max();
for (auto& k : keys) {
Expand All @@ -352,7 +379,7 @@ float GenericAnimation<FloatKey>::GetMinValue() const {
}

template<>
float GenericAnimation<FloatKey>::GetMaxValue() const {
GenericAnimation<FloatKey>::ValueType::ValueType GenericAnimation<FloatKey>::GetMaxValue() const {
if (!keys.empty()) {
auto max = std::numeric_limits<float>::lowest();
for (auto& k : keys) {
Expand All @@ -363,3 +390,15 @@ float GenericAnimation<FloatKey>::GetMaxValue() const {
return 1.0f;
}
}

template<>
GenericAnimation<ScriptedStringKey>::ValueType::ValueType GenericAnimation<ScriptedStringKey>::GetValue(
KeyTimeType time) const {
return ExpressionInterpreter::getInstance().EvaluateString(keys.begin()->second.script, time);
}

template<>
GenericAnimation<ScriptedFloatKey>::ValueType::ValueType GenericAnimation<ScriptedFloatKey>::GetValue(
KeyTimeType time) const {
return ExpressionInterpreter::getInstance().EvaluateFloat(keys.begin()->second.script, time);
}
58 changes: 58 additions & 0 deletions core/src/utility/animation/AnimationUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,26 @@ void animation::from_json(const nlohmann::json& j, VectorKey<FloatKey>& k) {
}
}

void animation::to_json(nlohmann::json& j, const ScriptedFloatKey& k) {
j = nlohmann::json{{"time", k.time}, {"value", k.value}, {"script", k.script}};
}

void animation::from_json(const nlohmann::json& j, ScriptedFloatKey& k) {
j["time"].get_to(k.time);
j["value"].get_to(k.value);
j["script"].get_to(k.script);
}

void animation::to_json(nlohmann::json& j, const ScriptedStringKey& k) {
j = nlohmann::json{{"time", k.time}, {"value", k.value}, {"script", k.script}};
}

void animation::from_json(const nlohmann::json& j, ScriptedStringKey& k) {
j["time"].get_to(k.time);
j["value"].get_to(k.value);
j["script"].get_to(k.script);
}


void animation::to_json(nlohmann::json& j, const FloatAnimation& f) {
j = nlohmann::json{{"name", f.GetName()}, {"type", "float"}};
Expand Down Expand Up @@ -116,6 +136,44 @@ void animation::from_json(const nlohmann::json& j, FloatVectorAnimation& v) {
}
}

void animation::to_json(nlohmann::json& j, const ScriptedFloatAnimation& f) {
j = nlohmann::json{{"name", f.GetName()}, {"type", "scripted_float"}};
auto v_array = nlohmann::json::array();
for (auto& k : f.GetAllKeys()) {
v_array.push_back(f[k]);
}
j["keys"] = v_array;
}

void animation::from_json(const nlohmann::json& j, ScriptedFloatAnimation& f) {
f = ScriptedFloatAnimation{j.at("name")};
assert(j.at("type") == "scripted_float");
for (auto& j : j["keys"]) {
ScriptedFloatKey k;
j.get_to(k);
f.AddKey(k);
}
}

void animation::to_json(nlohmann::json& j, const ScriptedStringAnimation& s) {
j = nlohmann::json{{"name", s.GetName()}, {"type", "scripted_string"}};
auto v_array = nlohmann::json::array();
for (auto& k : s.GetAllKeys()) {
v_array.push_back(s[k]);
}
j["keys"] = v_array;
}

void animation::from_json(const nlohmann::json& j, ScriptedStringAnimation& s) {
s = ScriptedStringAnimation{j.at("name")};
assert(j.at("type") == "scripted_string");
for (auto& j : j["keys"]) {
ScriptedStringKey k;
j.get_to(k);
s.AddKey(k);
}
}

// this does not seem okay
#if 0
static ImVector<ImRect> s_GroupPanelLabelStack;
Expand Down
6 changes: 1 addition & 5 deletions frontend/main/src/CLIConfigParsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
#include <cstdio>
#include <cstdlib>
#include <filesystem>
#include <fstream>

#define CXXOPTS_VECTOR_DELIMITER '\0'
#include <cxxopts.hpp>
#include <fstream>

// find user home
static std::filesystem::path getHomeDir() {
Expand Down Expand Up @@ -809,8 +809,6 @@ megamol::frontend_resources::RuntimeConfig megamol::frontend::handle_config(
accepted_log_level_strings,
make_option_callback(echolevel_option));

//lua.AddCallbacks(lua_config_callbacks);

for (auto& file : config.configuration_files) {
cli_options_from_configs.clear();
std::ifstream stream(file);
Expand Down Expand Up @@ -868,8 +866,6 @@ megamol::frontend_resources::RuntimeConfig megamol::frontend::handle_config(
[](std::string const& init, std::string const& elem) { return init + elem + " "; }));
}

//lua.ClearCallbacks();

return config;
}

Expand Down
Loading

0 comments on commit 2749f63

Please sign in to comment.