1f9b284de2
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> # Conflicts: # Code/Editor/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin_precompiled.h # Code/Editor/Plugins/EditorCommon/EditorCommon_precompiled.h # Code/Editor/Plugins/EditorCommon/stdafx.cpp # Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h # Code/Editor/Plugins/PerforcePlugin/PerforcePlugin_precompiled.h # Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsTool_precompiled.h # Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFramework_precompiled.h # Code/Tools/AssetProcessor/native/precompiled.h # Code/Tools/Standalone/StandaloneTools_precompiled.h # Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer_precompiled.h # Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageProcessing_precompiled.h # Gems/Atom/RHI/DX12/Code/Source/RHI/Atom_RHI_DX12_precompiled.h # Gems/Atom/RHI/Metal/Code/Include/Platform/Mac/Atom_RHI_Metal_precompiled_Platform.h # Gems/Atom/RHI/Metal/Code/Include/Platform/iOS/Atom_RHI_Metal_precompiled_Platform.h # Gems/Atom/RHI/Metal/Code/Source/Atom_RHI_Metal_precompiled.h # Gems/Atom/RHI/Metal/Code/atom_rhi_metal_common_files.cmake # Gems/Atom/RHI/Null/Code/Source/Atom_RHI_Null_precompiled.h # Gems/Atom/RHI/Null/Code/atom_rhi_null_common_files.cmake # Gems/Atom/RHI/Vulkan/Code/Include/Platform/Android/Atom_RHI_Vulkan_precompiled_Platform.h # Gems/Atom/RHI/Vulkan/Code/Include/Platform/Linux/Atom_RHI_Vulkan_precompiled_Platform.h # Gems/Atom/RHI/Vulkan/Code/Include/Platform/Mac/Atom_RHI_Vulkan_precompiled_Platform.h # Gems/Atom/RHI/Vulkan/Code/Include/Platform/Windows/Atom_RHI_Vulkan_precompiled_Platform.h # Gems/Atom/RHI/Vulkan/Code/Source/Atom_RHI_Vulkan_precompiled.h # Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp # Gems/Atom/RHI/Vulkan/Code/atom_rhi_vulkan_common_files.cmake # Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont_precompiled.h # Gems/Blast/Code/Source/StdAfx.cpp # Gems/Camera/Code/Source/Camera_precompiled.h # Gems/EMotionFX/Code/Source/EMotionFX_precompiled.h # Gems/FastNoise/Code/Source/FastNoise_precompiled.h # Gems/Gestures/Code/Source/Gestures_precompiled.h # Gems/GradientSignal/Code/Source/GradientSignal_precompiled.h # Gems/GraphCanvas/Code/precompiled.h # Gems/ImGui/Code/Source/ImGui_precompiled.h # Gems/InAppPurchases/Code/Source/InAppPurchases_precompiled.h # Gems/LmbrCentral/Code/Source/LmbrCentral_precompiled.h # Gems/LmbrCentral/Code/Tests/ShapeGeometryUtilTest.cpp # Gems/LyShine/Code/Editor/UiCanvasEditor_precompiled.h # Gems/LyShine/Code/Source/Animation/LyShine_precompiled.h # Gems/LyShine/Code/Source/LyShine_precompiled.h # Gems/LyShineExamples/Code/Source/LyShineExamples_precompiled.h # Gems/Maestro/Code/Source/Cinematics/Maestro_precompiled.h # Gems/Maestro/Code/Source/Maestro_precompiled.h # Gems/MessagePopup/Code/Source/MessagePopup_precompiled.h # Gems/Metastream/Code/Source/Metastream_precompiled.h # Gems/Microphone/Code/Source/Microphone_precompiled.h # Gems/Multiplayer/Code/Source/Multiplayer_precompiled.h # Gems/PhysX/Code/NumericalMethods/Source/NumericalMethods_precompiled.h # Gems/PhysX/Code/Source/PhysXUnsupported_precompiled.h # Gems/PhysX/Code/Source/PhysX_precompiled.h # Gems/PhysX/Code/physx_unsupported_files.cmake # Gems/PhysXDebug/Code/Source/PhysXDebugUnsupported_precompiled.h # Gems/PhysXDebug/Code/Source/PhysXDebug_precompiled.h # Gems/ScriptCanvas/Code/Editor/precompiled.h # Gems/ScriptCanvas/Code/Source/precompiled.h # Gems/ScriptCanvasDeveloper/Code/Source/precompiled.h # Gems/ScriptCanvasPhysics/Code/Source/ScriptCanvasPhysics_precompiled.h # Gems/ScriptEvents/Code/Source/precompiled.h # Gems/ScriptEvents/Code/Tests/Editor/EditorTests.cpp # Gems/ScriptedEntityTweener/Code/Source/ScriptedEntityTweener_precompiled.h # Gems/SliceFavorites/Code/Source/SliceFavorites_precompiled.h # Gems/StartingPointCamera/Code/Source/StartingPointCamera_precompiled.h # Gems/StartingPointInput/Code/Source/StartingPointInput_precompiled.h # Gems/StartingPointMovement/Code/Source/StartingPointMovement_precompiled.h # Gems/SurfaceData/Code/Source/SurfaceData_precompiled.h # Gems/TextureAtlas/Code/Source/TextureAtlas_precompiled.h # Gems/TickBusOrderViewer/Code/Source/TickBusOrderViewer_precompiled.h # Gems/Twitch/Code/Source/Twitch_precompiled.h # Gems/VirtualGamepad/Code/Source/VirtualGamepad_precompiled.h # Gems/WhiteBox/Code/Source/WhiteBoxUnsupported_precompiled.h # Gems/WhiteBox/Code/Source/WhiteBox_precompiled.h
336 lines
14 KiB
C++
336 lines
14 KiB
C++
/*
|
|
* 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
|
|
*
|
|
*/
|
|
|
|
#include <AzCore/Component/ComponentApplicationBus.h>
|
|
#include <AzCore/IO/FileIO.h>
|
|
#include <AzCore/Serialization/EditContext.h>
|
|
#include <AzCore/Serialization/SerializeContext.h>
|
|
#include <Blast/BlastMaterial.h>
|
|
#include <NvBlastExtDamageShaders.h>
|
|
|
|
namespace
|
|
{
|
|
const AZ::Data::Asset<Blast::BlastMaterialLibraryAsset> s_invalidMaterialLibrary = {
|
|
AZ::Data::AssetLoadBehavior::NoLoad};
|
|
} // namespace
|
|
|
|
namespace Blast
|
|
{
|
|
class BlastMaterialLibraryAssetEventHandler : public AZ::SerializeContext::IEventHandler
|
|
{
|
|
void OnReadBegin(void* classPtr)
|
|
{
|
|
auto matAsset = static_cast<BlastMaterialLibraryAsset*>(classPtr);
|
|
matAsset->GenerateMissingIds();
|
|
}
|
|
};
|
|
|
|
void BlastMaterialConfiguration::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
BlastMaterialId::Reflect(context);
|
|
BlastMaterialFromAssetConfiguration::Reflect(context);
|
|
|
|
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
|
if (serializeContext)
|
|
{
|
|
serializeContext->Class<BlastMaterialConfiguration>()
|
|
->Version(1)
|
|
->Field("MaterialName", &BlastMaterialConfiguration::m_materialName)
|
|
->Field("Health", &BlastMaterialConfiguration::m_health)
|
|
->Field("ForceDivider", &BlastMaterialConfiguration::m_forceDivider)
|
|
->Field("MinDamageThreshold", &BlastMaterialConfiguration::m_minDamageThreshold)
|
|
->Field("MaxDamageThreshold", &BlastMaterialConfiguration::m_maxDamageThreshold)
|
|
->Field("StressLinearFactor", &BlastMaterialConfiguration::m_stressLinearFactor)
|
|
->Field("StressAngularFactor", &BlastMaterialConfiguration::m_stressAngularFactor);
|
|
|
|
AZ::EditContext* editContext = serializeContext->GetEditContext();
|
|
if (editContext)
|
|
{
|
|
editContext->Class<BlastMaterialConfiguration>("", "")
|
|
->ClassElement(AZ::Edit::ClassElements::EditorData, "Blast Material")
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastMaterialConfiguration::m_materialName, "Material name",
|
|
"Name of the material")
|
|
->Attribute(AZ::Edit::Attributes::MaxLength, 64)
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastMaterialConfiguration::m_health, "Health",
|
|
"All damage is subtracted from this value")
|
|
->Attribute(AZ::Edit::Attributes::Min, 0.f)
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastMaterialConfiguration::m_forceDivider, "Force divider",
|
|
"All damage which originates with force is divided by this amount")
|
|
->Attribute(AZ::Edit::Attributes::Min, 0.f)
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastMaterialConfiguration::m_minDamageThreshold,
|
|
"Minimum damage threshold", "Incoming damage is discarded if it is less than this value")
|
|
->Attribute(AZ::Edit::Attributes::Min, 0.f)
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastMaterialConfiguration::m_maxDamageThreshold,
|
|
"Maximum damage threshold", "Incoming damage is capped at this value")
|
|
->Attribute(AZ::Edit::Attributes::Min, 0.f)
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastMaterialConfiguration::m_stressLinearFactor,
|
|
"Stress linear factor",
|
|
"Factor with which linear stress such as gravity, direct impulse, collision is applied")
|
|
->Attribute(AZ::Edit::Attributes::Min, 0.f)
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastMaterialConfiguration::m_stressAngularFactor,
|
|
"Stress angular factor", "Factor with which angular stress is applied")
|
|
->Attribute(AZ::Edit::Attributes::Min, 0.f);
|
|
}
|
|
}
|
|
}
|
|
|
|
void BlastMaterialLibraryAsset::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
|
if (serializeContext)
|
|
{
|
|
serializeContext->Class<BlastMaterialLibraryAsset>()
|
|
->Version(1)
|
|
->Attribute(AZ::Edit::Attributes::EnableForAssetEditor, true)
|
|
->EventHandler<BlastMaterialLibraryAssetEventHandler>()
|
|
->Field("Properties", &BlastMaterialLibraryAsset::m_materialLibrary);
|
|
|
|
AZ::EditContext* editContext = serializeContext->GetEditContext();
|
|
if (editContext)
|
|
{
|
|
editContext->Class<BlastMaterialLibraryAsset>("", "")
|
|
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastMaterialLibraryAsset::m_materialLibrary, "Blast Materials",
|
|
"List of blast materials")
|
|
->Attribute("EditButton", "")
|
|
->Attribute(AZ::Edit::Attributes::ForceAutoExpand, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
void BlastActorConfiguration::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<BlastActorConfiguration>()
|
|
->Version(1)
|
|
->Field("CollisionLayer", &BlastActorConfiguration::m_collisionLayer)
|
|
->Field("CollisionGroupId", &BlastActorConfiguration::m_collisionGroupId)
|
|
->Field("Simulated", &BlastActorConfiguration::m_isSimulated)
|
|
->Field("InSceneQueries", &BlastActorConfiguration::m_isInSceneQueries)
|
|
->Field("CcdEnabled", &BlastActorConfiguration::m_isCcdEnabled)
|
|
->Field("ColliderTag", &BlastActorConfiguration::m_tag);
|
|
|
|
if (auto editContext = serializeContext->GetEditContext())
|
|
{
|
|
editContext->Class<BlastActorConfiguration>("BlastActorConfiguration", "Configuration for a collider")
|
|
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
|
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastActorConfiguration::m_isSimulated, "Simulated",
|
|
"If set, this actor's collider will partake in collision in the physical simulation")
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastActorConfiguration::m_isInSceneQueries, "In Scene Queries",
|
|
"If set, this actor's collider will be visible for scene queries")
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastActorConfiguration::m_isCcdEnabled, "CCD Enabled",
|
|
"If set, actor's rigid body will have CCD enabled")
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastActorConfiguration::m_collisionLayer, "Collision Layer",
|
|
"The collision layer assigned to the collider")
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastActorConfiguration::m_collisionGroupId, "Collides With",
|
|
"The collision group containing the layers this collider collides with")
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastActorConfiguration::m_tag, "Tag",
|
|
"Tag used to identify colliders from one another");
|
|
}
|
|
}
|
|
}
|
|
|
|
void BlastMaterialFromAssetConfiguration::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
|
if (serializeContext)
|
|
{
|
|
serializeContext->Class<BlastMaterialFromAssetConfiguration>()
|
|
->Version(1)
|
|
->Field("Configuration", &BlastMaterialFromAssetConfiguration::m_configuration)
|
|
->Field("UID", &BlastMaterialFromAssetConfiguration::m_id);
|
|
|
|
AZ::EditContext* editContext = serializeContext->GetEditContext();
|
|
if (editContext)
|
|
{
|
|
editContext->Class<BlastMaterialFromAssetConfiguration>("", "")
|
|
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
|
->DataElement(
|
|
AZ::Edit::UIHandlers::Default, &BlastMaterialFromAssetConfiguration::m_configuration,
|
|
"Blast Material", "Blast Material properties")
|
|
->Attribute(AZ::Edit::Attributes::ForceAutoExpand, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
void BlastMaterialId::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<Blast::BlastMaterialId>()->Version(1)->Field(
|
|
"BlastMaterialId", &Blast::BlastMaterialId::m_id);
|
|
}
|
|
}
|
|
|
|
BlastMaterial::BlastMaterial(const BlastMaterialConfiguration& configuration)
|
|
{
|
|
m_health = configuration.m_health;
|
|
// This is not an error, health in ExtPxMaterial is actually damage divider and not health
|
|
m_material.health = configuration.m_forceDivider;
|
|
m_material.minDamageThreshold = configuration.m_minDamageThreshold;
|
|
m_material.maxDamageThreshold = configuration.m_maxDamageThreshold;
|
|
m_stressLinearFactor = configuration.m_stressLinearFactor;
|
|
m_stressAngularFactor = configuration.m_stressAngularFactor;
|
|
m_name = configuration.m_materialName;
|
|
}
|
|
|
|
const AZStd::string& BlastMaterial::GetMaterialName() const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
float BlastMaterial::GetHealth() const
|
|
{
|
|
return m_health;
|
|
}
|
|
|
|
float BlastMaterial::GetForceDivider() const
|
|
{
|
|
return m_material.health;
|
|
}
|
|
|
|
float BlastMaterial::GetMinDamageThreshold() const
|
|
{
|
|
return m_material.minDamageThreshold;
|
|
}
|
|
|
|
float BlastMaterial::GetMaxDamageThreshold() const
|
|
{
|
|
return m_material.maxDamageThreshold;
|
|
}
|
|
|
|
float BlastMaterial::GetStressLinearFactor() const
|
|
{
|
|
return m_stressLinearFactor;
|
|
}
|
|
|
|
float BlastMaterial::GetStressAngularFactor() const
|
|
{
|
|
return m_stressAngularFactor;
|
|
}
|
|
|
|
float BlastMaterial::GetNormalizedDamage(const float damage) const
|
|
{
|
|
return m_material.getNormalizedDamage(damage * m_material.health);
|
|
}
|
|
|
|
Nv::Blast::ExtStressSolverSettings BlastMaterial::GetStressSolverSettings(uint32_t iterationsCount) const
|
|
{
|
|
auto settings = Nv::Blast::ExtStressSolverSettings();
|
|
settings.hardness = m_material.health;
|
|
settings.stressLinearFactor = m_stressLinearFactor;
|
|
settings.stressAngularFactor = m_stressAngularFactor;
|
|
settings.graphReductionLevel = 0;
|
|
settings.bondIterationsPerFrame = iterationsCount;
|
|
return settings;
|
|
}
|
|
|
|
void* BlastMaterial::GetNativePointer()
|
|
{
|
|
return &m_material;
|
|
}
|
|
|
|
bool BlastMaterialLibraryAsset::GetDataForMaterialId(
|
|
const BlastMaterialId& materialId, BlastMaterialFromAssetConfiguration& configuration) const
|
|
{
|
|
const auto foundMaterialConfiguration = AZStd::find_if(
|
|
m_materialLibrary.begin(), m_materialLibrary.end(),
|
|
[materialId](const auto& data)
|
|
{
|
|
return data.m_id == materialId;
|
|
});
|
|
|
|
if (foundMaterialConfiguration != m_materialLibrary.end())
|
|
{
|
|
configuration = *foundMaterialConfiguration;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool BlastMaterialLibraryAsset::HasDataForMaterialId(const BlastMaterialId& materialId) const
|
|
{
|
|
auto foundMaterialConfiguration = AZStd::find_if(
|
|
m_materialLibrary.begin(), m_materialLibrary.end(),
|
|
[materialId](const auto& data)
|
|
{
|
|
return data.m_id == materialId;
|
|
});
|
|
return foundMaterialConfiguration != m_materialLibrary.end();
|
|
}
|
|
|
|
bool BlastMaterialLibraryAsset::GetDataForMaterialName(
|
|
const AZStd::string& materialName, BlastMaterialFromAssetConfiguration& configuration) const
|
|
{
|
|
auto foundMaterialConfiguration = AZStd::find_if(
|
|
m_materialLibrary.begin(), m_materialLibrary.end(),
|
|
[&materialName](const auto& data)
|
|
{
|
|
return data.m_configuration.m_materialName == materialName;
|
|
});
|
|
|
|
if (foundMaterialConfiguration != m_materialLibrary.end())
|
|
{
|
|
configuration = *foundMaterialConfiguration;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void BlastMaterialLibraryAsset::AddMaterialData(const BlastMaterialFromAssetConfiguration& data)
|
|
{
|
|
BlastMaterialFromAssetConfiguration existingConfiguration;
|
|
if (!data.m_id.IsNull() && GetDataForMaterialId(data.m_id, existingConfiguration))
|
|
{
|
|
AZ_Warning("BlastMaterialLibraryAsset", false, "Trying to add material that already exists");
|
|
return;
|
|
}
|
|
|
|
m_materialLibrary.push_back(data);
|
|
GenerateMissingIds();
|
|
}
|
|
|
|
void BlastMaterialLibraryAsset::GenerateMissingIds()
|
|
{
|
|
for (auto& materialData : m_materialLibrary)
|
|
{
|
|
if (materialData.m_id.IsNull())
|
|
{
|
|
materialData.m_id = BlastMaterialId::Create();
|
|
}
|
|
}
|
|
}
|
|
|
|
BlastMaterialId BlastMaterialId::Create()
|
|
{
|
|
BlastMaterialId id;
|
|
id.m_id = AZ::Uuid::Create();
|
|
return id;
|
|
}
|
|
} // namespace Blast
|