mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
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.
129 lines
3.0 KiB
C++
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|