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 "Utility/BsModule.h"
7#include "Utility/BsDrawHelper.h"
8#include "Renderer/BsParamBlocks.h"
9#include "Renderer/BsRendererExtension.h"
10#include "Renderer/BsRendererMaterial.h"
11
12namespace bs
13{
14 namespace ct { class DebugDrawRenderer; }
15
16 /** @addtogroup Utility-Engine
17 * @{
18 */
19
20 /** Supported types of materials (shaders) by DebugDraw. */
21 enum class DebugDrawMaterial
22 {
23 Solid, Wire, Line
24 };
25
26 /** Provides an easy access to draw basic 2D and 3D shapes, primarily meant for debugging purposes. */
27 class BS_EXPORT DebugDraw : public Module<DebugDraw>
28 {
29 public:
30 DebugDraw();
31 ~DebugDraw();
32
33 /** Changes the color of any further draw calls. */
34 void setColor(const Color& color);
35
36 /** Changes the transform that will be applied to meshes of any further draw calls. */
37 void setTransform(const Matrix4& transform);
38
39 /**
40 * Draws an axis aligned cuboid.
41 *
42 * @param[in] position Center of the cuboid.
43 * @param[in] extents Radius of the cuboid in each axis.
44 */
45 void drawCube(const Vector3& position, const Vector3& extents);
46
47 /** Draws a sphere. */
48 void drawSphere(const Vector3& position, float radius);
49
50 /**
51 * Draws a solid cone.
52 *
53 * @param[in] base Position of the center of the base of the cone.
54 * @param[in] normal Orientation of the cone, pointing from center base to the tip of the cone.
55 * @param[in] height Height of the cone (along the normal).
56 * @param[in] radius Radius of the base of the cone.
57 * @param[in] scale Scale applied to cone's disc width & height. Allows you to create elliptical cones.
58 */
59 void drawCone(const Vector3& base, const Vector3& normal, float height, float radius,
60 const Vector2& scale = Vector2::ONE);
61
62 /**
63 * Draws a solid disc.
64 *
65 * @param[in] position Center of the disc.
66 * @param[in] normal Orientation of the disc, pointing in the direction the disc is visible in.
67 * @param[in] radius Radius of the disc.
68 */
69 void drawDisc(const Vector3& position, const Vector3& normal, float radius);
70
71 /**
72 * Draws a wireframe axis aligned cuboid.
73 *
74 * @param[in] position Center of the cuboid.
75 * @param[in] extents Radius of the cuboid in each axis.
76 */
77 void drawWireCube(const Vector3& position, const Vector3& extents);
78
79 /** Draws a wireframe sphere represented by three discs. */
80 void drawWireSphere(const Vector3& position, float radius);
81
82 /**
83 * Draws a wireframe cone.
84 *
85 * @param[in] base Position of the center of the base of the cone.
86 * @param[in] normal Orientation of the cone, pointing from center base to the tip of the cone.
87 * @param[in] height Height of the cone (along the normal).
88 * @param[in] radius Radius of the base of the cone.
89 * @param[in] scale Scale applied to cone's disc width & height. Allows you to create elliptical cones.
90 */
91 void drawWireCone(const Vector3& base, const Vector3& normal, float height, float radius,
92 const Vector2& scale = Vector2::ONE);
93
94 /** Draws a line between two points. */
95 void drawLine(const Vector3& start, const Vector3& end);
96
97 /**
98 * Draws a list of lines. Provided array must contain pairs of the line start point followed by an end point.
99 */
100 void drawLineList(const Vector<Vector3>& linePoints);
101
102 /**
103 * Draws a wireframe disc.
104 *
105 * @param[in] position Center of the disc.
106 * @param[in] normal Orientation of the disc, pointing in the direction the disc is visible in.
107 * @param[in] radius Radius of the disc.
108 */
109 void drawWireDisc(const Vector3& position, const Vector3& normal, float radius);
110
111 /**
112 * Draws a wireframe arc.
113 *
114 * @param[in] position Center of the arc.
115 * @param[in] normal Orientation of the arc, pointing in the direction the arc is visible in.
116 * @param[in] radius Radius of the arc.
117 * @param[in] startAngle Angle at which to start the arc.
118 * @param[in] amountAngle Length of the arc.
119 */
120 void drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle);
121
122 /**
123 * Draws a wireframe mesh.
124 *
125 * @param[in] meshData Object containing mesh vertices and indices. Vertices must be Vertex3 and indices
126 * 32-bit.
127 */
128 void drawWireMesh(const SPtr<MeshData>& meshData);
129
130 /**
131 * Draws a wireframe frustum.
132 *
133 * @param[in] position Origin of the frustum, or the eye point.
134 * @param[in] aspect Ratio of frustum width over frustum height.
135 * @param[in] FOV Horizontal field of view in degrees.
136 * @param[in] near Distance to the near frustum plane.
137 * @param[in] far Distance to the far frustum plane.
138 */
139 void drawFrustum(const Vector3& position, float aspect, Degree FOV, float near, float far);
140
141 /**
142 * Clears any objects that are currently drawing. All objects must be re-queued.
143 */
144 void clear();
145
146 /** Performs per-frame operations. */
147 void _update();
148
149 private:
150 friend class ct::DebugDrawRenderer;
151
152 /** Data about a mesh rendered by the draw manager. */
153 struct MeshRenderData
154 {
155 MeshRenderData(const SPtr<ct::Mesh>& mesh, const SubMesh& subMesh, DebugDrawMaterial type)
156 :mesh(mesh), subMesh(subMesh), type(type)
157 { }
158
159 SPtr<ct::Mesh> mesh;
160 SubMesh subMesh;
161 DebugDrawMaterial type;
162 };
163
164 /** Converts mesh data from DrawHelper into mesh data usable by the debug draw renderer. */
165 Vector<MeshRenderData> createMeshProxyData(const Vector<DrawHelper::ShapeMeshData>& meshData);
166
167 DrawHelper* mDrawHelper = nullptr;
168 Vector<DrawHelper::ShapeMeshData> mActiveMeshes;
169
170 SPtr<ct::DebugDrawRenderer> mRenderer;
171 };
172
173 /** @} */
174
175 namespace ct
176 {
177 /** @addtogroup Utility-Engine-Internal
178 * @{
179 */
180
181 BS_PARAM_BLOCK_BEGIN(DebugDrawParamsDef)
182 BS_PARAM_BLOCK_ENTRY(Matrix4, gMatViewProj)
183 BS_PARAM_BLOCK_ENTRY(Vector4, gViewDir)
184 BS_PARAM_BLOCK_END
185
186 extern DebugDrawParamsDef gDebugDrawParamsDef;
187
188 /** Handles rendering of debug shapes. */
189 class DebugDrawMat : public RendererMaterial<DebugDrawMat>
190 {
191 RMAT_DEF("DebugDraw.bsl");
192
193 /** Helper method used for initializing variations of this material. */
194 template<bool solid, bool line, bool wire>
195 static const ShaderVariation& getVariation()
196 {
197 static ShaderVariation variation = ShaderVariation(
198 {
199 ShaderVariation::Param("SOLID", solid),
200 ShaderVariation::Param("LINE", line),
201 ShaderVariation::Param("WIRE", wire)
202 });
203
204 return variation;
205 }
206 public:
207 DebugDrawMat();
208
209 /** Executes the material using the provided parameters. */
210 void execute(const SPtr<GpuParamBlockBuffer>& params, const SPtr<Mesh>& mesh, const SubMesh& subMesh);
211
212 /** Returns the material variation matching the provided parameters. */
213 static DebugDrawMat* getVariation(DebugDrawMaterial drawMat);
214 };
215
216 /** Performs rendering of meshes provided by DebugDraw. */
217 class DebugDrawRenderer : public RendererExtension
218 {
219 friend class bs::DebugDraw;
220
221 public:
222 DebugDrawRenderer();
223
224 private:
225 /** @copydoc RendererExtension::initialize */
226 void initialize(const Any& data) override;
227
228 /** @copydoc RendererExtension::check */
229 bool check(const Camera& camera) override;
230
231 /** @copydoc RendererExtension::render */
232 void render(const Camera& camera) override;
233
234 /**
235 * Updates the internal data that is used for rendering. Normally you would call this after updating the meshes
236 * on the sim thread.
237 *
238 * @param[in] meshes Meshes to render.
239 */
240 void updateData(const Vector<DebugDraw::MeshRenderData>& meshes);
241
242 Vector<DebugDraw::MeshRenderData> mMeshes;
243 SPtr<GpuParamBlockBuffer> mParamBuffer;
244 };
245
246 /** @} */
247 }
248}
249