summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpacien2017-12-26 18:16:55 +0100
committerpacien2017-12-26 18:16:55 +0100
commit2f74af6a1069b9d662676e3d2cbbc671a67574b5 (patch)
treea6fb231ea2fe8ac4e836ee5ce384f41e059aca12 /src
parent45d01bc6d74ac1982c974f1b891b0ad96b878f3a (diff)
downloadmorpher-2f74af6a1069b9d662676e3d2cbbc671a67574b5.tar.gz
Implement morphing functions and adapt blender
Signed-off-by: pacien <pacien.trangirard@pacien.net>
Diffstat (limited to 'src')
-rw-r--r--src/blender/blender.c5
-rw-r--r--src/morpher/morphing.c44
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
6static inline ColorComponent blend_components(ColorComponent origin, ColorComponent target, TimeVector frame) { 5static 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
4static 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
12static 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
17static inline void update_center(Morphing *m) {
18 m->center = find_triangle(m->center, v(m->dim.x / 2, m->dim.y / 2));
19}
20
21static 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
27Morphing *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
35void morphing_destroy(Morphing *m) {
36 while (m->first != NULL) m->first = trianglemap_destroy(m->first);
37}
38
39void 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}