Kawe Mazidjatari 04bee896be Fix string/wstring type conflict
cppkore uses string/wstring as StringBase while we use std::string/std::wstring as string/wstring. Changed all types in cppkore to String/WString instead.
2022-05-21 21:51:35 +02:00

129 lines
3.0 KiB
C++

#include "stdafx.h"
#include "Animation.h"
namespace Assets
{
Animation::Animation()
: Animation(0)
{
}
Animation::Animation(uint32_t BoneCount)
: Animation(BoneCount, 30.0f)
{
}
Animation::Animation(uint32_t BoneCount, float FrameRate)
: Bones(BoneCount), Looping(false), FrameRate(FrameRate), Name("error"), TransformSpace(AnimationTransformSpace::Local), RotationInterpolation(AnimationRotationInterpolation::Quaternion)
{
}
List<Curve>& Animation::GetNodeCurves(const String& NodeName)
{
if (Curves.ContainsKey(NodeName))
return Curves[NodeName];
Curves.Add(NodeName, List<Curve>());
return Curves[NodeName];
}
void Animation::AddNotification(const String& Name, uint32_t Frame)
{
if (Notificiations.ContainsKey(Name))
Notificiations[Name].EmplaceBack(Frame);
Notificiations.Add(Name, List<uint32_t>());
Notificiations[Name].EmplaceBack(Frame);
}
const uint32_t Animation::FrameCount(bool Legacy) const
{
uint32_t Result = 0;
for (auto& Kvp : Curves)
{
for (auto& Curve : Kvp.Value())
{
if (Legacy)
{
// Used for animation types which do not support non-bone like curves
// So we only have quaternion rotation, translations, and scales
if (Curve.Property == CurveProperty::RotateQuaternion || (Curve.Property >= CurveProperty::TranslateX && Curve.Property <= CurveProperty::TranslateZ) || (Curve.Property >= CurveProperty::ScaleX && Curve.Property <= CurveProperty::ScaleZ))
{
for (auto& Keyframe : Curve.Keyframes)
Result = max(Result, Keyframe.Frame.Integer32);
}
}
else
{
// Support all curves
for (auto& Keyframe : Curve.Keyframes)
Result = max(Result, Keyframe.Frame.Integer32);
}
}
}
for (auto& NoteTrack : Notificiations)
for (auto& Note : NoteTrack.Value())
Result = max(Result, Note);
// Frame count is the length of the animation in frames
// Frames start at index 0, so we add one to get the count
return Result + 1;
}
const uint32_t Animation::NotificationCount() const
{
uint32_t Result = 0;
for (auto& NoteTrack : Notificiations)
Result += NoteTrack.Value().Count();
return Result;
}
void Animation::Scale(float Factor)
{
for (auto& Kvp : Curves)
{
for (auto& Curve : Kvp.Value())
{
// Translation keyframes are scaled here...
if (Curve.Property >= CurveProperty::TranslateX && Curve.Property <= CurveProperty::TranslateZ)
{
for (auto& Keyframe : Curve.Keyframes)
{
Keyframe.Value.Float *= Factor;
}
}
}
}
for (auto& Bone : Bones)
{
if (Bone.GetFlag(BoneFlags::HasLocalSpaceMatrices))
{
Bone.SetLocalPosition(Bone.LocalPosition() * Factor);
}
if (Bone.GetFlag(BoneFlags::HasGlobalSpaceMatrices))
{
Bone.SetGlobalPosition(Bone.GlobalPosition() * Factor);
}
}
}
void Animation::RemoveEmptyNodes()
{
for (auto& Kvp : Curves)
{
for (int32_t i = ((int32_t)Kvp.Value().Count() - 1); i >= 0; i--)
{
if (Kvp.Value()[i].Keyframes.Count() == 0)
{
Kvp.Value().RemoveAt(i);
}
}
}
}
}