diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/blender/blender.c | 5 | ||||
-rw-r--r-- | src/morpher/morphing.c | 44 |
2 files changed, 46 insertions, 3 deletions
diff --git a/src/blender/blender.c b/src/blender/blender.c index 99abedd..08cafa4 100644 --- a/src/blender/blender.c +++ b/src/blender/blender.c | |||
@@ -1,7 +1,6 @@ | |||
1 | #include "blender/blender.h" | 1 | #include "blender/blender.h" |
2 | #include <assert.h> | 2 | #include <assert.h> |
3 | #include <math.h> | 3 | #include <math.h> |
4 | #include "morpher/morpher.h" | ||
5 | 4 | ||
6 | static inline ColorComponent blend_components(ColorComponent origin, ColorComponent target, TimeVector frame) { | 5 | static inline ColorComponent blend_components(ColorComponent origin, ColorComponent target, TimeVector frame) { |
7 | // https://www.youtube.com/watch?v=LKnqECcg6Gw | 6 | // https://www.youtube.com/watch?v=LKnqECcg6Gw |
@@ -21,7 +20,7 @@ void blender_blend_canvas(Canvas *canvas, Canvas *source, Canvas *target, Morphi | |||
21 | CartesianMapping mapping; | 20 | CartesianMapping mapping; |
22 | Color pixel; | 21 | Color pixel; |
23 | 22 | ||
24 | dim = morpher_get_dim(morphing); | 23 | dim = morphing->dim; |
25 | 24 | ||
26 | assert(dim.x > 0 && dim.y > 0); | 25 | assert(dim.x > 0 && dim.y > 0); |
27 | assert(vector_equals(dim, canvas_get_dim(canvas))); | 26 | assert(vector_equals(dim, canvas_get_dim(canvas))); |
@@ -33,7 +32,7 @@ void blender_blend_canvas(Canvas *canvas, Canvas *source, Canvas *target, Morphi | |||
33 | point.x = flat_dim % dim.y; | 32 | point.x = flat_dim % dim.y; |
34 | point.y = flat_dim / dim.y; | 33 | point.y = flat_dim / dim.y; |
35 | 34 | ||
36 | mapping = morpher_get_point_mapping(morphing, point, frame); | 35 | mapping = (CartesianMapping) {point, point}; |
37 | pixel = blend_colors(canvas_get_pixel(source, mapping.origin), canvas_get_pixel(target, mapping.target), frame); | 36 | pixel = blend_colors(canvas_get_pixel(source, mapping.origin), canvas_get_pixel(target, mapping.target), frame); |
38 | canvas_set_pixel(canvas, point, pixel); | 37 | canvas_set_pixel(canvas, point, pixel); |
39 | } | 38 | } |
diff --git a/src/morpher/morphing.c b/src/morpher/morphing.c new file mode 100644 index 0000000..2ab22d0 --- /dev/null +++ b/src/morpher/morphing.c | |||
@@ -0,0 +1,44 @@ | |||
1 | #include "morpher/morphing.h" | ||
2 | #include "common/mem.h" | ||
3 | |||
4 | static inline TriangleMap *init_trianglemap(IntVector width, IntVector height) { | ||
5 | TriangleMap *bottom_left = trianglemap_create(m(0, 0), m(0, height), m(width, height)); | ||
6 | TriangleMap *top_right = trianglemap_create(m(0, 0), m(width, height), m(width, 0)); | ||
7 | trianglemap_set_neighbors(bottom_left, NULL, NULL, top_right, top_right); | ||
8 | trianglemap_set_neighbors(top_right, bottom_left, NULL, NULL, NULL); | ||
9 | return bottom_left; | ||
10 | } | ||
11 | |||
12 | static inline TriangleMap *find_triangle(TriangleMap *start, CartesianVector target) { | ||
13 | TriangleMap *t = trianglemap_to(start, target); | ||
14 | return t == start ? t : find_triangle(t, target); | ||
15 | } | ||
16 | |||
17 | static inline void update_center(Morphing *m) { | ||
18 | m->center = find_triangle(m->center, v(m->dim.x / 2, m->dim.y / 2)); | ||
19 | } | ||
20 | |||
21 | static inline void ensure_delaunay_neighborhood(TriangleMap *t) { | ||
22 | trianglemap_propagate_delaunay(t); | ||
23 | trianglemap_propagate_delaunay(t->next); | ||
24 | trianglemap_propagate_delaunay(t->next->next); | ||
25 | } | ||
26 | |||
27 | Morphing *morphing_create(IntVector width, IntVector height) { | ||
28 | Morphing *m = malloc_or_die(sizeof(Morphing)); | ||
29 | m->dim = (CartesianVector) {width, height}; | ||
30 | m->first = init_trianglemap(width, height); | ||
31 | m->center = m->first; | ||
32 | return m; | ||
33 | } | ||
34 | |||
35 | void morphing_destroy(Morphing *m) { | ||
36 | while (m->first != NULL) m->first = trianglemap_destroy(m->first); | ||
37 | } | ||
38 | |||
39 | void morphing_add_constraint(Morphing *m, CartesianVector origin, CartesianVector destination) { | ||
40 | TriangleMap *target = find_triangle(m->center, origin); | ||
41 | TriangleMap *split = trianglemap_split(target, (CartesianMapping) {origin, destination}); | ||
42 | ensure_delaunay_neighborhood(split); | ||
43 | update_center(m); | ||
44 | } | ||