diff options
| -rw-r--r-- | Animation.c | 1 | ||||
| -rw-r--r-- | AnimationInterpolate.c | 44 | ||||
| -rw-r--r-- | AnimationInterpolate.h | 13 | ||||
| -rw-r--r-- | AnimationMove.c | 2 | ||||
| -rw-r--r-- | AnimationMove.h | 1 | ||||
| -rw-r--r-- | graphics.c | 222 |
6 files changed, 181 insertions, 102 deletions
diff --git a/Animation.c b/Animation.c index 3ce79dc..a67c22e 100644 --- a/Animation.c +++ b/Animation.c @@ -76,7 +76,6 @@ Animation_pushEvent(Animation* anim, u32 startFrame, u32 endFrame, PixelRenderer void Animation_render(Animation* anim) { for (int currFrame = 0; currFrame < anim->frameCount; ++currFrame) { - if (anim->events != NULL) for (i32 r = 0; r < anim->frameBuffer.width; ++r) for (i32 c = 0; c < anim->frameBuffer.height; ++c) { diff --git a/AnimationInterpolate.c b/AnimationInterpolate.c index f24c678..37a0990 100644 --- a/AnimationInterpolate.c +++ b/AnimationInterpolate.c @@ -1,5 +1,7 @@ #include "AnimationInterpolate.h" #include "AnimationObject.h" +#include "AnimationMove.h" +#include <string.h> #define NUM_INTERPOLATE(a, b, perc) (a * (1.0 - (perc)) + b * (perc)) @@ -18,25 +20,59 @@ colorInterpolate(color ina, color inb, double percentage) { } ARGB -A_Interpolate(const Animation* anim, u32 frameIndex, ARGB pixel, i32 r, i32 c, void* priv) { - struct A_Interpolate in = *(struct A_Interpolate*)priv; +A_Interpolate(const Animation* anim, u32 frameIndex, ARGB pixel, i32 r, i32 c, void* value) { + struct A_Interpolate in = *(struct A_Interpolate*)value; + + if (in.interpolate == NULL) { + fprintf(stderr, "Interpolation function cannot be NULL!\n"); + ARGB_set(&pixel, 0xFFFF00FF); + return pixel; + } + + if (frameIndex == in.startFrame) { + memcpy(in.initialValueTemp, in.value, in.initialValueTempSize); + } double perc = (double)(frameIndex - in.startFrame) / (in.endFrame - in.startFrame); if (perc < 0.0) perc = 0.0; if (perc > 1.0) perc = 1.0; - in.interpolate(in.value, in.initialState, in.finalState, perc); + in.interpolate(in.value, in.initialValueTemp, in.goalValue, perc); - return in.callback(anim, frameIndex, pixel, r, c, in.priv); + return pixel; } void AO_LineInterpolate(void* valueLine, const void* initialLine, const void* finalLine, double percentage) { struct AO_Line* value = valueLine; const struct AO_Line* initial = initialLine, *final = finalLine; + value->a = NUM_INTERPOLATE(initial->a, final->a, percentage); value->b = NUM_INTERPOLATE(initial->b, final->b, percentage); value->c = NUM_INTERPOLATE(initial->c, final->c, percentage); value->width = NUM_INTERPOLATE(initial->width, final->width, percentage); value->color = colorInterpolate(initial->color, final->color, percentage); } + +void +AM_LinearInterpolate(void* valueIn, const void* initialIn, const void* finalIn, double percentage) { + struct AM_Linear* value = valueIn; + const struct AM_Linear* initial = initialIn, *final = finalIn; + + value->startRow = NUM_INTERPOLATE(initial->startRow, final->startRow, percentage); + value->startCol = NUM_INTERPOLATE(initial->startCol, final->startCol, percentage); + value->dRow = NUM_INTERPOLATE(initial->dRow, final->dRow, percentage); + value->dCol = NUM_INTERPOLATE(initial->dCol, final->dCol, percentage); + value->wrapCoordinates = NUM_INTERPOLATE(initial->wrapCoordinates, final->wrapCoordinates, percentage); +} + +void +AM_SpinInterpolate(void* valueIn, const void* initialIn, const void* finalIn, double percentage) { + struct AM_Spin* value = valueIn; + const struct AM_Spin* initial = initialIn, *final = finalIn; + + value->theta = NUM_INTERPOLATE(initial->theta, final->theta, percentage); + value->dTheta = NUM_INTERPOLATE(initial->dTheta, final->dTheta, percentage); + value->centerRow = NUM_INTERPOLATE(initial->centerRow, final->centerRow, percentage); + value->centerCol = NUM_INTERPOLATE(initial->centerCol, final->centerCol, percentage); +} diff --git a/AnimationInterpolate.h b/AnimationInterpolate.h index e9fcd57..c033525 100644 --- a/AnimationInterpolate.h +++ b/AnimationInterpolate.h @@ -4,14 +4,14 @@ #include "Animation.h" struct A_Interpolate { - PixelRenderer callback; - void* priv; - u32 startFrame; u32 endFrame; + + void* initialValueTemp; + size_t initialValueTempSize; + void* value; - void* initialState; - void* finalState; + void* goalValue; void (*interpolate)(void* value, const void* initialState, const void* finalState, double percentage); }; @@ -19,4 +19,7 @@ ARGB A_Interpolate(const Animation* anim, u32 frameIndex, ARGB pixel, i32 r, i32 void AO_LineInterpolate(void* valueLine, const void* initialLine, const void* finalLine, double percentage); +void AM_LinearInterpolate(void* valueLinear, const void* initialLinear, const void* finalLinear, double percentage); +void AM_SpinInterpolate(void* valueSpin, const void* initialSpin, const void* finalSpin, double percentage); + #endif /* _ANIMATION_INTERPOLATE */ diff --git a/AnimationMove.c b/AnimationMove.c index 3881bf1..696150c 100644 --- a/AnimationMove.c +++ b/AnimationMove.c @@ -23,7 +23,7 @@ AM_Spin(const Animation* anim, u32 frameIndex, ARGB pixel, i32 r, i32 c, void* p double radius = sqrt(r * r + c * c); double phi = atan2(c, r); - phi += ms.theta * frameIndex; + phi += ms.theta + ms.dTheta * frameIndex; r = (ms.centerRow + (i32)(radius * cos(phi))); c = (ms.centerCol + (i32)(radius * sin(phi))); diff --git a/AnimationMove.h b/AnimationMove.h index bdb5b21..342144e 100644 --- a/AnimationMove.h +++ b/AnimationMove.h @@ -21,6 +21,7 @@ struct AM_Spin { void* priv; float theta; + float dTheta; i32 centerRow; i32 centerCol; }; @@ -6,130 +6,170 @@ #include "AnimationObject.h" #include "AnimationMove.h" #include "AnimationInterpolate.h" -#include <stdio.h> +#include <math.h> + +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() { - Animation anim = Animation_new(512, 512, 120); + const u32 FPS = 60; + Animation anim = Animation_new(512, 512, FPS * 5); - // Background - struct AO_CheckerPattern chp1 = { - .squareSize = 32, - .colorA = 0xFF000000, .colorB = 0xFFFF00FF, + struct AO_Square background = { + .width = anim.width, .height = anim.height, + .color = 0xFFF0F0F0, }; - struct AM_Linear ml1 = { - .startRow = 0, .startCol = 0, - .dRow = -1, .dCol = -1, + Animation_pushEvent(&anim, 0, anim.frameCount, AO_Square, &background); - .callback = AO_CheckerPattern, .priv = &chp1, - }; - Animation_pushEvent(&anim, 0, 120, AM_Linear, &ml1); - - // Image - FILE* fbclc = fopen("bclc.ppm", "r"); - struct AO_Image bclc; - struct AM_Linear ml10; - if (fbclc != NULL) { - bclc.img = ppm_read(fbclc); - bclc.noRepeat = true; - bclc.zoom = 0.4; - - ml10 = (struct AM_Linear){ - .startRow = 0, .startCol = 0, - .dRow = 0.5, .dCol = 0.5, - - .callback = AO_Image, .priv = &bclc, - }; - Animation_pushEvent(&anim, 0, 100, AM_Linear, &ml10); - } - - // Line - struct AO_Line l1start = { - .a = -8, .b = 6, .c = -128, - .width = 0.5, - .color = 0xFF50F0F5 + /* Root node */ + struct AO_Circle rootNode_ = { + .radius = 60, .color = 0xFFFF0000, }; - struct AO_Line l1end = { - .a = 8, .b = -4, .c = 0, - .width = 10, - .color = 0xFFF550F0 + struct AM_Linear rootNode_linear = { + .callback = AO_Circle, .priv = &rootNode_, + + .startRow = anim.height / 4, .startCol = anim.width / 2, }; - struct AO_Line l1; - struct A_Interpolate i1 = { - .startFrame = 0, .endFrame = 120, - .value = &l1, .initialState = &l1start, .finalState = &l1end, - .interpolate = AO_LineInterpolate, + struct AM_Linear rootNode = rootNode_linear; - .callback = AO_Line, .priv = &l1, + /* Child node */ + struct AO_Circle childNode_ = { + .radius = 60, .color = 0xFF00FF00, }; - Animation_pushEvent(&anim, 0, 120, A_Interpolate, &i1); - // Yellow square - struct AO_Square s1 = { - .width = 20, .height = 20, .color = 0xFFFFFF00, - }; - struct AM_Spin ms1 = { - .theta = 3.14159 / 15, .centerCol = 10, .centerRow = 10, + struct AM_Linear childNode_left = { + .callback = AO_Circle, .priv = &childNode_, - .callback = AO_Square, .priv = &s1, + .startRow = anim.height * 3 / 4, .startCol = anim.width / 4, }; - struct AM_Linear ml3 = { - .startRow = 100, .startCol = 100, - .dRow = 3, .dCol = 1, + struct AM_Linear childNode_right = { + .callback = AO_Circle, .priv = &childNode_, - .callback = AM_Spin, .priv = &ms1, + .startRow = anim.height * 3 / 4, .startCol = anim.width * 3 / 4, }; - Animation_pushEvent(&anim, 0, 80, AM_Linear, &ml3); - // White circle - struct AO_Circle s4 = { - .radius = 20, .color = 0xFFFFFFFF, + struct AM_Linear childNode = childNode_right; + + /* Root Node --- Child Node */ + struct AO_HorSegment link_ = { + .color = 0xFFFF00FF, .width = 10, }; - struct AM_Linear ml4 = { - .startRow = 40, .startCol = 40, - .dRow = 2, .dCol = 2, - .callback = AO_Circle, .priv = &s4, + 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, }; - Animation_pushEvent(&anim, 0, 80, AM_Linear, &ml4); + struct AM_Spin temp11; + struct A_Interpolate segment_spin_moveToLeft = { + .initialValueTemp = &temp11, .initialValueTempSize = sizeof(temp11), - // Green square - struct AO_Square s2 = { - .width = 35, .height = 50, .color = 0xA009FAA5, + .interpolate = AM_SpinInterpolate, + .value = &link_spin, .goalValue = &link_spin_left, }; - struct AM_Linear ml2 = { - .startRow = 20, .startCol = 5, - .dRow = -4, .dCol = -2, - .wrapCoordinates = true, + struct AM_Linear temp12; + struct A_Interpolate segment_translate_moveToLeft = { + .initialValueTemp = &temp12, .initialValueTempSize = sizeof(temp12), - .callback = AO_Square, .priv = &s2, + .interpolate = AM_LinearInterpolate, + .value = &link_translate, .goalValue = &link_translate_left, }; - Animation_pushEvent(&anim, 30, 110, AM_Linear, &ml2); - // Segment - struct AO_HorSegment ls1 = { - .left = -40, .right = 40, - .width = 3, .color = 0xFFA0A0A0, + 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 ms3 = { - .theta = 3.14159 / 10, - .centerRow = 0, .centerCol = 0, + struct AM_Spin temp21; + struct A_Interpolate segment_spin_moveToRight = { + .initialValueTemp = &temp21, .initialValueTempSize = sizeof(temp21), - .callback = AO_HorSegment, .priv = &ls1, + .interpolate = AM_SpinInterpolate, + .value = &link_spin, .goalValue = &link_spin_right, }; - struct AM_Linear ml6 = { - .startRow = 0, .startCol = 0, - .dRow = 4, .dCol = 4, + struct AM_Linear temp22; + struct A_Interpolate segment_translate_moveToRight = { + .initialValueTemp = &temp22, .initialValueTempSize = sizeof(temp22), - .callback = AM_Spin, .priv = &ms3, + .interpolate = AM_LinearInterpolate, + .value = &link_translate, .goalValue = &link_translate_right, }; - Animation_pushEvent(&anim, 0, 120, AM_Linear, &ml6); + + /* Move child node from right to left */ + + childNode_moveToLeft.startFrame = segment_spin_moveToLeft.startFrame = segment_translate_moveToLeft.startFrame + = anim.frameCount / 3 - FPS; + childNode_moveToLeft.endFrame = segment_spin_moveToLeft.endFrame = segment_translate_moveToLeft.endFrame + = anim.frameCount / 3; + Animation_pushEvent(&anim, childNode_moveToLeft.startFrame, childNode_moveToLeft.endFrame, A_Interpolate, &childNode_moveToLeft); + Animation_pushEvent(&anim, childNode_moveToLeft.startFrame, childNode_moveToLeft.endFrame, A_Interpolate, &segment_spin_moveToLeft); + Animation_pushEvent(&anim, childNode_moveToLeft.startFrame, childNode_moveToLeft.endFrame, A_Interpolate, &segment_translate_moveToLeft); + + /* Move child node from left to right */ + + childNode_moveToRight.startFrame = segment_spin_moveToRight.startFrame = segment_translate_moveToRight.startFrame + = anim.frameCount * 2 / 3 - FPS; + childNode_moveToRight.endFrame = segment_spin_moveToRight.endFrame = segment_translate_moveToRight.endFrame + = anim.frameCount * 2 / 3; + Animation_pushEvent(&anim, childNode_moveToRight.startFrame, childNode_moveToRight.endFrame, A_Interpolate, &childNode_moveToRight); + Animation_pushEvent(&anim, childNode_moveToRight.startFrame, childNode_moveToRight.endFrame, A_Interpolate, &segment_spin_moveToRight); + Animation_pushEvent(&anim, childNode_moveToRight.startFrame, childNode_moveToRight.endFrame, A_Interpolate, &segment_translate_moveToRight); Animation_render(&anim); - fclose(fbclc); - RGBImage_delete(&bclc.img); Animation_delete(&anim); return 0; |
