summaryrefslogtreecommitdiff
path: root/meme
diff options
context:
space:
mode:
authorWerner Almesberger <werner@almesberger.net>2014-09-12 19:03:30 -0300
committerWerner Almesberger <werner@almesberger.net>2014-09-12 19:03:30 -0300
commit2cff1edad1a3ff6e4379ec90602c276a1a27dd51 (patch)
treed1fe37a9105cbcb9a35ef4798cf6c2d718a06436 /meme
parent7b7435012f7e510e08662463b0865327824e2ab9 (diff)
downloadmisc-2cff1edad1a3ff6e4379ec90602c276a1a27dd51.tar.gz
misc-2cff1edad1a3ff6e4379ec90602c276a1a27dd51.tar.bz2
misc-2cff1edad1a3ff6e4379ec90602c276a1a27dd51.zip
meme/: show intersection with XZ plane (WIP)
Doesn't look quite right yet. Also, there are rendering errors.
Diffstat (limited to 'meme')
-rw-r--r--meme/Makefile2
-rw-r--r--meme/gui.c64
-rw-r--r--meme/plane.c100
-rw-r--r--meme/plane.h27
4 files changed, 190 insertions, 3 deletions
diff --git a/meme/Makefile b/meme/Makefile
index 7857262..644d3c0 100644
--- a/meme/Makefile
+++ b/meme/Makefile
@@ -13,7 +13,7 @@
include Makefile.c-common
CFLAGS = -Wall -Wshadow -g -O9
-OBJS = main.o stl.o mesh.o gui.o time.o
+OBJS = main.o stl.o mesh.o gui.o time.o plane.o
CFLAGS += $(shell sdl-config --cflags)
LDLIBS = $(shell sdl-config --libs) -lSDL_gfx -lm
diff --git a/meme/gui.c b/meme/gui.c
index 93a5ad4..12f807e 100644
--- a/meme/gui.c
+++ b/meme/gui.c
@@ -21,6 +21,7 @@
#include "util.h"
#include "time.h"
#include "mesh.h"
+#include "plane.h"
#define XRES 1280
@@ -28,6 +29,7 @@
#define CURSOR_R 5
#define CURSOR_RGBA 0xff202080
+#define PROFILE_RGBA 0x2020ffff
static int x_orig, y_orig;
@@ -81,6 +83,30 @@ static int coord(int x, int y, Sint16 *res_x, Sint16 *res_y)
}
+static inline int xz_z_model2screen(int z)
+{
+ /* center at cursor in lower 1/4 of screen */
+ return YRES-(YRES >> 3) - ((z-cursor->z) >> zoom);
+}
+
+
+static int coord_xz(int x, int y, Sint16 *res_x, Sint16 *res_y)
+{
+ x = x_model2screen(x);
+ y = xz_z_model2screen(y);
+
+ if (x < -32768 || x > 32767)
+ return -1;
+ if (y < -32768 || y > 32767)
+ return -1;
+
+ *res_x = x;
+ *res_y = y;
+
+ return x >= 0 && x < XRES && y >= 0 && y < YRES;
+}
+
+
/* ----- Draw the mesh ----------------------------------------------------- */
@@ -173,8 +199,8 @@ static void change(SDL_Surface *s, int x, int y, int w, int h)
}
if (x+w >= XRES)
w = XRES-x-1;
- if (y+h >= XRES)
- h = XRES-y-1;
+ if (y+h >= YRES)
+ h = YRES-y-1;
/*
* @@@ this seems weird. do we really have no direct way to create
@@ -268,6 +294,39 @@ static void show_cursor(SDL_Surface *s, const struct vertex *v)
}
+/* ----- Profiles ---------------------------------------------------------- */
+
+
+static void show_xz_profile(SDL_Surface *s)
+{
+ struct point *xz;
+ unsigned n, i;
+ Sint16 xa = 0, ya = 0, xb = 0, yb = 0;
+ /* initialize because gcc seems to "see" that they can be left
+ uninitialized by coord_xz but then fails to notice that
+ we track this via the return value. */
+ int a, b;
+
+ xz = plane_xz(cursor->y, &n);
+
+ a = coord_xz(xz[0].x, xz[0].y, &xa, &ya);
+ change(s, 0, YRES - (YRES >> 2)-1, XRES, YRES >> 2);
+ SDL_LockSurface(s);
+ for (i = 1; i < n; i++) {
+ b = coord_xz(xz[i].x, xz[i].y, &xb, &yb);
+ if (a >= 0 && b >= 0 && (a || b))
+ aalineColor(s, xa, ya, xb, yb, PROFILE_RGBA);
+ xa = xb;
+ ya = yb;
+ a = b;
+ }
+ aalineColor(s, 0, YRES - (YRES >> 3), XRES-1, YRES - (YRES >> 3), PROFILE_RGBA);
+ SDL_UnlockSurface(s);
+
+ free(xz);
+}
+
+
/* ----- Find nearest vertex ----------------------------------------------- */
@@ -343,6 +402,7 @@ static void motion_event(SDL_Surface *s, SDL_MouseMotionEvent *motion)
hide_cursor(s);
cursor = find_nearest(x, y);
show_cursor(s, cursor);
+ show_xz_profile(s);
apply_changes(s);
}
diff --git a/meme/plane.c b/meme/plane.c
new file mode 100644
index 0000000..1a9b7ce
--- /dev/null
+++ b/meme/plane.c
@@ -0,0 +1,100 @@
+/*
+ * plane.c - Intersect mesh with planes
+ *
+ * Written 2014 by Werner Almesberger
+ * Copyright 2014 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "mesh.h"
+#include "plane.h"
+
+
+#define ALLOC 1024 /* must be power of two */
+
+
+struct cut {
+ int coord;
+ struct point *res;
+ unsigned n;
+};
+
+
+static void add_point(struct cut *cut, int x, int y)
+{
+ struct point *p;
+
+ if (!cut->res)
+ cut->res = calloc(ALLOC, sizeof(struct point *));
+
+ /* this tests if we're at a 2^n boundary */
+ if (cut->n >= ALLOC && (cut->n & (cut->n - 1)) == 0)
+ cut->res = realloc(cut->res,
+ cut->n * 2 * sizeof(struct point *));
+ p = &cut->res[cut->n];
+ p->x = x;
+ p->y = y;
+ cut->n++;
+}
+
+
+static bool cut_xz(const struct vertex *a, const struct vertex *b, void *user)
+{
+ struct cut *cut = user;
+ int y = cut->coord;
+ int dx, dy, dz;
+ float fx, fz;;
+
+ if ((a->y > y || b->y < y) && (a->y < y || b->y > y))
+ return 0;
+
+ if (a->y == b->y) {
+ add_point(cut, (a->x + b->x) / 2, (a->z + b->z) / 2);
+ return 0;
+ }
+
+ dx = a->x - b->x;
+ dy = a->y - b->y;
+ dz = a->z - b->z;
+ fx = dx/(float) dy;
+ fz = dz/(float) dy;
+ add_point(cut, b->x + fx * dx, b->z + fz * dz);
+
+ return 0;
+}
+
+
+static int comp_x(const void *a, const void *b)
+{
+ const struct point *pa = a;
+ const struct point *pb = b;
+
+ if (pa->x < pb->x)
+ return -1;
+ if (pa->x > pb->x)
+ return 1;
+ return 0;
+}
+
+
+struct point *plane_xz(int y, unsigned *n)
+{
+ struct cut cut = {
+ .coord = y,
+ .res = NULL,
+ .n = 0,
+ };
+
+ edge_foreach(cut_xz, &cut);
+ qsort(cut.res, cut.n, sizeof(struct point *), comp_x);
+ *n = cut.n-1;
+ return cut.res;
+}
diff --git a/meme/plane.h b/meme/plane.h
new file mode 100644
index 0000000..2389504
--- /dev/null
+++ b/meme/plane.h
@@ -0,0 +1,27 @@
+/*
+ * plane.h - Intersect mesh with planes
+ *
+ * Written 2014 by Werner Almesberger
+ * Copyright 2014 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#ifndef PLANE_H
+#define PLANE_H
+
+#include "mesh.h"
+
+
+struct point {
+ int x, y;
+};
+
+
+struct point *plane_xz(int y, unsigned *n);
+
+#endif /* !PLANE_H */