BsGizmoManager.h 20 KB

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