From 097a662814ab338dd7a2b118da177522314fff2d Mon Sep 17 00:00:00 2001 From: Garux Date: Thu, 27 Feb 2020 21:03:04 +0300 Subject: [PATCH] * preferences->Grid->Max grid coordinate: how much big grid to render (visual aid for games with small world) known minor issues: preference change to smaller value doesn't trigger 2d view origin, scale constraints evaluation (ok after doing manually) preference change during region mode resets grid region size --- radiant/grid.cpp | 35 +++++++++++++ radiant/grid.h | 2 + radiant/map.cpp | 17 +++--- radiant/map.h | 5 +- radiant/xywindow.cpp | 120 +++++++++++-------------------------------- 5 files changed, 78 insertions(+), 101 deletions(-) diff --git a/radiant/grid.cpp b/radiant/grid.cpp index 85d28f1f..93298fe2 100644 --- a/radiant/grid.cpp +++ b/radiant/grid.cpp @@ -191,6 +191,28 @@ void ToggleGridSnap(){ GridChangeNotify(); } + +int g_maxGridCoordPower = 4; +float g_maxGridCoord; +float GetMaxGridCoord(){ + return g_maxGridCoord; +} + +void Region_defaultMinMax(); +void maxGridCoordPowerImport( int value ){ + g_maxGridCoordPower = value; + g_maxGridCoord = pow( 2.0, std::min( 4, std::max( 0, g_maxGridCoordPower ) ) + 12 ); + Region_defaultMinMax(); + GridChangeNotify(); +} +typedef FreeCaller1 maxGridCoordPowerImportCaller; + +void maxGridCoordPowerExport( const IntImportCallback& importer ){ + importer( std::min( 4, std::max( 0, g_maxGridCoordPower ) ) ); +} +typedef FreeCaller1 maxGridCoordPowerExportCaller; + + void Grid_registerCommands(){ GlobalCommands_insert( "GridDown", FreeCaller(), Accelerator( '[' ) ); GlobalCommands_insert( "GridUp", FreeCaller(), Accelerator( ']' ) ); @@ -240,6 +262,16 @@ void Grid_constructPreferences( PreferencesPage& page ){ g_grid_default, ARRAY_RANGE( g_gridnames ) ); + { + const char* coords[] = { "4096", "8192", "16384", "32768", "65536" }; + + page.appendCombo( + "Max grid coordinate", + STRING_ARRAY_RANGE( coords ), + IntImportCallback( maxGridCoordPowerImportCaller() ), + IntExportCallback( maxGridCoordPowerExportCaller() ) + ); + } } void Grid_constructPage( PreferenceGroup& group ){ PreferencesPage page( group.createPage( "Grid", "Grid Settings" ) ); @@ -258,6 +290,9 @@ void Grid_construct(){ g_grid_power = GridPower_forGridDefault( g_grid_default ); g_gridsize = GridSize_forGridPower( g_grid_power ); + + GlobalPreferenceSystem().registerPreference( "GridMaxCoordPower", IntImportStringCaller( g_maxGridCoordPower ), IntExportStringCaller( g_maxGridCoordPower ) ); + maxGridCoordPowerImport( g_maxGridCoordPower ); // call manually to also work, when no preference was loaded (1st start) } void Grid_destroy(){ diff --git a/radiant/grid.h b/radiant/grid.h index 53b717c1..b1ccb433 100644 --- a/radiant/grid.h +++ b/radiant/grid.h @@ -28,6 +28,8 @@ float GetSnapGridSize(); float GetGridSize(); int Grid_getPower(); +float GetMaxGridCoord(); + void AddGridChangeCallback( const SignalHandler& handler ); void Grid_registerCommands(); diff --git a/radiant/map.cpp b/radiant/map.cpp index fc04ed13..4ab84a96 100644 --- a/radiant/map.cpp +++ b/radiant/map.cpp @@ -86,6 +86,7 @@ #include "brushmodule.h" #include "brush.h" #include "patch.h" +#include "grid.h" class NameObserver { @@ -398,11 +399,6 @@ void Map_SetWorldspawn( Map& map, scene::Node* node ){ } -// TTimo -// need that in a variable, will have to tweak depending on the game -float g_MaxWorldCoord = 64 * 1024; -float g_MinWorldCoord = -64 * 1024; - void AddRegionBrushes( void ); void RemoveRegionBrushes( void ); @@ -1474,8 +1470,12 @@ bool g_region_active = false; BoolExportCaller g_region_caller( g_region_active ); ToggleItem g_region_item( g_region_caller ); -Vector3 g_region_mins( g_MinWorldCoord, g_MinWorldCoord, g_MinWorldCoord ); -Vector3 g_region_maxs( g_MaxWorldCoord, g_MaxWorldCoord, g_MaxWorldCoord ); +Vector3 g_region_mins; +Vector3 g_region_maxs; +void Region_defaultMinMax(){ + g_region_maxs[0] = g_region_maxs[1] = g_region_maxs[2] = GetMaxGridCoord(); + g_region_mins[0] = g_region_mins[1] = g_region_mins[2] = -GetMaxGridCoord(); +} scene::Node* region_sides[6]; scene::Node* region_startpoint = 0; @@ -1590,8 +1590,7 @@ void Map_RegionOff(){ g_region_active = false; g_region_item.update(); - g_region_maxs[0] = g_region_maxs[1] = g_region_maxs[2] = g_MaxWorldCoord - 64; - g_region_mins[0] = g_region_mins[1] = g_region_mins[2] = g_MinWorldCoord + 64; + Region_defaultMinMax(); Scene_Exclude_All( false ); } diff --git a/radiant/map.h b/radiant/map.h index 2a2d0713..8656cce2 100644 --- a/radiant/map.h +++ b/radiant/map.h @@ -98,9 +98,8 @@ typedef BasicVector3 Vector3; extern Vector3 g_region_mins, g_region_maxs; extern bool g_region_active; -// used to be #defines, multiple engine support suggests we should go towards dynamic -extern float g_MaxWorldCoord; -extern float g_MinWorldCoord; +const float g_MaxWorldCoord = 64 * 1024; +const float g_MinWorldCoord = -64 * 1024; void Map_LoadFile( const char* filename ); bool Map_SaveFile( const char* filename ); diff --git a/radiant/xywindow.cpp b/radiant/xywindow.cpp index 3b5ebaf7..1bbefe02 100644 --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@ -239,7 +239,9 @@ inline unsigned int buttons_for_state( guint state ){ void XYWnd::SetScale( float f ){ const float max_scale = 64.f; - const float min_scale = std::min( Width(), Height() ) / ( 1.1f * ( g_MaxWorldCoord - g_MinWorldCoord ) ); + const float min_scale = std::min( Width(), Height() ) + / ( ( 1.1f + ( 1.f - GetMaxGridCoord() / g_MaxWorldCoord ) ) // adaptive min scale factor: from 2.0375 with 4096 grid to 1.1 with 64*1024 + * 2.f * GetMaxGridCoord() ); f = std::min( max_scale, std::max( min_scale, f ) ); if( !float_equal_epsilon( m_fScale, f, float_mid( m_fScale, f ) * 1e-5f ) ){ m_fScale = f; @@ -552,9 +554,9 @@ void XYWnd::overlayDraw(){ glBegin( GL_LINES ); for( int i = 0, dim1 = nDim1, dim2 = nDim2; i < 2; ++i, std::swap( dim1, dim2 ) ){ v[dim1] = m_mousePosition[dim1]; - v[dim2] = 2.0f * g_MinWorldCoord; + v[dim2] = 2.0f * -GetMaxGridCoord(); glVertex3fv( vector3_to_array( v ) ); - v[dim2] = 2.0f * g_MaxWorldCoord; + v[dim2] = 2.0f * GetMaxGridCoord(); glVertex3fv( vector3_to_array( v ) ); } glEnd(); @@ -770,7 +772,7 @@ const Vector3& XYWnd::GetOrigin() const { void XYWnd::SetOrigin( const Vector3& origin ){ for( std::size_t i = 0; i < 3; ++i ) - m_vOrigin[i] = std::min( g_MaxWorldCoord, std::max( g_MinWorldCoord, origin[i] ) ); + m_vOrigin[i] = std::min( GetMaxGridCoord(), std::max( -GetMaxGridCoord(), origin[i] ) ); updateModelview(); XYWnd_Update( *this ); } @@ -1467,31 +1469,31 @@ void XYWnd::XY_DrawAxis( void ){ } void XYWnd::XY_DrawGrid( void ) { - float x, y, xb, xe, yb, ye; - float w, h, a; + float x, y; char text[32]; float step, minor_step, stepx, stepy; step = minor_step = stepx = stepy = GetGridSize(); int minor_power = Grid_getPower(); - int mask; - while ( ( minor_step * m_fScale ) <= 4.0f ) { // make sure minor grid spacing is at least 4 pixels on the screen ++minor_power; minor_step *= 2; } + int power = minor_power; while ( ( power % 3 ) != 0 || ( step * m_fScale ) <= 32.0f ) { // make sure major grid spacing is at least 32 pixels on the screen ++power; step = pow( 2.0f, power ); } - mask = ( 1 << ( power - minor_power ) ) - 1; + + const int mask = ( 1 << ( power - minor_power ) ) - 1; + while ( ( stepx * m_fScale ) <= 32.0f ) // text step x must be at least 32 stepx *= 2; while ( ( stepy * m_fScale ) <= 32.0f ) // text step y must be at least 32 stepy *= 2; - a = ( ( GetSnapGridSize() > 0.0f ) ? 1.0f : 0.3f ); + const float a = ( ( GetSnapGridSize() > 0.0f ) ? 1.0f : 0.3f ); glDisable( GL_TEXTURE_2D ); glDisable( GL_TEXTURE_1D ); @@ -1499,34 +1501,15 @@ void XYWnd::XY_DrawGrid( void ) { glDisable( GL_BLEND ); glLineWidth( 1 ); - w = ( m_nWidth / 2 / m_fScale ); - h = ( m_nHeight / 2 / m_fScale ); + const float w = ( m_nWidth / 2 / m_fScale ); + const float h = ( m_nHeight / 2 / m_fScale ); NDIM1NDIM2( m_viewType ) - xb = m_vOrigin[nDim1] - w; - if ( xb < g_region_mins[nDim1] ) { - xb = g_region_mins[nDim1]; - } - xb = step * floor( xb / step ); - - xe = m_vOrigin[nDim1] + w; - if ( xe > g_region_maxs[nDim1] ) { - xe = g_region_maxs[nDim1]; - } - xe = step * ceil( xe / step ); - - yb = m_vOrigin[nDim2] - h; - if ( yb < g_region_mins[nDim2] ) { - yb = g_region_mins[nDim2]; - } - yb = step * floor( yb / step ); - - ye = m_vOrigin[nDim2] + h; - if ( ye > g_region_maxs[nDim2] ) { - ye = g_region_maxs[nDim2]; - } - ye = step * ceil( ye / step ); + const float xb = step * floor( std::max( m_vOrigin[nDim1] - w, g_region_mins[nDim1] ) / step ); + const float xe = step * ceil( std::min( m_vOrigin[nDim1] + w, g_region_maxs[nDim1] ) / step ); + const float yb = step * floor( std::max( m_vOrigin[nDim2] - h, g_region_mins[nDim2] ) / step ); + const float ye = step * ceil( std::min( m_vOrigin[nDim2] + h, g_region_maxs[nDim2] ) / step ); #define COLORS_DIFFER( a,b ) \ ( ( a )[0] != ( b )[0] || \ @@ -1582,31 +1565,10 @@ void XYWnd::XY_DrawGrid( void ) { } if( g_region_active ){ - float xb_, xe_, yb_, ye_; - - xb_ = m_vOrigin[nDim1] - w; - if ( xb_ < g_MinWorldCoord ) { - xb_ = g_MinWorldCoord; - } - xb_ = step * floor( xb_ / step ); - - xe_ = m_vOrigin[nDim1] + w; - if ( xe_ > g_MaxWorldCoord ) { - xe_ = g_MaxWorldCoord; - } - xe_ = step * ceil( xe_ / step ); - - yb_ = m_vOrigin[nDim2] - h; - if ( yb_ < g_MinWorldCoord ) { - yb_ = g_MinWorldCoord; - } - yb_ = step * floor( yb_ / step ); - - ye_ = m_vOrigin[nDim2] + h; - if ( ye_ > g_MaxWorldCoord ) { - ye_ = g_MaxWorldCoord; - } - ye_ = step * ceil( ye_ / step ); + const float xb_ = step * floor( std::max( m_vOrigin[nDim1] - w, -GetMaxGridCoord() ) / step ); + const float xe_ = step * ceil( std::min( m_vOrigin[nDim1] + w, GetMaxGridCoord() ) / step ); + const float yb_ = step * floor( std::max( m_vOrigin[nDim2] - h, -GetMaxGridCoord() ) / step ); + const float ye_ = step * ceil( std::min( m_vOrigin[nDim2] + h, GetMaxGridCoord() ) / step ); glEnable( GL_BLEND ); // draw minor blocks @@ -1653,8 +1615,8 @@ void XYWnd::XY_DrawGrid( void ) { // draw coordinate text if needed if ( g_xywindow_globals_private.show_coordinates ) { glColor4fv( vector4_to_array( Vector4( g_xywindow_globals.color_gridtext, 1.0f ) ) ); - float offx = m_vOrigin[nDim2] + h - ( 4 + GlobalOpenGL().m_font->getPixelAscent() ) / m_fScale; - float offy = m_vOrigin[nDim1] - w + 4 / m_fScale; + const float offx = m_vOrigin[nDim2] + h - ( 4 + GlobalOpenGL().m_font->getPixelAscent() ) / m_fScale; + const float offy = m_vOrigin[nDim1] - w + 4 / m_fScale; for ( x = xb - fmod( xb, stepx ); x <= xe ; x += stepx ) { glRasterPos2f( x, offx ); sprintf( text, "%g", x ); @@ -1713,8 +1675,7 @@ void XYWnd::XY_DrawBlockGrid(){ g_xywindow_globals_private.blockSize = 1024; } - float x, y, xb, xe, yb, ye; - float w, h; + float x, y; char text[32]; glDisable( GL_TEXTURE_2D ); @@ -1722,34 +1683,15 @@ void XYWnd::XY_DrawBlockGrid(){ glDisable( GL_DEPTH_TEST ); glDisable( GL_BLEND ); - w = ( m_nWidth / 2 / m_fScale ); - h = ( m_nHeight / 2 / m_fScale ); + const float w = ( m_nWidth / 2 / m_fScale ); + const float h = ( m_nHeight / 2 / m_fScale ); NDIM1NDIM2( m_viewType ) - xb = m_vOrigin[nDim1] - w; - if ( xb < g_region_mins[nDim1] ) { - xb = g_region_mins[nDim1]; - } - xb = static_cast( g_xywindow_globals_private.blockSize * floor( xb / g_xywindow_globals_private.blockSize ) ); - - xe = m_vOrigin[nDim1] + w; - if ( xe > g_region_maxs[nDim1] ) { - xe = g_region_maxs[nDim1]; - } - xe = static_cast( g_xywindow_globals_private.blockSize * ceil( xe / g_xywindow_globals_private.blockSize ) ); - - yb = m_vOrigin[nDim2] - h; - if ( yb < g_region_mins[nDim2] ) { - yb = g_region_mins[nDim2]; - } - yb = static_cast( g_xywindow_globals_private.blockSize * floor( yb / g_xywindow_globals_private.blockSize ) ); - - ye = m_vOrigin[nDim2] + h; - if ( ye > g_region_maxs[nDim2] ) { - ye = g_region_maxs[nDim2]; - } - ye = static_cast( g_xywindow_globals_private.blockSize * ceil( ye / g_xywindow_globals_private.blockSize ) ); + const float xb = g_xywindow_globals_private.blockSize * floor( std::max( m_vOrigin[nDim1] - w, g_region_mins[nDim1] ) / g_xywindow_globals_private.blockSize ); + const float xe = g_xywindow_globals_private.blockSize * ceil( std::min( m_vOrigin[nDim1] + w, g_region_maxs[nDim1] ) / g_xywindow_globals_private.blockSize ); + const float yb = g_xywindow_globals_private.blockSize * floor( std::max( m_vOrigin[nDim2] - h, g_region_mins[nDim2] ) / g_xywindow_globals_private.blockSize ); + const float ye = g_xywindow_globals_private.blockSize * ceil( std::min( m_vOrigin[nDim2] + h, g_region_maxs[nDim2] ) / g_xywindow_globals_private.blockSize ); // draw major blocks