summaryrefslogtreecommitdiff
path: root/src/editor/view2d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/editor/view2d.cpp')
-rw-r--r--src/editor/view2d.cpp317
1 files changed, 207 insertions, 110 deletions
diff --git a/src/editor/view2d.cpp b/src/editor/view2d.cpp
index 92988df..b68846e 100644
--- a/src/editor/view2d.cpp
+++ b/src/editor/view2d.cpp
@@ -8,8 +8,43 @@ const I32 EDITORVIEW_TITLE_OFFSET = 15;
const I32 EDITORVIEW_GUTTERS_OFFSETX = 22;
const I32 EDITORVIEW_GUTTERS_OFFSETY = 16;
const I32 EDITORVIEW_TOOLBAR_OFFSET = 20;
+const I32 EDITOR_POLY_SIDES_RUNTIME_MAX = 256;
VEC2 gui_editor_2dview_screen_to_world( GUI_EDITOR_2DVIEW* view, I32 x, I32 y );
+VEC2 gui_editor_2dview_world_to_screen( GUI_EDITOR_2DVIEW* view, VEC2 world );
+F32 gui_editor_2dview_placement_z();
+
+VEC3 gui_editor_2dview_plane_to_world3( VEC2 plane, F32 depth ) {
+ return { plane.x, plane.y, depth };
+}
+
+void gui_editor_2dview_set_plane( VEC3* v, VEC2 plane ) {
+ if( !v )
+ return;
+
+ v->x = plane.x;
+ v->y = plane.y;
+}
+
+void gui_editor_2dview_add_plane_delta( VEC3* v, VEC2 delta ) {
+ if( !v )
+ return;
+
+ v->x += delta.x;
+ v->y += delta.y;
+}
+
+void gui_editor_2dview_snap_plane( VEC3* v ) {
+ if( !v )
+ return;
+
+ v->x = m_snap_to_grid( v->x, editor->grid );
+ v->y = m_snap_to_grid( v->y, editor->grid );
+}
+
+VEC2 gui_editor_2dview_world3_to_screen( GUI_EDITOR_2DVIEW* view, const VEC3& v ) {
+ return gui_editor_2dview_world_to_screen( view, { v.x, v.y } );
+}
F32 gui_editor_2dview_ground_z() {
WORLD_MAP* map = editor->map;
@@ -177,9 +212,16 @@ void gui_editor_2dview_draw_gizmo( I32 x, I32 y, CLR clr, U8 selected = 0 ) {
}
I32 gui_editor_2dview_poly_sides() {
- I32 sides = (I32)floorf( editor->tool.polysides + 0.5f );
+ F32 raw = editor->tool.polysides;
+ if( !isfinite( raw ) )
+ raw = EDITOR_DEFAULT_POLY_SIDES;
+
+ if( raw > (F32)EDITOR_POLY_SIDES_RUNTIME_MAX )
+ raw = (F32)EDITOR_POLY_SIDES_RUNTIME_MAX;
+
+ I32 sides = (I32)floorf( raw + 0.5f );
if( sides < EDITOR_POLY_SIDES_MIN ) sides = EDITOR_POLY_SIDES_MIN;
- if( sides > EDITOR_POLY_SIDES_MAX ) sides = EDITOR_POLY_SIDES_MAX;
+ if( sides > EDITOR_POLY_SIDES_RUNTIME_MAX ) sides = EDITOR_POLY_SIDES_RUNTIME_MAX;
return sides;
}
@@ -199,7 +241,7 @@ U8 gui_editor_2dview_is_poly_drag_tool() {
}
I32 gui_editor_2dview_poly_points( VEC2 start, VEC2 end, I32 sides, U8 regular, VEC2* out_points ) {
- if( !out_points || sides < EDITOR_POLY_SIDES_MIN || sides > EDITOR_POLY_SIDES_MAX )
+ if( !out_points || sides < EDITOR_POLY_SIDES_MIN )
return 0;
F32 minx = start.x < end.x ? start.x : end.x;
@@ -246,7 +288,7 @@ struct EDITORVIEW_DRAG_RECT {
struct EDITORVIEW_DRAG_SHAPE {
EDITORVIEW_DRAG_RECT rect;
- VEC2 points[EDITOR_POLY_SIDES_MAX];
+ LIST<VEC2> points;
I32 pointc;
};
@@ -266,13 +308,14 @@ U8 gui_editor_2dview_build_drag_shape( GUI_EDITOR_2DVIEW* view, EDITORVIEW_DRAG_
return 0;
I32 sides = gui_editor_2dview_poly_sides();
+ out_shape->points.resize( sides );
U8 regular = gui_editor_2dview_poly_keep_regular( sides );
out_shape->pointc = gui_editor_2dview_poly_points(
view->poly_start,
view->poly_end,
sides,
regular,
- out_shape->points
+ out_shape->points.data
);
return out_shape->pointc >= 3;
@@ -371,15 +414,16 @@ void gui_editor_2dview_create_poly_from_drag( GUI_EDITOR_2DVIEW* view ) {
MAP_POLYGON newp{};
newp.propid = 0;
newp.type = MPT_FLOOR;
- F32 placez = gui_editor_2dview_placement_z();
+ F32 depth = gui_editor_2dview_placement_z();
F32 invw = 1.f / shape.rect.w;
F32 invh = 1.f / shape.rect.h;
for( I32 i = 0; i < shape.pointc; ++i ) {
VEC2 p = shape.points[i];
+ VEC3 world = gui_editor_2dview_plane_to_world3( p, depth );
MAP_VERTEX v{};
- v.pos = { p.x, p.y, placez };
+ v.pos = world;
v.uv = {
( p.x - shape.rect.minx ) * invw,
( shape.rect.maxy - p.y ) * invh
@@ -389,7 +433,9 @@ void gui_editor_2dview_create_poly_from_drag( GUI_EDITOR_2DVIEW* view ) {
}
map_polygon_calc_bounds( &newp );
+ I32 poly_idx = editor->map->polygons.size;
editor->map->polygons.push( newp );
+ editor_undo_record_create_poly( editor, poly_idx );
gui_editor_2dview_check_bounds_preserve_view( view );
}
@@ -399,19 +445,25 @@ void gui_editor_2dview_create_wallpoly_from_drag( GUI_EDITOR_2DVIEW* view ) {
return;
I32 propid = gui_editor_2dview_find_or_create_wallpoly_propid();
+ I32 first_wall_idx = editor->map->walls.size;
- F32 basez = gui_editor_2dview_placement_z();
+ F32 depth = gui_editor_2dview_placement_z();
F32 wallheight = gui_editor_2dview_wall_height();
for( I32 i = 0; i < shape.pointc; ++i ) {
VEC2 p0 = shape.points[i];
VEC2 p1 = shape.points[(i + 1) % shape.pointc];
+ VEC3 w0 = gui_editor_2dview_plane_to_world3( p0, depth );
+ VEC3 w1 = gui_editor_2dview_plane_to_world3( p1, depth );
MAP_WALL wall{};
- wall.start = { p0.x, p0.y, basez };
- wall.end = { p1.x, p1.y, wallheight };
+ wall.start = w0;
+ wall.end = w1;
+ wall.end.z = wallheight;
wall.propid = propid;
editor->map->walls.push( wall );
}
+ I32 new_wall_count = editor->map->walls.size - first_wall_idx;
+ editor_undo_record_create_walls( editor, first_wall_idx, new_wall_count );
gui_editor_2dview_check_bounds_preserve_view( view );
}
@@ -420,6 +472,10 @@ void gui_editor_2dview_draw_gutters( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
WORLD_MAP* m = editor->map;
F32 w = view->w;
F32 h = view->h;
+ F32 min_u = m->mins.x;
+ F32 max_u = m->maxs.x;
+ F32 min_v = m->mins.y;
+ F32 max_v = m->maxs.y;
gui_draw_str( x + 2, y, ALIGN_L, FNT_JPN12, ui_clr.txt, "%1.f,%1.f", view->posx, view->posy );
for( U32 i = 1; i <= 5; ++i ) {
@@ -428,7 +484,7 @@ void gui_editor_2dview_draw_gutters( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
F32 tp = (tx - x) / w;
- F32 scaledx = m->mins.x + (m->maxs.x - m->mins.x) * tp;
+ F32 scaledx = min_u + ( max_u - min_u ) * tp;
if( w > h )
scaledx *= ( w / h );
scaledx /= view->scale;
@@ -443,7 +499,7 @@ void gui_editor_2dview_draw_gutters( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
F32 tp = (ty - y) / h;
- F32 scaledy = m->mins.y + (m->maxs.y - m->mins.y) * tp;
+ F32 scaledy = min_v + ( max_v - min_v ) * tp;
if( w < h )
scaledy *= h / w;
scaledy /= view->scale;
@@ -456,19 +512,19 @@ void gui_editor_2dview_draw_gutters( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
void gui_editor_2dview_draw_polygons( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
WORLD_MAP* m = editor->map;
- F32 scale = gui_editor_2dview_calc_scale( view );
- F32 xoff = m->mins.x + view->posx;
- F32 yoff = m->mins.y + view->posy;
-
m->polygons.each( fn( MAP_POLYGON* p ) {
+ SURF_PROPS fallback_props{ .tex = 0, .clr = CLR::WHITE() };
SURF_PROPS* props = polygon_get_props( m, p );
+ if( !props )
+ props = &fallback_props;
if( !editor->wireframe ) {
LIST<VERTEX> vertices;
p->vertices.each( fn( MAP_VERTEX* v ) {
+ VEC2 screen = gui_editor_2dview_world3_to_screen( view, v->pos );
VERTEX v2;
v2.uv = v->uv;
- v2.pos.x = x + (v->pos.x - xoff) * scale;
- v2.pos.y = y + (v->pos.y - yoff) * scale;
+ v2.pos.x = screen.x;
+ v2.pos.y = screen.y;
v2.clr = props->clr;
vertices.push( v2 );
} );
@@ -482,11 +538,13 @@ void gui_editor_2dview_draw_polygons( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
for( U32 i = 0; i < p->vertices.size; ++i ) {
MAP_VERTEX* v1 = &p->vertices[i];
MAP_VERTEX* v2 = &p->vertices[(i+1) % p->vertices.size];
+ VEC2 s0 = gui_editor_2dview_world3_to_screen( view, v1->pos );
+ VEC2 s1 = gui_editor_2dview_world3_to_screen( view, v2->pos );
- I32 x0 = x + (I32)( (v1->pos.x - xoff) * scale );
- I32 y0 = y + (I32)( (v1->pos.y - yoff) * scale );
- I32 x1 = x + (I32)( (v2->pos.x - xoff) * scale );
- I32 y1 = y + (I32)( (v2->pos.y - yoff) * scale );
+ I32 x0 = (I32)s0.x;
+ I32 y0 = (I32)s0.y;
+ I32 x1 = (I32)s1.x;
+ I32 y1 = (I32)s1.y;
gui_draw_line( x0, y0, x1, y1, props->clr );
}
@@ -496,8 +554,9 @@ void gui_editor_2dview_draw_polygons( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
return;
// draw gizmos
p->vertices.each( fn( MAP_VERTEX* v ) {
- I32 vx = (I32)( x + (v->pos.x - xoff) * scale );
- I32 vy = (I32)( y + (v->pos.y - yoff) * scale );
+ VEC2 screen = gui_editor_2dview_world3_to_screen( view, v->pos );
+ I32 vx = (I32)screen.x;
+ I32 vy = (I32)screen.y;
U8 selected = gui_editor_2dview_is_gizmo_active( view, v, EDITOR_SELECT_PVERTEX )
|| gui_editor_2dview_is_gizmo_active( view, p, EDITOR_SELECT_POLY );
@@ -509,17 +568,20 @@ void gui_editor_2dview_draw_polygons( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
void gui_editor_2dview_draw_walls( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
WORLD_MAP* m = editor->map;
- F32 scale = gui_editor_2dview_calc_scale( view );
- F32 xoff = m->mins.x + view->posx;
- F32 yoff = m->mins.y + view->posy;
-
m->walls.each( fn( MAP_WALL* s ) {
+ SURF_PROPS fallback_props{ .tex = 0, .clr = CLR::WHITE() };
SURF_PROPS* props = wall_get_props( m, s );
-
- I32 x0 = (I32)( x + (s->start.x - xoff) * scale );
- I32 y0 = (I32)( y + (s->start.y - yoff) * scale );
- I32 x1 = (I32)( x + (s->end.x - xoff) * scale );
- I32 y1 = (I32)( y + (s->end.y - yoff) * scale );
+ if( !props )
+ props = &fallback_props;
+ VEC3 w0 = { s->start.x, s->start.y, s->start.z };
+ VEC3 w1 = { s->end.x, s->end.y, s->end.z };
+ VEC2 p0 = gui_editor_2dview_world3_to_screen( view, w0 );
+ VEC2 p1 = gui_editor_2dview_world3_to_screen( view, w1 );
+
+ I32 x0 = (I32)p0.x;
+ I32 y0 = (I32)p0.y;
+ I32 x1 = (I32)p1.x;
+ I32 y1 = (I32)p1.y;
gui_draw_line( x0, y0, x1, y1, props->clr );
if( gui_editor_2dview_is_gizmo_active( view, s, EDITOR_SELECT_WALL ) ) {
@@ -535,10 +597,14 @@ void gui_editor_2dview_draw_walls( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
// gizmos
m->walls.each( fn( MAP_WALL* s ) {
- I32 x0 = (I32)( x + (s->start.x - xoff) * scale );
- I32 y0 = (I32)( y + (s->start.y - yoff) * scale );
- I32 x1 = (I32)( x + (s->end.x - xoff) * scale );
- I32 y1 = (I32)( y + (s->end.y - yoff) * scale );
+ VEC3 w0 = { s->start.x, s->start.y, s->start.z };
+ VEC3 w1 = { s->end.x, s->end.y, s->end.z };
+ VEC2 p0 = gui_editor_2dview_world3_to_screen( view, w0 );
+ VEC2 p1 = gui_editor_2dview_world3_to_screen( view, w1 );
+ I32 x0 = (I32)p0.x;
+ I32 y0 = (I32)p0.y;
+ I32 x1 = (I32)p1.x;
+ I32 y1 = (I32)p1.y;
U8 sel = gui_editor_2dview_is_gizmo_active( view, s, EDITOR_SELECT_WALL );
U8 sel1 = gui_editor_2dview_is_gizmo_active( view, &s->start, EDITOR_SELECT_WVERTEX );
@@ -552,19 +618,12 @@ void gui_editor_2dview_draw_walls( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
void gui_editor_2dview_draw_sprites( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
WORLD_MAP* m = editor->map;
- F32 scale = gui_editor_2dview_calc_scale( view );
- F32 xoff = m->mins.x + view->posx;
- F32 yoff = m->mins.y + view->posy;
-
m->sprites.each( fn( MAP_SPRITE* s ) {
F32 wantedsize = editor->spritesize;
F32 aspect = s->size.x / s->size.y;
F32 w = (aspect > 1.0f)? wantedsize : wantedsize * aspect;
F32 h = (aspect < 1.0f)? wantedsize : wantedsize / aspect;
- VEC2 pos = {
- (F32)x + (s->pos.x - xoff) * scale,
- (F32)y + (s->pos.y - yoff) * scale
- };
+ VEC2 pos = gui_editor_2dview_world3_to_screen( view, s->pos );
U8 sel= gui_editor_2dview_is_gizmo_active( view, s, EDITOR_SELECT_SPRITE );
if( sel ) {
@@ -582,27 +641,18 @@ void gui_editor_2dview_draw_sprites( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
}
void gui_editor_2dview_draw_player( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
- WORLD_MAP* m = editor->map;
if( !objl->pl )
return;
- F32 scale = gui_editor_2dview_calc_scale( view );
- F32 xoff = m->mins.x + view->posx;
- F32 yoff = m->mins.y + view->posy;
-
VEC3 pos = objl->pl->pos;
-
- VEC2 pos2d = {
- (F32)x + (pos.x - xoff) * scale,
- (F32)y + (pos.y - yoff) * scale
- };
+ VEC2 pos2d = gui_editor_2dview_world3_to_screen( view, pos );
F32 yaw = objl->pl->rot.y;
VEC2 dir = m_radial_offset( yaw, 20.f );
VEC2 ray = pos2d + dir;
-
gui_draw_line( (I32)pos2d.x, (I32)pos2d.y, (I32)ray.x, (I32)ray.y, CLR::GREEN() );
+
gui_draw_frect( (I32)pos2d.x-4, (I32)pos2d.y-4, 8, 8, CLR::WHITE() );
gui_draw_frect( (I32)pos2d.x-3, (I32)pos2d.y-3, 6, 6, CLR::RED() );
}
@@ -610,13 +660,10 @@ void gui_editor_2dview_draw_player( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
void gui_editor_2dview_draw_origin( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
WORLD_MAP* m = editor->map;
- F32 scale = gui_editor_2dview_calc_scale( view );
- F32 xoff = m->mins.x + view->posx;
- F32 yoff = m->mins.y + view->posy;
-
VEC3 pos = m->startpos;
- I32 screenx = (I32)( x + (pos.x - xoff) * scale );
- I32 screeny = (I32)( y + (pos.y - yoff) * scale );
+ VEC2 screen = gui_editor_2dview_world3_to_screen( view, pos );
+ I32 screenx = (I32)screen.x;
+ I32 screeny = (I32)screen.y;
if( gui_editor_2dview_is_gizmo_active( view, m, EDITOR_SELECT_ORIGIN ) ) {
I32 w, h;
@@ -758,15 +805,13 @@ void gui_editor_2dview_input_select_onmove( GUI_EDITOR_2DVIEW* view ) {
void gui_editor_2dview_input_select_drag_wall( GUI_EDITOR_2DVIEW* view ) {
MAP_WALL* s = (MAP_WALL*)view->curdrag;
- s->start.x = m_snap_to_grid( s->start.x, editor->grid );
- s->start.y = m_snap_to_grid( s->start.y, editor->grid );
- s->end.x = m_snap_to_grid( s->end.x, editor->grid );
- s->end.y = m_snap_to_grid( s->end.y, editor->grid );
+ gui_editor_2dview_snap_plane( &s->start );
+ gui_editor_2dview_snap_plane( &s->end );
VEC2 mv = gui_editor_2dview_input_get_drag_vec( view );
if( !is_zero( mv ) ) {
- s->start += mv;
- s->end += mv;
+ gui_editor_2dview_add_plane_delta( &s->start, mv );
+ gui_editor_2dview_add_plane_delta( &s->end, mv );
map_check_bounds( editor->map );
gui_editor_2dview_input_select_onmove( view );
@@ -774,13 +819,25 @@ void gui_editor_2dview_input_select_drag_wall( GUI_EDITOR_2DVIEW* view ) {
}
void gui_editor_2dview_input_select_drag_vertex( GUI_EDITOR_2DVIEW* view ) {
- VEC2* v = (VEC2*)view->curdrag;
- v->x = m_snap_to_grid( v->x, editor->grid );
- v->y = m_snap_to_grid( v->y, editor->grid );
+ if( view->dragtype == EDITOR_SELECT_WVERTEX ) {
+ VEC3* v = (VEC3*)view->curdrag;
+ gui_editor_2dview_snap_plane( v );
+
+ VEC2 mv = gui_editor_2dview_input_get_drag_vec( view );
+ if( !is_zero( mv ) ) {
+ gui_editor_2dview_add_plane_delta( v, mv );
+ map_check_bounds( editor->map );
+ gui_editor_2dview_input_select_onmove( view );
+ }
+ return;
+ }
+
+ MAP_VERTEX* v = (MAP_VERTEX*)view->curdrag;
+ gui_editor_2dview_snap_plane( &v->pos );
VEC2 mv = gui_editor_2dview_input_get_drag_vec( view );
if( !is_zero( mv ) ) {
- *v += mv;
+ gui_editor_2dview_add_plane_delta( &v->pos, mv );
map_check_bounds( editor->map );
gui_editor_2dview_input_select_onmove( view );
@@ -793,11 +850,8 @@ void gui_editor_2dview_input_select_drag_polygon( GUI_EDITOR_2DVIEW* view ) {
VEC2 mv = gui_editor_2dview_input_get_drag_vec( view );
if( !is_zero( mv ) ) {
p->vertices.each( fn( MAP_VERTEX* v ) {
- v->pos.x = m_snap_to_grid( v->pos.x, editor->grid );
- v->pos.y = m_snap_to_grid( v->pos.y, editor->grid );
-
- v->pos.x += mv.x;
- v->pos.y += mv.y;
+ gui_editor_2dview_snap_plane( &v->pos );
+ gui_editor_2dview_add_plane_delta( &v->pos, mv );
} );
map_polygon_calc_bounds( p );
@@ -809,12 +863,11 @@ void gui_editor_2dview_input_select_drag_polygon( GUI_EDITOR_2DVIEW* view ) {
void gui_editor_2dview_input_select_drag_sprite( GUI_EDITOR_2DVIEW* view ) {
MAP_SPRITE* s = (MAP_SPRITE*)view->curdrag;
- s->pos.x = m_snap_to_grid( s->pos.x, editor->grid );
- s->pos.y = m_snap_to_grid( s->pos.y, editor->grid );
+ gui_editor_2dview_snap_plane( &s->pos );
VEC2 mv = gui_editor_2dview_input_get_drag_vec( view );
if( !is_zero( mv ) ) {
- s->pos += mv;
+ gui_editor_2dview_add_plane_delta( &s->pos, mv );
gui_editor_2dview_input_select_onmove( view );
}
}
@@ -822,12 +875,11 @@ void gui_editor_2dview_input_select_drag_sprite( GUI_EDITOR_2DVIEW* view ) {
void gui_editor_2dview_input_select_drag_origin( GUI_EDITOR_2DVIEW* view ) {
WORLD_MAP* m = editor->map;
- m->startpos.x = m_snap_to_grid( m->startpos.x, editor->grid );
- m->startpos.y = m_snap_to_grid( m->startpos.y, editor->grid );
+ gui_editor_2dview_snap_plane( &m->startpos );
VEC2 mv = gui_editor_2dview_input_get_drag_vec( view );
if( !is_zero( mv ) ) {
- m->startpos += mv;
+ gui_editor_2dview_add_plane_delta( &m->startpos, mv );
gui_editor_2dview_input_select_onmove( view );
}
}
@@ -890,10 +942,10 @@ void gui_editor_2dview_input_select_walls( GUI_EDITOR_2DVIEW* view ) {
for( U32 i = 0; i < m->walls.size; ++i ) {
MAP_WALL* w = &m->walls[i];
- VEC2 w1 = { w->start.x, w->start.y };
- VEC2 w2 = { w->end.x, w->end.y };
- w1 = gui_editor_2dview_world_to_screen( view, w1 );
- w2 = gui_editor_2dview_world_to_screen( view, w2 );
+ VEC3 wp0 = { w->start.x, w->start.y, w->start.z };
+ VEC3 wp1 = { w->end.x, w->end.y, w->end.z };
+ VEC2 w1 = gui_editor_2dview_world3_to_screen( view, wp0 );
+ VEC2 w2 = gui_editor_2dview_world3_to_screen( view, wp1 );
F32 d1 = vec_dist( mpos, w1 );
F32 d2 = vec_dist( mpos, w2 );
@@ -938,8 +990,7 @@ void gui_editor_2dview_input_select_polygons( GUI_EDITOR_2DVIEW* view ) {
LIST<VEC2> plist;
p->vertices.each( fn( MAP_VERTEX* v ) {
- VEC2 world = { v->pos.x, v->pos.y };
- VEC2 screen = gui_editor_2dview_world_to_screen( view, world );
+ VEC2 screen = gui_editor_2dview_world3_to_screen( view, v->pos );
F32 d = vec_dist( mpos, screen );
if( d < mindist ) {
gui_editor_2dview_select( view, v, EDITOR_SELECT_PVERTEX );
@@ -975,8 +1026,7 @@ void gui_editor_2dview_input_select_sprites( GUI_EDITOR_2DVIEW* view ) {
for( U32 i = 0; i < m->sprites.size; ++i ) {
MAP_SPRITE* s = &m->sprites[i];
- VEC2 world = { s->pos.x, s->pos.y };
- VEC2 screen = gui_editor_2dview_world_to_screen( view, world );
+ VEC2 screen = gui_editor_2dview_world3_to_screen( view, s->pos );
if( mpos.x >= screen.x - hsize && mpos.x <= screen.x + hsize
&& mpos.y >= screen.y - hsize && mpos.y <= screen.y + hsize )
@@ -1002,8 +1052,7 @@ void gui_editor_2dview_input_select_origin( GUI_EDITOR_2DVIEW* view ) {
gui_cursor_pos( &mx, &my );
VEC2 mpos = { (F32)mx, (F32)my };
- VEC2 world = { m->startpos.x, m->startpos.y };
- VEC2 screen = gui_editor_2dview_world_to_screen( view, world );
+ VEC2 screen = gui_editor_2dview_world3_to_screen( view, m->startpos );
I32 w, h;
gui_draw_get_str_bounds( &w, &h, FNT_JPN12, "(origin)" );
@@ -1097,8 +1146,11 @@ void gui_editor_2dview_input_tool_wall( GUI_EDITOR_2DVIEW* view ) {
U8 m1 = gui_mbutton_down( 0 );
if( !m1 ) {
if( view->held ) {
+ if( view->pending_wall_undo_idx >= 0 )
+ editor_undo_record_create_walls( editor, view->pending_wall_undo_idx, 1 );
gui_editor_2dview_check_bounds_preserve_view( view );
}
+ view->pending_wall_undo_idx = -1;
view->held = 0;
view->curdrag = 0;
return;
@@ -1109,18 +1161,22 @@ void gui_editor_2dview_input_tool_wall( GUI_EDITOR_2DVIEW* view ) {
VEC2 world = gui_editor_2dview_screen_to_world( view, mx, my );
if( !view->held ) {
- F32 basez = gui_editor_2dview_placement_z();
+ F32 depth = gui_editor_2dview_placement_z();
+ VEC3 wp = gui_editor_2dview_plane_to_world3( world, depth );
MAP_WALL neww;
neww.start = neww.end = {
- m_snap_to_grid( world.x, editor->grid ),
- m_snap_to_grid( world.y, editor->grid ),
- basez
+ wp.x,
+ wp.y,
+ wp.z
};
+ gui_editor_2dview_snap_plane( &neww.start );
+ gui_editor_2dview_snap_plane( &neww.end );
neww.end.z = gui_editor_2dview_wall_height();
neww.propid = 0;
I32 idx = editor->map->walls.size;
editor->map->walls.push( neww );
+ view->pending_wall_undo_idx = idx;
view->curdrag = &editor->map->walls[idx].end;
view->held = 1;
@@ -1133,8 +1189,8 @@ void gui_editor_2dview_input_tool_wall( GUI_EDITOR_2DVIEW* view ) {
VEC3* end = (VEC3*)view->curdrag;
if( end ) {
- end->x = m_snap_to_grid( world.x, editor->grid );
- end->y = m_snap_to_grid( world.y, editor->grid );
+ gui_editor_2dview_set_plane( end, world );
+ gui_editor_2dview_snap_plane( end );
}
}
@@ -1180,13 +1236,15 @@ void gui_editor_2dview_input_tool_sprite( GUI_EDITOR_2DVIEW* view ) {
VEC2 world = gui_editor_2dview_screen_to_world( view, mx, my );
if( !view->held ) {
+ VEC3 wpos = gui_editor_2dview_plane_to_world3( world, gui_editor_2dview_placement_z() );
MAP_SPRITE news;
- news.pos = { world.x, world.y, 20.f };
+ news.pos = wpos;
+ gui_editor_2dview_snap_plane( &news.pos );
news.size = { 20.f, 20.f };
news.clr = { 1.f, 1.f, 1.f, 1.f };
news.tex = 0;
- I32 idx = editor->map->walls.size;
+ I32 idx = editor->map->sprites.size;
editor->map->sprites.push( news );
view->curdrag = &editor->map->sprites[idx];
view->held = 1;
@@ -1289,12 +1347,31 @@ void gui_editor_view2d_delete_obj( GUI_EDITOR_2DVIEW* view ) {
void gui_editor_2dview_key_input( GUI_EDITOR_2DVIEW* view ) {
static U8 del_held = 0;
+ static U8 undo_held = 0;
+ static U8 redo_held = 0;
if( kb_down( SDLK_DELETE ) && !input.mouselock ) {
if( !del_held )
gui_editor_view2d_delete_obj( view );
del_held = 1;
} else del_held = 0;
+
+ U8 ctrl = kb_down( SDLK_LCTRL ) || kb_down( SDLK_RCTRL );
+ U8 z = kb_down( SDLK_z );
+ if( ctrl && z && !input.mouselock ) {
+ if( !undo_held )
+ editor_undo( editor );
+
+ undo_held = 1;
+ } else undo_held = 0;
+
+ U8 r = kb_down( SDLK_r );
+ if( ctrl && r && !input.mouselock ) {
+ if( !redo_held )
+ editor_redo( editor );
+
+ redo_held = 1;
+ } else redo_held = 0;
}
void gui_editor_2dview_input_fn( void* ptr ) {
@@ -1344,30 +1421,44 @@ void gui_editor_2dview_input_fn( void* ptr ) {
}
}
+static U8 GRID_DEP_LABEL_TAG;
+static U8 GRID_DEP_PROPVIEW_TAG;
+static U8 GRID_DEP_TOOLVIEW_TAG;
+
void update_view_settings( GAME_EDITOR* e ) {
GAME_EDITOR::EDITOR_GUI* egui = &e->gui;
+ if( !egui->gridlabel )
+ return;
sprintf( egui->gridlabel->name, "grid: %1.2f", e->grid );
}
+void editor_grid_dependency_update_label( GAME_EDITOR* e ) {
+ update_view_settings( e );
+}
+
+void editor_grid_dependency_update_propview( GAME_EDITOR* e ) {
+ if( e->propgrid && e->gui.props )
+ editor_update_properties_column( e );
+}
+
+void editor_grid_dependency_update_toolview( GAME_EDITOR* e ) {
+ if( e->gui.tool )
+ gui_editor_toolview_update( e->gui.tool );
+}
+
void grid_increment_cb( void* ) {
if( editor->grid < 16.f ) editor->grid *= 2.f;
- update_view_settings( editor );
-
- if( editor->propgrid )
- editor_update_properties_column( editor );
+ editor_notify_grid_change( editor );
}
void grid_decrement_cb( void* ) {
if( editor->grid > 0.25f ) editor->grid *= 0.5f;
- update_view_settings( editor );
-
- if( editor->propgrid )
- editor_update_properties_column( editor );
+ editor_notify_grid_change( editor );
}
void grid_propgrid_cb( void* ) {
- editor_update_properties_column( editor );
+ editor_notify_grid_change( editor );
}
void gui_editor_2dview_create_toolbar( GUI_EDITOR_2DVIEW* view ) {
@@ -1375,6 +1466,9 @@ void gui_editor_2dview_create_toolbar( GUI_EDITOR_2DVIEW* view ) {
I32 x = 150, y = view->h - 4;
editor->gui.gridlabel = gui_label( x, y + 1, "grid: %1.2f", e->grid );
+ editor_register_grid_dependency( e, &GRID_DEP_LABEL_TAG, editor_grid_dependency_update_label );
+ editor_register_grid_dependency( e, &GRID_DEP_PROPVIEW_TAG, editor_grid_dependency_update_propview );
+ editor_register_grid_dependency( e, &GRID_DEP_TOOLVIEW_TAG, editor_grid_dependency_update_toolview );
x += 70;
gui_button( x, y, 18, 18, "+", grid_increment_cb );
gui_button( x + 23, y, 18, 18, "-", grid_decrement_cb );
@@ -1383,6 +1477,8 @@ void gui_editor_2dview_create_toolbar( GUI_EDITOR_2DVIEW* view ) {
check->cb = grid_propgrid_cb;
x += 120;
gui_checkbox( x, y, "wireframe", &e->wireframe );
+
+ editor_notify_grid_change( e );
}
GUI_EDITOR_2DVIEW* gui_editor_2dview( I32 x, I32 y, I32 w, I32 h ) {
@@ -1401,6 +1497,7 @@ GUI_EDITOR_2DVIEW* gui_editor_2dview( I32 x, I32 y, I32 w, I32 h ) {
view->poly_drag = 0;
view->poly_start = { 0.f, 0.f };
view->poly_end = { 0.f, 0.f };
+ view->pending_wall_undo_idx = -1;
GUI_BASE* parent = gui_get_view();
if( !parent )