BsGizmoManager.h 14 KB

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