Files
o3de/Gems/PhysX/Code/Source/Material.h
T
Aaron Ruiz Mora 00e860f326 Physics material system for spectra launch
- Invalidate 'Physics Materials From Mesh' boolean from collider component
- Removed material library from material selector. Default material library will always be used instead.
- Marking failing automated test as xfail
- Added default material to physics configuration.
- Moved material library asset from physx configuration to physics configuration, as it doesn't need to be physx specific.
- Refactor physics material system having into account that there is only one material library in the project.
- Renaming code from DefaultMaterialLibrary to MaterialLibrary.
- All queries about physics materials unified under PhysicsMaterialRequests bus.
- PhysXSystem only manages the material library asset.
- Saving and reloading the same physics material asset with different content didn't trigger a events that the material library has changed.
- Changing Physics Material Request interface to use shared_ptr instead of weak_ptr to be simpler to handle the returned materials and having a more consistent code.
- Refactored Material Manager to improve its implementation. Still following the same approach of "creating materials on the fly as they are requested", but now it's doing it consistently across the interface, with private helpers functions FindOrCreateMaterial that simplify vastly the implementation.
- Material Manager now listens to change event of material library asset and default material configuration so it updates its materials accordingly.
- Complete Material move constructor and operator.
2021-05-28 20:16:25 +01:00

206 lines
9.1 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <PxPhysicsAPI.h>
#include <AzFramework/Physics/Material.h>
#include <AzFramework/Physics/MaterialBus.h>
#include <AzFramework/Physics/ShapeConfiguration.h>
#include <AzFramework/Physics/Common/PhysicsEvents.h>
#include <AzCore/std/smart_ptr/enable_shared_from_this.h>
namespace PhysX
{
/// Name used by physx asset exporter to indicate that the default
/// physics material should be used for a mesh surface. The exporter
/// will use it as the fallback option when it's not possible to obtain
/// the surface information from the mesh material.
static const char* const DefaultPhysicsMaterialNameFromPhysicsAsset = "<Default>";
/// PhysX implementation of Physics::Material interface
/// ===================================================
///
/// PhysX::Material stores a reference to physx::PxMaterial and manages its lifetime
/// The userData pointer of PxMaterial points to this class.
///
/// Usage example
/// -------------------------
/// You can construct instance of PhysX::Material directly and retrieve PxMaterial reference from it
///
/// Physics::MaterialConfiguration properties;
/// Material newMaterial{properties};
/// physx::PxMaterial* material = newMaterial.GetPxMaterial();
///
/// You can use retrieved PxMaterial pointer on its own, provided you increment its reference count.
/// If this class goes out of scope, the PxMaterial pointer will be valid, but its userData
/// will be cleaned up to point to nullptr.
class Material
: public Physics::Material
, public AZStd::enable_shared_from_this<Material>
{
public:
AZ_CLASS_ALLOCATOR(Material, AZ::SystemAllocator, 0);
AZ_RTTI(Material, "{F5497337-DCFE-44BA-BB40-B9EF225D16D6}", Physics::Material);
Material(const Physics::MaterialConfiguration& configuration);
Material(Material&& material);
virtual ~Material() = default;
Material& operator=(Material&& material);
Material(const Material& shape) = delete;
Material& operator=(const Material& shape) = delete;
void UpdateWithConfiguration(const Physics::MaterialConfiguration& configuration);
physx::PxMaterial* GetPxMaterial();
// Physics::Material
AZ::Crc32 GetSurfaceType() const override;
const AZStd::string& GetSurfaceTypeName() const override;
void SetSurfaceTypeName(const AZStd::string& surfaceTypeName) override;
float GetDynamicFriction() const override;
void SetDynamicFriction(float dynamicFriction) override;
float GetStaticFriction() const override;
void SetStaticFriction(float staticFriction) override;
float GetRestitution() const override;
void SetRestitution(float restitution) override;
CombineMode GetFrictionCombineMode() const override;
void SetFrictionCombineMode(CombineMode mode) override;
CombineMode GetRestitutionCombineMode() const override;
void SetRestitutionCombineMode(CombineMode mode) override;
float GetDensity() const override;
void SetDensity(float density) override;
AZ::Color GetDebugColor() const override;
void SetDebugColor(const AZ::Color& debugColor) override;
AZ::u32 GetCryEngineSurfaceId() const override;
void* GetNativePointer() override;
private:
using PxMaterialUniquePtr = AZStd::unique_ptr<physx::PxMaterial, AZStd::function<void(physx::PxMaterial*)>>;
PxMaterialUniquePtr m_pxMaterial;
AZ::Crc32 m_surfaceType = 0;
AZ::u32 m_cryEngineSurfaceId = -1;
AZStd::string m_surfaceString;
float m_density = 1000.0f;
AZ::Color m_debugColor = AZ::Colors::White;
};
/// Bus with requests to MaterialsManager
/// =====================================
///
/// Can be used to retrieve material instance from user selection.\n
/// Refer to MaterialsManager for more details. \n
class MaterialManagerRequests
: public Physics::PhysicsMaterialRequests
{
public:
using MutexType = AZStd::mutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
/// Returns weak pointers to physx::PxMaterial.
/// Equivalent to PhysicsMaterialRequests::GetMaterials but it returns physx::PxMaterial pointers instead.
/// @param materialSelection MaterialSelection instance to create or get materials for
/// @param outMaterials vector of pointers to physx::PxMaterial to fill with. The vector will be cleared inside the function.
virtual void GetPxMaterials(const Physics::MaterialSelection& materialSelection, AZStd::vector<physx::PxMaterial*>& outMaterials) = 0;
/// Returns default material
/// @return default PhysX::Material instance
virtual AZStd::shared_ptr<Material> GetDefaultMaterial() = 0;
/// Releases ownership of all materials created before.
virtual void ReleaseAllMaterials() = 0;
};
using MaterialManagerRequestsBus = AZ::EBus<MaterialManagerRequests>;
/// Manages materials created from MaterialLibraryAsset
/// ===================================================
///
/// Material managers creates PhysX::Material instances from MaterialLibraryAsset and assumes their ownership.
/// Also keeps a reference to the default material.
///
/// Note: Materials will be created on the fly while doing queries and
/// they will be updated when the material library changes.
class MaterialsManager
: public MaterialManagerRequestsBus::Handler
, public Physics::PhysicsMaterialRequestBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(MaterialsManager, AZ::SystemAllocator, 0);
AZ_RTTI(MaterialsManager, "{4A6E59A7-D41A-470A-B31D-622BDA207FC7}");
MaterialsManager();
~MaterialsManager() override;
// PhysicsMaterialRequestBus::Handler overrides...
void GetMaterials(const Physics::MaterialSelection& materialSelection
, AZStd::vector<AZStd::shared_ptr<Physics::Material>>& outMaterials) override;
AZStd::shared_ptr<Physics::Material> GetMaterialById(Physics::MaterialId id) override;
AZStd::shared_ptr<Physics::Material> GetMaterialByName(const AZStd::string& name) override;
void UpdateMaterialSelectionFromPhysicsAsset(
const Physics::ShapeConfiguration& shapeConfiguration,
Physics::MaterialSelection& materialSelection) override;
AZStd::shared_ptr<Physics::Material> GetGenericDefaultMaterial() override;
// MaterialManagerRequestsBus::Handler overrides...
void GetPxMaterials(const Physics::MaterialSelection& materialSelection, AZStd::vector<physx::PxMaterial*>& outMaterials) override;
AZStd::shared_ptr<Material> GetDefaultMaterial() override;
void ReleaseAllMaterials() override;
/// Connect to any necessary buses
void Connect();
/// Disconnect from any necessary buses
void Disconnect();
private:
using Materials = AZStd::unordered_map<AZ::Uuid, AZStd::shared_ptr<Material>>;
/// Search a material by id, if it exists already it returns its iterator,
/// if it doesn't exist it tries to create it and add it to the list.
/// If the material id is null or not part of the material library then the
/// iterator returned is end of material list.
Materials::iterator FindOrCreateMaterial(Physics::MaterialId materialId);
/// Search a material by name, if it exists already it returns its iterator,
/// if it doesn't exist it tries to create it and add it to the list.
/// If the material id is null or not part of the material library then the
/// iterator returned is end of material list.
Materials::iterator FindOrCreateMaterial(const AZStd::string& materialName);
/// Returns the material library of the project.
Physics::MaterialLibraryAsset* GetMaterialLibrary();
void OnPhysicsConfigurationChanged(const AzPhysics::SystemConfiguration* config);
void OnMaterialLibraryChanged(const AZ::Data::AssetId& materialLibraryAssetId);
Materials m_materials;
AZStd::shared_ptr<Material> m_defaultMaterial;
Physics::MaterialConfiguration m_defaultMaterialConfiguration;
AzPhysics::SystemEvents::OnConfigurationChangedEvent::Handler m_physicsConfigChangedHandler;
AzPhysics::SystemEvents::OnMaterialLibraryChangedEvent::Handler m_materialLibraryChangedHandler;
};
}