/* 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 "AnimationRender/AnimationRender.h" #include "AnimationRender/F_Draw.h" #include "AnimationRender/F_FrameRange.h" #include "AnimationRender/F_Interpolate.h" #include "AnimationRender/FrameCallback.h" #include "FrameRender/FrameRender.h" #include "FrameRender/P_Checker.h" #include "FrameRender/P_Circle.h" #include "FrameRender/P_Image.h" #include "FrameRender/P_LineSegment.h" #include "FrameRender/P_Square.h" #include "FrameRender/P_TransformCenter.h" #include "FrameRender/P_TransformRotate.h" #include "FrameRender/PixelCallback.h" #include "RGBImage.h" #include # define M_PI 3.14159265358979323846 /* pi */ int main() { u32 width = 512; u32 height = 512; const u32 FPS = 60; u32 frames = FPS * 5; TransformCenter childLeft = { .centerX = width / 4, .centerY = height * 3 / 4, }; TransformCenter childRight = { .centerX = width * 3 / 4, .centerY = height * 3 / 4, }; LineSegment segmentRight = { .aX = width / 2, .aY = height / 4, .bX = width * 3 / 4, .bY = height * 3 / 4, .width = 10, .color = 0xFFFF00FF, }; LineSegment segmentLeft = { .aX = width / 2, .aY = height / 4, .bX = width / 4, .bY = height * 3 / 4, .width = 10, .color = 0xFFFF00FF, }; PixelCallback* callbacks[] = { /* Background */ Square_setup((Square){ .size = width, .color = 0xFFF0F0F0, }), /* Root node */ TransformCenter_setup((TransformCenter){ .centerX = width / 2, .centerY = height / 4, }), Circle_setup((Circle){ .radius = 60, .color = 0xFFFF0000, }), /* Child node */ NULL, TransformCenter_setup(childRight), Circle_setup((Circle){ .radius = 60, .color = 0xFF00FF00, }), /* Connecting line */ NULL, LineSegment_setup((LineSegment){ .aX = width / 2, .aY = height / 4, .bX = width * 3 / 4, .bY = height * 3 / 4, .width = 10, .color = 0xFFFF00FF, }), }; u32 sizeCallbacks = sizeof(callbacks) / sizeof(*callbacks); FrameCallback* frameCallbacks[] = { FrameRange_setup((FrameRange){ .startFrame = frames / 3 - FPS, .endFrame = frames / 3, }), Interpolate_setup((Interpolate){ .startValue = &childRight, .endValue = &childLeft, .value = callbacks[4]->callback_self, .interpolate = (f_interpolate)Interpolate_TransformCenter, }), Interpolate_setup((Interpolate){ .startValue = &segmentRight, .endValue = &segmentLeft, .value = callbacks[7]->callback_self, .interpolate = (f_interpolate)Interpolate_LineSegment, }), NULL, FrameRange_setup((FrameRange){ .startFrame = frames * 2 / 3 - FPS, .endFrame = frames * 2 / 3, }), Interpolate_setup((Interpolate){ .startValue = &childLeft, .endValue = &childRight, .value = callbacks[4]->callback_self, .interpolate = (f_interpolate)Interpolate_TransformCenter, }), Interpolate_setup((Interpolate){ .startValue = &segmentLeft, .endValue = &segmentRight, .value = callbacks[7]->callback_self, .interpolate = (f_interpolate)Interpolate_LineSegment, }), NULL, Draw_setup((Draw){ .callbacks = (const PixelCallback**)callbacks, .sizeCallbacks = sizeCallbacks, }), }; u32 sizeFrameCallbacks = sizeof(frameCallbacks) / sizeof(*frameCallbacks); RenderAnimation(width, height, frames, (const FrameCallback**)frameCallbacks, sizeFrameCallbacks); for (u32 i = 0; i < sizeCallbacks; ++i) { if (callbacks[i] == NULL) continue; free(callbacks[i]->callback_self); free(callbacks[i]); } for (u32 i = 0; i < sizeFrameCallbacks; ++i) { if (frameCallbacks[i] == NULL) continue; free(frameCallbacks[i]->callback_self); free(frameCallbacks[i]); } return 0; }