5 #include "PhysicsEngine/BodySetup.h" 6 #include "PhysicsEngine/PhysicsSettings.h" 7 #include "IPhysXCookingModule.h" 16 #include "NavigationSystem.h" 20 DECLARE_CYCLE_STAT(TEXT(
"RMC - New Collision Data Recieved"), STAT_RuntimeMeshComponent_NewCollisionMeshReceived, STATGROUP_RuntimeMesh);
26 URuntimeMeshComponent::URuntimeMeshComponent(
const FObjectInitializer& ObjectInitializer)
27 : Super(ObjectInitializer)
28 #if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 21
36 void URuntimeMeshComponent::EnsureHasRuntimeMesh()
38 if (RuntimeMeshReference ==
nullptr)
40 SetRuntimeMesh(NewObject<URuntimeMesh>(
this));
44 void URuntimeMeshComponent::SetRuntimeMesh(
URuntimeMesh* NewMesh)
47 if (RuntimeMeshReference)
49 RuntimeMeshReference->UnRegisterLinkedComponent(
this);
50 RuntimeMeshReference =
nullptr;
55 RuntimeMeshReference = NewMesh;
59 MarkRenderStateDirty();
63 void URuntimeMeshComponent::NewCollisionMeshReceived()
65 SCOPE_CYCLE_COUNTER(STAT_RuntimeMeshComponent_NewCollisionMeshReceived);
68 RecreatePhysicsState();
71 #if ENGINE_MAJOR_VERSION >= 4 && ENGINE_MINOR_VERSION >= 20 72 FNavigationSystem::UpdateComponentData(*
this);
74 if (UNavigationSystemV1::ShouldUpdateNavOctreeOnComponentChange() && IsRegistered())
76 UWorld* MyWorld = GetWorld();
78 if (MyWorld !=
nullptr && FNavigationSystem::GetCurrent(MyWorld) !=
nullptr &&
79 (FNavigationSystem::GetCurrent(MyWorld)->ShouldAllowClientSideNavigation() || !MyWorld->IsNetMode(ENetMode::NM_Client)))
81 UNavigationSystemV1::UpdateComponentInNavOctree(*
this);
87 void URuntimeMeshComponent::NewBoundsReceived()
90 MarkRenderTransformDirty();
93 void URuntimeMeshComponent::ForceProxyRecreate()
95 MarkRenderStateDirty();
102 void URuntimeMeshComponent::SendSectionCreation(int32 SectionIndex)
104 MarkRenderStateDirty();
107 void URuntimeMeshComponent::SendSectionPropertiesUpdate(int32 SectionIndex)
109 MarkRenderStateDirty();
112 FBoxSphereBounds URuntimeMeshComponent::CalcBounds(
const FTransform& LocalToWorld)
const 114 if (GetRuntimeMesh())
116 return GetRuntimeMesh()->GetLocalBounds().TransformBy(LocalToWorld);
119 return FBoxSphereBounds(FSphere(FVector::ZeroVector, 1));
123 FPrimitiveSceneProxy* URuntimeMeshComponent::CreateSceneProxy()
128 UBodySetup* URuntimeMeshComponent::GetBodySetup()
130 #if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 21 133 if (GetRuntimeMesh())
135 return GetRuntimeMesh()->BodySetup;
143 int32 URuntimeMeshComponent::GetNumMaterials()
const 145 int32 RuntimeMeshSections = GetRuntimeMesh() !=
nullptr ? GetRuntimeMesh()->GetNumSections() : 0;
147 return FMath::Max(Super::GetNumMaterials(), RuntimeMeshSections);
150 void URuntimeMeshComponent::GetUsedMaterials(TArray<UMaterialInterface*>& OutMaterials,
bool bGetDebugMaterials)
const 154 Mesh->GetUsedMaterials(OutMaterials);
157 Super::GetUsedMaterials(OutMaterials, bGetDebugMaterials);
160 UMaterialInterface* URuntimeMeshComponent::GetMaterial(int32 ElementIndex)
const 162 UMaterialInterface* Mat = Super::GetMaterial(ElementIndex);
171 return Mesh->GetSectionMaterial(ElementIndex);
178 UMaterialInterface* URuntimeMeshComponent::GetOverrideMaterial(int32 ElementIndex)
const 180 return Super::GetMaterial(ElementIndex);
183 int32 URuntimeMeshComponent::GetSectionIdFromCollisionFaceIndex(int32 FaceIndex)
const 185 int32 SectionIndex = 0;
189 SectionIndex = Mesh->GetSectionIdFromCollisionFaceIndex(FaceIndex);
195 void URuntimeMeshComponent::GetSectionIdAndFaceIdFromCollisionFaceIndex(int32 FaceIndex, int32 & SectionIndex, int32 & SectionFaceIndex)
const 199 Mesh->GetSectionIdAndFaceIdFromCollisionFaceIndex(FaceIndex, SectionIndex, SectionFaceIndex);
203 UMaterialInterface* URuntimeMeshComponent::GetMaterialFromCollisionFaceIndex(int32 FaceIndex, int32& SectionIndex)
const 205 UMaterialInterface* Result =
nullptr;
210 Result = Mesh->GetMaterialFromCollisionFaceIndex(FaceIndex, SectionIndex);
218 void URuntimeMeshComponent::Serialize(FArchive& Ar)
220 Super::Serialize(Ar);
239 void URuntimeMeshComponent::PostLoad()
243 if (RuntimeMeshReference)
245 RuntimeMeshReference->RegisterLinkedComponent(
this);
250 #if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 22 252 bool URuntimeMeshComponent::GetPhysicsTriMeshData(
struct FTriMeshCollisionData* CollisionData,
bool InUseAllTriData)
263 bool URuntimeMeshComponent::ContainsPhysicsTriMeshData(
bool InUseAllTriData)
const 275 #if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 21 277 UBodySetup* URuntimeMeshComponent::CreateNewBodySetup()
279 UBodySetup* NewBodySetup = NewObject<UBodySetup>(
this, NAME_None, (IsTemplate() ? RF_Public : RF_NoFlags));
280 NewBodySetup->BodySetupGuid = FGuid::NewGuid();
285 void URuntimeMeshComponent::FinishPhysicsAsyncCook(UBodySetup* FinishedBodySetup)
288 check(IsInGameThread());
291 if (AsyncBodySetupQueue.Find(FinishedBodySetup, FoundIdx))
294 BodySetup = FinishedBodySetup;
297 for (int32
Index = FoundIdx + 1;
Index < AsyncBodySetupQueue.Num();
Index++)
299 AsyncBodySetupQueue[
Index - (FoundIdx + 1)] = AsyncBodySetupQueue[
Index];
300 AsyncBodySetupQueue[
Index] =
nullptr;
302 AsyncBodySetupQueue.SetNum(AsyncBodySetupQueue.Num() - (FoundIdx + 1));
304 NewCollisionMeshReceived();
308 void URuntimeMeshComponent::UpdateCollision(
bool bForceCookNow)
311 check(IsInGameThread());
313 if (!GetRuntimeMesh())
317 UWorld* World = GetWorld();
318 const bool bShouldCookAsync = !bForceCookNow && World && World->IsGameWorld() && GetRuntimeMesh()->bUseAsyncCooking;
320 if (bShouldCookAsync)
322 UBodySetup* NewBodySetup = CreateNewBodySetup();
323 AsyncBodySetupQueue.Add(NewBodySetup);
325 GetRuntimeMesh()->SetBasicBodySetupParameters(NewBodySetup);
326 GetRuntimeMesh()->CopyCollisionElementsToBodySetup(NewBodySetup);
328 NewBodySetup->CreatePhysicsMeshesAsync(
329 FOnAsyncPhysicsCookFinished::CreateUObject(
this, &URuntimeMeshComponent::FinishPhysicsAsyncCook, NewBodySetup));
333 AsyncBodySetupQueue.Empty();
334 UBodySetup* NewBodySetup = CreateNewBodySetup();
337 NewBodySetup->BodySetupGuid = FGuid::NewGuid();
339 GetRuntimeMesh()->SetBasicBodySetupParameters(NewBodySetup);
340 GetRuntimeMesh()->CopyCollisionElementsToBodySetup(NewBodySetup);
343 NewBodySetup->bHasCookedCollisionData =
true;
344 NewBodySetup->InvalidatePhysicsData();
345 NewBodySetup->CreatePhysicsMeshes();
347 BodySetup = NewBodySetup;
348 NewCollisionMeshReceived();
354 bool URuntimeMeshComponent::IsAsyncCollisionCookingPending()
const 356 return AsyncBodySetupQueue.Num() != 0;
virtual bool GetPhysicsTriMeshData(struct FTriMeshCollisionData *CollisionData, bool InUseAllTriData) override
virtual bool ContainsPhysicsTriMeshData(bool InUseAllTriData) const override
DECLARE_CYCLE_STAT(TEXT("RMC - New Collision Data Recieved"), STAT_RuntimeMeshComponent_NewCollisionMeshReceived, STATGROUP_RuntimeMesh)
static const textual_icon check
static bool Serialize(FArchive &Ar)
void RegisterLinkedComponent(URuntimeMeshComponent *NewComponent)