You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
9.8 KiB
C++
234 lines
9.8 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.
|
|
*
|
|
*/
|
|
|
|
#include <PhysX_precompiled.h>
|
|
|
|
#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 <I3DEngine.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
|
|
{
|
|
static bool CreateSurfaceTypeMaterialLibrary(const AZStd::string & targetFilePath)
|
|
{
|
|
auto assetType = AZ::AzTypeInfo<Physics::MaterialLibraryAsset>::Uuid();
|
|
|
|
// Create File
|
|
AZ::Data::Asset<AZ::Data::AssetData> newAsset = AZ::Data::AssetManager::Instance().CreateAsset(AZ::Uuid::CreateRandom(), assetType, AZ::Data::AssetLoadBehavior::Default);
|
|
|
|
AZ::IO::FileIOStream fileStream(targetFilePath.c_str(), AZ::IO::OpenMode::ModeWrite);
|
|
if (fileStream.IsOpen())
|
|
{
|
|
Physics::MaterialLibraryAsset* materialLibraryAsset = azrtti_cast<Physics::MaterialLibraryAsset*>(newAsset.GetData());
|
|
if (materialLibraryAsset)
|
|
{
|
|
IEditor* editor = nullptr;
|
|
AzToolsFramework::EditorRequests::Bus::BroadcastResult(editor, &AzToolsFramework::EditorRequests::GetEditor);
|
|
|
|
ISurfaceTypeEnumerator* surfaceTypeEnumerator = nullptr;
|
|
if (surfaceTypeEnumerator)
|
|
{
|
|
// Enumerate through CryEngine surface types and create a Physics API material for each of them
|
|
for (ISurfaceType* pSurfaceType = surfaceTypeEnumerator->GetFirst(); pSurfaceType != nullptr;
|
|
pSurfaceType = surfaceTypeEnumerator->GetNext())
|
|
{
|
|
const ISurfaceType::SPhysicalParams& physicalParams = pSurfaceType->GetPhyscalParams();
|
|
|
|
Physics::MaterialFromAssetConfiguration configuration;
|
|
configuration.m_configuration = Physics::MaterialConfiguration();
|
|
configuration.m_configuration.m_dynamicFriction = AZ::GetMax(0.0f, physicalParams.friction);
|
|
configuration.m_configuration.m_staticFriction = AZ::GetMax(0.0f, physicalParams.friction);
|
|
configuration.m_configuration.m_restitution = AZ::GetClamp(physicalParams.bouncyness, 0.0f, 1.0f);
|
|
configuration.m_configuration.m_surfaceType = pSurfaceType->GetType();
|
|
configuration.m_id = Physics::MaterialId::Create();
|
|
|
|
materialLibraryAsset->AddMaterialData(configuration);
|
|
}
|
|
}
|
|
|
|
// check it out in the source control system
|
|
AzToolsFramework::SourceControlCommandBus::Broadcast(
|
|
&AzToolsFramework::SourceControlCommandBus::Events::RequestEdit, targetFilePath.c_str(), true,
|
|
[](bool /*success*/, const AzToolsFramework::SourceControlFileInfo& /*info*/) {});
|
|
|
|
// Save the material library asset into a file
|
|
auto assetHandler = const_cast<AZ::Data::AssetHandler*>(AZ::Data::AssetManager::Instance().GetHandler(assetType));
|
|
if (assetHandler->SaveAssetData(newAsset, &fileStream))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
AZ_Error("PhysX", false,
|
|
"CreateSurfaceTypeMaterialLibrary: Unable to save Surface Types Material Library Asset to %s",
|
|
targetFilePath.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
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();
|
|
|
|
if (auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
|
|
{
|
|
AzPhysics::SceneConfiguration editorWorldConfiguration = physicsSystem->GetDefaultSceneConfiguration();
|
|
editorWorldConfiguration.m_sceneName = AzPhysics::EditorPhysicsSceneName;
|
|
m_editorWorldSceneHandle = physicsSystem->AddScene(editorWorldConfiguration);
|
|
}
|
|
|
|
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();
|
|
Physics::EditorWorldBus::Handler::BusDisconnect();
|
|
|
|
if (auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
|
|
{
|
|
physicsSystem->RemoveScene(m_editorWorldSceneHandle);
|
|
}
|
|
m_editorWorldSceneHandle = AzPhysics::InvalidSceneHandle;
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
AZ::Data::AssetId EditorSystemComponent::GenerateSurfaceTypesLibrary()
|
|
{
|
|
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)
|
|
{
|
|
const char* DefaultAssetFilename = "SurfaceTypeMaterialLibrary";
|
|
|
|
// 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);
|
|
|
|
if (!resultAssetId.IsValid())
|
|
{
|
|
const char* assetRoot = AZ::IO::FileIOBase::GetInstance()->GetAlias("@devassets@");
|
|
|
|
AZStd::string fullPath;
|
|
AzFramework::StringFunc::Path::ConstructFull(assetRoot, DefaultAssetFilename, assetExtension.c_str(), fullPath);
|
|
|
|
if (CreateSurfaceTypeMaterialLibrary(fullPath))
|
|
{
|
|
// Find out the asset ID for the material library we've just created
|
|
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
|
resultAssetId, &AZ::Data::AssetCatalogRequests::GetAssetIdByPath,
|
|
relativePath.c_str(),
|
|
azrtti_typeid<Physics::MaterialLibraryAsset>(), true);
|
|
}
|
|
else
|
|
{
|
|
AZ_Warning("PhysX", false,
|
|
"GenerateSurfaceTypesLibrary: Failed to create material library at %s. "
|
|
"Please check if the file is writable", fullPath.c_str());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AZ_Warning("PhysX", false,
|
|
"GenerateSurfaceTypesLibrary: 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 resultAssetId;
|
|
}
|
|
}
|
|
|