diff --git a/radiant/brush.h b/radiant/brush.h index 714edf12..9aee6583 100644 --- a/radiant/brush.h +++ b/radiant/brush.h @@ -600,8 +600,8 @@ void Convert( TexdefTypeId in, TexdefTypeId out, const Plane3& plane ){ m_scaleApplied = true; } -void fit( const Vector3& normal, const Winding& winding, float s_repeat, float t_repeat ){ - Texdef_FitTexture( m_projection, m_shader.width(), m_shader.height(), normal, winding, s_repeat, t_repeat ); +void fit( const Vector3& normal, const Winding& winding, float s_repeat, float t_repeat, bool only_dimension ){ + Texdef_FitTexture( m_projection, m_shader.width(), m_shader.height(), normal, winding, s_repeat, t_repeat, only_dimension ); } void emitTextureCoordinates( Winding& winding, const Vector3& normal, const Matrix4& localToWorld ){ @@ -1292,9 +1292,9 @@ void Convert( TexdefTypeId in, TexdefTypeId out ){ texdefChanged(); } -void FitTexture( float s_repeat, float t_repeat ){ +void FitTexture( float s_repeat, float t_repeat, bool only_dimension ){ undoSave(); - m_texdef.fit( m_plane.plane3().normal(), m_winding, s_repeat, t_repeat ); + m_texdef.fit( m_plane.plane3().normal(), m_winding, s_repeat, t_repeat, only_dimension ); texdefChanged(); } diff --git a/radiant/brush_primit.cpp b/radiant/brush_primit.cpp index baf5c6d4..3e9a2851 100644 --- a/radiant/brush_primit.cpp +++ b/radiant/brush_primit.cpp @@ -1258,7 +1258,7 @@ void Texdef_Rotate( TextureProjection& projection, float angle ){ } } -void Texdef_FitTexture( TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, const Winding& w, float s_repeat, float t_repeat ){ +void Texdef_FitTexture( TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, const Winding& w, float s_repeat, float t_repeat, bool only_dimension ){ if ( w.numpoints < 3 ) { return; } @@ -1293,14 +1293,24 @@ void Texdef_FitTexture( TextureProjection& projection, std::size_t width, std::s perfect.extents = Vector3( s_repeat * 0.5, t_repeat * 0.5, 1 ); } if( t_repeat == 0 ){ - //fit width - perfect.origin = Vector3( s_repeat * 0.5, s_repeat * 0.5 * bounds.extents.y() / bounds.extents.x(), 0 ); - perfect.extents = Vector3( s_repeat * 0.5, s_repeat * 0.5 * bounds.extents.y() / bounds.extents.x(), 1 ); + if( only_dimension ){ //fit width, keep height + perfect.origin = Vector3( s_repeat * 0.5, bounds.origin.y(), 0 ); + perfect.extents = Vector3( s_repeat * 0.5, bounds.extents.y(), 1 ); + } + else{ //fit width + perfect.origin = Vector3( s_repeat * 0.5, s_repeat * 0.5 * bounds.extents.y() / bounds.extents.x(), 0 ); + perfect.extents = Vector3( s_repeat * 0.5, s_repeat * 0.5 * bounds.extents.y() / bounds.extents.x(), 1 ); + } } else if( s_repeat == 0 ){ - //fit height - perfect.origin = Vector3( t_repeat * 0.5 * bounds.extents.x() / bounds.extents.y(), t_repeat * 0.5, 0 ); - perfect.extents = Vector3( t_repeat * 0.5 * bounds.extents.x() / bounds.extents.y(), t_repeat * 0.5, 1 ); + if( only_dimension ){ //fit height, keep width + perfect.origin = Vector3( bounds.origin.x(), t_repeat * 0.5, 0 ); + perfect.extents = Vector3( bounds.extents.x(), t_repeat * 0.5, 1 ); + } + else{ //fit height + perfect.origin = Vector3( t_repeat * 0.5 * bounds.extents.x() / bounds.extents.y(), t_repeat * 0.5, 0 ); + perfect.extents = Vector3( t_repeat * 0.5 * bounds.extents.x() / bounds.extents.y(), t_repeat * 0.5, 1 ); + } } else{ perfect.origin = Vector3( s_repeat * 0.5, t_repeat * 0.5, 0 ); diff --git a/radiant/brush_primit.h b/radiant/brush_primit.h index ac679788..f0ff98fe 100644 --- a/radiant/brush_primit.h +++ b/radiant/brush_primit.h @@ -109,7 +109,7 @@ void Texdef_Scale( TextureProjection& projection, float s, float t ); void Texdef_Rotate( TextureProjection& projection, float angle ); void Texdef_ProjectTexture( TextureProjection& projection, std::size_t width, std::size_t height, const Plane3& plane, const texdef_t& texdef, const Vector3* direction ); void Texdef_ProjectTexture( TextureProjection& projection, std::size_t width, std::size_t height, const Plane3& plane, TextureProjection other_proj, const Vector3& other_normal ); -void Texdef_FitTexture( TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, const Winding& w, float s_repeat, float t_repeat ); +void Texdef_FitTexture( TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, const Winding& w, float s_repeat, float t_repeat, bool only_dimension ); void Texdef_Construct_local2tex( const TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, Matrix4& local2tex ); void Texdef_Construct_local2tex4projection( const texdef_t& texdef, std::size_t width, std::size_t height, const Vector3& normal, const Vector3* direction, Matrix4& local2tex ); void Texdef_EmitTextureCoordinates( const TextureProjection& projection, std::size_t width, std::size_t height, Winding& w, const Vector3& normal, const Matrix4& localToWorld ); diff --git a/radiant/brushmanip.cpp b/radiant/brushmanip.cpp index f090ab79..d6c43578 100644 --- a/radiant/brushmanip.cpp +++ b/radiant/brushmanip.cpp @@ -784,22 +784,23 @@ void Scene_BrushProjectTexture_Component_Selected( scene::Graph& graph, const Te class FaceFitTexture { -float m_s_repeat, m_t_repeat; +const float m_s_repeat, m_t_repeat; +const bool m_only_dimension; public: -FaceFitTexture( float s_repeat, float t_repeat ) : m_s_repeat( s_repeat ), m_t_repeat( t_repeat ){ +FaceFitTexture( float s_repeat, float t_repeat, bool only_dimension ) : m_s_repeat( s_repeat ), m_t_repeat( t_repeat ), m_only_dimension( only_dimension ) { } void operator()( Face& face ) const { - face.FitTexture( m_s_repeat, m_t_repeat ); + face.FitTexture( m_s_repeat, m_t_repeat, m_only_dimension ); } }; -void Scene_BrushFitTexture_Selected( scene::Graph& graph, float s_repeat, float t_repeat ){ - Scene_ForEachSelectedBrush_ForEachFace( graph, FaceFitTexture( s_repeat, t_repeat ) ); +void Scene_BrushFitTexture_Selected( scene::Graph& graph, float s_repeat, float t_repeat, bool only_dimension ){ + Scene_ForEachSelectedBrush_ForEachFace( graph, FaceFitTexture( s_repeat, t_repeat, only_dimension ) ); SceneChangeNotify(); } -void Scene_BrushFitTexture_Component_Selected( scene::Graph& graph, float s_repeat, float t_repeat ){ - Scene_ForEachSelectedBrushFace( graph, FaceFitTexture( s_repeat, t_repeat ) ); +void Scene_BrushFitTexture_Component_Selected( scene::Graph& graph, float s_repeat, float t_repeat, bool only_dimension ){ + Scene_ForEachSelectedBrushFace( graph, FaceFitTexture( s_repeat, t_repeat, only_dimension ) ); SceneChangeNotify(); } diff --git a/radiant/brushmanip.h b/radiant/brushmanip.h index 47aebfbe..b4527eb4 100644 --- a/radiant/brushmanip.h +++ b/radiant/brushmanip.h @@ -83,8 +83,8 @@ void Scene_BrushProjectTexture_Component_Selected( scene::Graph& graph, const te void Scene_BrushProjectTexture_Selected( scene::Graph& graph, const TextureProjection& projection, const Vector3& normal ); void Scene_BrushProjectTexture_Component_Selected( scene::Graph& graph, const TextureProjection& projection, const Vector3& normal ); -void Scene_BrushFitTexture_Selected( scene::Graph& graph, float s_repeat, float t_repeat ); -void Scene_BrushFitTexture_Component_Selected( scene::Graph& graph, float s_repeat, float t_repeat ); +void Scene_BrushFitTexture_Selected( scene::Graph& graph, float s_repeat, float t_repeat, bool only_dimension ); +void Scene_BrushFitTexture_Component_Selected( scene::Graph& graph, float s_repeat, float t_repeat, bool only_dimension ); typedef struct _GtkMenu GtkMenu; void Brush_constructMenu( GtkMenu* menu ); diff --git a/radiant/select.cpp b/radiant/select.cpp index 846da18f..62e6b6a3 100644 --- a/radiant/select.cpp +++ b/radiant/select.cpp @@ -908,11 +908,11 @@ void Select_ProjectTexture( const TextureProjection& projection, const Vector3& SceneChangeNotify(); } -void Select_FitTexture( float horizontal, float vertical ){ +void Select_FitTexture( float horizontal, float vertical, bool only_dimension ){ if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) { - Scene_BrushFitTexture_Selected( GlobalSceneGraph(), horizontal, vertical ); + Scene_BrushFitTexture_Selected( GlobalSceneGraph(), horizontal, vertical, only_dimension ); } - Scene_BrushFitTexture_Component_Selected( GlobalSceneGraph(), horizontal, vertical ); + Scene_BrushFitTexture_Component_Selected( GlobalSceneGraph(), horizontal, vertical, only_dimension ); SceneChangeNotify(); } diff --git a/radiant/select.h b/radiant/select.h index 30922662..510390c6 100644 --- a/radiant/select.h +++ b/radiant/select.h @@ -70,7 +70,7 @@ void Select_ShiftTexture( float x, float y ); class texdef_t; void Select_ProjectTexture( const texdef_t& texdef, const Vector3* direction ); void Select_ProjectTexture( const TextureProjection& projection, const Vector3& normal ); -void Select_FitTexture( float horizontal = 1, float vertical = 1 ); +void Select_FitTexture( float horizontal = 1, float vertical = 1, bool only_dimension = false ); void FindReplaceTextures( const char* pFind, const char* pReplace, bool bSelected ); void HideSelected(); diff --git a/radiant/surfacedialog.cpp b/radiant/surfacedialog.cpp index 3ebb2f81..06133bec 100644 --- a/radiant/surfacedialog.cpp +++ b/radiant/surfacedialog.cpp @@ -545,18 +545,37 @@ static void OnBtnFaceFit( GtkWidget *widget, gpointer data ){ SurfaceInspector_FitTexture(); } -static void OnBtnFaceFitW( GtkWidget *widget, gpointer data ){ +static void OnBtnFaceFitWidth( GtkWidget *widget, gpointer data ){ UndoableCommand undo( "textureAutoFitWidth" ); getSurfaceInspector().exportData(); Select_FitTexture( getSurfaceInspector().m_fitHorizontal, 0 ); } -static void OnBtnFaceFitH( GtkWidget *widget, gpointer data ){ +static void OnBtnFaceFitHeight( GtkWidget *widget, gpointer data ){ UndoableCommand undo( "textureAutoFitHeight" ); getSurfaceInspector().exportData(); Select_FitTexture( 0, getSurfaceInspector().m_fitVertical ); } +static gboolean OnBtnFaceFitWidthOnly( GtkWidget *widget, GdkEventButton *event, gpointer data ){ + if ( event->button == 3 && event->type == GDK_BUTTON_PRESS ) { + UndoableCommand undo( "textureAutoFitWidthOnly" ); + getSurfaceInspector().exportData(); + Select_FitTexture( getSurfaceInspector().m_fitHorizontal, 0, true ); + return TRUE; + } + return FALSE; +} + +static gboolean OnBtnFaceFitHeightOnly( GtkWidget *widget, GdkEventButton *event, gpointer data ){ + if ( event->button == 3 && event->type == GDK_BUTTON_PRESS ) { + UndoableCommand undo( "textureAutoFitHeightOnly" ); + getSurfaceInspector().exportData(); + Select_FitTexture( 0, getSurfaceInspector().m_fitVertical, true ); + return TRUE; + } + return FALSE; +} typedef const char* FlagName; @@ -918,22 +937,26 @@ GtkWindow* SurfaceInspector::BuildDialog(){ } { GtkWidget* button = gtk_button_new_with_label( "Width" ); + gtk_widget_set_tooltip_text( button, "Fit texture width, scale height\nRightClick: fit width, keep height" ); gtk_widget_show( button ); gtk_table_attach( GTK_TABLE( table ), button, 2, 3, 0, 1, (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), (GtkAttachOptions) ( 0 ), 0, 0 ); g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnFaceFitW ), 0 ); + G_CALLBACK( OnBtnFaceFitWidth ), 0 ); + g_signal_connect( G_OBJECT( button ), "button_press_event", G_CALLBACK( OnBtnFaceFitWidthOnly ), 0 ); gtk_widget_set_usize( button, 60, -2 ); } { GtkWidget* button = gtk_button_new_with_label( "Height" ); + gtk_widget_set_tooltip_text( button, "Fit texture height, scale width\nRightClick: fit height, keep width" ); gtk_widget_show( button ); gtk_table_attach( GTK_TABLE( table ), button, 3, 4, 0, 1, (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), (GtkAttachOptions) ( 0 ), 0, 0 ); g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnFaceFitH ), 0 ); + G_CALLBACK( OnBtnFaceFitHeight ), 0 ); + g_signal_connect( G_OBJECT( button ), "button_press_event", G_CALLBACK( OnBtnFaceFitHeightOnly ), 0 ); gtk_widget_set_usize( button, 60, -2 ); } {