BsGizmoManager.h 17 KB

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