BsGizmoManager.h 17 KB

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