/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace AZ { namespace Render { //! A configuration structure for the MeshComponentController class MeshComponentConfig final : public AZ::ComponentConfig { public: AZ_RTTI(AZ::Render::MeshComponentConfig, "{63737345-51B1-472B-9355-98F99993909B}", ComponentConfig); AZ_CLASS_ALLOCATOR(MeshComponentConfig, SystemAllocator, 0); static void Reflect(AZ::ReflectContext* context); // Editor helper functions bool IsAssetSet(); bool LodTypeIsScreenCoverage(); bool LodTypeIsSpecificLOD(); bool ShowLodConfig(); AZStd::vector> GetLodOverrideValues(); Data::Asset m_modelAsset = { AZ::Data::AssetLoadBehavior::QueueLoad }; RHI::DrawItemSortKey m_sortKey = 0; bool m_excludeFromReflectionCubeMaps = false; bool m_useForwardPassIblSpecular = false; RPI::Cullable::LodType m_lodType = RPI::Cullable::LodType::Default; RPI::Cullable::LodOverride m_lodOverride = aznumeric_cast(0); float m_minimumScreenCoverage = 1.0f / 1080.0f; float m_qualityDecayRate = 0.5f; }; class MeshComponentController final : private MeshComponentRequestBus::Handler , public AzFramework::BoundsRequestBus::Handler , public AzFramework::RenderGeometry::IntersectionRequestBus::Handler , private TransformNotificationBus::Handler , private MaterialReceiverRequestBus::Handler , private MaterialComponentNotificationBus::Handler { public: friend class EditorMeshComponent; AZ_CLASS_ALLOCATOR(MeshComponentController, AZ::SystemAllocator, 0); AZ_RTTI(AZ::Render::MeshComponentController, "{D0F35FAC-4194-4C89-9487-D000DDB8B272}"); ~MeshComponentController(); static void Reflect(AZ::ReflectContext* context); static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); MeshComponentController() = default; MeshComponentController(const MeshComponentConfig& config); void Activate(const AZ::EntityComponentIdPair& entityComponentIdPair); void Deactivate(); void SetConfiguration(const MeshComponentConfig& config); const MeshComponentConfig& GetConfiguration() const; private: AZ_DISABLE_COPY(MeshComponentController); // MeshComponentRequestBus::Handler overrides ... void SetModelAsset(Data::Asset modelAsset) override; Data::Asset GetModelAsset() const override; void SetModelAssetId(Data::AssetId modelAssetId) override; Data::AssetId GetModelAssetId() const override; void SetModelAssetPath(const AZStd::string& modelAssetPath) override; AZStd::string GetModelAssetPath() const override; AZ::Data::Instance GetModel() const override; void SetSortKey(RHI::DrawItemSortKey sortKey) override; RHI::DrawItemSortKey GetSortKey() const override; void SetLodType(RPI::Cullable::LodType lodType) override; RPI::Cullable::LodType GetLodType() const override; virtual void SetLodOverride(RPI::Cullable::LodOverride lodOverride); virtual RPI::Cullable::LodOverride GetLodOverride() const; virtual void SetMinimumScreenCoverage(float minimumScreenCoverage); virtual float GetMinimumScreenCoverage() const; virtual void SetQualityDecayRate(float qualityDecayRate); virtual float GetQualityDecayRate() const; void SetVisibility(bool visible) override; bool GetVisibility() const override; // BoundsRequestBus and MeshComponentRequestBus overrides ... AZ::Aabb GetWorldBounds() override; AZ::Aabb GetLocalBounds() override; // IntersectionRequestBus overrides ... AzFramework::RenderGeometry::RayResult RenderGeometryIntersect(const AzFramework::RenderGeometry::RayRequest& ray) override; // TransformNotificationBus::Handler overrides ... void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; // MaterialReceiverRequestBus::Handler overrides ... virtual MaterialAssignmentId FindMaterialAssignmentId( const MaterialAssignmentLodIndex lod, const AZStd::string& label) const override; RPI::ModelMaterialSlotMap GetModelMaterialSlots() const override; MaterialAssignmentMap GetMaterialAssignments() const override; AZStd::unordered_set GetModelUvNames() const override; // MaterialComponentNotificationBus::Handler overrides ... void OnMaterialsUpdated(const MaterialAssignmentMap& materials) override; //! Check if the model asset requires to be cloned (e.g. cloth) for unique model instances. //! @param modelAsset The model asset to check. //! @result True in case the model asset needs to be cloned before creating the model. False if there is a 1:1 relationship between //! the model asset and the model and it is static and shared. In the second case the m_originalModelAsset of the mesh handle is //! equal to the model asset that the model is linked to. static bool RequiresCloning(const Data::Asset& modelAsset); void HandleModelChange(Data::Instance model); void RegisterModel(); void UnregisterModel(); void RefreshModelRegistration(); RPI::Cullable::LodConfiguration GetMeshLodConfiguration() const; void HandleNonUniformScaleChange(const AZ::Vector3& nonUniformScale); Render::MeshFeatureProcessorInterface* m_meshFeatureProcessor = nullptr; Render::MeshFeatureProcessorInterface::MeshHandle m_meshHandle; TransformInterface* m_transformInterface = nullptr; AZ::EntityComponentIdPair m_entityComponentIdPair; bool m_isVisible = true; MeshComponentConfig m_configuration; AZ::Vector3 m_cachedNonUniformScale = AZ::Vector3::CreateOne(); MeshFeatureProcessorInterface::ModelChangedEvent::Handler m_changeEventHandler { [&](Data::Instance model) { HandleModelChange(model); } }; AZ::NonUniformScaleChangedEvent::Handler m_nonUniformScaleChangedHandler { [&](const AZ::Vector3& nonUniformScale) { HandleNonUniformScaleChange(nonUniformScale); } }; }; } // namespace Render } // namespace AZ