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

189 lines
7.6 KiB
C++
Raw Normal View History

2020-10-05 20:17:33 +00:00
//
// 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.Used);
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.Used; i++)
{
gs_list_entry<animation_block>* AnimationBlockEntry = Anim.Blocks.GetEntryAtIndex(i);
if (EntryIsFree(AnimationBlockEntry)) { continue; }
gs_list_handle CurrentBlockHandle = AnimationBlockEntry->Handle;
animation_block AnimationBlockAt = AnimationBlockEntry->Value;
// 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, animation_clip* GlobalClips, 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);
// TODO(pjs): We're not using this now because Blocks are built on gs_list or something,
// but I want to replace that eventually, so this is here to preallocate the blocks we need
u32 BlocksCount = Parser_ReadU32Value(&Parser, AnimField_BlocksCount);
if (Parser_ReadOpenStruct(&Parser, AnimField_PlayableRange))
{
Result.PlayableRange.Min = Parser_ReadU32Value(&Parser, AnimField_PlayableRangeMin);
Result.PlayableRange.Max = Parser_ReadU32Value(&Parser, AnimField_PlayableRangeMax);
}
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))
{
Result.Blocks.PushElementOnList(Block);
}
else
{
// TODO(pjs): Error
}
}
}
}
}
return Result;
}
2020-10-05 20:17:33 +00:00
#define FOLDHAUS_ANIMATION_SERIALIZER_CPP
#endif // FOLDHAUS_ANIMATION_SERIALIZER_CPP