TerrainPhysicsColliderComponent.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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 <AzCore/Component/Component.h>
  10. #include <AzCore/Math/Aabb.h>
  11. #include <AzCore/Asset/AssetCommon.h>
  12. #include <AzFramework/Physics/HeightfieldProviderBus.h>
  13. #include <AzFramework/Physics/Material/PhysicsMaterialAsset.h>
  14. #include <AzFramework/Terrain/TerrainDataRequestBus.h>
  15. #include <SurfaceData/SurfaceTag.h>
  16. #include <TerrainSystem/TerrainSystemBus.h>
  17. #include <LmbrCentral/Shape/ShapeComponentBus.h>
  18. namespace LmbrCentral
  19. {
  20. template<typename, typename>
  21. class EditorWrappedComponentBase;
  22. }
  23. namespace Terrain
  24. {
  25. class EditorSurfaceTagListProvider;
  26. static const uint8_t InvalidSurfaceTagIndex = 0xFF;
  27. struct TerrainPhysicsSurfaceMaterialMapping final
  28. {
  29. public:
  30. AZ_CLASS_ALLOCATOR(TerrainPhysicsSurfaceMaterialMapping, AZ::SystemAllocator);
  31. AZ_TYPE_INFO(TerrainPhysicsSurfaceMaterialMapping, "{A88B5289-DFCD-4564-8395-E2177DFE5B18}");
  32. static void Reflect(AZ::ReflectContext* context);
  33. AZStd::vector<AZStd::pair<AZ::u32, AZStd::string>> BuildSelectableTagList() const;
  34. void SetTagListProvider(const EditorSurfaceTagListProvider* tagListProvider);
  35. SurfaceData::SurfaceTag m_surfaceTag;
  36. AZ::Data::Asset<Physics::MaterialAsset> m_materialAsset;
  37. private:
  38. const EditorSurfaceTagListProvider* m_tagListProvider = nullptr;
  39. };
  40. class TerrainPhysicsColliderConfig
  41. {
  42. public:
  43. AZ_CLASS_ALLOCATOR(TerrainPhysicsColliderConfig, AZ::SystemAllocator);
  44. AZ_TYPE_INFO(TerrainPhysicsColliderConfig, "{E9EADB8F-C3A5-4B9C-A62D-2DBC86B4CE59}");
  45. static void Reflect(AZ::ReflectContext* context);
  46. AZ::Data::Asset<Physics::MaterialAsset> m_defaultMaterialAsset;
  47. AZStd::vector<TerrainPhysicsSurfaceMaterialMapping> m_surfaceMaterialMappings;
  48. };
  49. class TerrainPhysicsColliderComponent
  50. : public AZ::Component
  51. , public Physics::HeightfieldProviderRequestsBus::Handler
  52. , protected LmbrCentral::ShapeComponentNotificationsBus::Handler
  53. , protected AzFramework::Terrain::TerrainDataNotificationBus::Handler
  54. {
  55. public:
  56. friend class EditorTerrainPhysicsColliderComponent;
  57. AZ_COMPONENT(TerrainPhysicsColliderComponent, "{33C20287-1D37-44D0-96A0-2C3766E23624}");
  58. static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services);
  59. static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services);
  60. static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services);
  61. static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& services);
  62. static void Reflect(AZ::ReflectContext* context);
  63. TerrainPhysicsColliderComponent(const TerrainPhysicsColliderConfig& configuration);
  64. TerrainPhysicsColliderComponent();
  65. ~TerrainPhysicsColliderComponent() = default;
  66. // HeightfieldProviderRequestsBus
  67. AZ::Vector2 GetHeightfieldGridSpacing() const override;
  68. void GetHeightfieldGridSize(size_t& numColumns, size_t& numRows) const override;
  69. AZ::u64 GetHeightfieldGridColumns() const override;
  70. AZ::u64 GetHeightfieldGridRows() const override;
  71. void GetHeightfieldHeightBounds(float& minHeightBounds, float& maxHeightBounds) const override;
  72. float GetHeightfieldMinHeight() const override;
  73. float GetHeightfieldMaxHeight() const override;
  74. AZ::Aabb GetHeightfieldAabb() const override;
  75. AZ::Transform GetHeightfieldTransform() const override;
  76. AZStd::vector<AZ::Data::Asset<Physics::MaterialAsset>> GetMaterialList() const override;
  77. AZStd::vector<float> GetHeights() const override;
  78. AZStd::vector<Physics::HeightMaterialPoint> GetHeightsAndMaterials() const override;
  79. void GetHeightfieldIndicesFromRegion(
  80. const AZ::Aabb& region, size_t& startColumn, size_t& startRow, size_t& numColumns, size_t& numRows) const override;
  81. //! Updates the list of heights and materials within the region.
  82. void UpdateHeightsAndMaterials(
  83. const Physics::UpdateHeightfieldSampleFunction& updateHeightsMaterialsCallback,
  84. size_t startColumn, size_t startRow, size_t numColumns, size_t numRows) const override;
  85. void UpdateHeightsAndMaterialsAsync(
  86. const Physics::UpdateHeightfieldSampleFunction& updateHeightsMaterialsCallback,
  87. const Physics::UpdateHeightfieldCompleteFunction& updateHeightsCompleteCallback,
  88. size_t startColumn,
  89. size_t startRow,
  90. size_t numColumns,
  91. size_t numRows) const override;
  92. void UpdateConfiguration(const TerrainPhysicsColliderConfig& newConfiguration);
  93. protected:
  94. //////////////////////////////////////////////////////////////////////////
  95. // AZ::Component interface implementation
  96. void Activate() override;
  97. void Deactivate() override;
  98. uint8_t GetMaterialIndex(const AZ::Data::Asset<Physics::MaterialAsset>& materialAsset, const AZStd::vector<AZ::Data::Asset<Physics::MaterialAsset>>& materialList) const;
  99. AZ::Data::Asset<Physics::MaterialAsset> FindMaterialAssetForSurfaceTag(const SurfaceData::SurfaceTag tag) const;
  100. void GenerateHeightsInBounds(AZStd::vector<float>& heights) const;
  101. void NotifyListenersOfHeightfieldDataChange(
  102. Physics::HeightfieldProviderNotifications::HeightfieldChangeMask heightfieldChangeMask,
  103. const AZ::Aabb& dirtyRegion);
  104. // ShapeComponentNotificationsBus
  105. void OnShapeChanged(ShapeChangeReasons changeReason) override;
  106. void OnTerrainDataCreateEnd() override;
  107. void OnTerrainDataDestroyBegin() override;
  108. void OnTerrainDataChanged(const AZ::Aabb& dirtyRegion, TerrainDataChangedMask dataChangedMask) override;
  109. void CalculateHeightfieldRegion();
  110. void BuildSurfaceTagToMaterialIndexLookup();
  111. private:
  112. // The default material will always be the first material in the material list.
  113. static inline constexpr uint8_t DefaultMaterialIndex = 0;
  114. TerrainPhysicsColliderConfig m_configuration;
  115. AZStd::atomic_bool m_terrainDataActive = false;
  116. AzFramework::Terrain::TerrainQueryRegion m_heightfieldRegion;
  117. AZStd::unordered_map<SurfaceData::SurfaceTag, uint8_t> m_surfaceTagToMaterialIndexLookup;
  118. // Protect state reads from happening in parallel with state writes.
  119. mutable AZStd::shared_mutex m_stateMutex;
  120. };
  121. }