1 /* 2 Copyright (C) 2010-2014 Kristian Duske 3 4 This file is part of TrenchBroom. 5 6 TrenchBroom is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 TrenchBroom is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "ResizeBrushesToolController.h" 21 22 #include "PreferenceManager.h" 23 #include "Preferences.h" 24 #include "Reference.h" 25 #include "Model/BrushFace.h" 26 #include "Model/BrushGeometry.h" 27 #include "Model/HitQuery.h" 28 #include "Model/PickResult.h" 29 #include "Renderer/RenderContext.h" 30 #include "Renderer/VertexArray.h" 31 #include "Renderer/VertexSpec.h" 32 #include "View/InputState.h" 33 #include "View/ResizeBrushesTool.h" 34 35 #include <cassert> 36 37 namespace TrenchBroom { 38 namespace View { ResizeBrushesToolController(ResizeBrushesTool * tool)39 ResizeBrushesToolController::ResizeBrushesToolController(ResizeBrushesTool* tool) : 40 m_tool(tool) { 41 assert(m_tool != NULL); 42 } 43 ~ResizeBrushesToolController()44 ResizeBrushesToolController::~ResizeBrushesToolController() {} 45 doGetTool()46 Tool* ResizeBrushesToolController::doGetTool() { 47 return m_tool; 48 } 49 doPick(const InputState & inputState,Model::PickResult & pickResult)50 void ResizeBrushesToolController::doPick(const InputState& inputState, Model::PickResult& pickResult) { 51 if (handleInput(inputState)) { 52 const Model::Hit hit = doPick(inputState.pickRay(), pickResult); 53 if (hit.isMatch()) 54 pickResult.addHit(hit); 55 } 56 } 57 doModifierKeyChange(const InputState & inputState)58 void ResizeBrushesToolController::doModifierKeyChange(const InputState& inputState) { 59 updateDragFaces(inputState); 60 } 61 doMouseMove(const InputState & inputState)62 void ResizeBrushesToolController::doMouseMove(const InputState& inputState) { 63 if (handleInput(inputState)) 64 updateDragFaces(inputState); 65 } 66 doStartMouseDrag(const InputState & inputState)67 bool ResizeBrushesToolController::doStartMouseDrag(const InputState& inputState) { 68 if (!handleInput(inputState)) 69 return false; 70 const bool split = inputState.modifierKeysDown(ModifierKeys::MKCtrlCmd); 71 if (m_tool->beginResize(inputState.pickResult(), split)) { 72 updateDragFaces(inputState); 73 return true; 74 } 75 return false; 76 } 77 doMouseDrag(const InputState & inputState)78 bool ResizeBrushesToolController::doMouseDrag(const InputState& inputState) { 79 return m_tool->resize(inputState.pickRay(), inputState.camera()); 80 } 81 doEndMouseDrag(const InputState & inputState)82 void ResizeBrushesToolController::doEndMouseDrag(const InputState& inputState) { 83 m_tool->commitResize(); 84 } 85 doCancelMouseDrag()86 void ResizeBrushesToolController::doCancelMouseDrag() { 87 m_tool->cancelResize(); 88 } 89 doSetRenderOptions(const InputState & inputState,Renderer::RenderContext & renderContext) const90 void ResizeBrushesToolController::doSetRenderOptions(const InputState& inputState, Renderer::RenderContext& renderContext) const { 91 if (thisToolDragging()) 92 renderContext.setForceShowSelectionGuide(); 93 // TODO: force rendering of all other map views if the input applies and the tool has drag faces 94 } 95 doRender(const InputState & inputState,Renderer::RenderContext & renderContext,Renderer::RenderBatch & renderBatch)96 void ResizeBrushesToolController::doRender(const InputState& inputState, Renderer::RenderContext& renderContext, Renderer::RenderBatch& renderBatch) { 97 if (m_tool->hasDragFaces()) { 98 Renderer::DirectEdgeRenderer edgeRenderer = buildEdgeRenderer(); 99 edgeRenderer.renderOnTop(renderBatch, pref(Preferences::ResizeHandleColor)); 100 } 101 } 102 buildEdgeRenderer()103 Renderer::DirectEdgeRenderer ResizeBrushesToolController::buildEdgeRenderer() { 104 typedef Renderer::VertexSpecs::P3::Vertex Vertex; 105 Vertex::List vertices; 106 107 const Model::BrushFaceList& dragFaces = m_tool->dragFaces(); 108 Model::BrushFaceList::const_iterator faceIt, faceEnd; 109 Model::BrushFace::EdgeList::const_iterator edgeIt, edgeEnd; 110 for (faceIt = dragFaces.begin(), faceEnd = dragFaces.end(); faceIt != faceEnd; ++faceIt) { 111 const Model::BrushFace* face = *faceIt; 112 const Model::BrushFace::EdgeList edges = face->edges(); 113 for (edgeIt = edges.begin(), edgeEnd = edges.end(); edgeIt != edgeEnd; ++edgeIt) { 114 const Model::BrushEdge* edge = *edgeIt; 115 vertices.push_back(Vertex(edge->firstVertex()->position())); 116 vertices.push_back(Vertex(edge->secondVertex()->position())); 117 } 118 } 119 120 return Renderer::DirectEdgeRenderer(Renderer::VertexArray::swap(vertices), GL_LINES); 121 } 122 doCancel()123 bool ResizeBrushesToolController::doCancel() { 124 return false; 125 } 126 updateDragFaces(const InputState & inputState)127 void ResizeBrushesToolController::updateDragFaces(const InputState& inputState) { 128 if (!anyToolDragging(inputState)) 129 m_tool->updateDragFaces(inputState.pickResult()); 130 } 131 handleInput(const InputState & inputState) const132 bool ResizeBrushesToolController::handleInput(const InputState& inputState) const { 133 return ((inputState.modifierKeysPressed(ModifierKeys::MKShift) || 134 inputState.modifierKeysPressed(ModifierKeys::MKShift | ModifierKeys::MKCtrlCmd)) && 135 m_tool->applies()); 136 } 137 ResizeBrushesToolController2D(ResizeBrushesTool * tool)138 ResizeBrushesToolController2D::ResizeBrushesToolController2D(ResizeBrushesTool* tool) : 139 ResizeBrushesToolController(tool) {} 140 doPick(const Ray3 & pickRay,const Model::PickResult & pickResult)141 Model::Hit ResizeBrushesToolController2D::doPick(const Ray3& pickRay, const Model::PickResult& pickResult) { 142 return m_tool->pick2D(pickRay, pickResult); 143 } 144 ResizeBrushesToolController3D(ResizeBrushesTool * tool)145 ResizeBrushesToolController3D::ResizeBrushesToolController3D(ResizeBrushesTool* tool) : 146 ResizeBrushesToolController(tool) {} 147 doPick(const Ray3 & pickRay,const Model::PickResult & pickResult)148 Model::Hit ResizeBrushesToolController3D::doPick(const Ray3& pickRay, const Model::PickResult& pickResult) { 149 return m_tool->pick3D(pickRay, pickResult); 150 } 151 } 152 } 153