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 "CreateSimpleBrushToolController3D.h" 21 22 #include "PreferenceManager.h" 23 #include "Preferences.h" 24 #include "Model/Brush.h" 25 #include "Model/BrushFace.h" 26 #include "Model/BrushGeometry.h" 27 #include "Model/HitAdapter.h" 28 #include "Model/HitQuery.h" 29 #include "Model/PickResult.h" 30 #include "Renderer/Camera.h" 31 #include "Renderer/RenderService.h" 32 #include "View/CreateSimpleBrushTool.h" 33 #include "View/Grid.h" 34 #include "View/InputState.h" 35 #include "View/MapDocument.h" 36 37 #include <cassert> 38 39 namespace TrenchBroom { 40 namespace View { CreateSimpleBrushToolController3D(CreateSimpleBrushTool * tool,MapDocumentWPtr document)41 CreateSimpleBrushToolController3D::CreateSimpleBrushToolController3D(CreateSimpleBrushTool* tool, MapDocumentWPtr document) : 42 m_tool(tool), 43 m_document(document) { 44 assert(tool != NULL); 45 } 46 doGetTool()47 Tool* CreateSimpleBrushToolController3D::doGetTool() { 48 return m_tool; 49 } 50 doModifierKeyChange(const InputState & inputState)51 void CreateSimpleBrushToolController3D::doModifierKeyChange(const InputState& inputState) { 52 if (thisToolDragging()) { 53 if (inputState.modifierKeys() == ModifierKeys::MKAlt) { 54 setRestricter(inputState, new LineDragRestricter(Line3(curPoint(), Vec3::PosZ)), true); 55 } else { 56 setRestricter(inputState, new PlaneDragRestricter(horizontalDragPlane(curPoint())), true); 57 } 58 } 59 } 60 doStartDrag(const InputState & inputState)61 RestrictedDragPolicy::DragInfo CreateSimpleBrushToolController3D::doStartDrag(const InputState& inputState) { 62 if (!inputState.mouseButtonsPressed(MouseButtons::MBLeft)) 63 return DragInfo(); 64 if (!inputState.modifierKeysPressed(ModifierKeys::MKNone)) 65 return DragInfo(); 66 67 MapDocumentSPtr document = lock(m_document); 68 if (document->hasSelection()) 69 return DragInfo(); 70 71 const Model::PickResult& pickResult = inputState.pickResult(); 72 const Model::Hit& hit = pickResult.query().pickable().type(Model::Brush::BrushHit).occluded().first(); 73 if (hit.isMatch()) 74 m_initialPoint = hit.hitPoint(); 75 else 76 m_initialPoint = inputState.defaultPointUnderMouse(); 77 78 updateBounds(m_initialPoint); 79 refreshViews(); 80 81 82 const Plane3 plane = Plane3(m_initialPoint, Vec3::PosZ); 83 return DragInfo(new PlaneDragRestricter(plane), new NoDragSnapper(), m_initialPoint); 84 } 85 doDrag(const InputState & inputState,const Vec3 & lastPoint,const Vec3 & curPoint)86 RestrictedDragPolicy::DragResult CreateSimpleBrushToolController3D::doDrag(const InputState& inputState, const Vec3& lastPoint, const Vec3& curPoint) { 87 updateBounds(curPoint); 88 refreshViews(); 89 return DR_Continue; 90 } 91 doEndDrag(const InputState & inputState)92 void CreateSimpleBrushToolController3D::doEndDrag(const InputState& inputState) { 93 m_tool->createBrush(); 94 } 95 doCancelDrag()96 void CreateSimpleBrushToolController3D::doCancelDrag() { 97 m_tool->cancel(); 98 } 99 doSetRenderOptions(const InputState & inputState,Renderer::RenderContext & renderContext) const100 void CreateSimpleBrushToolController3D::doSetRenderOptions(const InputState& inputState, Renderer::RenderContext& renderContext) const {} 101 doRender(const InputState & inputState,Renderer::RenderContext & renderContext,Renderer::RenderBatch & renderBatch)102 void CreateSimpleBrushToolController3D::doRender(const InputState& inputState, Renderer::RenderContext& renderContext, Renderer::RenderBatch& renderBatch) { 103 m_tool->render(renderContext, renderBatch); 104 } 105 doCancel()106 bool CreateSimpleBrushToolController3D::doCancel() { 107 return false; 108 } 109 updateBounds(const Vec3 & point)110 void CreateSimpleBrushToolController3D::updateBounds(const Vec3& point) { 111 BBox3 bounds; 112 bounds.min = min(m_initialPoint, point); 113 bounds.max = max(m_initialPoint, point); 114 115 MapDocumentSPtr document = lock(m_document); 116 const Grid& grid = document->grid(); 117 118 // prevent flickering due to very small rounding errors 119 bounds.min.correct(); 120 bounds.max.correct(); 121 122 bounds.min = grid.snapDown(bounds.min); 123 bounds.max = grid.snapUp(bounds.max); 124 125 for (size_t i = 0; i < 3; i++) 126 if (bounds.max[i] <= bounds.min[i]) 127 bounds.max[i] = bounds.min[i] + grid.actualSize(); 128 129 m_tool->update(bounds); 130 } 131 } 132 } 133