techkaczynski.dev / code

summaryrefslogtreecommitdiff
path: root/editor.c
diff options
context:
space:
mode:
authortech kaczynski <tk@techkaczynski.dev>2026-11-04 06:21:11 +1000
committertech kaczynski <tk@techkaczynski.dev>2026-11-04 06:21:11 +1000
commita318ed02db01b0b9c754ebfeb02c51f3ffa15fd0 (patch)
treef960587ff9cdaa099b615788462c782f63e58cd7 /editor.c
parentea84213ece95e3ef8ff7f0095cee73ee6bdd0f9a (diff)
changed move tool default behaviormain
Diffstat (limited to 'editor.c')
-rw-r--r--editor.c123
1 files changed, 102 insertions, 21 deletions
diff --git a/editor.c b/editor.c
index 18cd918..9257870 100644
--- a/editor.c
+++ b/editor.c
@@ -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},