3
0

EditorWhiteBoxComponent.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include "Rendering/WhiteBoxMaterial.h"
  10. #include "Rendering/WhiteBoxRenderData.h"
  11. #include "Viewport/WhiteBoxViewportConstants.h"
  12. #include <AzCore/Component/TransformBus.h>
  13. #include <AzCore/Math/Aabb.h>
  14. #include <AzCore/std/optional.h>
  15. #include <AzFramework/Entity/EntityDebugDisplayBus.h>
  16. #include <AzFramework/Visibility/BoundsBus.h>
  17. #include <AzToolsFramework/API/ComponentEntitySelectionBus.h>
  18. #include <AzToolsFramework/ComponentMode/ComponentModeDelegate.h>
  19. #include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
  20. #include <AzToolsFramework/ToolsComponents/EditorVisibilityBus.h>
  21. #include <WhiteBox/EditorWhiteBoxComponentBus.h>
  22. #include <WhiteBox/WhiteBoxToolApi.h>
  23. namespace WhiteBox
  24. {
  25. class EditorWhiteBoxMeshAsset;
  26. class RenderMeshInterface;
  27. //! Editor representation of White Box Tool.
  28. class EditorWhiteBoxComponent
  29. : public AzToolsFramework::Components::EditorComponentBase
  30. , public AzToolsFramework::EditorComponentSelectionRequestsBus::Handler
  31. , public AzFramework::BoundsRequestBus::Handler
  32. , public EditorWhiteBoxComponentRequestBus::Handler
  33. , private EditorWhiteBoxComponentNotificationBus::Handler
  34. , private AZ::TransformNotificationBus::Handler
  35. , private AzFramework::EntityDebugDisplayEventBus::Handler
  36. , private AzToolsFramework::EditorVisibilityNotificationBus::Handler
  37. {
  38. public:
  39. AZ_EDITOR_COMPONENT(EditorWhiteBoxComponent, "{C9F2D913-E275-49BB-AB4F-2D221C16170A}", EditorComponentBase);
  40. static void Reflect(AZ::ReflectContext* context);
  41. EditorWhiteBoxComponent();
  42. EditorWhiteBoxComponent(const EditorWhiteBoxComponent&) = delete;
  43. EditorWhiteBoxComponent& operator=(const EditorWhiteBoxComponent&) = delete;
  44. ~EditorWhiteBoxComponent();
  45. // AZ::Component overrides ...
  46. void Init() override;
  47. void Activate() override;
  48. void Deactivate() override;
  49. // EditorWhiteBoxComponentRequestBus overrides ...
  50. WhiteBoxMesh* GetWhiteBoxMesh() override;
  51. void SerializeWhiteBox() override;
  52. void DeserializeWhiteBox() override;
  53. void WriteAssetToComponent() override;
  54. void RebuildWhiteBox() override;
  55. void SetDefaultShape(DefaultShapeType defaultShape) override;
  56. // EditorComponentSelectionRequestsBus overrides ...
  57. AZ::Aabb GetEditorSelectionBoundsViewport(const AzFramework::ViewportInfo& viewportInfo) override;
  58. bool EditorSelectionIntersectRayViewport(
  59. const AzFramework::ViewportInfo& viewportInfo, const AZ::Vector3& src, const AZ::Vector3& dir,
  60. float& distance) override;
  61. bool SupportsEditorRayIntersect() override;
  62. // BoundsRequestBus overrides ...
  63. AZ::Aabb GetWorldBounds() override;
  64. AZ::Aabb GetLocalBounds() override;
  65. //! Returns if the component currently has an instance of RenderMeshInterface.
  66. bool HasRenderMesh() const;
  67. //! Returns if the component is currently using a White Box mesh asset to store its data.
  68. bool AssetInUse() const;
  69. //! Override the internal EditorWhiteBoxMeshAsset with an external instance.
  70. //! @note EditorWhiteBoxComponent takes ownership of the editorMeshAsset and will handle deleting it
  71. void OverrideEditorWhiteBoxMeshAsset(EditorWhiteBoxMeshAsset* editorMeshAsset);
  72. private:
  73. static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
  74. static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
  75. static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
  76. // EditorComponentBase overrides ...
  77. void BuildGameEntity(AZ::Entity* gameEntity) override;
  78. // EditorVisibilityNotificationBus overrides ...
  79. void OnEntityVisibilityChanged(bool visibility) override;
  80. // AzFramework::EntityDebugDisplayEventBus overrides ...
  81. void DisplayEntityViewport(
  82. const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
  83. // TransformNotificationBus overrides ...
  84. void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override;
  85. // EditorWhiteBoxComponentNotificationBus overrides ...
  86. void OnWhiteBoxMeshModified() override;
  87. void ShowRenderMesh();
  88. void HideRenderMesh();
  89. void RebuildRenderMesh();
  90. void RebuildPhysicsMesh();
  91. void ExportToFile();
  92. AZ::Crc32 SaveAsAsset();
  93. AZ::Crc32 OnDefaultShapeChange();
  94. void OnMaterialChange();
  95. AZ::Crc32 AssetVisibility() const;
  96. using ComponentModeDelegate = AzToolsFramework::ComponentModeFramework::ComponentModeDelegate;
  97. ComponentModeDelegate m_componentModeDelegate; //!< Responsible for detecting ComponentMode activation
  98. //!< and creating a concrete ComponentMode.
  99. Api::WhiteBoxMeshPtr m_whiteBox; //!< Handle/opaque pointer to the White Box mesh data.
  100. AZStd::optional<AZStd::unique_ptr<RenderMeshInterface>>
  101. m_renderMesh; //!< The render mesh to use for the White Box mesh data.
  102. AZ::Transform m_worldFromLocal = AZ::Transform::CreateIdentity(); //!< Cached world transform of Entity.
  103. Api::WhiteBoxMeshStream m_whiteBoxData; //!< Serialized White Box mesh data.
  104. //! Holds a reference to an optional WhiteBoxMeshAsset and manages the lifecycle of adding/removing an asset.
  105. EditorWhiteBoxMeshAsset* m_editorMeshAsset = nullptr;
  106. AZStd::optional<AZ::Aabb> m_worldAabb; //!< Cached world aabb (used for selection/view determination).
  107. AZStd::optional<AZ::Aabb> m_localAabb; //!< Cached local aabb (used for center pivot calculation).
  108. AZStd::optional<Api::Faces> m_faces; //!< Cached faces (triangles of mesh used for intersection/selection).
  109. WhiteBoxRenderData m_renderData; //!< Cached render data constructed from the White Box mesh source data.
  110. WhiteBoxMaterial m_material = {
  111. DefaultMaterialTint, DefaultMaterialUseTexture}; //!< Render material for White Box mesh.
  112. DefaultShapeType m_defaultShape =
  113. DefaultShapeType::Cube; //!< Used for selecting a default shape for the White Box mesh.
  114. };
  115. inline bool EditorWhiteBoxComponent::SupportsEditorRayIntersect()
  116. {
  117. return true;
  118. };
  119. //! The outcome of attempting to save a white box mesh.
  120. struct WhiteBoxSaveResult
  121. {
  122. AZStd::optional<AZStd::string> m_relativeAssetPath; //!< Optional relative asset path (the file may not have
  123. //!< been saved in the project folder).
  124. AZStd::string m_absoluteFilePath; // The absolute path of the saved file (valid wherever the file is saved).
  125. };
  126. //! Attempt to create a WhiteBoxSaveResult so that a WhiteBoxMeshAsset may be created.
  127. //! An optional relative path determines if a WhiteBoxMeshAsset can be created or not (was it saved inside the
  128. //! project folder) and an absolute path is returned for the White Box Mesh to be written to disk (wbm file).
  129. //! The operation can fail or be cancelled in which case an empty optional is returned.
  130. //! @param entityName The name of the entity the WhiteBoxMesh is on.
  131. //! @param absoluteSavePathFn Returns the absolute path for where the asset should be saved. Takes as its only
  132. //! argument a first guess at where the file should be saved (this can then be overridden by the user in the Editor
  133. //! by using a file dialog.
  134. //! @param relativePathFn Takes as its first argument the absolute path returned by absoluteSavePathFn and then
  135. //! attempts to create a relative path from it. In the Editor, if the asset was saved inside the project folder a
  136. //! relative path is returned. The function can fail to return a valid relative path but still have a valid
  137. //! absolute path.
  138. //! @param saveDecision Returns if the user decided to save the asset when attempting to save outside the project
  139. //! root or if they cancelled the operation (QMessageBox::Save or QMessageBox::Cancel are the expected return
  140. //! values).
  141. AZStd::optional<WhiteBoxSaveResult> TrySaveAs(
  142. AZStd::string_view entityName,
  143. const AZStd::function<AZStd::string(const AZStd::string& initialAbsolutePath)>& absoluteSavePathFn,
  144. const AZStd::function<AZStd::optional<AZStd::string>(const AZStd::string& absolutePath)>& relativePathFn,
  145. const AZStd::function<int()>& saveDecisionFn);
  146. } // namespace WhiteBox