From 2f74af6a1069b9d662676e3d2cbbc671a67574b5 Mon Sep 17 00:00:00 2001 From: pacien Date: Tue, 26 Dec 2017 18:16:55 +0100 Subject: Implement morphing functions and adapt blender Signed-off-by: pacien --- src/blender/blender.c | 5 ++--- src/morpher/morphing.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 src/morpher/morphing.c (limited to 'src') 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 @@ #include "blender/blender.h" #include #include -#include "morpher/morpher.h" static inline ColorComponent blend_components(ColorComponent origin, ColorComponent target, TimeVector frame) { // https://www.youtube.com/watch?v=LKnqECcg6Gw @@ -21,7 +20,7 @@ void blender_blend_canvas(Canvas *canvas, Canvas *source, Canvas *target, Morphi CartesianMapping mapping; Color pixel; - dim = morpher_get_dim(morphing); + dim = morphing->dim; assert(dim.x > 0 && dim.y > 0); assert(vector_equals(dim, canvas_get_dim(canvas))); @@ -33,7 +32,7 @@ void blender_blend_canvas(Canvas *canvas, Canvas *source, Canvas *target, Morphi point.x = flat_dim % dim.y; point.y = flat_dim / dim.y; - mapping = morpher_get_point_mapping(morphing, point, frame); + mapping = (CartesianMapping) {point, point}; pixel = blend_colors(canvas_get_pixel(source, mapping.origin), canvas_get_pixel(target, mapping.target), frame); canvas_set_pixel(canvas, point, pixel); } 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 @@ +#include "morpher/morphing.h" +#include "common/mem.h" + +static inline TriangleMap *init_trianglemap(IntVector width, IntVector height) { + TriangleMap *bottom_left = trianglemap_create(m(0, 0), m(0, height), m(width, height)); + TriangleMap *top_right = trianglemap_create(m(0, 0), m(width, height), m(width, 0)); + trianglemap_set_neighbors(bottom_left, NULL, NULL, top_right, top_right); + trianglemap_set_neighbors(top_right, bottom_left, NULL, NULL, NULL); + return bottom_left; +} + +static inline TriangleMap *find_triangle(TriangleMap *start, CartesianVector target) { + TriangleMap *t = trianglemap_to(start, target); + return t == start ? t : find_triangle(t, target); +} + +static inline void update_center(Morphing *m) { + m->center = find_triangle(m->center, v(m->dim.x / 2, m->dim.y / 2)); +} + +static inline void ensure_delaunay_neighborhood(TriangleMap *t) { + trianglemap_propagate_delaunay(t); + trianglemap_propagate_delaunay(t->next); + trianglemap_propagate_delaunay(t->next->next); +} + +Morphing *morphing_create(IntVector width, IntVector height) { + Morphing *m = malloc_or_die(sizeof(Morphing)); + m->dim = (CartesianVector) {width, height}; + m->first = init_trianglemap(width, height); + m->center = m->first; + return m; +} + +void morphing_destroy(Morphing *m) { + while (m->first != NULL) m->first = trianglemap_destroy(m->first); +} + +void morphing_add_constraint(Morphing *m, CartesianVector origin, CartesianVector destination) { + TriangleMap *target = find_triangle(m->center, origin); + TriangleMap *split = trianglemap_split(target, (CartesianMapping) {origin, destination}); + ensure_delaunay_neighborhood(split); + update_center(m); +} -- cgit v1.2.3