diff --git a/include/iselection.h b/include/iselection.h index a5e78b99..4f1cf203 100644 --- a/include/iselection.h +++ b/include/iselection.h @@ -90,6 +90,7 @@ enum EManipulatorMode eSkew, eDrag, eClip, + eBuild, }; virtual void SetMode( EMode mode ) = 0; diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index a06c0955..3de798e9 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -1429,6 +1429,10 @@ void ClipperToolExport( const BoolImportCallback& importCallback ){ importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip ); } +void BuildToolExport( const BoolImportCallback& importCallback ){ + importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eBuild ); +} + FreeCaller1 g_translatemode_button_caller; BoolExportCallback g_translatemode_button_callback( g_translatemode_button_caller ); ToggleItem g_translatemode_button( g_translatemode_button_callback ); @@ -1453,6 +1457,10 @@ FreeCaller1 g_clipper_button_calle BoolExportCallback g_clipper_button_callback( g_clipper_button_caller ); ToggleItem g_clipper_button( g_clipper_button_callback ); +FreeCaller1 g_build_button_caller; +BoolExportCallback g_build_button_callback( g_build_button_caller ); +ToggleItem g_build_button( g_build_button_callback ); + void ToolChanged(){ g_translatemode_button.update(); g_rotatemode_button.update(); @@ -1460,6 +1468,7 @@ void ToolChanged(){ g_skewmode_button.update(); g_dragmode_button.update(); g_clipper_button.update(); + g_build_button.update(); } const char* const c_ResizeMode_status = "QE4 Drag Tool: move and resize objects"; @@ -1556,7 +1565,6 @@ void SkewMode(){ const char* const c_ClipperMode_status = "Clipper Tool: apply clip planes to brushes"; - void ClipperMode(){ if ( g_currentToolMode == ClipperMode && g_defaultToolMode != ClipperMode ) { g_defaultToolMode(); @@ -1577,6 +1585,28 @@ void ClipperMode(){ } +const char* const c_BuildMode_status = "Build Tool: extrude, build chains, clone"; + +void BuildMode(){ + if ( g_currentToolMode == BuildMode && g_defaultToolMode != BuildMode ) { + g_defaultToolMode(); + } + else + { + g_currentToolMode = BuildMode; + g_currentToolModeSupportsComponentEditing = false; + + SelectionSystem_DefaultMode(); + ComponentModeChanged(); + + Sys_Status( c_BuildMode_status ); + GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eBuild ); + ToolChanged(); + ModeChangeNotify(); + } +} + + void ToggleRotateScaleModes(){ return g_currentToolMode == RotateMode? ScaleMode() : RotateMode(); } @@ -2347,22 +2377,27 @@ void PatchInspector_registerShortcuts(){ } void Patch_registerShortcuts(){ -// command_connect_accelerator( "InvertCurveTextureX" ); -// command_connect_accelerator( "InvertCurveTextureY" ); -// command_connect_accelerator( "PatchInsertInsertColumn" ); -// command_connect_accelerator( "PatchInsertInsertRow" ); -// command_connect_accelerator( "PatchDeleteLastColumn" ); -// command_connect_accelerator( "PatchDeleteLastRow" ); -// command_connect_accelerator( "NaturalizePatch" ); - //command_connect_accelerator("CapCurrentCurve"); + command_connect_accelerator( "InvertCurveTextureX" ); + command_connect_accelerator( "InvertCurveTextureY" ); + command_connect_accelerator( "PatchInsertInsertColumn" ); + command_connect_accelerator( "PatchInsertInsertRow" ); + command_connect_accelerator( "PatchDeleteLastColumn" ); + command_connect_accelerator( "PatchDeleteLastRow" ); + command_connect_accelerator( "NaturalizePatch" ); + command_connect_accelerator( "CapCurrentCurve" ); } void Manipulators_registerShortcuts(){ toggle_add_accelerator( "MouseRotate" ); toggle_add_accelerator( "MouseTranslate" ); toggle_add_accelerator( "MouseScale" ); + toggle_add_accelerator( "MouseTransform" ); toggle_add_accelerator( "MouseDrag" ); toggle_add_accelerator( "ToggleClipper" ); + toggle_add_accelerator( "MouseBuild" ); + + command_connect_accelerator( "MouseRotateOrScale" ); + command_connect_accelerator( "MouseDragOrTransform" ); } void TexdefNudge_registerShortcuts(){ @@ -2379,14 +2414,12 @@ void TexdefNudge_registerShortcuts(){ } void SelectNudge_registerShortcuts(){ - //command_connect_accelerator( "MoveSelectionDOWN" ); - //command_connect_accelerator( "MoveSelectionUP" ); - //command_connect_accelerator("SelectNudgeLeft"); - //command_connect_accelerator("SelectNudgeRight"); - //command_connect_accelerator("SelectNudgeUp"); - //command_connect_accelerator("SelectNudgeDown"); - command_connect_accelerator( "UnSelectSelection2" ); - command_connect_accelerator( "DeleteSelection2" ); + command_connect_accelerator( "MoveSelectionDOWN" ); + command_connect_accelerator( "MoveSelectionUP" ); + command_connect_accelerator( "SelectNudgeLeft" ); + command_connect_accelerator( "SelectNudgeRight" ); + command_connect_accelerator( "SelectNudgeUp" ); + command_connect_accelerator( "SelectNudgeDown" ); } void SnapToGrid_registerShortcuts(){ @@ -2413,21 +2446,22 @@ void TexBro_registerShortcuts(){ void Misc_registerShortcuts(){ command_connect_accelerator( "RefreshReferences" ); //refresh models - command_connect_accelerator( "MouseRotateOrScale" ); - command_connect_accelerator( "MouseDragOrTransform" ); + command_connect_accelerator( "UnSelectSelection2" ); + command_connect_accelerator( "DeleteSelection2" ); + } void register_shortcuts(){ // PatchInspector_registerShortcuts(); - //Patch_registerShortcuts(); +// Patch_registerShortcuts(); Grid_registerShortcuts(); // XYWnd_registerShortcuts(); CamWnd_registerShortcuts(); Manipulators_registerShortcuts(); SurfaceInspector_registerShortcuts(); TexdefNudge_registerShortcuts(); - SelectNudge_registerShortcuts(); +// SelectNudge_registerShortcuts(); // SnapToGrid_registerShortcuts(); // SelectByType_registerShortcuts(); TexBro_registerShortcuts(); @@ -2477,11 +2511,6 @@ void ComponentModes_constructToolbar( GtkToolbar* toolbar ){ toolbar_append_toggle_button( toolbar, "Select Faces (F)", "modify_faces.png", "DragFaces" ); } -void Clipper_constructToolbar( GtkToolbar* toolbar ){ - - toolbar_append_toggle_button( toolbar, "Clipper (X)", "select_clipper.png", "ToggleClipper" ); -} - void XYWnd_constructToolbar( GtkToolbar* toolbar ){ toolbar_append_button( toolbar, "Change views (CTRL + TAB)", "view_change.png", "NextView" ); } @@ -2492,8 +2521,8 @@ void Manipulators_constructToolbar( GtkToolbar* toolbar ){ toolbar_append_toggle_button( toolbar, "Scale", "select_mousescale.png", "MouseScale" ); toolbar_append_toggle_button( toolbar, "Transform (Q)", "select_mousetransform.png", "MouseTransform" ); toolbar_append_toggle_button( toolbar, "Resize (Q)", "select_mouseresize.png", "MouseDrag" ); - - Clipper_constructToolbar( toolbar ); + toolbar_append_toggle_button( toolbar, "Clipper (X)", "select_clipper.png", "ToggleClipper" ); +// toolbar_append_toggle_button( toolbar, "Build (B)", "select_mouserotate.png", "MouseBuild" ); } GtkToolbar* create_main_toolbar( MainFrame::EViewStyle style ){ @@ -3543,6 +3572,7 @@ void MainFrame_Construct(){ GlobalToggles_insert( "MouseScale", FreeCaller(), ToggleItem::AddCallbackCaller( g_scalemode_button ) ); GlobalToggles_insert( "MouseTransform", FreeCaller(), ToggleItem::AddCallbackCaller( g_skewmode_button ) ); GlobalToggles_insert( "MouseDrag", FreeCaller(), ToggleItem::AddCallbackCaller( g_dragmode_button ) ); + GlobalToggles_insert( "MouseBuild", FreeCaller(), ToggleItem::AddCallbackCaller( g_build_button ), Accelerator( 'B' ) ); GlobalCommands_insert( "MouseRotateOrScale", FreeCaller() ); GlobalCommands_insert( "MouseDragOrTransform", FreeCaller(), Accelerator( 'Q' ) ); diff --git a/radiant/selection.cpp b/radiant/selection.cpp index babc48cc..5b5b89e7 100644 --- a/radiant/selection.cpp +++ b/radiant/selection.cpp @@ -207,9 +207,19 @@ public: virtual void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ) = 0; virtual void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ) = 0; static const View* m_view; +static float m_device_point[2]; static float m_device_epsilon[2]; +static void assign_static( const View& view, const float device_point[2], const float device_epsilon[2] ){ + m_view = &view; + m_device_point[0] = device_point[0]; + m_device_point[1] = device_point[1]; + m_device_epsilon[0] = device_epsilon[0]; + m_device_epsilon[1] = device_epsilon[1]; + +} }; -const View* Manipulatable::m_view; +const View* Manipulatable::m_view = 0; +float Manipulatable::m_device_point[2]; float Manipulatable::m_device_epsilon[2]; void transform_local2object( Matrix4& object, const Matrix4& local, const Matrix4& local2object ){ @@ -4191,6 +4201,95 @@ Shader* ClipManipulator::m_state; +class BuildManipulator : public Manipulator, public Manipulatable +{ + struct RenderableLine : public OpenGLRenderable { + PointVertex m_line[2]; + + RenderableLine() { + } + void render( RenderStateFlags state ) const { + glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_line[0].colour ); + glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_line[0].vertex ); + glDrawArrays( GL_LINES, 0, 2 ); + } + void setColour( const Colour4b& colour ) { + m_line[0].colour = colour; + m_line[1].colour = colour; + } + }; + struct RenderablePoint : public OpenGLRenderable + { + PointVertex m_point; + RenderablePoint(): + m_point( vertex3f_identity ) { + } + void render( RenderStateFlags state ) const { + glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_point.colour ); + glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_point.vertex ); + glDrawArrays( GL_POINTS, 0, 1 ); + } + void setColour( const Colour4b & colour ) { + m_point.colour = colour; + } + }; + bool m_isSelected; + bool m_isInitialised; + RenderablePoint m_point; + RenderableLine m_line; + RenderableLine m_midline; +public: + static Shader* m_state_point; + static Shader* m_state_line; + + BuildManipulator() : m_isSelected( false ), m_isInitialised( false ) { + m_point.setColour( g_colour_selected ); + m_line.setColour( g_colour_selected ); + m_midline.setColour( g_colour_screen ); + } + void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& pivot2world ) { + renderer.SetState( m_state_point, Renderer::eWireframeOnly ); + renderer.SetState( m_state_point, Renderer::eFullMaterials ); + renderer.addRenderable( m_point, g_matrix4_identity ); + renderer.SetState( m_state_line, Renderer::eWireframeOnly ); + renderer.SetState( m_state_line, Renderer::eFullMaterials ); + renderer.addRenderable( m_line, g_matrix4_identity ); + renderer.addRenderable( m_midline, g_matrix4_identity ); + } + void initialise(){ + } + void highlight( const View& view ){ + SceneChangeNotify(); + } + + void testSelect( const View& view, const Matrix4& pivot2world ) { + m_isSelected = true; + } + /* Manipulatable */ + void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){ + //do things with undo + } + void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){ + } + + Manipulatable* GetManipulatable() { + m_isSelected = false; //don't handle the manipulator move part void MoveSelected() + return this; + } + + void setSelected( bool select ) { + m_isSelected = select; + } + bool isSelected() const { + return m_isSelected; + } +}; +Shader* BuildManipulator::m_state_point; +Shader* BuildManipulator::m_state_line; + + + + class TransformOriginTranslatable { public: @@ -4422,6 +4521,7 @@ ScaleManipulator m_scale_manipulator; SkewManipulator m_skew_manipulator; DragManipulator m_drag_manipulator; ClipManipulator m_clip_manipulator; +BuildManipulator m_build_manipulator; mutable TransformOriginManipulator m_transformOrigin_manipulator; typedef SelectionList selection_t; @@ -4524,6 +4624,11 @@ void SetManipulatorMode( EManipulatorMode mode ){ case eSkew: m_manipulator = &m_skew_manipulator; break; case eDrag: m_manipulator = &m_drag_manipulator; break; case eClip: m_manipulator = &m_clip_manipulator; break; + case eBuild: + { + m_build_manipulator.initialise(); + m_manipulator = &m_build_manipulator; break; + } } pivotChanged(); } @@ -4629,13 +4734,11 @@ void startMove(){ bool SelectManipulator( const View& view, const float device_point[2], const float device_epsilon[2] ){ bool movingOrigin = false; - if ( !nothingSelected() || ManipulatorMode() == eDrag || ManipulatorMode() == eClip ) { + if ( !nothingSelected() || ManipulatorMode() == eDrag || ManipulatorMode() == eClip || ManipulatorMode() == eBuild ) { #if defined ( DEBUG_SELECTION ) g_render_clipped.destroy(); #endif - Manipulatable::m_view = &view; //this b4 m_manipulator calls! - Manipulatable::m_device_epsilon[0] = device_epsilon[0]; - Manipulatable::m_device_epsilon[1] = device_epsilon[1]; + Manipulatable::assign_static( view, device_point, device_epsilon ); //this b4 m_manipulator calls! m_transformOrigin_manipulator.setSelected( false ); m_manipulator->setSelected( false ); @@ -4681,7 +4784,9 @@ bool SelectManipulator( const View& view, const float device_point[2], const flo } void HighlightManipulator( const View& view, const float device_point[2], const float device_epsilon[2] ){ - if ( ( !nothingSelected() && transformOrigin_isTranslatable() ) || ManipulatorMode() == eClip ) { + Manipulatable::assign_static( view, device_point, device_epsilon ); //this b4 m_manipulator calls! + + if ( ( !nothingSelected() && transformOrigin_isTranslatable() ) || ManipulatorMode() == eClip || ManipulatorMode() == eBuild ) { #if defined ( DEBUG_SELECTION ) g_render_clipped.destroy(); #endif @@ -4701,6 +4806,9 @@ void HighlightManipulator( const View& view, const float device_point[2], const else if( ManipulatorMode() == eClip ){ m_clip_manipulator.testSelect_points( scissored ); } + else if( ManipulatorMode() == eBuild ){ + m_build_manipulator.highlight( scissored ); + } } } @@ -5125,12 +5233,14 @@ static void constructStatic(){ m_state = GlobalShaderCache().capture( "$POINT" ); TranslateManipulator::m_state_wire = RotateManipulator::m_state_outer = - SkewManipulator::m_state_wire = GlobalShaderCache().capture( "$WIRE_OVERLAY" ); + SkewManipulator::m_state_wire = + BuildManipulator::m_state_line = GlobalShaderCache().capture( "$WIRE_OVERLAY" ); TranslateManipulator::m_state_fill = SkewManipulator::m_state_fill = GlobalShaderCache().capture( "$FLATSHADE_OVERLAY" ); TransformOriginManipulator::m_state = ClipManipulator::m_state = - SkewManipulator::m_state_point = GlobalShaderCache().capture( "$BIGPOINT" ); + SkewManipulator::m_state_point = + BuildManipulator::m_state_point = GlobalShaderCache().capture( "$BIGPOINT" ); } static void destroyStatic(){ @@ -5575,7 +5685,7 @@ AABB RadiantSelectionSystem::getSelectionAABB() const { void RadiantSelectionSystem::renderSolid( Renderer& renderer, const VolumeTest& volume ) const { //if(view->TestPoint(m_object_pivot)) - if ( !nothingSelected() || ManipulatorMode() == eClip ) { + if ( !nothingSelected() || ManipulatorMode() == eClip || ManipulatorMode() == eBuild ) { renderer.Highlight( Renderer::ePrimitive, false ); renderer.Highlight( Renderer::eFace, false ); @@ -6057,7 +6167,8 @@ void onMouseUp( const WindowVector& position, ButtonIdentifier button, ModifierF && !m_selector.m_mouseMovedWhilePressed && !m_manipulator.m_moving_transformOrigin && !( getSelectionSystem().Mode() == SelectionSystem::eComponent && getSelectionSystem().ManipulatorMode() == SelectionSystem::eDrag ) - && getSelectionSystem().ManipulatorMode() != SelectionSystem::eClip ){ + && getSelectionSystem().ManipulatorMode() != SelectionSystem::eClip + && getSelectionSystem().ManipulatorMode() != SelectionSystem::eBuild ){ m_selector.testSelect_simpleM1( device( position ) ); } if( getSelectionSystem().ManipulatorMode() == SelectionSystem::eClip )