diff --git a/radiant/brush.h b/radiant/brush.h index 0024557b..877300a6 100644 --- a/radiant/brush.h +++ b/radiant/brush.h @@ -588,6 +588,10 @@ void rotate( float angle ){ addScale(); } +void ProjectTexture( const Plane3& plane, const texdef_t& texdef, Vector3* direction ){ + Texdef_ProjectTexture( m_projection, m_shader.width(), m_shader.height(), plane, texdef, direction ); +} + 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 ); } @@ -1187,6 +1191,12 @@ void RotateTexdef( float angle ){ texdefChanged(); } +void ProjectTexture( const texdef_t& texdef, Vector3* direction ){ + undoSave(); + m_texdef.ProjectTexture( m_plane.plane3(), texdef, direction ); + texdefChanged(); +} + void FitTexture( float s_repeat, float t_repeat ){ undoSave(); m_texdef.fit( m_plane.plane3().normal(), m_winding, s_repeat, t_repeat ); diff --git a/radiant/brush_primit.cpp b/radiant/brush_primit.cpp index 9362a9f9..e99b0972 100644 --- a/radiant/brush_primit.cpp +++ b/radiant/brush_primit.cpp @@ -181,6 +181,7 @@ inline void BPTexdef_fromTransform( brushprimit_texdef_t& bp_texdef, const Matri bp_texdef.coords[1][0] = transform.xy(); bp_texdef.coords[1][1] = transform.yy(); bp_texdef.coords[1][2] = transform.ty(); + //globalOutputStream() << bp_texdef.coords[0][0] << " " << bp_texdef.coords[0][1] << " " << bp_texdef.coords[0][2] << "\n"; } inline void Texdef_fromTransform( TextureProjection& projection, float width, float height, const Matrix4& transform ){ @@ -222,7 +223,9 @@ void Texdef_normalise( TextureProjection& projection, float width, float height } } -void ComputeAxisBase( const Vector3& normal, Vector3& texS, Vector3& texT ); +//void ComputeAxisBase( const Vector3& normal, Vector3& texS, Vector3& texT ); +template +void ComputeAxisBase( const BasicVector3& normal, BasicVector3& texS, BasicVector3& texT ); inline void DebugAxisBase( const Vector3& normal ){ Vector3 x, y; @@ -455,18 +458,19 @@ void MatrixForPoints( Vector3 M[3], Vector3 D[2], brushprimit_texdef_t *T ){ // NOTE : ComputeAxisBase here and in q3map code must always BE THE SAME ! // WARNING : special case behaviour of atan2(y,x) <-> atan(y/x) might not be the same everywhere when x == 0 // rotation by (0,RotY,RotZ) assigns X to normal -void ComputeAxisBase( const Vector3& normal, Vector3& texS, Vector3& texT ){ +template +void ComputeAxisBase( const BasicVector3& normal, BasicVector3& texS, BasicVector3& texT ){ #if 1 - const Vector3 up( 0, 0, 1 ); - const Vector3 down( 0, 0, -1 ); + const BasicVector3 up( 0, 0, 1 ); + const BasicVector3 down( 0, 0, -1 ); - if ( vector3_equal_epsilon( normal, up, float(1e-6) ) ) { - texS = Vector3( 0, 1, 0 ); - texT = Vector3( 1, 0, 0 ); + if ( vector3_equal_epsilon( normal, up, Element(1e-6) ) ) { + texS = BasicVector3( 0, 1, 0 ); + texT = BasicVector3( 1, 0, 0 ); } - else if ( vector3_equal_epsilon( normal, down, float(1e-6) ) ) { - texS = Vector3( 0, 1, 0 ); - texT = Vector3( -1, 0, 0 ); + else if ( vector3_equal_epsilon( normal, down, Element(1e-6) ) ) { + texS = BasicVector3( 0, 1, 0 ); + texT = BasicVector3( -1, 0, 0 ); } else { @@ -1385,3 +1389,83 @@ void Q3_to_BP( const texdef_t& texdef, float width, float height, const Vector3& BP_from_matrix( bp_texdef, normal, matrix ); } #endif + + + + +/// for arbitrary texture projections +void EmitTextureCoordinates( const texdef_t& texdef, std::size_t width, std::size_t height, const Vector3& normal, DoubleVector3 points[3], DoubleVector3 st[3], Vector3* direction ){ + Matrix4 local2tex; + Texdef_toTransform( texdef, (float)width, (float)height, local2tex ); + { + if( direction ){ //arbitrary + Matrix4 basis = g_matrix4_identity; + ComputeAxisBase( *direction, vector4_to_vector3( basis.x() ), vector4_to_vector3( basis.y() ) ); + vector4_to_vector3( basis.z() ) = *direction; + matrix4_transpose( basis ); + + matrix4_multiply_by_matrix4( local2tex, basis ); + } + else{ //ap + Matrix4 xyz2st; + Normal_GetTransform( normal, xyz2st ); //Texdef_basisForNormal for ap + matrix4_multiply_by_matrix4( local2tex, xyz2st ); + } + } + + for ( std::size_t i = 0; i < 3; ++i ) + { + DoubleVector3 texcoord = matrix4_transformed_point( local2tex, points[i] ); + //globalOutputStream() << texcoord << "\n"; + st[i][0] = texcoord[0]; + st[i][1] = texcoord[1]; + } +} + +void Texdef_ProjectTexture( TextureProjection& projection, std::size_t width, std::size_t height, const Plane3& plane, const texdef_t& texdef, Vector3* direction ){ + //texdef_t texdef; + //Q3_to_BP( texdef, (float)width, (float)height, normal, projection.m_brushprimit_texdef ); + + + DoubleVector3 texX, texY; + DoubleVector3 proj; + +#ifdef DBG_BP + if( f->plane.normal[0] == 0.0f && f->plane.normal[1] == 0.0f && f->plane.normal[2] == 0.0f ) { + globalOutputStream() << "Warning : f->plane.normal is (0,0,0) in FaceToBrushPrimitFace\n"; + } + // check d_texture + if( !f->d_texture ) { + globalOutputStream() << "Warning : f.d_texture is 0 in FaceToBrushPrimitFace\n"; + return; + } +#endif + // compute axis base + ComputeAxisBase( plane.normal(), texX, texY ); + // compute projection vector + proj = plane.normal() * plane.dist(); + + // (0,0) in plane axis base is (0,0,0) in world coordinates + projection on the affine plane + // (1,0) in plane axis base is texX in world coordinates + projection on the affine plane + // (0,1) in plane axis base is texY in world coordinates + projection on the affine plane + // use old texture code to compute the ST coords of these points + // ST of (0,0) (1,0) (0,1) + DoubleVector3 points[3]; + DoubleVector3 st[3]; +// texdef_t texdef; +// texdef.scale[0] = texdef.scale[1] = 0.5f; + + points[0] = proj; + points[1] = texX + proj; + points[2] = texY + proj; + EmitTextureCoordinates( texdef, width, height, plane.normal(), points, st, direction ); + // compute texture matrix + projection.m_brushprimit_texdef.coords[0][2] = st[0][0]; + projection.m_brushprimit_texdef.coords[1][2] = st[0][1]; + projection.m_brushprimit_texdef.coords[0][0] = st[1][0] - st[0][0]; + projection.m_brushprimit_texdef.coords[1][0] = st[1][1] - st[0][1]; + projection.m_brushprimit_texdef.coords[0][1] = st[2][0] - st[0][0]; + projection.m_brushprimit_texdef.coords[1][1] = st[2][1] - st[0][1]; + + Texdef_normalise( projection, (float)width, (float)height ); +} diff --git a/radiant/brush_primit.h b/radiant/brush_primit.h index 79d27f3e..8de1cbbd 100644 --- a/radiant/brush_primit.h +++ b/radiant/brush_primit.h @@ -105,6 +105,7 @@ void Texdef_Assign( TextureProjection& projection, const TextureProjection& othe void Texdef_Shift( TextureProjection& projection, float s, float t ); 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, Vector3* direction ); 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_EmitTextureCoordinates( const TextureProjection& projection, std::size_t width, std::size_t height, Winding& w, const Vector3& normal, const Matrix4& localToWorld ); @@ -132,6 +133,8 @@ struct bp_globals_t extern bp_globals_t g_bp_globals; extern float g_texdef_default_scale; -void ComputeAxisBase( const Vector3& normal, Vector3& texS, Vector3& texT ); +//void ComputeAxisBase( const Vector3& normal, Vector3& texS, Vector3& texT ); +template +void ComputeAxisBase( const BasicVector3& normal, BasicVector3& texS, BasicVector3& texT ); #endif diff --git a/radiant/brushmanip.cpp b/radiant/brushmanip.cpp index 83202140..754ed97b 100644 --- a/radiant/brushmanip.cpp +++ b/radiant/brushmanip.cpp @@ -629,6 +629,29 @@ void Scene_BrushFindReplaceShader_Component_Selected( scene::Graph& graph, const } +class FaceProjectTexture +{ + const texdef_t& m_texdef; + Vector3* m_direction; +public: + FaceProjectTexture( const texdef_t& texdef, Vector3* direction ) : m_texdef( texdef ), m_direction( direction ) { + } + void operator()( Face& face ) const { + face.ProjectTexture( m_texdef, m_direction ); + } +}; + +void Scene_BrushProjectTexture_Selected( scene::Graph& graph, const texdef_t& texdef, Vector3* direction ){ + Scene_ForEachSelectedBrush_ForEachFace( graph, FaceProjectTexture( texdef, direction ) ); + SceneChangeNotify(); +} + +void Scene_BrushProjectTexture_Component_Selected( scene::Graph& graph, const texdef_t& texdef, Vector3* direction ){ + Scene_ForEachSelectedBrushFace( graph, FaceProjectTexture( texdef, direction ) ); + SceneChangeNotify(); +} + + class FaceFitTexture { float m_s_repeat, m_t_repeat; diff --git a/radiant/brushmanip.h b/radiant/brushmanip.h index 06f67271..411cf332 100644 --- a/radiant/brushmanip.h +++ b/radiant/brushmanip.h @@ -68,6 +68,13 @@ void Scene_BrushFindReplaceShader_Selected( scene::Graph& graph, const char* fin void Scene_BrushFindReplaceShader_Component_Selected( scene::Graph& graph, const char* find, const char* replace ); void Scene_BrushSelectByShader( scene::Graph& graph, const char* name ); void Scene_BrushSelectByShader_Component( scene::Graph& graph, const char* name ); + +#include "itexdef.h" +template class BasicVector3; +typedef BasicVector3 Vector3; +void Scene_BrushProjectTexture_Selected( scene::Graph& graph, const texdef_t& texdef, Vector3* direction ); +void Scene_BrushProjectTexture_Component_Selected( scene::Graph& graph, const texdef_t& texdef, Vector3* direction ); + 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 ); diff --git a/radiant/camwindow.cpp b/radiant/camwindow.cpp index 8fbc8a65..17ea0e90 100644 --- a/radiant/camwindow.cpp +++ b/radiant/camwindow.cpp @@ -141,6 +141,7 @@ struct camera_t bool m_strafe; // true when in strafemode toggled by the ctrl-key bool m_strafe_forward; // true when in strafemode by ctrl-key and shift is pressed for forward strafing bool m_strafe_forward_invert; //silly option to invert forward strafing to support old fegs + int m_focus_offset; unsigned int movementflags; // movement flags Timer m_keycontrol_timer; @@ -167,6 +168,7 @@ struct camera_t origin( 0, 0, 0 ), angles( 0, 0, 0 ), color( 0, 0, 0 ), + m_focus_offset( 0 ), movementflags( 0 ), m_keymove_handler( 0 ), m_mouseMove( motionDelta, this ), @@ -526,9 +528,11 @@ void Camera_PitchDown_KeyUp( camera_t& camera ){ void Camera_Focus_KeyDown( camera_t& camera ){ Camera_setMovementFlags( camera, MOVE_FOCUS ); + camera.m_focus_offset = 0; } void Camera_Focus_KeyUp( camera_t& camera ){ Camera_clearMovementFlags( camera, MOVE_FOCUS ); + camera.m_focus_offset = 0; } typedef ReferenceCaller FreeMoveCameraMoveForwardKeyDownCaller; @@ -713,6 +717,8 @@ guint m_freelook_button_press_handler; guint m_sizeHandler; guint m_exposeHandler; +Timer m_render_time; + CamWnd(); ~CamWnd(); @@ -777,6 +783,11 @@ void CamWnd_destroyStatic(){ CamWnd::releaseStates(); } +void CamWnd_reconstructStatic(){ + CamWnd_destroyStatic(); + CamWnd_constructStatic(); +} + static CamWnd* g_camwnd = 0; void GlobalCamera_setCamWnd( CamWnd& camwnd ){ @@ -823,6 +834,10 @@ void Camera_setAngles( CamWnd& camwnd, const Vector3& angles ){ Camera_setAngles( camwnd.getCamera(), angles ); } +const Vector3& Camera_getViewVector( CamWnd& camwnd ){ + return camwnd.getCamera().vpn; +} + // ============================================================================= // CamWnd class @@ -953,6 +968,11 @@ gboolean wheelmove_scroll( GtkWidget* widget, GdkEventScroll* event, CamWnd* cam gtk_window_present( camwnd->m_parent ); if ( event->direction == GDK_SCROLL_UP ) { + if ( camwnd->getCamera().movementflags & MOVE_FOCUS ) { + ++camwnd->getCamera().m_focus_offset; + return FALSE; + } + Camera_Freemove_updateAxes( camwnd->getCamera() ); if( camwnd->m_bFreeMove || !g_camwindow_globals.m_bZoomInToPointer ){ Camera_setOrigin( *camwnd, vector3_added( Camera_getOrigin( *camwnd ), vector3_scaled( camwnd->getCamera().forward, static_cast( g_camwindow_globals_private.m_nMoveSpeed ) ) ) ); @@ -982,6 +1002,11 @@ gboolean wheelmove_scroll( GtkWidget* widget, GdkEventScroll* event, CamWnd* cam } } else if ( event->direction == GDK_SCROLL_DOWN ) { + if ( camwnd->getCamera().movementflags & MOVE_FOCUS ) { + --camwnd->getCamera().m_focus_offset; + return FALSE; + } + Camera_Freemove_updateAxes( camwnd->getCamera() ); Camera_setOrigin( *camwnd, vector3_added( Camera_getOrigin( *camwnd ), vector3_scaled( camwnd->getCamera().forward, -static_cast( g_camwindow_globals_private.m_nMoveSpeed ) ) ) ); } @@ -1562,6 +1587,8 @@ void ShowStatsToggle(){ UpdateAllWindows(); } +#include "stream/stringstream.h" + void CamWnd::Cam_Draw(){ glViewport( 0, 0, m_Camera.width, m_Camera.height ); #if 0 @@ -1709,6 +1736,11 @@ void CamWnd::Cam_Draw(){ extern const char* Renderer_GetStats(); GlobalOpenGL().drawString( Renderer_GetStats() ); + StringOutputStream stream; + stream << " | f2f: " << m_render_time.elapsed_msec(); + GlobalOpenGL().drawString( stream.c_str() ); + m_render_time.start(); + glRasterPos3f( 1.0f, static_cast( m_Camera.height ) - GlobalOpenGL().m_font->getPixelDescent() - GlobalOpenGL().m_font->getPixelHeight(), 0.0f ); extern const char* Cull_GetStats(); GlobalOpenGL().drawString( Cull_GetStats() ); @@ -1792,8 +1824,8 @@ Vector3 Camera_getFocusPos( camera_t& camera ){ Vector3 corners[8]; aabb_corners( aabb, corners ); - for ( size_t i = 0; i < 4; ++i ){ - for ( size_t j = 0; j < 8; ++j ){ + for ( std::size_t i = 0; i < 4; ++i ){ + for ( std::size_t j = 0; j < 8; ++j ){ Ray ray( aabb.origin, -viewvector ); //Plane3 newplane( frustumPlanes[i].normal(), vector3_dot( frustumPlanes[i].normal(), corners[j] - frustumPlanes[i].normal() * 16.0f ) ); Plane3 newplane( frustumPlanes[i].normal(), vector3_dot( frustumPlanes[i].normal(), corners[j] ) ); @@ -1804,6 +1836,12 @@ Vector3 Camera_getFocusPos( camera_t& camera ){ } } } + if( camera.m_focus_offset < 0 || camera.m_focus_offset > 16 ){ + offset -= offset * camera.m_focus_offset / 8 * pow( 2.0f, static_cast( camera.m_focus_offset < 0 ? -camera.m_focus_offset : camera.m_focus_offset - 16 ) / 8.f ); + } + else{ + offset -= offset * camera.m_focus_offset / 8; + } return ( aabb.origin - viewvector * offset ); } diff --git a/radiant/camwindow.h b/radiant/camwindow.h index bc6c847b..00c9fdcb 100644 --- a/radiant/camwindow.h +++ b/radiant/camwindow.h @@ -61,6 +61,7 @@ enum const Vector3& Camera_getAngles( CamWnd& camwnd ); void Camera_setAngles( CamWnd& camwnd, const Vector3& angles ); +const Vector3& Camera_getViewVector( CamWnd& camwnd ); struct camwindow_globals_t @@ -86,6 +87,8 @@ struct camwindow_globals_t extern camwindow_globals_t g_camwindow_globals; +void CamWnd_reconstructStatic(); + void CamWnd_Construct(); void CamWnd_Destroy(); diff --git a/radiant/entity.cpp b/radiant/entity.cpp index 6b8e1a23..f1e4e471 100644 --- a/radiant/entity.cpp +++ b/radiant/entity.cpp @@ -213,12 +213,12 @@ void post( const scene::Path& path, scene::Instance& instance ) const { } }; -void Entity_groupSelected(){ +void Entity_regroupSelected(){ if ( GlobalSelectionSystem().countSelected() < 1 ) { return; } - UndoableCommand undo( "groupSelectedEntities" ); + UndoableCommand undo( "reGroupSelectedEntities" ); scene::Path world_path( makeReference( GlobalSceneGraph().root() ) ); world_path.push( makeReference( Map_FindOrInsertWorldspawn( g_map ) ) ); @@ -633,7 +633,7 @@ void ToggleShowLightRadii(){ } void Entity_constructMenu( GtkMenu* menu ){ - create_menu_item_with_mnemonic( menu, "_Regroup", "GroupSelection" ); + create_menu_item_with_mnemonic( menu, "_Regroup", "RegroupSelection" ); create_menu_item_with_mnemonic( menu, "_Ungroup", "UngroupSelection" ); create_menu_item_with_mnemonic( menu, "_Connect", "ConnectSelection" ); if ( g_pGameDescription->mGameType == "nexuiz" ) { @@ -653,7 +653,7 @@ void Entity_Construct(){ GlobalCommands_insert( "NormalizeColor", FreeCaller() ); GlobalCommands_insert( "ConnectSelection", FreeCaller(), Accelerator( 'K', (GdkModifierType)GDK_CONTROL_MASK ) ); GlobalCommands_insert( "KillConnectSelection", FreeCaller(), Accelerator( 'K', (GdkModifierType)( GDK_SHIFT_MASK ) ) ); - GlobalCommands_insert( "GroupSelection", FreeCaller() ); + GlobalCommands_insert( "RegroupSelection", FreeCaller() ); GlobalCommands_insert( "UngroupSelection", FreeCaller() ); GlobalToggles_insert( "ShowLightRadiuses", FreeCaller(), ToggleItem::AddCallbackCaller( g_show_lightradii_item ) ); diff --git a/radiant/entityinspector.cpp b/radiant/entityinspector.cpp index d63b1804..05d4ba1e 100644 --- a/radiant/entityinspector.cpp +++ b/radiant/entityinspector.cpp @@ -1700,7 +1700,7 @@ GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){ gtk_button_set_relief( GTK_BUTTON( button ), GTK_RELIEF_NONE ); GTK_WIDGET_UNSET_FLAGS( button, GTK_CAN_FOCUS ); gtk_box_pack_start( hbox, button, FALSE, FALSE, 0 ); - gtk_widget_set_tooltip_text( button, "Focus on Selected" ); + gtk_widget_set_tooltip_text( button, "AutoFocus on Selection" ); gtk_widget_show( button ); g_focusToggleButton = GTK_TOGGLE_BUTTON( button ); } diff --git a/radiant/entitylist.cpp b/radiant/entitylist.cpp index acb7eaa0..d08414e5 100644 --- a/radiant/entitylist.cpp +++ b/radiant/entitylist.cpp @@ -334,7 +334,7 @@ void EntityList_constructWindow( GtkWindow* main_window ){ getEntityList().m_tree_view = GTK_TREE_VIEW( view ); } { - GtkWidget* check = gtk_check_button_new_with_label( "Focus on Selected" ); + GtkWidget* check = gtk_check_button_new_with_label( "AutoFocus on Selection" ); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( check ), FALSE ); gtk_widget_show( check ); gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 ); diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 4ec23d11..868d9605 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -738,6 +738,7 @@ void ColorScheme_Original(){ g_camwindow_globals.color_selbrushes3d = Vector3( 1.0f, 0.0f, 0.0f ); g_camwindow_globals.color_cameraback = Vector3( 0.25f, 0.25f, 0.25f ); + CamWnd_reconstructStatic(); CamWnd_Update( *g_pParentWnd->GetCamWnd() ); g_xywindow_globals.color_gridback = Vector3( 1.0f, 1.0f, 1.0f ); @@ -746,7 +747,9 @@ void ColorScheme_Original(){ g_xywindow_globals.color_gridblock = Vector3( 0.0f, 0.0f, 1.0f ); g_xywindow_globals.color_gridtext = Vector3( 0.0f, 0.0f, 0.0f ); g_xywindow_globals.color_selbrushes = Vector3( 1.0f, 0.0f, 0.0f ); + XYWnd::recaptureStates(); g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); + Brush_clipperColourChanged(); g_xywindow_globals.color_brushes = Vector3( 0.0f, 0.0f, 0.0f ); SetWorldspawnColour( g_xywindow_globals.color_brushes ); g_xywindow_globals.color_viewname = Vector3( 0.5f, 0.0f, 0.75f ); @@ -758,6 +761,7 @@ void ColorScheme_QER(){ g_camwindow_globals.color_cameraback = Vector3( 0.25f, 0.25f, 0.25f ); g_camwindow_globals.color_selbrushes3d = Vector3( 1.0f, 0.0f, 0.0f ); + CamWnd_reconstructStatic(); CamWnd_Update( *g_pParentWnd->GetCamWnd() ); g_xywindow_globals.color_gridback = Vector3( 1.0f, 1.0f, 1.0f ); @@ -766,7 +770,9 @@ void ColorScheme_QER(){ g_xywindow_globals.color_gridblock = Vector3( 0.0f, 0.0f, 1.0f ); g_xywindow_globals.color_gridtext = Vector3( 0.0f, 0.0f, 0.0f ); g_xywindow_globals.color_selbrushes = Vector3( 1.0f, 0.0f, 0.0f ); + XYWnd::recaptureStates(); g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); + Brush_clipperColourChanged(); g_xywindow_globals.color_brushes = Vector3( 0.0f, 0.0f, 0.0f ); SetWorldspawnColour( g_xywindow_globals.color_brushes ); g_xywindow_globals.color_viewname = Vector3( 0.5f, 0.0f, 0.75f ); @@ -778,6 +784,7 @@ void ColorScheme_Black(){ g_camwindow_globals.color_cameraback = Vector3( 0.25f, 0.25f, 0.25f ); g_camwindow_globals.color_selbrushes3d = Vector3( 1.0f, 0.0f, 0.0f ); + CamWnd_reconstructStatic(); CamWnd_Update( *g_pParentWnd->GetCamWnd() ); g_xywindow_globals.color_gridback = Vector3( 0.0f, 0.0f, 0.0f ); @@ -786,7 +793,9 @@ void ColorScheme_Black(){ g_xywindow_globals.color_gridblock = Vector3( 0.0f, 0.0f, 1.0f ); g_xywindow_globals.color_gridtext = Vector3( 1.0f, 1.0f, 1.0f ); g_xywindow_globals.color_selbrushes = Vector3( 1.0f, 0.0f, 0.0f ); + XYWnd::recaptureStates(); g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); + Brush_clipperColourChanged(); g_xywindow_globals.color_brushes = Vector3( 1.0f, 1.0f, 1.0f ); SetWorldspawnColour( g_xywindow_globals.color_brushes ); g_xywindow_globals.color_viewname = Vector3( 0.7f, 0.7f, 0.0f ); @@ -799,6 +808,7 @@ void ColorScheme_Ydnar(){ g_camwindow_globals.color_cameraback = Vector3( 0.25f, 0.25f, 0.25f ); g_camwindow_globals.color_selbrushes3d = Vector3( 1.0f, 0.0f, 0.0f ); + CamWnd_reconstructStatic(); CamWnd_Update( *g_pParentWnd->GetCamWnd() ); g_xywindow_globals.color_gridback = Vector3( 0.77f, 0.77f, 0.77f ); @@ -807,13 +817,38 @@ void ColorScheme_Ydnar(){ g_xywindow_globals.color_gridblock = Vector3( 1.0f, 1.0f, 1.0f ); g_xywindow_globals.color_gridtext = Vector3( 0.0f, 0.0f, 0.0f ); g_xywindow_globals.color_selbrushes = Vector3( 1.0f, 0.0f, 0.0f ); + XYWnd::recaptureStates(); g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); + Brush_clipperColourChanged(); g_xywindow_globals.color_brushes = Vector3( 0.0f, 0.0f, 0.0f ); SetWorldspawnColour( g_xywindow_globals.color_brushes ); g_xywindow_globals.color_viewname = Vector3( 0.5f, 0.0f, 0.75f ); XY_UpdateAllWindows(); } +void ColorScheme_Blender(){ + TextureBrowser_setBackgroundColour( GlobalTextureBrowser(), Vector3( 0.25f, 0.25f, 0.25f ) ); + + g_camwindow_globals.color_cameraback = Vector3( 0.25f, 0.25f, 0.25f ); + g_camwindow_globals.color_selbrushes3d = Vector3( 1.0f, 0.627451f, 0.0f ); + CamWnd_reconstructStatic(); + CamWnd_Update( *g_pParentWnd->GetCamWnd() ); + + g_xywindow_globals.color_gridback = Vector3( .225803f, .225803f, .225803f ); + g_xywindow_globals.color_gridminor = Vector3( .254902f, .254902f, .254902f ); + g_xywindow_globals.color_gridmajor = Vector3( .294118f, .294118f, .294118f ); + g_xywindow_globals.color_gridblock = Vector3( 1.0f, 1.0f, 1.0f ); + g_xywindow_globals.color_gridtext = Vector3( .972549f, .972549f, .972549f ); + g_xywindow_globals.color_selbrushes = Vector3( 1.0f, 0.627451f, 0.0f ); + XYWnd::recaptureStates(); + g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); + Brush_clipperColourChanged(); + g_xywindow_globals.color_brushes = Vector3( 0.0f, 0.0f, 0.0f ); + SetWorldspawnColour( g_xywindow_globals.color_brushes ); + g_xywindow_globals.color_viewname = Vector3( 0.516136f, 0.516136f, 0.516136f ); + XY_UpdateAllWindows(); +} + typedef Callback1 GetColourCallback; typedef Callback1 SetColourCallback; @@ -853,6 +888,20 @@ void BrushColour_set( const Vector3& other ){ } typedef FreeCaller1 BrushColourSetCaller; +void SelectedBrushColour_set( const Vector3& other ){ + g_xywindow_globals.color_selbrushes = other; + XYWnd::recaptureStates(); + SceneChangeNotify(); +} +typedef FreeCaller1 SelectedBrushColourSetCaller; + +void SelectedBrush3dColour_set( const Vector3& other ){ + g_camwindow_globals.color_selbrushes3d = other; + CamWnd_reconstructStatic(); + SceneChangeNotify(); +} +typedef FreeCaller1 SelectedBrush3dColourSetCaller; + void ClipperColour_set( const Vector3& other ){ g_xywindow_globals.color_clipper = other; Brush_clipperColourChanged(); @@ -896,8 +945,8 @@ ColoursMenu() : m_gridblock( ColourGetCaller( g_xywindow_globals.color_gridblock ), ColourSetCaller( g_xywindow_globals.color_gridblock ) ), m_cameraback( ColourGetCaller( g_camwindow_globals.color_cameraback ), ColourSetCaller( g_camwindow_globals.color_cameraback ) ), m_brush( ColourGetCaller( g_xywindow_globals.color_brushes ), BrushColourSetCaller() ), - m_selectedbrush( ColourGetCaller( g_xywindow_globals.color_selbrushes ), ColourSetCaller( g_xywindow_globals.color_selbrushes ) ), - m_selectedbrush3d( ColourGetCaller( g_camwindow_globals.color_selbrushes3d ), ColourSetCaller( g_camwindow_globals.color_selbrushes3d ) ), + m_selectedbrush( ColourGetCaller( g_xywindow_globals.color_selbrushes ), SelectedBrushColourSetCaller() ), + m_selectedbrush3d( ColourGetCaller( g_camwindow_globals.color_selbrushes3d ), SelectedBrush3dColourSetCaller() ), m_clipper( ColourGetCaller( g_xywindow_globals.color_clipper ), ClipperColourSetCaller() ), m_viewname( ColourGetCaller( g_xywindow_globals.color_viewname ), ColourSetCaller( g_xywindow_globals.color_viewname ) ){ } @@ -921,6 +970,7 @@ GtkMenuItem* create_colours_menu(){ create_menu_item_with_mnemonic( menu_3, "Q3Radiant Original", "ColorSchemeQER" ); create_menu_item_with_mnemonic( menu_3, "Black and Green", "ColorSchemeBlackAndGreen" ); create_menu_item_with_mnemonic( menu_3, "Maya/Max/Lightwave Emulation", "ColorSchemeYdnar" ); + create_menu_item_with_mnemonic( menu_3, "Blender/Dark", "ColorSchemeBlender" ); create_menu_item_with_mnemonic( menu_in_menu, "GTK Theme...", "gtkThemeDlg" ); create_menu_item_with_mnemonic( menu_in_menu, "OpenGL Font...", "OpenGLFont" ); @@ -3523,6 +3573,7 @@ void MainFrame_Construct(){ GlobalCommands_insert( "ColorSchemeQER", FreeCaller() ); GlobalCommands_insert( "ColorSchemeBlackAndGreen", FreeCaller() ); GlobalCommands_insert( "ColorSchemeYdnar", FreeCaller() ); + GlobalCommands_insert( "ColorSchemeBlender", FreeCaller() ); GlobalCommands_insert( "ChooseTextureBackgroundColor", makeCallback( g_ColoursMenu.m_textureback ) ); GlobalCommands_insert( "ChooseGridBackgroundColor", makeCallback( g_ColoursMenu.m_xyback ) ); GlobalCommands_insert( "ChooseGridMajorColor", makeCallback( g_ColoursMenu.m_gridmajor ) ); diff --git a/radiant/select.cpp b/radiant/select.cpp index a0c72b78..f06818d5 100644 --- a/radiant/select.cpp +++ b/radiant/select.cpp @@ -876,6 +876,15 @@ void Select_Touching( void ){ SelectByBounds::DoSelection( false ); } +void Select_ProjectTexture( const texdef_t& texdef, Vector3* direction ){ + if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) { + Scene_BrushProjectTexture_Selected( GlobalSceneGraph(), texdef, direction ); + } + Scene_BrushProjectTexture_Component_Selected( GlobalSceneGraph(), texdef, direction ); + + SceneChangeNotify(); +} + void Select_FitTexture( float horizontal, float vertical ){ if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) { Scene_BrushFitTexture_Selected( GlobalSceneGraph(), horizontal, vertical ); diff --git a/radiant/select.h b/radiant/select.h index 503a3862..ed314fc9 100644 --- a/radiant/select.h +++ b/radiant/select.h @@ -66,6 +66,8 @@ void Select_SetFlags( const ContentsFlagsValue& flags ); void Select_RotateTexture( float amt ); void Select_ScaleTexture( float x, float y ); void Select_ShiftTexture( float x, float y ); +class texdef_t; +void Select_ProjectTexture( const texdef_t& texdef, Vector3* direction ); void Select_FitTexture( float horizontal = 1, float vertical = 1 ); void FindReplaceTextures( const char* pFind, const char* pReplace, bool bSelected ); diff --git a/radiant/surfacedialog.cpp b/radiant/surfacedialog.cpp index 7ff1e8bb..c73c4d90 100644 --- a/radiant/surfacedialog.cpp +++ b/radiant/surfacedialog.cpp @@ -175,6 +175,8 @@ WindowPositionTrackerExportStringCaller m_exportPosition; float m_fitHorizontal; float m_fitVertical; +int m_projectRadio; + Increment m_hshiftIncrement; Increment m_vshiftIncrement; Increment m_hscaleIncrement; @@ -205,6 +207,7 @@ SurfaceInspector() : m_rotateIncrement( g_si_globals.rotate ){ m_fitVertical = 1; m_fitHorizontal = 1; + m_projectRadio = 0; m_positionTracker.setPosition( c_default_window_pos ); } @@ -436,6 +439,42 @@ void SurfaceInspector_toggleShown(){ } } +#include "camwindow.h" + +void SurfaceInspector_ProjectTexture(){ + UndoableCommand undo( "textureProject" ); + + texdef_t texdef; + texdef.shift[0] = static_cast( gtk_spin_button_get_value_as_float( getSurfaceInspector().m_hshiftIncrement.m_spin ) ); + texdef.shift[1] = static_cast( gtk_spin_button_get_value_as_float( getSurfaceInspector().m_vshiftIncrement.m_spin ) ); + texdef.scale[0] = static_cast( gtk_spin_button_get_value_as_float( getSurfaceInspector().m_hscaleIncrement.m_spin ) ); + texdef.scale[1] = static_cast( gtk_spin_button_get_value_as_float( getSurfaceInspector().m_vscaleIncrement.m_spin ) ); + texdef.rotate = static_cast( gtk_spin_button_get_value_as_float( getSurfaceInspector().m_rotateIncrement.m_spin ) ); + + Vector3 direction; + + if( getSurfaceInspector().m_projectRadio == 0 ){ + return Select_ProjectTexture( texdef, NULL ); + } + else if( getSurfaceInspector().m_projectRadio == 1 ){ + if( GlobalXYWnd_getCurrentViewType() == YZ ){ + direction = Vector3( 1, 0, 0 ); + } + else if( GlobalXYWnd_getCurrentViewType() == XZ ){ + direction = Vector3( 0, 1, 0 ); + } + else if( GlobalXYWnd_getCurrentViewType() == XY ){ + direction = Vector3( 0, 0, 1 ); + } + } + else if( getSurfaceInspector().m_projectRadio == 2 ){ + //direction = -g_pParentWnd->GetCamWnd()->getCamera().vpn ; + direction = -Camera_getViewVector( *g_pParentWnd->GetCamWnd() ); + } + + Select_ProjectTexture( texdef, &direction ); +} + void SurfaceInspector_FitTexture(){ UndoableCommand undo( "textureAutoFit" ); Select_FitTexture( getSurfaceInspector().m_fitHorizontal, getSurfaceInspector().m_fitVertical ); @@ -467,7 +506,7 @@ static void OnBtnPatchFit( GtkWidget *widget, gpointer data ){ Patch_FitTexture(); } -static void OnBtnAxial( GtkWidget *widget, gpointer data ){ +static void OnBtnReset( GtkWidget *widget, gpointer data ){ //globalOutputStream() << "--> [OnBtnAxial]...\n"; UndoableCommand undo( "textureDefault" ); TextureProjection projection; @@ -496,6 +535,15 @@ static void OnBtnAxial( GtkWidget *widget, gpointer data ){ Select_SetTexdef( projection ); } +static void OnBtnProject( GtkWidget *widget, gpointer data ){ + if ( g_bp_globals.m_texdefTypeId != TEXDEFTYPEID_BRUSHPRIMITIVES ) { + globalErrorStream() << "function is implemented for BRUSHPRIMITIVES map format only\n"; + return; + } + getSurfaceInspector().exportData(); + SurfaceInspector_ProjectTexture(); +} + static void OnBtnFaceFit( GtkWidget *widget, gpointer data ){ getSurfaceInspector().exportData(); SurfaceInspector_FitTexture(); @@ -850,7 +898,7 @@ GtkWindow* SurfaceInspector::BuildDialog(){ gtk_widget_show( frame ); gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( frame ), FALSE, FALSE, 0 ); { - GtkWidget* table = gtk_table_new( 4, 4, FALSE ); + GtkWidget* table = gtk_table_new( 5, 4, FALSE ); gtk_widget_show( table ); gtk_container_add( GTK_CONTAINER( frame ), table ); gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); @@ -866,7 +914,7 @@ GtkWindow* SurfaceInspector::BuildDialog(){ { GtkWidget* label = gtk_label_new( "Patch" ); gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3, + gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 3, 4, (GtkAttachOptions) ( GTK_FILL ), (GtkAttachOptions) ( 0 ), 0, 0 ); } @@ -891,13 +939,13 @@ GtkWindow* SurfaceInspector::BuildDialog(){ gtk_widget_set_usize( button, 60, -2 ); } { - GtkWidget* button = gtk_button_new_with_label( "Axial" ); + GtkWidget* button = gtk_button_new_with_label( "Reset" ); gtk_widget_show( button ); gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 1, 2, (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), (GtkAttachOptions) ( 0 ), 0, 0 ); g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnAxial ), 0 ); + G_CALLBACK( OnBtnReset ), 0 ); gtk_widget_set_usize( button, 60, -2 ); } { @@ -910,10 +958,42 @@ GtkWindow* SurfaceInspector::BuildDialog(){ G_CALLBACK( OnBtnFaceFit ), 0 ); gtk_widget_set_usize( button, 60, -2 ); } + { + GtkWidget* button = gtk_button_new_with_label( "Project" ); + gtk_widget_show( button ); + gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 2, 3, + (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions) ( 0 ), 0, 0 ); + g_signal_connect( G_OBJECT( button ), "clicked", + G_CALLBACK( OnBtnProject ), 0 ); + gtk_widget_set_usize( button, 60, -2 ); + } + { + //radio button group for choosing projection style + GtkWidget* radAxial = gtk_radio_button_new_with_label( NULL, "Axial" ); + gtk_widget_set_tooltip_text( radAxial, "Axial projection (along nearest axis)" ); + gtk_widget_show( radAxial ); + gtk_table_attach( GTK_TABLE( table ), radAxial, 1, 2, 2, 3, + ( GtkAttachOptions )( GTK_EXPAND | GTK_FILL ), + ( GtkAttachOptions )( 0 ), 0, 0 ); + GtkWidget* rad = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( radAxial ), "Ortho" ); + gtk_widget_set_tooltip_text( rad, "Project along active ortho view" ); + gtk_widget_show( rad ); + gtk_table_attach( GTK_TABLE( table ), rad, 2, 3, 2, 3, + ( GtkAttachOptions )( GTK_EXPAND | GTK_FILL ), + ( GtkAttachOptions )( 0 ), 0, 0 ); + rad = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( radAxial ), "Cam" ); + gtk_widget_set_tooltip_text( rad, "Project along camera view direction" ); + gtk_widget_show( rad ); + gtk_table_attach( GTK_TABLE( table ), rad, 3, 4, 2, 3, + ( GtkAttachOptions )( GTK_EXPAND | GTK_FILL ), + ( GtkAttachOptions )( 0 ), 0, 0 ); + AddDialogData( *GTK_RADIO_BUTTON( radAxial ), m_projectRadio ); + } { GtkWidget* button = gtk_button_new_with_label( "CAP" ); gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 3, 4, + gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 4, 5, (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), (GtkAttachOptions) ( 0 ), 0, 0 ); g_signal_connect( G_OBJECT( button ), "clicked", @@ -923,7 +1003,7 @@ GtkWindow* SurfaceInspector::BuildDialog(){ { GtkWidget* button = gtk_button_new_with_label( "Set..." ); gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 1, 2, 3, 4, + gtk_table_attach( GTK_TABLE( table ), button, 1, 2, 4, 5, (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), (GtkAttachOptions) ( 0 ), 0, 0 ); g_signal_connect( G_OBJECT( button ), "clicked", @@ -933,7 +1013,7 @@ GtkWindow* SurfaceInspector::BuildDialog(){ { GtkWidget* button = gtk_button_new_with_label( "Natural" ); gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 2, 3, 3, 4, + gtk_table_attach( GTK_TABLE( table ), button, 2, 3, 4, 5, (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), (GtkAttachOptions) ( 0 ), 0, 0 ); g_signal_connect( G_OBJECT( button ), "clicked", @@ -943,7 +1023,7 @@ GtkWindow* SurfaceInspector::BuildDialog(){ { GtkWidget* button = gtk_button_new_with_label( "Fit" ); gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 3, 4, 3, 4, + gtk_table_attach( GTK_TABLE( table ), button, 3, 4, 4, 5, (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), (GtkAttachOptions) ( 0 ), 0, 0 ); g_signal_connect( G_OBJECT( button ), "clicked", diff --git a/radiant/xywindow.cpp b/radiant/xywindow.cpp index 6cd80183..974cda1d 100644 --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@ -2784,6 +2784,12 @@ void XYWnd::XY_Draw(){ glRasterPos3f( 2.f, GlobalOpenGL().m_font->getPixelDescent() + 1.f, 0.0f ); extern const char* Renderer_GetStats(); GlobalOpenGL().drawString( Renderer_GetStats() ); + + //globalOutputStream() << m_render_time.elapsed_msec() << "\n"; + StringOutputStream stream; + stream << " | f2f: " << m_render_time.elapsed_msec(); + GlobalOpenGL().drawString( stream.c_str() ); + m_render_time.start(); } GlobalOpenGL_debugAssertNoErrors(); diff --git a/radiant/xywindow.h b/radiant/xywindow.h index 5492b45b..e1183f50 100644 --- a/radiant/xywindow.h +++ b/radiant/xywindow.h @@ -65,6 +65,8 @@ inline const char* ViewType_getTitle( VIEWTYPE viewtype ){ return ""; } +#include "timer.h" + class XYWnd { GtkWidget* m_gl_widget; @@ -92,6 +94,10 @@ WindowPositionTracker m_positionTracker; static void captureStates(); static void releaseStates(); +static void recaptureStates(){ + releaseStates(); + captureStates(); +} void PositionView( const Vector3& position ); const Vector3& GetOrigin(); @@ -212,6 +218,8 @@ void PaintSizeInfo( int nDim1, int nDim2, Vector3& vMinBounds, Vector3& vMaxBoun int m_entityCreate_x, m_entityCreate_y; bool m_entityCreate; +Timer m_render_time; + public: void OnContextMenu(); void ButtonState_onMouseDown( unsigned int buttons ){