Refactor easings, serialize per-line items, constexpr path

pull/3236/head
Sam Hellawell 8 months ago
parent 72c95a51df
commit 014cba807b

@ -767,7 +767,7 @@ namespace MWRender
Misc::StringUtils::replaceLast(yamlpath, ".dae", ".yaml"); Misc::StringUtils::replaceLast(yamlpath, ".dae", ".yaml");
// globalBlendConfigPath is only used with actors! Objects have no default blending. // globalBlendConfigPath is only used with actors! Objects have no default blending.
const VFS::Path::NormalizedView globalBlendConfigPath("animations/animation-config.yaml"); constexpr VFS::Path::NormalizedView globalBlendConfigPath("animations/animation-config.yaml");
const VFS::Path::NormalizedView blendConfigPath(yamlpath); const VFS::Path::NormalizedView blendConfigPath(yamlpath);
osg::ref_ptr<const SceneUtil::AnimBlendRules> blendRules; osg::ref_ptr<const SceneUtil::AnimBlendRules> blendRules;

@ -10,84 +10,127 @@
namespace MWRender namespace MWRender
{ {
/// Animation Easing/Blending functions namespace
{
// Animation Easing/Blending functions
namespace Easings namespace Easings
{ {
float linear(float x) float linear(float x)
{ {
return x; return x;
} }
float sineOut(float x) float sineOut(float x)
{ {
return sin((x * 3.14) / 2); return sin((x * osg::PIf) / 2);
} }
float sineIn(float x) float sineIn(float x)
{ {
return 1 - cos((x * 3.14) / 2); return 1 - cos((x * osg::PIf) / 2);
} }
float sineInOut(float x) float sineInOut(float x)
{ {
return -(cos(3.14 * x) - 1) / 2; return -(cos(osg::PIf * x) - 1) / 2;
} }
float cubicOut(float t) float cubicOut(float t)
{ {
return 1 - powf(1 - t, 3); float t1 = 1 - t;
return 1 - (t1 * t1 * t1); // (1-t)^3
} }
float cubicIn(float x) float cubicIn(float x)
{ {
return powf(x, 3); return x * x * x; // x^3
} }
float cubicInOut(float x) float cubicInOut(float x)
{ {
return x < 0.5 ? 4 * x * x * x : 1 - powf(-2 * x + 2, 3) / 2; if (x < 0.5)
{
return 4 * x * x * x; // 4x^3
}
else
{
float x2 = -2 * x + 2;
return 1 - (x2 * x2 * x2) / 2; // (1 - (-2x + 2)^3)/2
} }
}
float quartOut(float t) float quartOut(float t)
{ {
return 1 - powf(1 - t, 4); float t1 = 1 - t;
return 1 - (t1 * t1 * t1 * t1); // (1-t)^4
} }
float quartIn(float t) float quartIn(float t)
{ {
return powf(t, 4); return t * t * t * t; // t^4
} }
float quartInOut(float x) float quartInOut(float x)
{ {
return x < 0.5 ? 8 * x * x * x * x : 1 - powf(-2 * x + 2, 4) / 2; if (x < 0.5)
{
return 8 * x * x * x * x; // 8x^4
} }
else
{
float x2 = -2 * x + 2;
return 1 - (x2 * x2 * x2 * x2) / 2; // 1 - ((-2x + 2)^4)/2
}
}
float springOutGeneric(float x, float lambda, float w) float springOutGeneric(float x, float lambda, float w)
{ {
// Higher lambda = lower swing amplitude. 1 = 150% swing amplitude. // Higher lambda = lower swing amplitude. 1 = 150% swing amplitude.
// W corresponds to the amount of overswings, more = more. 4.71 = 1 overswing, 7.82 = 2 // W corresponds to the amount of overswings, more = more. 4.71 = 1 overswing, 7.82 = 2
return 1 - expf(-lambda * x) * cos(w * x); return 1 - expf(-lambda * x) * cos(w * x);
} }
float springOutWeak(float x) float springOutWeak(float x)
{ {
return springOutGeneric(x, 4, 4.71); return springOutGeneric(x, 4, 4.71);
} }
float springOutMed(float x) float springOutMed(float x)
{ {
return springOutGeneric(x, 3, 4.71); return springOutGeneric(x, 3, 4.71);
} }
float springOutStrong(float x) float springOutStrong(float x)
{ {
return springOutGeneric(x, 2, 4.71); return springOutGeneric(x, 2, 4.71);
} }
float springOutTooMuch(float x) float springOutTooMuch(float x)
{ {
return springOutGeneric(x, 1, 4.71); return springOutGeneric(x, 1, 4.71);
} }
std::unordered_map<std::string, EasingFn> easingsMap = { { "linear", Easings::linear },
{ "sineOut", Easings::sineOut }, { "sineIn", Easings::sineIn }, { "sineInOut", Easings::sineInOut }, const std::unordered_map<std::string, EasingFn> easingsMap = {
{ "cubicOut", Easings::cubicOut }, { "cubicIn", Easings::cubicIn }, { "cubicInOut", Easings::cubicInOut }, { "linear", Easings::linear },
{ "quartOut", Easings::quartOut }, { "quartIn", Easings::quartIn }, { "quartInOut", Easings::quartInOut }, { "sineOut", Easings::sineOut },
{ "springOutWeak", Easings::springOutWeak }, { "springOutMed", Easings::springOutMed }, { "sineIn", Easings::sineIn },
{ "springOutStrong", Easings::springOutStrong }, { "springOutTooMuch", Easings::springOutTooMuch } }; { "sineInOut", Easings::sineInOut },
{ "cubicOut", Easings::cubicOut },
{ "cubicIn", Easings::cubicIn },
{ "cubicInOut", Easings::cubicInOut },
{ "quartOut", Easings::quartOut },
{ "quartIn", Easings::quartIn },
{ "quartInOut", Easings::quartInOut },
{ "springOutWeak", Easings::springOutWeak },
{ "springOutMed", Easings::springOutMed },
{ "springOutStrong", Easings::springOutStrong },
{ "springOutTooMuch", Easings::springOutTooMuch },
};
} }
namespace osg::Vec3f vec3fLerp(float t, const osg::Vec3f& start, const osg::Vec3f& end)
{
osg::Vec3f vec3fLerp(float t, const osg::Vec3f& A, const osg::Vec3f& B)
{ {
return A + (B - A) * t; return start + (end - start) * t;
} }
} }
@ -129,10 +172,10 @@ namespace MWRender
if (blendRule) if (blendRule)
{ {
if (Easings::easingsMap.contains(blendRule->mEasing)) if (const auto it = Easings::easingsMap.find(blendRule->mEasing); it != Easings::easingsMap.end())
{ {
mEasingFn = it->second;
mBlendDuration = blendRule->mDuration; mBlendDuration = blendRule->mDuration;
mEasingFn = Easings::easingsMap[blendRule->mEasing];
} }
else else
{ {

@ -16,10 +16,7 @@
namespace MWRender namespace MWRender
{ {
namespace Easings
{
typedef float (*EasingFn)(float); typedef float (*EasingFn)(float);
}
struct AnimBlendStateData struct AnimBlendStateData
{ {
@ -41,7 +38,7 @@ namespace MWRender
bool getBlendTrigger() const { return mBlendTrigger; } bool getBlendTrigger() const { return mBlendTrigger; }
protected: protected:
Easings::EasingFn mEasingFn; EasingFn mEasingFn;
float mBlendDuration = 0.0f; float mBlendDuration = 0.0f;
float mBlendStartTime = 0.0f; float mBlendStartTime = 0.0f;
float mTimeFactor = 0.0f; float mTimeFactor = 0.0f;

@ -187,20 +187,48 @@ namespace SceneUtil
mgr->addWrapper(new GeometrySerializer); mgr->addWrapper(new GeometrySerializer);
// ignore the below for now to avoid warning spam // ignore the below for now to avoid warning spam
const char* ignore[] = { "Debug::DebugDrawer", "MWRender::NifAnimBlendController", const char* ignore[] = {
"MWRender::BoneAnimBlendController", "MWRender::BoneAnimBlendControllerWrapper", "MWRender::PtrHolder", "Debug::DebugDrawer",
"Resource::TemplateRef", "Resource::TemplateMultiRef", "SceneUtil::CompositeStateSetUpdater", "MWRender::NifAnimBlendController",
"SceneUtil::UBOManager", "SceneUtil::LightListCallback", "SceneUtil::LightManagerUpdateCallback", "MWRender::BoneAnimBlendController",
"SceneUtil::FFPLightStateAttribute", "SceneUtil::UpdateRigBounds", "SceneUtil::UpdateRigGeometry", "MWRender::BoneAnimBlendControllerWrapper",
"SceneUtil::LightSource", "SceneUtil::DisableLight", "SceneUtil::MWShadowTechnique", "MWRender::PtrHolder",
"SceneUtil::TextKeyMapHolder", "Shader::AddedState", "Shader::RemovedAlphaFunc", "Resource::TemplateRef",
"NifOsg::FlipController", "NifOsg::KeyframeController", "NifOsg::Emitter", "Resource::TemplateMultiRef",
"NifOsg::ParticleColorAffector", "NifOsg::ParticleSystem", "NifOsg::GravityAffector", "SceneUtil::CompositeStateSetUpdater",
"NifOsg::ParticleBomb", "NifOsg::GrowFadeAffector", "NifOsg::InverseWorldMatrix", "SceneUtil::UBOManager",
"NifOsg::StaticBoundingBoxCallback", "NifOsg::GeomMorpherController", "NifOsg::UpdateMorphGeometry", "SceneUtil::LightListCallback",
"NifOsg::UVController", "NifOsg::VisController", "osgMyGUI::Drawable", "osg::DrawCallback", "SceneUtil::LightManagerUpdateCallback",
"osg::UniformBufferObject", "osgOQ::ClearQueriesCallback", "osgOQ::RetrieveQueriesCallback", "SceneUtil::FFPLightStateAttribute",
"osg::DummyObject" }; "SceneUtil::UpdateRigBounds",
"SceneUtil::UpdateRigGeometry",
"SceneUtil::LightSource",
"SceneUtil::DisableLight",
"SceneUtil::MWShadowTechnique",
"SceneUtil::TextKeyMapHolder",
"Shader::AddedState",
"Shader::RemovedAlphaFunc",
"NifOsg::FlipController",
"NifOsg::KeyframeController",
"NifOsg::Emitter",
"NifOsg::ParticleColorAffector",
"NifOsg::ParticleSystem",
"NifOsg::GravityAffector",
"NifOsg::ParticleBomb",
"NifOsg::GrowFadeAffector",
"NifOsg::InverseWorldMatrix",
"NifOsg::StaticBoundingBoxCallback",
"NifOsg::GeomMorpherController",
"NifOsg::UpdateMorphGeometry",
"NifOsg::UVController",
"NifOsg::VisController",
"osgMyGUI::Drawable",
"osg::DrawCallback",
"osg::UniformBufferObject",
"osgOQ::ClearQueriesCallback",
"osgOQ::RetrieveQueriesCallback",
"osg::DummyObject",
};
for (size_t i = 0; i < sizeof(ignore) / sizeof(ignore[0]); ++i) for (size_t i = 0; i < sizeof(ignore) / sizeof(ignore[0]); ++i)
{ {
mgr->addWrapper(makeDummySerializer(ignore[i])); mgr->addWrapper(makeDummySerializer(ignore[i]));

Loading…
Cancel
Save