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
275 lines
12 KiB
C++
275 lines
12 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 "EditorSystemComponent.h"
|
|
#include <AzCore/Interface/Interface.h>
|
|
#include <AzCore/Serialization/SerializeContext.h>
|
|
#include <AzFramework/Physics/SystemBus.h>
|
|
#include <AzFramework/Physics/Collision/CollisionEvents.h>
|
|
#include <AzFramework/Physics/Common/PhysicsSimulatedBody.h>
|
|
|
|
#include <IEditor.h>
|
|
#include <ISurfaceType.h>
|
|
|
|
#include <Editor/ConfigStringLineEditCtrl.h>
|
|
#include <Editor/EditorJointConfiguration.h>
|
|
#include <Editor/EditorWindow.h>
|
|
#include <Editor/PropertyTypes.h>
|
|
#include <System/PhysXSystem.h>
|
|
|
|
namespace PhysX
|
|
{
|
|
constexpr const char* DefaultAssetFilename = "SurfaceTypeMaterialLibrary";
|
|
constexpr const char* TemplateAssetFilename = "PhysX/TemplateMaterialLibrary";
|
|
|
|
static AZStd::optional<AZ::Data::Asset<AZ::Data::AssetData>> GetMaterialLibraryTemplate()
|
|
{
|
|
const auto& assetType = AZ::AzTypeInfo<Physics::MaterialLibraryAsset>::Uuid();
|
|
|
|
AZStd::vector<AZStd::string> assetTypeExtensions;
|
|
AZ::AssetTypeInfoBus::Event(assetType, &AZ::AssetTypeInfo::GetAssetTypeExtensions, assetTypeExtensions);
|
|
|
|
if (assetTypeExtensions.size() == 1)
|
|
{
|
|
// Constructing the path to the library asset
|
|
const AZStd::string& assetExtension = assetTypeExtensions[0];
|
|
|
|
// Use the path relative to the asset root to avoid hardcoding full path in the configuration
|
|
AZStd::string relativePath = TemplateAssetFilename;
|
|
AzFramework::StringFunc::Path::ReplaceExtension(relativePath, assetExtension.c_str());
|
|
|
|
AZ::Data::AssetId assetId;
|
|
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
|
assetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, relativePath.c_str(), assetType, false /*autoRegisterIfNotFound*/);
|
|
|
|
if (assetId.IsValid())
|
|
{
|
|
return AZ::Data::AssetManager::Instance().GetAsset<Physics::MaterialLibraryAsset>(assetId, AZ::Data::AssetLoadBehavior::NoLoad);
|
|
}
|
|
}
|
|
|
|
return AZStd::nullopt;
|
|
}
|
|
|
|
static AZStd::optional<AZ::Data::Asset<AZ::Data::AssetData>> CreateMaterialLibrary(const AZStd::string& fullTargetFilePath, const AZStd::string& relativePath)
|
|
{
|
|
AZ::IO::FileIOStream fileStream(fullTargetFilePath.c_str(), AZ::IO::OpenMode::ModeWrite);
|
|
if (fileStream.IsOpen())
|
|
{
|
|
const auto& assetType = AZ::AzTypeInfo<Physics::MaterialLibraryAsset>::Uuid();
|
|
AZ::Data::AssetId assetId;
|
|
|
|
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
|
assetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, relativePath.c_str(), assetType, true /*autoRegisterIfNotFound*/);
|
|
|
|
AZ::Data::Asset<AZ::Data::AssetData> newAsset =
|
|
AZ::Data::AssetManager::Instance().GetAsset(assetId, assetType, AZ::Data::AssetLoadBehavior::Default);
|
|
|
|
if (auto* newMaterialLibraryData = azrtti_cast<Physics::MaterialLibraryAsset*>(newAsset.GetData()))
|
|
{
|
|
if (auto templateLibraryOpt = GetMaterialLibraryTemplate())
|
|
{
|
|
if (const auto* templateMaterialLibData = azrtti_cast<Physics::MaterialLibraryAsset*>(templateLibraryOpt->GetData()))
|
|
{
|
|
templateLibraryOpt->QueueLoad();
|
|
templateLibraryOpt->BlockUntilLoadComplete();
|
|
|
|
// Fill the newly created material library using the template data
|
|
for (const auto& materialData : templateMaterialLibData->GetMaterialsData())
|
|
{
|
|
newMaterialLibraryData->AddMaterialData(materialData);
|
|
}
|
|
|
|
// check it out in the source control system
|
|
AzToolsFramework::SourceControlCommandBus::Broadcast(
|
|
&AzToolsFramework::SourceControlCommandBus::Events::RequestEdit, fullTargetFilePath.c_str(), true /*allowMultiCheckout*/,
|
|
[](bool /*success*/, const AzToolsFramework::SourceControlFileInfo& /*info*/) {});
|
|
|
|
// Save the material library asset into a file
|
|
auto assetHandler = AZ::Data::AssetManager::Instance().GetHandler(assetType);
|
|
if (assetHandler->SaveAssetData(newAsset, &fileStream))
|
|
{
|
|
return newAsset;
|
|
}
|
|
else
|
|
{
|
|
AZ_Error(
|
|
"PhysX", false,
|
|
"CreateSurfaceTypeMaterialLibrary: Unable to save Surface Types Material Library Asset to %s",
|
|
fullTargetFilePath.c_str());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return AZStd::nullopt;
|
|
}
|
|
|
|
void EditorSystemComponent::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
EditorJointLimitConfig::Reflect(context);
|
|
EditorJointLimitPairConfig::Reflect(context);
|
|
EditorJointLimitConeConfig::Reflect(context);
|
|
EditorJointConfig::Reflect(context);
|
|
|
|
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<EditorSystemComponent, AZ::Component>()
|
|
->Version(1);
|
|
}
|
|
}
|
|
|
|
void EditorSystemComponent::Activate()
|
|
{
|
|
Physics::EditorWorldBus::Handler::BusConnect();
|
|
AzToolsFramework::EditorContextMenuBus::Handler::BusConnect();
|
|
|
|
m_onMaterialLibraryLoadErrorEventHandler = AzPhysics::SystemEvents::OnMaterialLibraryLoadErrorEvent::Handler(
|
|
[this]([[maybe_unused]] AzPhysics::SystemEvents::MaterialLibraryLoadErrorType error)
|
|
{
|
|
// Attempt to set/create the default material library if there was an error
|
|
if (auto* physxSystem = GetPhysXSystem())
|
|
{
|
|
if (auto retrievedMaterialLibrary = RetrieveDefaultMaterialLibrary())
|
|
{
|
|
physxSystem->UpdateMaterialLibrary(retrievedMaterialLibrary.value());
|
|
}
|
|
}
|
|
}
|
|
);
|
|
|
|
if (auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
|
|
{
|
|
AzPhysics::SceneConfiguration editorWorldConfiguration = physicsSystem->GetDefaultSceneConfiguration();
|
|
editorWorldConfiguration.m_sceneName = AzPhysics::EditorPhysicsSceneName;
|
|
m_editorWorldSceneHandle = physicsSystem->AddScene(editorWorldConfiguration);
|
|
physicsSystem->RegisterOnMaterialLibraryLoadErrorEventHandler(m_onMaterialLibraryLoadErrorEventHandler);
|
|
}
|
|
|
|
PhysX::RegisterConfigStringLineEditHandler(); // Register custom unique string line edit control
|
|
PhysX::Editor::RegisterPropertyTypes();
|
|
|
|
AzToolsFramework::EditorEvents::Bus::Handler::BusConnect();
|
|
AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusConnect();
|
|
}
|
|
|
|
void EditorSystemComponent::Deactivate()
|
|
{
|
|
AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusDisconnect();
|
|
AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect();
|
|
AzToolsFramework::EditorContextMenuBus::Handler::BusDisconnect();
|
|
Physics::EditorWorldBus::Handler::BusDisconnect();
|
|
|
|
if (auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
|
|
{
|
|
physicsSystem->RemoveScene(m_editorWorldSceneHandle);
|
|
}
|
|
m_editorWorldSceneHandle = AzPhysics::InvalidSceneHandle;
|
|
|
|
m_onMaterialLibraryLoadErrorEventHandler.Disconnect();
|
|
}
|
|
|
|
AzPhysics::SceneHandle EditorSystemComponent::GetEditorSceneHandle() const
|
|
{
|
|
return m_editorWorldSceneHandle;
|
|
}
|
|
|
|
void EditorSystemComponent::OnStartPlayInEditorBegin()
|
|
{
|
|
if (auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
|
|
{
|
|
if (AzPhysics::Scene* scene = physicsSystem->GetScene(m_editorWorldSceneHandle))
|
|
{
|
|
scene->SetEnabled(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void EditorSystemComponent::OnStopPlayInEditor()
|
|
{
|
|
if (auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
|
|
{
|
|
if (AzPhysics::Scene* scene = physicsSystem->GetScene(m_editorWorldSceneHandle))
|
|
{
|
|
scene->SetEnabled(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
void EditorSystemComponent::PopulateEditorGlobalContextMenu([[maybe_unused]] QMenu* menu, [[maybe_unused]] const AZ::Vector2& point, [[maybe_unused]] int flags)
|
|
{
|
|
|
|
}
|
|
|
|
void EditorSystemComponent::NotifyRegisterViews()
|
|
{
|
|
PhysX::Editor::EditorWindow::RegisterViewClass();
|
|
}
|
|
|
|
AZStd::optional<AZ::Data::Asset<AZ::Data::AssetData>> EditorSystemComponent::RetrieveDefaultMaterialLibrary()
|
|
{
|
|
AZ::Data::AssetId resultAssetId;
|
|
|
|
auto assetType = AZ::AzTypeInfo<Physics::MaterialLibraryAsset>::Uuid();
|
|
|
|
AZStd::vector<AZStd::string> assetTypeExtensions;
|
|
AZ::AssetTypeInfoBus::Event(assetType, &AZ::AssetTypeInfo::GetAssetTypeExtensions, assetTypeExtensions);
|
|
|
|
if (assetTypeExtensions.size() == 1)
|
|
{
|
|
// Constructing the path to the library asset
|
|
const AZStd::string& assetExtension = assetTypeExtensions[0];
|
|
|
|
// Use the path relative to the asset root to avoid hardcoding full path in the configuration
|
|
AZStd::string relativePath = DefaultAssetFilename;
|
|
AzFramework::StringFunc::Path::ReplaceExtension(relativePath, assetExtension.c_str());
|
|
|
|
// Try to find an already existing material library
|
|
AZ::Data::AssetCatalogRequestBus::BroadcastResult(resultAssetId,
|
|
&AZ::Data::AssetCatalogRequests::GetAssetIdByPath, relativePath.c_str(), azrtti_typeid<Physics::MaterialLibraryAsset>(), false /*autoRegisterIfNotFound*/);
|
|
|
|
if (!resultAssetId.IsValid())
|
|
{
|
|
// No file for the default material library, create it
|
|
const char* assetRoot = AZ::IO::FileIOBase::GetInstance()->GetAlias("@devassets@");
|
|
AZStd::string fullPath;
|
|
AzFramework::StringFunc::Path::ConstructFull(assetRoot, DefaultAssetFilename, assetExtension.c_str(), fullPath);
|
|
|
|
if (auto materialLibraryOpt = CreateMaterialLibrary(fullPath, relativePath))
|
|
{
|
|
return materialLibraryOpt;
|
|
}
|
|
else
|
|
{
|
|
AZ_Warning("PhysX", false,
|
|
"CreateMaterialLibrary: Failed to create material library at %s. "
|
|
"Please check if the file is writable", fullPath.c_str());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AZ::Data::Asset<AZ::Data::AssetData> existingMaterialLibrary =
|
|
AZ::Data::AssetManager::Instance().GetAsset<Physics::MaterialLibraryAsset>(resultAssetId, AZ::Data::AssetLoadBehavior::NoLoad);
|
|
|
|
return existingMaterialLibrary;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AZ_Warning("PhysX", false,
|
|
"RetrieveDefaultMaterialLibrary: Number of extensions for the physics material library asset is %u"
|
|
" but should be 1. Please check if the asset registered itself with the asset system correctly",
|
|
assetTypeExtensions.size())
|
|
}
|
|
|
|
return AZStd::nullopt;
|
|
}
|
|
}
|
|
|