Lumenarium/src/app/engine/animation/foldhaus_animation_serializ...

192 lines
7.5 KiB
C++

//
// File: foldhaus_animation_serializer.cpp
// Author: Peter Slattery
// Creation Date: 2020-10-04
//
#ifndef FOLDHAUS_ANIMATION_SERIALIZER_CPP
internal gs_string
AnimSerializer_Serialize(animation Anim, animation_clip* GlobalClips, gs_memory_arena* Arena)
{
serializer Serializer = {0};
Serializer.String = PushString(Arena, 4096);
Serializer.Identifiers = AnimationFieldStrings;
Serializer.IdentifiersCount = AnimField_Count;
Serializer_WriteF(&Serializer, "%S;\n", AnimationFieldStrings[AnimField_FileIdent]);
Serializer_WriteStringValue(&Serializer, AnimField_AnimName, Anim.Name.ConstString);
Serializer_WriteValue(&Serializer, AnimField_LayersCount, Anim.Layers.Count);
Serializer_WriteValue(&Serializer, AnimField_BlocksCount, Anim.Blocks_.Count);
Serializer_OpenStruct(&Serializer, AnimField_PlayableRange);
{
Serializer_WriteValue(&Serializer, AnimField_PlayableRangeMin, (u32)Anim.PlayableRange.Min);
Serializer_WriteValue(&Serializer, AnimField_PlayableRangeMax, (u32)Anim.PlayableRange.Max);
}
Serializer_CloseStruct(&Serializer);
Serializer_OpenStruct(&Serializer, AnimField_LayersArray);
for (u32 i = 0; i < Anim.Layers.Count; i++)
{
anim_layer LayerAt = Anim.Layers.Values[i];
Serializer_OpenStruct(&Serializer, AnimField_Layer);
{
Serializer_WriteStringValue(&Serializer, AnimField_LayerName, LayerAt.Name.ConstString);
Serializer_WriteStringValue(&Serializer, AnimField_LayerBlendMode, BlendModeStrings[LayerAt.BlendMode]);
}
Serializer_CloseStruct(&Serializer);
}
Serializer_CloseStruct(&Serializer);
Serializer_OpenStruct(&Serializer, AnimField_BlocksArray);
for (u32 i = 0; i < Anim.Blocks_.Count; i++)
{
// TODO(pjs): Handle free'd animation blocks
animation_block AnimationBlockAt = Anim.Blocks_.Values[i];
// TODO(pjs): Systematize the AnimationProcHandle
// :AnimProcHandle
u32 AnimationProcIndex = AnimationBlockAt.AnimationProcHandle - 1;
animation_clip Animation = GlobalClips[AnimationProcIndex];
Serializer_OpenStruct(&Serializer, AnimField_Block);
{
Serializer_OpenStruct(&Serializer, AnimField_BlockFrameRange);
{
Serializer_WriteValue(&Serializer, AnimField_BlockFrameRangeMin, (u32)AnimationBlockAt.Range.Min);
Serializer_WriteValue(&Serializer, AnimField_BlockFrameRangeMax, (u32)AnimationBlockAt.Range.Max);
}
Serializer_CloseStruct(&Serializer);
Serializer_WriteValue(&Serializer, AnimField_BlockLayerIndex, AnimationBlockAt.Layer);
Serializer_WriteStringValue(&Serializer, AnimField_BlockAnimName, ConstString(Animation.Name));
}
Serializer_CloseStruct(&Serializer);
}
Serializer_CloseStruct(&Serializer);
return Serializer.String;
}
internal animation
AnimParser_Parse(gs_string File, gs_memory_arena* Arena, u32 AnimClipsCount, animation_clip* AnimClips)
{
animation Result = {0};
parser Parser = {0};
Parser.String = File;
Parser.At = Parser.String.Str;
Parser.Identifiers = AnimationFieldStrings;
Parser.IdentifiersCount = AnimField_Count;
Parser.Arena = Arena;
if (Parser_ReadString(&Parser, AnimationFieldStrings[AnimField_FileIdent]))
{
Result.Name = Parser_ReadStringValue(&Parser, AnimField_AnimName);
Result.Layers.CountMax = Parser_ReadU32Value(&Parser, AnimField_LayersCount);
Result.Layers.Values = PushArray(Arena, anim_layer, Result.Layers.CountMax);
Result.Blocks_.CountMax = Parser_ReadU32Value(&Parser, AnimField_BlocksCount);
Result.Blocks_.Generations = PushArray(Arena, u32, Result.Blocks_.CountMax);
Result.Blocks_.Values = PushArray(Arena, animation_block, Result.Blocks_.CountMax);
if (Parser_ReadOpenStruct(&Parser, AnimField_PlayableRange))
{
Result.PlayableRange.Min = Parser_ReadU32Value(&Parser, AnimField_PlayableRangeMin);
Result.PlayableRange.Max = Parser_ReadU32Value(&Parser, AnimField_PlayableRangeMax);
if (Parser_ReadCloseStruct(&Parser))
{
// TODO(pjs): Error
}
}
else
{
// TODO(pjs): Error
}
if (Parser_ReadOpenStruct(&Parser, AnimField_LayersArray))
{
while (!Parser_ReadCloseStruct(&Parser))
{
anim_layer Layer = {0};
if (Parser_ReadOpenStruct(&Parser, AnimField_Layer))
{
Layer.Name = Parser_ReadStringValue(&Parser, AnimField_LayerName);
gs_string BlendModeName = Parser_ReadStringValue(&Parser, AnimField_LayerBlendMode);
for (u32 i = 0; i < BlendMode_Count; i++)
{
if (StringsEqual(BlendModeName.ConstString, BlendModeStrings[i]))
{
Layer.BlendMode = (blend_mode)i;
break;
}
}
if (Parser_ReadCloseStruct(&Parser))
{
Animation_AddLayer(&Result, Layer);
}
else
{
// TODO(pjs): Error
}
}
}
}
if (Parser_ReadOpenStruct(&Parser, AnimField_BlocksArray))
{
while(!Parser_ReadCloseStruct(&Parser))
{
animation_block Block = {0};
if (Parser_ReadOpenStruct(&Parser, AnimField_Block))
{
if (Parser_ReadOpenStruct(&Parser, AnimField_BlockFrameRange))
{
Block.Range.Min = Parser_ReadU32Value(&Parser, AnimField_BlockFrameRangeMin);
Block.Range.Max = Parser_ReadU32Value(&Parser, AnimField_BlockFrameRangeMax);
Parser_ReadCloseStruct(&Parser);
}
else
{
// TODO(pjs): Error
}
Block.Layer = Parser_ReadU32Value(&Parser, AnimField_BlockLayerIndex);
// TODO(pjs): AnimName -> Animation Proc Handle
gs_string AnimName = Parser_ReadStringValue(&Parser, AnimField_BlockAnimName);
Block.AnimationProcHandle = 0;
for (u32 i = 0; i < AnimClipsCount; i++)
{
if (StringEqualsCharArray(AnimName.ConstString, AnimClips[i].Name, CStringLength(AnimClips[i].Name)))
{
Block.AnimationProcHandle = i + 1;
break;
}
}
if (Parser_ReadCloseStruct(&Parser))
{
AnimBlockArray_Push(&Result.Blocks_, Block);
}
else
{
// TODO(pjs): Error
}
}
}
}
}
return Result;
}
#define FOLDHAUS_ANIMATION_SERIALIZER_CPP
#endif // FOLDHAUS_ANIMATION_SERIALIZER_CPP