diff options
| author | tech kaczynski <tk@techkaczynski.dev> | 2026-11-04 06:21:11 +1000 |
|---|---|---|
| committer | tech kaczynski <tk@techkaczynski.dev> | 2026-11-04 06:21:11 +1000 |
| commit | a318ed02db01b0b9c754ebfeb02c51f3ffa15fd0 (patch) | |
| tree | f960587ff9cdaa099b615788462c782f63e58cd7 | |
| parent | ea84213ece95e3ef8ff7f0095cee73ee6bdd0f9a (diff) | |
changed move tool default behaviormain
| -rw-r--r-- | editor.c | 123 | ||||
| -rw-r--r-- | editor.h | 2 |
2 files changed, 103 insertions, 22 deletions
@@ -1320,13 +1320,45 @@ ray_plane_hit(Vec3 plane_pos, Vec3 plane_dir, Vec3 *out) { return true; } +static float +move_surface_hit(b3ShapeId shape_id, b3Pos point, b3Vec3 normal, + float fraction, uint64_t material_id, + int triangle_index, int child_index, void *context) { + (void)material_id; + (void)triangle_index; + (void)child_index; + + u64 *owner = b3Body_GetUserData(b3Shape_GetBody(shape_id)); + u64 id = owner ? *owner : 0; + + while (id) { + Entity *ent = entity_get(id); + if (!ent) { + break; + } + if (ent->ed.selected) { + return -1.0f; + } + id = ent->tr.parent; + } + + b3RayResult *result = context; + + if (!result->hit || fraction < result->fraction) { + result->hit = true; + result->shapeId = shape_id; + result->point = point; + result->normal = normal; + result->fraction = fraction; + } + + return result->fraction; +} + void editor_move(void) { - static Vec3 mv_start; - static Vec3 previous_axis; - static bool previous_plane; - static Vec3 raw_pivot; - static bool previous_local; + static Vec3 mv_start, previous_axis, raw_pivot; + static bool previous_plane, previous_local, previous_surface; if (!tr_action.item) { tr_action = action_begin(ED_ACTION_TRANSFORM, true); @@ -1342,6 +1374,8 @@ editor_move(void) { ed.move_plane = true; previous_axis = (Vec3){0, 1, 0}; previous_plane = true; + previous_surface = true; + ed.move_normal = (Vec3){0, 1, 0}; } bool cancel = IsKeyPressed(KEY_ESCAPE) || !tr_action.item_cnt; @@ -1396,11 +1430,6 @@ editor_move(void) { } } - /* Global XZ is simply the default floor plane. */ - if (!local && ed.move_axis == 1 && ed.move_plane) { - ed.move_axis = -1; - } - Vec3 axes[3] = { {1, 0, 0}, {0, 1, 0}, @@ -1419,8 +1448,11 @@ editor_move(void) { } } - if (IsKeyDown(KEY_LEFT_ALT)) { - axis = (Vec3){0, 1, 0}; + bool alt = IsKeyDown(KEY_LEFT_ALT); + bool surface = ed.move_axis < 0 && !alt; + + if (alt) { + axis = ed.move_normal; plane = false; } @@ -1429,7 +1461,8 @@ editor_move(void) { if (reset || !Vector3Equals(axis, previous_axis) || plane != previous_plane || - use_local != previous_local) { + use_local != previous_local || + surface != previous_surface) { if (reset) { action_apply(&tr_action, true); } @@ -1437,6 +1470,7 @@ editor_move(void) { previous_axis = axis; previous_plane = plane; previous_local = use_local; + previous_surface = surface; raw_pivot = selected_pivot(); ed.move_snap_origin = raw_pivot; @@ -1446,7 +1480,37 @@ editor_move(void) { Vec3 pivot = selected_pivot(); Vec3 delta = {0}; - if (plane) { + if (surface) { + Ray ray = GetScreenToWorldRay( + GetMousePosition(), main_cam.cam); + Vec3 direction = Vector3Scale(ray.direction, 1000.0f); + + b3QueryFilter filter = { + .categoryBits = BIT(PHYS_MASK_EDITOR_RAYCAST), + .maskBits = BIT(PHYS_MASK_EDITOR_SELECTABLE), + }; + + b3RayResult hit = {0}; + b3World_CastRay( + physics.world_id, + (b3Pos){ + ray.position.x, + ray.position.y, + ray.position.z}, + (b3Vec3){ + direction.x, + direction.y, + direction.z}, + filter, move_surface_hit, &hit); + + if (!hit.hit) { + return; + } + + raw_pivot = (Vec3){hit.point.x, hit.point.y, hit.point.z}; + ed.move_normal = Vector3Normalize( + (Vec3){hit.normal.x, hit.normal.y, hit.normal.z}); + } else if (plane) { Vec3 hit; if (!ray_plane_hit(pivot, axis, &hit)) { return; @@ -1484,12 +1548,17 @@ editor_move(void) { raw_pivot = Vector3Add(raw_pivot, delta); Vec3 destination = raw_pivot; - if (IsKeyDown(KEY_LEFT_CONTROL) && ed.grid_sz > 0) { - int constrained_axis = ed.move_axis >= 0 ? ed.move_axis : 1; + bool snap = IsKeyDown(KEY_LEFT_CONTROL) && ed.grid_sz > 0; - if (IsKeyDown(KEY_LEFT_ALT)) { - constrained_axis = 1; - } + if (snap && alt) { + f32 coordinate = Vector3DotProduct( + Vector3Subtract(raw_pivot, ed.move_snap_origin), axis); + f32 snapped = roundf(coordinate / ed.grid_sz) * ed.grid_sz; + + destination = Vector3Add(ed.move_snap_origin, + Vector3Scale(axis, snapped)); + } else if (snap && !surface) { + int constrained_axis = ed.move_axis >= 0 ? ed.move_axis : 1; Vec3 origin = use_local ? ed.move_snap_origin : Vector3Zero(); @@ -1883,7 +1952,7 @@ statusline(void) { cstr axes[3] = {"X", "Y", "Z"}; cstr planes[3] = {"YZ", "XZ", "XY"}; - cstr constraint = "XZ"; + cstr constraint = "Surface"; bool local = main_cam.local_space && ed.sel_cnt == 1 && ed.move_axis >= 0; @@ -1893,7 +1962,7 @@ statusline(void) { } if (IsKeyDown(KEY_LEFT_ALT)) { - constraint = "Y"; + constraint = "Normal"; local = false; } @@ -5232,6 +5301,18 @@ gizmo_transform(void) { static void gizmo_move(void) { Vec3 pivot = ed.sel_point; + + bool alt = IsKeyDown(KEY_LEFT_ALT); + if (alt || ed.move_axis < 0) { + Vec3 extent = Vector3Scale( + ed.move_normal, alt ? 100.0f : 1.0f); + + DrawLine3D( + alt ? Vector3Subtract(pivot, extent) : pivot, + Vector3Add(pivot, extent), GREEN); + return; + } + Vec3 axes[3] = { {1, 0, 0}, {0, 1, 0}, @@ -114,7 +114,7 @@ typedef struct { int move_axis; bool move_plane; - Vec3 move_snap_origin; + Vec3 move_snap_origin, move_normal; int rotate_axis; bool rotate_group; |
