/apps/tools/twndel: plane intersection based point move
This commit is contained in:
parent
ce2c2513aa
commit
75737b738f
@ -222,6 +222,23 @@ static bool find_closest_point(uint8_t* object_result, uint16_t *point_result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* o = vector origin */
|
||||||
|
/* v = vector direction, normalized */
|
||||||
|
/* p = any point on plane */
|
||||||
|
/* 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) {
|
||||||
|
Vec3 w = vec3_sub(o, p);
|
||||||
|
float fac = -vec3_dot(n, w) / dot;
|
||||||
|
*out = vec3_add(o, vec3_scale(v, fac));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/* vector and plane are perpendicular, assume that it lies exactly on it */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void process_operation_move_point(Operation *op) {
|
static void process_operation_move_point(Operation *op) {
|
||||||
/* finish dragging around */
|
/* finish dragging around */
|
||||||
/* TODO: dont keep empty ops on stack? */
|
/* TODO: dont keep empty ops on stack? */
|
||||||
@ -238,33 +255,46 @@ static void process_operation_move_point(Operation *op) {
|
|||||||
(Color){255,255,255,255},
|
(Color){255,255,255,255},
|
||||||
false);
|
false);
|
||||||
|
|
||||||
DrawCameraUnprojectResult pos_and_ray = unproject_point(ctx.mouse_position);
|
DrawCameraUnprojectResult cam = unproject_point(ctx.mouse_position);
|
||||||
|
|
||||||
Vec3 p = point_to_vec3(op->data.move_point.object, op->data.move_point.point);
|
Vec3 p = point_to_vec3(op->data.move_point.object, op->data.move_point.point);
|
||||||
Vec3 d = vec3_sub(pos_and_ray.position, p);
|
bool point_moved = false;
|
||||||
Vec3 b = vec3_cross(d, pos_and_ray.direction);
|
|
||||||
|
|
||||||
/* TODO: show thresholds */
|
/* TODO: show thresholds */
|
||||||
|
/* TODO: planes used should depend on looking angle */
|
||||||
|
/* for example, editing from the side makes better use of x/z facing planes */
|
||||||
|
|
||||||
log_vec3(b, "cross");
|
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)) {
|
||||||
|
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;
|
||||||
|
op->data.move_point.delta_x += xch;
|
||||||
|
if (xch != 0) point_moved = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* change along axes, delta is accumulated when threshold is met*/
|
if (!state.axis_mask[1]) {
|
||||||
int16_t xch = (int16_t)(floorf(vec3_dot(b, (Vec3){0,0,1}) * (float)POINTS_PER_METER)) * !state.axis_mask[0];
|
if (vector_plane_intersection(cam.position, cam.direction, p, (Vec3){0,0,copysignf(1,cam.direction.z)}, &s)) {
|
||||||
xch -= xch % state.grid_snap_granularity;
|
int16_t ych = (int16_t)(floorf(vec3_dot(vec3_sub(s, p), (Vec3){0,1,0}) * (float)POINTS_PER_METER));
|
||||||
state.points[op->data.move_point.point].x += xch;
|
ych -= ych % state.grid_snap_granularity;
|
||||||
op->data.move_point.delta_x += xch;
|
state.points[op->data.move_point.point].y += ych;
|
||||||
|
op->data.move_point.delta_y += ych;
|
||||||
|
if (ych != 0) point_moved = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int16_t ych = (int16_t)(floorf(vec3_dot(vec3_cross(b, pos_and_ray.direction), (Vec3){0,-1,0}) * (float)POINTS_PER_METER)) * !state.axis_mask[1];
|
if (!state.axis_mask[2]) {
|
||||||
ych -= ych % state.grid_snap_granularity;
|
if (vector_plane_intersection(cam.position, cam.direction, p, (Vec3){0,copysignf(1,cam.direction.y),0}, &s)) {
|
||||||
state.points[op->data.move_point.point].y += ych;
|
int16_t zch = (int16_t)(floorf(vec3_dot(vec3_sub(s, p), (Vec3){0,0,1}) * (float)POINTS_PER_METER));
|
||||||
op->data.move_point.delta_y += ych;
|
zch -= zch % state.grid_snap_granularity;
|
||||||
|
state.points[op->data.move_point.point].z += zch;
|
||||||
|
op->data.move_point.delta_z += zch;
|
||||||
|
if (zch != 0) point_moved = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int16_t zch = (int16_t)(floorf(vec3_dot(b, (Vec3){-1,0,0}) * (float)POINTS_PER_METER)) * !state.axis_mask[2];
|
if (point_moved)
|
||||||
zch -= zch % state.grid_snap_granularity;
|
|
||||||
state.points[op->data.move_point.point].z += zch;
|
|
||||||
op->data.move_point.delta_z += zch;
|
|
||||||
|
|
||||||
if (xch != 0 || ych != 0 || zch != 0)
|
|
||||||
audio_play("/data/bong.ogg", NULL, false, 0.12f, 0.0f);
|
audio_play("/data/bong.ogg", NULL, false, 0.12f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user