Files
UnrealEngineUWP/Engine/Source/Runtime/PhysicsCore/Private/PhysicalMaterial.cpp
benn gallagher 9ff531aa82 Fixed access to inner physics materials during update. If an update is requested before we've made the physics engine material we would hit an ensure. This was harmless but it's due to not correctly accessing the material during the update - this fix sets it up correctly.
#rb Cedric.Caillaud
#jira UE-126497
#preflight 61489e7cb4b2fb00016c9c5a

#ROBOMERGE-AUTHOR: benn.gallagher
#ROBOMERGE-SOURCE: CL 17571348 in //UE5/Main/...
#ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v871-17566257)

[CL 17571353 by benn gallagher in ue5-release-engine-test branch]
2021-09-20 11:45:35 -04:00

139 lines
3.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
PhysicalMaterial.cpp
=============================================================================*/
#include "PhysicalMaterials/PhysicalMaterial.h"
#include "PhysicalMaterials/PhysicalMaterialPropertyBase.h"
#include "UObject/UObjectIterator.h"
#if WITH_CHAOS
#include "Chaos/PhysicalMaterials.h"
#endif
UDEPRECATED_PhysicalMaterialPropertyBase::UDEPRECATED_PhysicalMaterialPropertyBase(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
UPhysicalMaterial::UPhysicalMaterial(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
Friction = 0.7f;
StaticFriction = 0.f;
Restitution = 0.3f;
RaiseMassToPower = 0.75f;
Density = 1.0f;
SleepLinearVelocityThreshold = 1.f;
SleepAngularVelocityThreshold = 0.05f;
SleepCounterThreshold = 4;
DestructibleDamageThresholdScale = 1.0f;
bOverrideFrictionCombineMode = false;
UserData = FChaosUserData(this);
}
UPhysicalMaterial::UPhysicalMaterial(FVTableHelper& Helper)
: Super(Helper)
{
}
UPhysicalMaterial::~UPhysicalMaterial() = default;
#if WITH_EDITOR
void UPhysicalMaterial::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
bool bSkipUpdate = false;
if(!MaterialHandle)
{
// If we don't currently have a material calling GetPhysicsMaterial will already call update as a side effect
// to set the initial state - so we can skip it in that case.
bSkipUpdate = true;
}
FPhysicsMaterialHandle& PhysMaterial = GetPhysicsMaterial();
if(!bSkipUpdate)
{
FChaosEngineInterface::UpdateMaterial(*MaterialHandle, this);
}
Super::PostEditChangeProperty(PropertyChangedEvent);
}
void UPhysicalMaterial::RebuildPhysicalMaterials()
{
for (FThreadSafeObjectIterator Iter(UPhysicalMaterial::StaticClass()); Iter; ++Iter)
{
if (UPhysicalMaterial * PhysicalMaterial = Cast<UPhysicalMaterial>(*Iter))
{
if(!PhysicalMaterial->MaterialHandle)
{
PhysicalMaterial->MaterialHandle = MakeUnique<FPhysicsMaterialHandle>();
}
FChaosEngineInterface::UpdateMaterial(*PhysicalMaterial->MaterialHandle, PhysicalMaterial);
}
}
}
#endif // WITH_EDITOR
void UPhysicalMaterial::PostLoad()
{
Super::PostLoad();
// we're removing physical material property, so convert to Material type
if (GetLinkerUEVersion() < VER_UE4_REMOVE_PHYSICALMATERIALPROPERTY)
{
if (PhysicalMaterialProperty_DEPRECATED)
{
SurfaceType = PhysicalMaterialProperty_DEPRECATED->ConvertToSurfaceType();
}
}
}
void UPhysicalMaterial::FinishDestroy()
{
if(MaterialHandle)
{
FChaosEngineInterface::ReleaseMaterial(*MaterialHandle);
}
Super::FinishDestroy();
}
FPhysicsMaterialHandle& UPhysicalMaterial::GetPhysicsMaterial()
{
if(!MaterialHandle)
{
MaterialHandle = MakeUnique<FPhysicsMaterialHandle>();
}
if(!MaterialHandle->IsValid())
{
*MaterialHandle = FChaosEngineInterface::CreateMaterial(this);
check(MaterialHandle->IsValid());
FChaosEngineInterface::SetUserData(*MaterialHandle, &UserData);
FChaosEngineInterface::UpdateMaterial(*MaterialHandle, this);
}
return *MaterialHandle;
}
//This is a bit of a hack, should probably just have a default material live in PhysicsCore instead of in Engine
static UPhysicalMaterial* GEngineDefaultPhysMaterial = nullptr;
void UPhysicalMaterial::SetEngineDefaultPhysMaterial(UPhysicalMaterial* Material)
{
GEngineDefaultPhysMaterial = Material;
}
EPhysicalSurface UPhysicalMaterial::DetermineSurfaceType(UPhysicalMaterial const* PhysicalMaterial)
{
if (PhysicalMaterial == NULL)
{
PhysicalMaterial = GEngineDefaultPhysMaterial;
}
return PhysicalMaterial->SurfaceType;
}