/* gcc -std=c99 *.c -lm && ./a.out | mpv --no-correct-pts --container-fps-override=30 - * gcc -std=c99 *.c -lm && ./a.out | ffmpeg -r 30 -i - output.mp4 */ #include "Animation.h" #include "AnimationObject.h" #include "AnimationMove.h" #include "AnimationInterpolate.h" #include double pointDistance(i32 rowA, i32 colA, i32 rowB, i32 colB) { return sqrt(pow(rowA - rowB, 2) + pow(colA - colB, 2)); } void HorSegmentByPoints( i32 rowA, i32 colA, i32 rowB, i32 colB, struct AO_HorSegment* segment, struct AM_Spin* rotate, struct AM_Linear* translate) { segment->left = 0; segment->right = pointDistance(rowA, colA, rowB, colB); rotate->theta = atan2(rowB - rowA, colB - colA); translate->startRow = rowA; translate->startCol = colA; rotate->callback = AO_HorSegment; rotate->priv = segment; translate->callback = AM_Spin; translate->priv = rotate; } int main() { const u32 FPS = 60; Animation anim = Animation_new(512, 512, FPS * 5); struct AO_Square background = { .width = anim.width, .height = anim.height, .color = 0xFFF0F0F0, }; Animation_pushEvent(&anim, 0, anim.frameCount, AO_Square, &background); /* Root node */ struct AO_Circle rootNode_ = { .radius = 60, .color = 0xFFFF0000, }; struct AM_Linear rootNode_linear = { .callback = AO_Circle, .priv = &rootNode_, .startRow = anim.height / 4, .startCol = anim.width / 2, }; struct AM_Linear rootNode = rootNode_linear; /* Child node */ struct AO_Circle childNode_ = { .radius = 60, .color = 0xFF00FF00, }; struct AM_Linear childNode_left = { .callback = AO_Circle, .priv = &childNode_, .startRow = anim.height * 3 / 4, .startCol = anim.width / 4, }; struct AM_Linear childNode_right = { .callback = AO_Circle, .priv = &childNode_, .startRow = anim.height * 3 / 4, .startCol = anim.width * 3 / 4, }; struct AM_Linear childNode = childNode_right; /* Root Node --- Child Node */ struct AO_HorSegment link_ = { .color = 0xFFFF00FF, .width = 10, }; struct AM_Spin link_spin_left = {}; struct AM_Linear link_translate_left = {}; HorSegmentByPoints( rootNode_linear.startRow, rootNode_linear.startCol, childNode_left.startRow, childNode_left.startCol, &link_, &link_spin_left, &link_translate_left); struct AM_Spin link_spin_right = {}; struct AM_Linear link_translate_right = {}; HorSegmentByPoints( rootNode_linear.startRow, rootNode_linear.startCol, childNode_right.startRow, childNode_right.startCol, &link_, &link_spin_right, &link_translate_right); struct AM_Spin link_spin = link_spin_right; struct AM_Linear link_translate = link_translate_right; link_translate.priv = &link_spin; Animation_pushEvent(&anim, 0, anim.frameCount, AM_Linear, &link_translate); Animation_pushEvent(&anim, 0, anim.frameCount, AM_Linear, &rootNode); Animation_pushEvent(&anim, 0, anim.frameCount, AM_Linear, &childNode); /* Movement */ struct AM_Linear temp1; struct A_Interpolate childNode_moveToLeft = { .initialValueTemp = &temp1, .initialValueTempSize = sizeof(temp1), .interpolate = AM_LinearInterpolate, .value = &childNode, .goalValue = &childNode_left, }; struct AM_Spin temp11; struct A_Interpolate segment_spin_moveToLeft = { .initialValueTemp = &temp11, .initialValueTempSize = sizeof(temp11), .interpolate = AM_SpinInterpolate, .value = &link_spin, .goalValue = &link_spin_left, }; struct AM_Linear temp12; struct A_Interpolate segment_translate_moveToLeft = { .initialValueTemp = &temp12, .initialValueTempSize = sizeof(temp12), .interpolate = AM_LinearInterpolate, .value = &link_translate, .goalValue = &link_translate_left, }; struct AM_Linear temp2; struct A_Interpolate childNode_moveToRight = { .initialValueTemp = &temp2, .initialValueTempSize = sizeof(temp2), .interpolate = AM_LinearInterpolate, .value = &childNode, .goalValue = &childNode_right, }; struct AM_Spin temp21; struct A_Interpolate segment_spin_moveToRight = { .initialValueTemp = &temp21, .initialValueTempSize = sizeof(temp21), .interpolate = AM_SpinInterpolate, .value = &link_spin, .goalValue = &link_spin_right, }; struct AM_Linear temp22; struct A_Interpolate segment_translate_moveToRight = { .initialValueTemp = &temp22, .initialValueTempSize = sizeof(temp22), .interpolate = AM_LinearInterpolate, .value = &link_translate, .goalValue = &link_translate_right, }; /* Move child node from right to left */ u32 start = anim.frameCount / 3 - FPS, end = anim.frameCount / 3; Animation_pushEvent(&anim, start, end, A_Interpolate, &childNode_moveToLeft); Animation_pushEvent(&anim, start, end, A_Interpolate, &segment_spin_moveToLeft); Animation_pushEvent(&anim, start, end, A_Interpolate, &segment_translate_moveToLeft); /* Move child node from left to right */ start = anim.frameCount * 2 / 3 - FPS, end = anim.frameCount * 2 / 3; Animation_pushEvent(&anim, start, end, A_Interpolate, &childNode_moveToRight); Animation_pushEvent(&anim, start, end, A_Interpolate, &segment_spin_moveToRight); Animation_pushEvent(&anim, start, end, A_Interpolate, &segment_translate_moveToRight); Animation_render(&anim); Animation_delete(&anim); return 0; }