BsGizmoManager.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsEditorPrerequisites.h"
  5. #include "BsModule.h"
  6. #include "BsColor.h"
  7. #include "BsVector2I.h"
  8. #include "BsMatrix4.h"
  9. #include "BsGpuParam.h"
  10. #include "BsDrawHelper.h"
  11. namespace BansheeEngine
  12. {
  13. /** @addtogroup Scene-Editor
  14. * @{
  15. */
  16. class GizmoManagerCore;
  17. /**
  18. * Handles the rendering and picking of gizmo elements. Gizmos are icons and 3D objects usually rendered in scene view
  19. * for various visualization purposes (e.g. a Camera component will have a gizmo that draws a Camera icon since
  20. * otherwise it has no visual representation). Aside from being rendered, gizmos can also be selected by the user as if
  21. * they were normal scene elements.
  22. */
  23. class BS_ED_EXPORT GizmoManager : public Module<GizmoManager>
  24. {
  25. public:
  26. GizmoManager();
  27. ~GizmoManager();
  28. /**
  29. * Starts gizmo creation. All further call will be referencing this gizmo. Must be followed by a matching
  30. * endGizmo().
  31. *
  32. * @param gizmoParent Scene object this gizmo is attached to. Selecting the gizmo will select this scene object.
  33. */
  34. void startGizmo(const HSceneObject& gizmoParent);
  35. /** Ends gizmo creation. Must be called after a matching startGizmo(). */
  36. void endGizmo();
  37. /** Changes the color of any further gizmo draw calls. */
  38. void setColor(const Color& color);
  39. /** Changes the transform that will be applied to meshes of any further gizmo draw calls. */
  40. void setTransform(const Matrix4& transform);
  41. /**
  42. * If pickable is set to true, gizmo can be selected by the user, otherwise it will be drawn but cannot be
  43. * interacted with.
  44. *
  45. * @note Must be called between startGizmo/endGizmo calls.
  46. */
  47. void setPickable(bool pickable) { mPickable = pickable; }
  48. /** Returns the currently set gizmo color. */
  49. Color getColor() const { return mColor; }
  50. /** Returns the currently set gizmo transform. */
  51. Matrix4 getTransform() const { return mTransform; }
  52. /**
  53. * Draws an axis aligned cuboid.
  54. *
  55. * @param[in] position Center of the cuboid.
  56. * @param[in] extents Radius of the cuboid in each axis.
  57. *
  58. * @note Must be called between startGizmo/endGizmo calls.
  59. */
  60. void drawCube(const Vector3& position, const Vector3& extents);
  61. /**
  62. * Draws a sphere.
  63. *
  64. * @note Must be called between startGizmo/endGizmo calls.
  65. */
  66. void drawSphere(const Vector3& position, float radius);
  67. /**
  68. * Draws a wireframe axis aligned cuboid.
  69. *
  70. * @param[in] position Center of the cuboid.
  71. * @param[in] extents Radius of the cuboid in each axis.
  72. *
  73. * @note Must be called between startGizmo/endGizmo calls.
  74. */
  75. void drawWireCube(const Vector3& position, const Vector3& extents);
  76. /**
  77. * Draws a wireframe sphere represented by three discs.
  78. *
  79. * @note Must be called between startGizmo/endGizmo calls.
  80. */
  81. void drawWireSphere(const Vector3& position, float radius);
  82. /**
  83. * Draws a line between two points.
  84. *
  85. * @note Must be called between startGizmo/endGizmo calls.
  86. */
  87. void drawLine(const Vector3& start, const Vector3& end);
  88. /**
  89. * Draws a wireframe disc.
  90. *
  91. * @param[in] position Center of the disc.
  92. * @param[in] normal Orientation of the disc, pointing in the direction the disc is visible in.
  93. * @param[in] radius Radius of the disc.
  94. */
  95. void drawWireDisc(const Vector3& position, const Vector3& normal, float radius);
  96. /**
  97. * Draws a wireframe arc.
  98. *
  99. * @param[in] position Center of the arc.
  100. * @param[in] normal Orientation of the arc, pointing in the direction the arc is visible in.
  101. * @param[in] radius Radius of the arc.
  102. * @param[in] startAngle Angle at which to start the arc.
  103. * @param[in] amountAngle Length of the arc.
  104. */
  105. void drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle);
  106. /**
  107. * Draws a wireframe frustum.
  108. *
  109. * @param[in] position Origin of the frustum, or the eye point.
  110. * @param[in] aspect Ratio of frustum width over frustum height.
  111. * @param[in] FOV Horizontal field of view in degrees.
  112. * @param[in] near Distance to the near frustum plane.
  113. * @param[in] far Distance to the far frustum plane.
  114. *
  115. * @note Must be called between startGizmo/endGizmo calls.
  116. */
  117. void drawFrustum(const Vector3& position, float aspect, Degree FOV, float near, float far);
  118. /**
  119. * Draws an icon that always faces the camera.
  120. *
  121. * @param[in] position Position of the center of the icon.
  122. * @param[in] image Sprite image for the icon to draw.
  123. * @param[in] fixedScale If true then the icon will remain the same size regardless of the distance from camera.
  124. *
  125. * @note Must be called between startGizmo/endGizmo calls.
  126. */
  127. void drawIcon(Vector3 position, HSpriteTexture image, bool fixedScale);
  128. /**
  129. * Draws a mesh representing 2D text with the specified properties.
  130. *
  131. * @param[in] position Position to render the text at. Text will be centered around this point.
  132. * @param[in] text Text to draw.
  133. * @param[in] font Font to use for rendering the text's characters.
  134. * @param[in] fontSize Size of the characters, in points.
  135. */
  136. void drawText(const Vector3& position, const WString& text, const HFont& font, UINT32 fontSize = 16);
  137. /**
  138. * Clears all gizmo data, but doesn't update the meshes or the render data. (Calling update would create empty
  139. * meshes, but before calling update gizmos will still be drawn).
  140. */
  141. void clearGizmos();
  142. /**
  143. * Clears gizmo render data like meshes, but doesn't clear the original gizmo data (Calling update would just
  144. * recreate the render data).
  145. */
  146. void clearRenderData();
  147. /**
  148. * Returns a scene object that was attached to a specific gizmo.
  149. *
  150. * @param[in] gizmoIdx Index of the gizmo to look for.
  151. */
  152. HSceneObject getSceneObject(UINT32 gizmoIdx);
  153. /** @cond INTERNAL */
  154. /**
  155. * Updates all the gizmo meshes to reflect all draw calls submitted since clearGizmos().
  156. *
  157. * @note Internal method.
  158. */
  159. void update(const CameraPtr& camera);
  160. /**
  161. * @brief Queues all gizmos to be rendered for picking. Each gizmo is draw with a separate
  162. * color so we can identify them later.
  163. *
  164. * @param camera Camera to draw the gizmos on.
  165. * @param idxToColorCallback Callback that assigns a unique color to each gizmo index.
  166. *
  167. * @note Internal method.
  168. */
  169. void renderForPicking(const CameraPtr& camera, std::function<Color(UINT32)> idxToColorCallback);
  170. /** @endcond */
  171. private:
  172. friend class GizmoManagerCore;
  173. /** Supported types of gizmo materials (i.e. shaders) */
  174. enum class GizmoMaterial
  175. {
  176. Solid, Wire, Picking, PickingAlpha, Text
  177. };
  178. /** Common data shared by all gizmo types. */
  179. struct CommonData
  180. {
  181. UINT32 idx;
  182. Color color;
  183. Matrix4 transform;
  184. HSceneObject sceneObject;
  185. bool pickable;
  186. };
  187. /** Data required for rendering a cuboid gizmo. */
  188. struct CubeData : public CommonData
  189. {
  190. Vector3 position;
  191. Vector3 extents;
  192. };
  193. /** Data required for rendering a sphere gizmo. */
  194. struct SphereData : public CommonData
  195. {
  196. Vector3 position;
  197. float radius;
  198. };
  199. /** Data required for rendering a line gizmo. */
  200. struct LineData : public CommonData
  201. {
  202. Vector3 start;
  203. Vector3 end;
  204. };
  205. /** Data required for rendering a wireframe disc gizmo. */
  206. struct WireDiscData : public CommonData
  207. {
  208. Vector3 position;
  209. Vector3 normal;
  210. float radius;
  211. };
  212. /** Data required for rendering a wireframe arc gizmo. */
  213. struct WireArcData : public CommonData
  214. {
  215. Vector3 position;
  216. Vector3 normal;
  217. float radius;
  218. Degree startAngle;
  219. Degree amountAngle;
  220. };
  221. /** Data required for rendering a frustum gizmo. */
  222. struct FrustumData : public CommonData
  223. {
  224. Vector3 position;
  225. float aspect;
  226. Degree FOV;
  227. float near;
  228. float far;
  229. };
  230. /** Data required for rendering an icon gizmo. */
  231. struct IconData : public CommonData
  232. {
  233. Vector3 position;
  234. bool fixedScale;
  235. HSpriteTexture texture;
  236. };
  237. /** Data required for rendering text. */
  238. struct TextData : public CommonData
  239. {
  240. Vector3 position;
  241. WString text;
  242. HFont font;
  243. UINT32 fontSize;
  244. };
  245. /** Stores how many icons use a specific texture. */
  246. struct IconRenderData
  247. {
  248. UINT32 count;
  249. SPtr<TextureCore> texture;
  250. };
  251. /** Data used for initializing the core thread equivalent of the gizmo manager. */
  252. struct CoreInitData
  253. {
  254. SPtr<MaterialCore> solidMat;
  255. SPtr<MaterialCore> wireMat;
  256. SPtr<MaterialCore> iconMat;
  257. SPtr<MaterialCore> textMat;
  258. SPtr<MaterialCore> pickingMat;
  259. SPtr<MaterialCore> alphaPickingMat;
  260. };
  261. typedef Vector<IconRenderData> IconRenderDataVec;
  262. typedef std::shared_ptr<IconRenderDataVec> IconRenderDataVecPtr;
  263. /**
  264. * Builds a brand new mesh that can be used for rendering all icon gizmos.
  265. *
  266. * @param[in] camera Camera the mesh will be rendered to.
  267. * @param[in] iconData A list of all icons and their properties.
  268. * @param[in] forPicking Whether the icons will be rendered normally, or with a special material for picking.
  269. * @param[in] renderData Output data that outlines the structure of the returned mesh. It tells us which portions
  270. * of the mesh use which icon texture.
  271. *
  272. * @return A mesh containing all of the visible icons. Mesh is allocated using the icon mesh heap
  273. * and should be deallocated manually.
  274. */
  275. TransientMeshPtr buildIconMesh(const CameraPtr& camera, const Vector<IconData>& iconData, bool forPicking, IconRenderDataVecPtr& renderData);
  276. /** Resizes the icon width/height so it is always scaled to optimal size (with preserved aspect). */
  277. void limitIconSize(UINT32& width, UINT32& height);
  278. /**
  279. * Calculates colors for an icon based on its position in the camera. e.g. icons too close to too far might be faded.
  280. *
  281. * @param[in] tint Primary tint for the icon.
  282. * @param[in] camera Camera in which the icon will be rendered in.
  283. * @param[in] iconHeight Height of the icon in pixels.
  284. * @param[in] fixedScale Whether the icon size changes depending on distance from the camera.
  285. * @param[in] normalColor Normal color of the icon.
  286. * @param[in] fadedColor Faded color to be used when icon is occluded by geometry.
  287. */
  288. void calculateIconColors(const Color& tint, const CameraPtr& camera, UINT32 iconHeight, bool fixedScale,
  289. Color& normalColor, Color& fadedColor);
  290. /** Initializes the core thread version of the gizmo manager. */
  291. void initializeCore(const CoreInitData& initData);
  292. /** Destroys the core thread version of the gizmo manager. */
  293. void destroyCore(GizmoManagerCore* core);
  294. static const UINT32 VERTEX_BUFFER_GROWTH;
  295. static const UINT32 INDEX_BUFFER_GROWTH;
  296. static const UINT32 SPHERE_QUALITY;
  297. static const UINT32 WIRE_SPHERE_QUALITY;
  298. static const float MAX_ICON_RANGE;
  299. static const UINT32 OPTIMAL_ICON_SIZE;
  300. static const float ICON_TEXEL_WORLD_SIZE;
  301. typedef Set<IconData, std::function<bool(const IconData&, const IconData&)>> IconSet;
  302. Color mColor;
  303. Matrix4 mTransform;
  304. HSceneObject mActiveSO;
  305. bool mPickable;
  306. UINT32 mCurrentIdx;
  307. DrawHelper* mDrawHelper;
  308. DrawHelper* mPickingDrawHelper;
  309. Vector<CubeData> mSolidCubeData;
  310. Vector<CubeData> mWireCubeData;
  311. Vector<SphereData> mSolidSphereData;
  312. Vector<SphereData> mWireSphereData;
  313. Vector<LineData> mLineData;
  314. Vector<WireDiscData> mWireDiscData;
  315. Vector<WireArcData> mWireArcData;
  316. Vector<FrustumData> mFrustumData;
  317. Vector<IconData> mIconData;
  318. Vector<TextData> mTextData;
  319. Map<UINT32, HSceneObject> mIdxToSceneObjectMap;
  320. Vector<DrawHelper::ShapeMeshData> mActiveMeshes;
  321. MeshHeapPtr mIconMeshHeap;
  322. TransientMeshPtr mIconMesh;
  323. std::atomic<GizmoManagerCore*> mCore;
  324. // Immutable
  325. VertexDataDescPtr mIconVertexDesc;
  326. // Transient
  327. struct SortedIconData
  328. {
  329. float distance;
  330. Vector2I screenPosition;
  331. UINT32 iconIdx;
  332. };
  333. Vector<SortedIconData> mSortedIconData;
  334. };
  335. /** @cond INTERNAL */
  336. /**
  337. * Core thread version of the gizmo manager that handles most of the rendering of meshes provided by the gizmo manager.
  338. */
  339. class GizmoManagerCore
  340. {
  341. friend class GizmoManager;
  342. /** Solid gizmo material and parameter handles. */
  343. struct SolidMaterialData
  344. {
  345. SPtr<MaterialCore> mat;
  346. GpuParamMat4Core mViewProj;
  347. GpuParamVec4Core mViewDir;
  348. };
  349. /** Wire gizmo material and parameter handles. */
  350. struct WireMaterialData
  351. {
  352. SPtr<MaterialCore> mat;
  353. GpuParamMat4Core mViewProj;
  354. };
  355. /** Icon gizmo material and parameter handles. */
  356. struct IconMaterialData
  357. {
  358. SPtr<MaterialCore> mat;
  359. SPtr<GpuParamsCore> mFragParams[2];
  360. GpuParamMat4Core mViewProj[2];
  361. GpuParamTextureCore mTexture[2];
  362. };
  363. /** Text gizmo material and parameter handles. */
  364. struct TextMaterialData
  365. {
  366. SPtr<MaterialCore> mat;
  367. GpuParamMat4Core mViewProj;
  368. GpuParamTextureCore mTexture;
  369. };
  370. /** Gizmo material and parameter handles used for picking. */
  371. struct PickingMaterialData
  372. {
  373. SPtr<MaterialCore> mat;
  374. GpuParamMat4Core mViewProj;
  375. };
  376. /**
  377. * Gizmo material and parameter handles used for picking, with blending support (generally used for icon picking).
  378. */
  379. struct AlphaPickingMaterialData
  380. {
  381. SPtr<MaterialCore> mat;
  382. SPtr<GpuParamsCore> mFragParams;
  383. GpuParamMat4Core mViewProj;
  384. GpuParamTextureCore mTexture;
  385. };
  386. /** Type of mesh that can be drawn. */
  387. enum class MeshType
  388. {
  389. Solid, Wire, Text
  390. };
  391. /** Data about a mesh rendered by the draw manager. */
  392. struct MeshData
  393. {
  394. MeshData(const SPtr<MeshCoreBase>& mesh, SPtr<TextureCore> texture, MeshType type)
  395. :mesh(mesh), texture(texture), type(type)
  396. { }
  397. SPtr<MeshCoreBase> mesh;
  398. SPtr<TextureCore> texture;
  399. MeshType type;
  400. };
  401. struct PrivatelyConstuct { };
  402. public:
  403. GizmoManagerCore(const PrivatelyConstuct& dummy);
  404. ~GizmoManagerCore();
  405. private:
  406. /** Initializes the core gizmo manager. Must be called right after creation. */
  407. void initialize(const GizmoManager::CoreInitData& initData);
  408. /** Renders all gizmos in the parent camera. */
  409. void render();
  410. /**
  411. * Renders a non-icon gizmo mesh using the provided parameters.
  412. *
  413. * @param[in] viewMatrix View matrix of the camera we are rendering with.
  414. * @param[in] projMatrix Projection matrix of the camera we are rendering with.
  415. * @param[in] viewDir View direction of the camera we are rendering with.
  416. * @param[in] mesh Mesh to render. This is normally the solid or wireframe gizmo mesh.
  417. * @param[in] texture Texture to apply to the material, if the material supports a texture.
  418. * @param[in] material Material to use for rendering. This is normally the solid, wireframe or picking material.
  419. */
  420. void renderGizmos(const Matrix4& viewMatrix, const Matrix4& projMatrix, const Vector3& viewDir,
  421. const SPtr<MeshCoreBase>& mesh, const SPtr<TextureCore>& texture, GizmoManager::GizmoMaterial material);
  422. /**
  423. * Renders the icon gizmo mesh using the provided parameters.
  424. *
  425. * @param[in] screenArea Area of the viewport to render the gizmos in, in pixels.
  426. * @param[in] mesh Mesh containing the icons.
  427. * @param[in] renderData Icon render data outlining which parts of the icon mesh use which textures.
  428. * @param[in] usePickingMaterial Should the icons be rendered normally or for picking.
  429. */
  430. void renderIconGizmos(Rect2I screenArea, SPtr<MeshCoreBase> mesh, GizmoManager::IconRenderDataVecPtr renderData, bool usePickingMaterial);
  431. /**
  432. * Updates the internal data that is used for rendering. Normally you would call this after updating the camera or
  433. * meshes on the sim thread.
  434. *
  435. * @param[in] camera Sets the camera all rendering will be performed to.
  436. * @param[in] meshes Meshes to render.
  437. * @param[in] iconMesh Mesh containing icon meshes.
  438. * @param[in] iconRenderData Icon render data outlining which parts of the icon mesh use which textures.
  439. */
  440. void updateData(const SPtr<CameraCore>& camera, const Vector<MeshData>& meshes, const SPtr<MeshCoreBase>& iconMesh,
  441. const GizmoManager::IconRenderDataVecPtr& iconRenderData);
  442. static const float PICKING_ALPHA_CUTOFF;
  443. SPtr<CameraCore> mCamera;
  444. Vector<MeshData> mMeshes;
  445. SPtr<MeshCoreBase> mIconMesh;
  446. GizmoManager::IconRenderDataVecPtr mIconRenderData;
  447. // Immutable
  448. SolidMaterialData mSolidMaterial;
  449. WireMaterialData mWireMaterial;
  450. IconMaterialData mIconMaterial;
  451. TextMaterialData mTextMaterial;
  452. PickingMaterialData mPickingMaterial;
  453. AlphaPickingMaterialData mAlphaPickingMaterial;
  454. };
  455. /** @endcond */
  456. /** @} */
  457. }