EditorWhiteBoxComponent.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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() const override;
  64. AZ::Aabb GetLocalBounds() const 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. void ExportDescendantsToFile();
  93. AZ::Crc32 SaveAsAsset();
  94. AZ::Crc32 OnDefaultShapeChange();
  95. void OnMaterialChange();
  96. AZ::Crc32 AssetVisibility() const;
  97. using ComponentModeDelegate = AzToolsFramework::ComponentModeFramework::ComponentModeDelegate;
  98. ComponentModeDelegate m_componentModeDelegate; //!< Responsible for detecting ComponentMode activation
  99. //!< and creating a concrete ComponentMode.
  100. Api::WhiteBoxMeshPtr m_whiteBox; //!< Handle/opaque pointer to the White Box mesh data.
  101. AZStd::optional<AZStd::unique_ptr<RenderMeshInterface>>
  102. m_renderMesh; //!< The render mesh to use for the White Box mesh data.
  103. AZ::Transform m_worldFromLocal = AZ::Transform::CreateIdentity(); //!< Cached world transform of Entity.
  104. Api::WhiteBoxMeshStream m_whiteBoxData; //!< Serialized White Box mesh data.
  105. //! Holds a reference to an optional WhiteBoxMeshAsset and manages the lifecycle of adding/removing an asset.
  106. EditorWhiteBoxMeshAsset* m_editorMeshAsset = nullptr;
  107. mutable AZStd::optional<AZ::Aabb> m_worldAabb; //!< Cached world aabb (used for selection/view determination).
  108. mutable AZStd::optional<AZ::Aabb> m_localAabb; //!< Cached local aabb (used for center pivot calculation).
  109. AZStd::optional<Api::Faces> m_faces; //!< Cached faces (triangles of mesh used for intersection/selection).
  110. WhiteBoxRenderData m_renderData; //!< Cached render data constructed from the White Box mesh source data.
  111. WhiteBoxMaterial m_material = {
  112. DefaultMaterialTint, DefaultMaterialUseTexture}; //!< Render material for White Box mesh.
  113. DefaultShapeType m_defaultShape =
  114. DefaultShapeType::Cube; //!< Used for selecting a default shape for the White Box mesh.
  115. bool m_flipYZForExport = false; //!< Flips the Y and Z components of white box vertices when exporting for different coordinate systems
  116. };
  117. inline bool EditorWhiteBoxComponent::SupportsEditorRayIntersect()
  118. {
  119. return true;
  120. };
  121. //! The outcome of attempting to save a white box mesh.
  122. struct WhiteBoxSaveResult
  123. {
  124. AZStd::optional<AZStd::string> m_relativeAssetPath; //!< Optional relative asset path (the file may not have
  125. //!< been saved in the project folder).
  126. AZStd::string m_absoluteFilePath; // The absolute path of the saved file (valid wherever the file is saved).
  127. };
  128. //! Attempt to create a WhiteBoxSaveResult so that a WhiteBoxMeshAsset may be created.
  129. //! An optional relative path determines if a WhiteBoxMeshAsset can be created or not (was it saved inside the
  130. //! project folder) and an absolute path is returned for the White Box Mesh to be written to disk (wbm file).
  131. //! The operation can fail or be cancelled in which case an empty optional is returned.
  132. //! @param entityName The name of the entity the WhiteBoxMesh is on.
  133. //! @param absoluteSavePathFn Returns the absolute path for where the asset should be saved. Takes as its only
  134. //! argument a first guess at where the file should be saved (this can then be overridden by the user in the Editor
  135. //! by using a file dialog.
  136. //! @param relativePathFn Takes as its first argument the absolute path returned by absoluteSavePathFn and then
  137. //! attempts to create a relative path from it. In the Editor, if the asset was saved inside the project folder a
  138. //! relative path is returned. The function can fail to return a valid relative path but still have a valid
  139. //! absolute path.
  140. //! @param saveDecision Returns if the user decided to save the asset when attempting to save outside the project
  141. //! root or if they cancelled the operation (QMessageBox::Save or QMessageBox::Cancel are the expected return
  142. //! values).
  143. AZStd::optional<WhiteBoxSaveResult> TrySaveAs(
  144. AZStd::string_view entityName,
  145. const AZStd::function<AZStd::string(const AZStd::string& initialAbsolutePath)>& absoluteSavePathFn,
  146. const AZStd::function<AZStd::optional<AZStd::string>(const AZStd::string& absolutePath)>& relativePathFn,
  147. const AZStd::function<int()>& saveDecisionFn);
  148. } // namespace WhiteBox