BsGizmoManager.h 17 KB

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