!XT (BREAK-16) (Sandbox) Remove double-newlines at the end of files.
[CRYENGINE.git] / Code / Sandbox / Plugins / CryDesigner / Tools / Shape / BoxTool.cpp
blob4e57212137601a633a9c19efc41969784e07b3cd
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "StdAfx.h"
4 #include "BoxTool.h"
5 #include "DesignerEditor.h"
6 #include "Tools/Select/SelectTool.h"
7 #include "Viewport.h"
8 #include "Util/HeightManipulator.h"
9 #include "Util/ExtrusionSnappingHelper.h"
10 #include "ToolFactory.h"
11 #include "Core/Helper.h"
12 #include "DesignerSession.h"
14 namespace Designer
16 void BoxTool::Serialize(Serialization::IArchive& ar)
18 __super::Serialize(ar);
19 m_BoxParameter.Serialize(ar);
22 void BoxTool::OnLButtonDownAboutPlaceStartingPointPhase(CViewport* view, UINT nFlags, CPoint point)
24 __super::OnLButtonDownAboutPlaceStartingPointPhase(view, nFlags, point);
26 StoreSeparateStatus();
27 m_BoxParameter.m_Height = 0;
28 s_SnappingHelper.Init(GetModel());
31 bool BoxTool::OnLButtonDown(CViewport* view, UINT nFlags, CPoint point)
33 __super::OnLButtonDown(view, nFlags, point);
35 if (m_Phase == eBoxPhase_RaiseHeight)
36 m_Phase = eBoxPhase_Done;
38 return true;
41 bool BoxTool::OnLButtonUp(CViewport* view, UINT nFlags, CPoint point)
43 if (m_Phase == eBoxPhase_DrawRectangle)
45 if (std::abs(GetCurrentSpotPos().x - GetStartSpotPos().x) > (BrushFloat)0.01 ||
46 std::abs(GetCurrentSpotPos().y - GetStartSpotPos().y) > (BrushFloat)0.01 ||
47 std::abs(GetCurrentSpotPos().z - GetStartSpotPos().z) > (BrushFloat)0.01)
49 m_Phase = eBoxPhase_RaiseHeight;
50 s_SnappingHelper.SearchForOppositePolygons(m_pCapPolygon);
51 m_pCapPolygon = NULL;
52 m_bIsOverOpposite = false;
53 s_HeightManipulator.Init(GetPlane(), GetCurrentSpotPos());
57 return true;
60 bool BoxTool::OnMouseMove(CViewport* view, UINT nFlags, CPoint point)
62 __super::OnMouseMove(view, nFlags, point);
64 if (m_Phase == eBoxPhase_RaiseHeight)
66 m_BoxParameter.m_Height = (float)s_HeightManipulator.Update(GetWorldTM(), view, GetDesigner()->GetRay());
68 if (m_BoxParameter.m_Height < (float)kInitialPrimitiveHeight)
69 m_BoxParameter.m_Height = 0;
71 if (m_BoxParameter.m_bAlignment)
73 PolygonPtr pAlignedPolygon = s_SnappingHelper.FindAlignedPolygon(m_pCapPolygon, GetWorldTM(), view, point);
74 if (pAlignedPolygon)
75 m_BoxParameter.m_Height = (float)(GetPlane().Distance() - pAlignedPolygon->GetPlane().Distance());
78 UpdateShapeWithBoundaryCheck();
81 return true;
84 void BoxTool::UpdateShapeWithBoundaryCheck(bool bUpdateUIs)
86 UpdateShape(bUpdateUIs);
87 m_bIsOverOpposite = m_pCapPolygon && s_SnappingHelper.IsOverOppositePolygon(m_pCapPolygon, ePP_Pull);
88 if (m_bIsOverOpposite)
90 m_BoxParameter.m_Height = (float)s_SnappingHelper.GetNearestDistanceToOpposite(ePP_Pull);
91 UpdateShape(bUpdateUIs);
95 void BoxTool::UpdateShape(bool bUpdateUIs)
97 std::vector<PolygonPtr> polygonList;
99 m_v[0] = GetStartSpotPos();
100 m_v[1] = GetCurrentSpotPos();
102 BrushVec2 p0 = GetPlane().W2P(m_v[0]);
103 BrushVec2 p1 = GetPlane().W2P(m_v[1]);
105 std::vector<BrushVec3> vList(4);
106 vList[0] = m_v[0];
107 vList[1] = GetPlane().P2W(BrushVec2(p1.x, p0.y));
108 vList[2] = m_v[1];
109 vList[3] = GetPlane().P2W(BrushVec2(p0.x, p1.y));
111 polygonList.push_back(new Polygon(vList));
112 if (polygonList[0]->IsOpen())
113 return;
114 if (polygonList[0]->GetPlane().IsSameFacing(GetPlane()))
115 polygonList[0]->Flip();
117 for (int i = 0; i < 4; ++i)
118 vList[i] += GetPlane().Normal() * (BrushFloat)m_BoxParameter.m_Height;
119 polygonList.push_back(new Polygon(vList));
120 if (!polygonList[1]->GetPlane().IsSameFacing(GetPlane()))
121 polygonList[1]->Flip();
123 for (int i = 0; i < 4; ++i)
125 BrushEdge3D e = polygonList[0]->GetEdge(i);
127 vList[0] = e.m_v[1];
128 vList[1] = e.m_v[0];
129 vList[2] = e.m_v[0] + GetPlane().Normal() * (BrushFloat)m_BoxParameter.m_Height;
130 vList[3] = e.m_v[1] + GetPlane().Normal() * (BrushFloat)m_BoxParameter.m_Height;
132 polygonList.push_back(new Polygon(vList));
135 MODEL_SHELF_RECONSTRUCTOR(GetModel());
137 GetModel()->SetShelf(eShelf_Construction);
138 GetModel()->Clear();
140 for (int i = 0, iCount(polygonList.size()); i < iCount; ++i)
142 if (polygonList[i]->IsOpen())
143 continue;
145 if (GetStartSpot().m_pPolygon)
147 polygonList[i]->SetTexInfo(GetStartSpot().m_pPolygon->GetTexInfo());
148 polygonList[i]->SetSubMatID(GetStartSpot().m_pPolygon->GetSubMatID());
151 AddPolygonWithSubMatID(polygonList[i]);
153 if (Comparison::IsEquivalent(polygonList[i]->GetPlane().Normal(), GetPlane().Normal()))
154 m_pCapPolygon = polygonList[i];
157 if (bUpdateUIs)
159 m_RectangleParameter.m_Width = std::abs(p0.x - p1.x);
160 m_RectangleParameter.m_Depth = std::abs(p0.y - p1.y);
161 DesignerSession::GetInstance()->signalDesignerEvent(eDesignerNotify_SubtoolOptionChanged, nullptr);
164 ApplyPostProcess(ePostProcess_Mesh | ePostProcess_Mirror | ePostProcess_SmoothingGroup);
167 void BoxTool::Display(SDisplayContext& dc)
169 DisplayCurrentSpot(dc);
170 DisplayDimensionHelper(dc, eShelf_Construction);
171 if (GetStartSpot().m_pPolygon)
172 DisplayDimensionHelper(dc);
173 s_HeightManipulator.Display(dc);
176 void BoxTool::Register()
178 RegisterShape(GetStartSpot().m_pPolygon);
181 void BoxTool::RegisterShape(PolygonPtr pFloorPolygon)
183 if (!GetModel() || GetModel()->IsEmpty(eShelf_Construction))
184 return;
186 MODEL_SHELF_RECONSTRUCTOR(GetModel());
188 if (m_pCapPolygon)
190 GetModel()->SetShelf(eShelf_Construction);
191 if (m_bIsOverOpposite)
193 s_SnappingHelper.ApplyOppositePolygons(m_pCapPolygon, ePP_Pull, true);
194 GetModel()->RemovePolygon(GetModel()->QueryEquivalentPolygon(m_pCapPolygon));
197 if (!IsSeparateStatus())
199 std::vector<PolygonPtr> sidePolygons;
201 BrushPlane invertedCapPolygonPlane = m_pCapPolygon->GetPlane().GetInverted();
202 for (int i = 0, iPolygonCount(GetModel()->GetPolygonCount()); i < iPolygonCount; ++i)
204 PolygonPtr pPolygon = GetModel()->GetPolygon(i);
205 if (pPolygon != m_pCapPolygon && !Comparison::IsEquivalent(invertedCapPolygonPlane.Normal(), pPolygon->GetPlane().Normal()))
206 sidePolygons.push_back(pPolygon);
209 std::vector<PolygonPtr> intersectedSidePolygons;
210 for (int i = 0, iSidePolygonCount(sidePolygons.size()); i < iSidePolygonCount; ++i)
212 for (int k = 0; k < 2; ++k)
214 PolygonPtr pSidePolygon = k == 0 ? sidePolygons[i]->Clone()->Flip() : sidePolygons[i];
216 GetModel()->SetShelf(eShelf_Base);
217 bool bHasIntersected = GetModel()->HasIntersection(pSidePolygon, true);
218 bool bTouched = GetModel()->HasTouched(pSidePolygon);
219 if ((!bHasIntersected && !bTouched) || (bTouched && k == 0))
220 continue;
222 GetModel()->SetShelf(eShelf_Construction);
223 GetModel()->RemovePolygon(sidePolygons[i]);
225 GetModel()->SetShelf(eShelf_Base);
226 if (bHasIntersected)
228 GetModel()->AddXORPolygon(pSidePolygon);
229 intersectedSidePolygons.push_back(pSidePolygon);
231 else if (bTouched)
233 GetModel()->AddUnionPolygon(pSidePolygon);
235 break;
239 for (int i = 0, iCount(intersectedSidePolygons.size()); i < iCount; ++i)
241 GetModel()->SetShelf(eShelf_Base);
246 __super::RegisterShape(pFloorPolygon);
251 REGISTER_DESIGNER_TOOL_WITH_PROPERTYTREE_PANEL_AND_COMMAND(eDesigner_Box, eToolGroup_Shape, "Box", BoxTool,
252 box, "runs box tool", "designer.box");