EditorWhiteBoxComponent.h 9.3 KB

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