From e11e63f273a00b83ebdbdd1d02dad5c645e8203c Mon Sep 17 00:00:00 2001 From: veclavtalica Date: Sun, 9 Mar 2025 06:24:05 +0300 Subject: [PATCH] /apps/tools/twndel: more plane awareness --- apps/tools/twndel/tool.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/apps/tools/twndel/tool.c b/apps/tools/twndel/tool.c index 1d36ae1..4c46f01 100644 --- a/apps/tools/twndel/tool.c +++ b/apps/tools/twndel/tool.c @@ -13,6 +13,9 @@ /* billboard render to specified angles */ /* 1 point light primitive lighting */ +/* assumptions: */ +/* up is always (0,1,0) */ + static State state; static bool init; @@ -228,7 +231,7 @@ static bool find_closest_point(uint8_t* object_result, uint16_t *point_result) { /* n = normal of a plane */ static bool vector_plane_intersection(Vec3 o, Vec3 v, Vec3 p, Vec3 n, Vec3 *out) { float dot = vec3_dot(n, v); - if (dot > FLT_EPSILON) { + if (fabsf(dot) > FLT_EPSILON) { Vec3 w = vec3_sub(o, p); float fac = -vec3_dot(n, w) / dot; *out = vec3_add(o, vec3_scale(v, fac)); @@ -263,9 +266,15 @@ static void process_operation_move_point(Operation *op) { /* TODO: planes used should depend on looking angle */ /* for example, editing from the side makes better use of x/z facing planes */ + /* figure out which planes are angled acutely against the viewing direction */ + bool y_closer_than_horizon = fabsf(vec3_dot(state.camera_direction, (Vec3){0,1,0})) >= 0.5f; + + Vec3 plane_normal_x = y_closer_than_horizon ? (Vec3){0,1,0} : (Vec3){0,0,1}; + Vec3 plane_normal_z = y_closer_than_horizon ? (Vec3){0,1,0} : (Vec3){1,0,0}; + Vec3 s; if (!state.axis_mask[0]) { - if (vector_plane_intersection(cam.position, cam.direction, p, (Vec3){0,copysignf(1,cam.direction.y),0}, &s)) { + if (vector_plane_intersection(cam.position, cam.direction, p, plane_normal_x, &s)) { int16_t xch = (int16_t)(floorf(vec3_dot(vec3_sub(s, p), (Vec3){1,0,0}) * (float)POINTS_PER_METER)); xch -= xch % state.grid_snap_granularity; state.points[op->data.move_point.point].x += xch; @@ -275,7 +284,7 @@ static void process_operation_move_point(Operation *op) { } if (!state.axis_mask[1]) { - if (vector_plane_intersection(cam.position, cam.direction, p, (Vec3){0,0,copysignf(1,cam.direction.z)}, &s)) { + if (vector_plane_intersection(cam.position, cam.direction, p, (Vec3){0,0,1}, &s)) { int16_t ych = (int16_t)(floorf(vec3_dot(vec3_sub(s, p), (Vec3){0,1,0}) * (float)POINTS_PER_METER)); ych -= ych % state.grid_snap_granularity; state.points[op->data.move_point.point].y += ych; @@ -285,7 +294,7 @@ static void process_operation_move_point(Operation *op) { } if (!state.axis_mask[2]) { - if (vector_plane_intersection(cam.position, cam.direction, p, (Vec3){0,copysignf(1,cam.direction.y),0}, &s)) { + if (vector_plane_intersection(cam.position, cam.direction, p, plane_normal_z, &s)) { int16_t zch = (int16_t)(floorf(vec3_dot(vec3_sub(s, p), (Vec3){0,0,1}) * (float)POINTS_PER_METER)); zch -= zch % state.grid_snap_granularity; state.points[op->data.move_point.point].z += zch;