1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsPrerequisites.h"
6#include "Math/BsMatrix4.h"
7#include "Math/BsVector3.h"
8#include "Math/BsVector2.h"
9#include "Image/BsColor.h"
10#include "Math/BsRect3.h"
11#include "RenderAPI/BsSubMesh.h"
12#include "Scene/BsTransform.h"
13
14namespace bs
15{
16 /** @addtogroup Utility-Engine
17 * @{
18 */
19
20 /** Helper class for immediate drawing of common geometric shapes. */
21 class BS_EXPORT DrawHelper
22 {
23 public:
24 /** Controls in what order will elements be rendered, depending on some reference point. */
25 enum class SortType
26 {
27 BackToFront,
28 FrontToBack,
29 None
30 };
31
32 /** Type of meshes that are output by DrawHelper. */
33 enum class MeshType
34 {
35 Solid, Wire, Line, Text
36 };
37
38 /** Container for mesh of a specific type output by the DrawHelper. */
39 struct ShapeMeshData
40 {
41 SPtr<Mesh> mesh;
42 SubMesh subMesh;
43 MeshType type;
44 HTexture texture;
45 };
46
47 DrawHelper();
48
49 /** Sets a color that will be used for any shapes recorded after this call. */
50 void setColor(const Color& color);
51
52 /** Sets a transform matrix that will be used for any shapes recorded after this call. */
53 void setTransform(const Matrix4& transform);
54
55 /** Sets the layer bitfield that can be used for filtering which objects are output into the final mesh. */
56 void setLayer(UINT64 layer);
57
58 /** Records a solid cuboid with the specified properties in the internal draw queue. */
59 void cube(const Vector3& position, const Vector3& extents);
60
61 /** Records a solid sphere with the specified properties in the internal draw queue. */
62 void sphere(const Vector3& position, float radius, UINT32 quality = 1);
63
64 /** Records a wireframe cube with the specified properties in the internal draw queue. */
65 void wireCube(const Vector3& position, const Vector3& extents);
66
67 /** Records a wireframe sphere with the specified properties in the internal draw queue. */
68 void wireSphere(const Vector3& position, float radius, UINT32 quality = 10);
69
70 /** Records a wireframe hemisphere with the specified properties in the internal draw queue. */
71 void wireHemisphere(const Vector3& position, float radius, UINT32 quality = 10);
72
73 /** Records a line with the specified properties in the internal draw queue. */
74 void line(const Vector3& start, const Vector3& end);
75
76 /**
77 * Records a list of lines in the internal draw queue. The list must contain lines as pair of vertices, starting
78 * point followed by an end point, and so on.
79 */
80 void lineList(const Vector<Vector3>& lines);
81
82 /** Records a wireframe frustum with the specified properties in the internal draw queue. */
83 void frustum(const Vector3& position, float aspect, Degree FOV, float near, float far);
84
85 /** Records a solid cone with the specified properties in the internal draw queue. */
86 void cone(const Vector3& base, const Vector3& normal, float height, float radius,
87 const Vector2& scale = Vector2::ONE, UINT32 quality = 10);
88
89 /** Records a wire cone with the specified properties in the internal draw queue. */
90 void wireCone(const Vector3& base, const Vector3& normal, float height, float radius,
91 const Vector2& scale = Vector2::ONE, UINT32 quality = 10);
92
93 /** Records a solid disc with the specified properties in the internal draw queue. */
94 void disc(const Vector3& position, const Vector3& normal, float radius, UINT32 quality = 10);
95
96 /** Records a wireframe disc with the specified properties in the internal draw queue. */
97 void wireDisc(const Vector3& position, const Vector3& normal, float radius, UINT32 quality = 10);
98
99 /** Records a solid arc with the specified properties in the internal draw queue. */
100 void arc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle,
101 UINT32 quality = 10);
102
103 /** Records a wireframe arc with the specified properties in the internal draw queue. */
104 void wireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle,
105 UINT32 quality = 10);
106
107 /** Records a 3D mesh to be drawn as wireframe in the internal draw queue. */
108 void wireMesh(const SPtr<MeshData>& meshData);
109
110 /** Records a solid rectangle with the specified properties in the internal draw queue. */
111 void rectangle(const Rect3& area);
112
113 /**
114 * Records a mesh representing 2D text with the specified properties in the internal draw queue.
115 *
116 * @param[in] position Position to render the text at. Text will be centered around this point.
117 * @param[in] text Text to draw.
118 * @param[in] font Font to use for rendering the text's characters.
119 * @param[in] size Size of the characters, in points.
120 */
121 void text(const Vector3& position, const String& text, const HFont& font, UINT32 size = 10);
122
123 /** Clears all recorded shapes. */
124 void clear();
125
126 /**
127 * Generates a set of meshes from all the recorded solid and wireframe shapes. The meshes can be accessed via
128 * getMeshes() and released via clearMeshes().
129 *
130 * @param sorting (optional) Determines how (and if) should elements be sorted
131 * based on their distance from the reference point.
132 * @param camera (optional) Camera through which the meshes will be rendered.
133 * @param layers (optional) Layers bitfield that can be used for controlling which shapes will be included
134 * in the mesh. This bitfield will be ANDed with the layer specified when recording the shape.
135 * @return Generated mesh data.
136 */
137 Vector<ShapeMeshData> buildMeshes(SortType sorting = SortType::None,
138 const Camera* camera = nullptr, UINT64 layers = 0xFFFFFFFFFFFFFFFF);
139
140 private:
141 struct CommonData
142 {
143 Color color;
144 Matrix4 transform;
145 Vector3 center;
146 UINT64 layer;
147 };
148
149 struct CubeData : CommonData
150 {
151 Vector3 position;
152 Vector3 extents;
153 };
154
155 struct SphereData : CommonData
156 {
157 Vector3 position;
158 float radius;
159 UINT32 quality;
160 };
161
162 struct LineData : CommonData
163 {
164 Vector3 start;
165 Vector3 end;
166 };
167
168 struct LineListData : CommonData
169 {
170 Vector<Vector3> lines;
171 };
172
173 struct Rect3Data : CommonData
174 {
175 Rect3 area;
176 };
177
178 struct FrustumData : CommonData
179 {
180 Vector3 position;
181 float aspect;
182 Degree FOV;
183 float nearDist;
184 float farDist;
185 };
186
187 struct ConeData : CommonData
188 {
189 Vector3 base;
190 Vector3 normal;
191 float height;
192 float radius;
193 Vector2 scale;
194 UINT32 quality;
195 };
196
197 struct DiscData : CommonData
198 {
199 Vector3 position;
200 Vector3 normal;
201 float radius;
202 UINT32 quality;
203 };
204
205 struct ArcData : CommonData
206 {
207 Vector3 position;
208 Vector3 normal;
209 float radius;
210 Degree startAngle;
211 Degree amountAngle;
212 UINT32 quality;
213 };
214
215 struct Text2DData : CommonData
216 {
217 Vector3 position;
218 String text;
219 HFont font;
220 UINT32 size;
221 };
222
223 struct WireMeshData : CommonData
224 {
225 SPtr<MeshData> meshData;
226 };
227
228 static const UINT32 VERTEX_BUFFER_GROWTH;
229 static const UINT32 INDEX_BUFFER_GROWTH;
230
231 Color mColor;
232 Matrix4 mTransform;
233 UINT64 mLayer;
234
235 Vector<CubeData> mSolidCubeData;
236 Vector<CubeData> mWireCubeData;
237 Vector<SphereData> mSolidSphereData;
238 Vector<SphereData> mWireSphereData;
239 Vector<SphereData> mWireHemisphereData;
240 Vector<LineData> mLineData;
241 Vector<LineListData> mLineListData;
242 Vector<Rect3Data> mRect3Data;
243 Vector<FrustumData> mFrustumData;
244 Vector<ConeData> mConeData;
245 Vector<ConeData> mWireConeData;
246 Vector<DiscData> mDiscData;
247 Vector<DiscData> mWireDiscData;
248 Vector<ArcData> mArcData;
249 Vector<ArcData> mWireArcData;
250 Vector<Text2DData> mText2DData;
251 Vector<WireMeshData> mWireMeshData;
252
253 SPtr<VertexDataDesc> mSolidVertexDesc;
254 SPtr<VertexDataDesc> mWireVertexDesc;
255 SPtr<VertexDataDesc> mLineVertexDesc;
256 SPtr<VertexDataDesc> mTextVertexDesc;
257 };
258
259 /** @} */
260}
261