summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Animation.c1
-rw-r--r--AnimationInterpolate.c44
-rw-r--r--AnimationInterpolate.h13
-rw-r--r--AnimationMove.c2
-rw-r--r--AnimationMove.h1
-rw-r--r--graphics.c222
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;
};
diff --git a/graphics.c b/graphics.c
index 76bb347..97b07df 100644
--- a/graphics.c
+++ b/graphics.c
@@ -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;