RuntimeMeshComponent.cpp
Go to the documentation of this file.
1 // Copyright 2016-2018 Chris Conway (Koderz). All Rights Reserved.
2 
3 #include "RuntimeMeshComponent.h"
5 #include "PhysicsEngine/BodySetup.h"
6 #include "PhysicsEngine/PhysicsSettings.h"
7 #include "IPhysXCookingModule.h"
8 #include "RuntimeMeshCore.h"
11 #include "RuntimeMeshSection.h"
13 #include "RuntimeMesh.h"
16 #include "NavigationSystem.h"
17 
18 
19 
20 DECLARE_CYCLE_STAT(TEXT("RMC - New Collision Data Recieved"), STAT_RuntimeMeshComponent_NewCollisionMeshReceived, STATGROUP_RuntimeMesh);
21 
22 
23 
24 
25 
26 URuntimeMeshComponent::URuntimeMeshComponent(const FObjectInitializer& ObjectInitializer)
27  : Super(ObjectInitializer)
28 #if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 21
29  , BodySetup(nullptr)
30 #endif
31 
32 {
33  SetNetAddressable();
34 }
35 
36 void URuntimeMeshComponent::EnsureHasRuntimeMesh()
37 {
38  if (RuntimeMeshReference == nullptr)
39  {
40  SetRuntimeMesh(NewObject<URuntimeMesh>(this));
41  }
42 }
43 
44 void URuntimeMeshComponent::SetRuntimeMesh(URuntimeMesh* NewMesh)
45 {
46  // Unlink from any existing runtime mesh
47  if (RuntimeMeshReference)
48  {
49  RuntimeMeshReference->UnRegisterLinkedComponent(this);
50  RuntimeMeshReference = nullptr;
51  }
52 
53  if (NewMesh)
54  {
55  RuntimeMeshReference = NewMesh;
56  RuntimeMeshReference->RegisterLinkedComponent(this);
57  }
58 
59  MarkRenderStateDirty();
60 }
61 
62 
63 void URuntimeMeshComponent::NewCollisionMeshReceived()
64 {
65  SCOPE_CYCLE_COUNTER(STAT_RuntimeMeshComponent_NewCollisionMeshReceived);
66 
67  // First recreate the physics state
68  RecreatePhysicsState();
69 
70  // Now update the navigation.
71 #if ENGINE_MAJOR_VERSION >= 4 && ENGINE_MINOR_VERSION >= 20
72  FNavigationSystem::UpdateComponentData(*this);
73 #else
74  if (UNavigationSystemV1::ShouldUpdateNavOctreeOnComponentChange() && IsRegistered())
75  {
76  UWorld* MyWorld = GetWorld();
77 
78  if (MyWorld != nullptr && FNavigationSystem::GetCurrent(MyWorld) != nullptr &&
79  (FNavigationSystem::GetCurrent(MyWorld)->ShouldAllowClientSideNavigation() || !MyWorld->IsNetMode(ENetMode::NM_Client)))
80  {
81  UNavigationSystemV1::UpdateComponentInNavOctree(*this);
82  }
83  }
84 #endif
85 }
86 
87 void URuntimeMeshComponent::NewBoundsReceived()
88 {
89  UpdateBounds();
90  MarkRenderTransformDirty();
91 }
92 
93 void URuntimeMeshComponent::ForceProxyRecreate()
94 {
95  MarkRenderStateDirty();
96 }
97 
98 
99 
100 
101 
102 void URuntimeMeshComponent::SendSectionCreation(int32 SectionIndex)
103 {
104  MarkRenderStateDirty();
105 }
106 
107 void URuntimeMeshComponent::SendSectionPropertiesUpdate(int32 SectionIndex)
108 {
109  MarkRenderStateDirty();
110 }
111 
112 FBoxSphereBounds URuntimeMeshComponent::CalcBounds(const FTransform& LocalToWorld) const
113 {
114  if (GetRuntimeMesh())
115  {
116  return GetRuntimeMesh()->GetLocalBounds().TransformBy(LocalToWorld);
117  }
118 
119  return FBoxSphereBounds(FSphere(FVector::ZeroVector, 1));
120 }
121 
122 
123 FPrimitiveSceneProxy* URuntimeMeshComponent::CreateSceneProxy()
124 {
125  return RuntimeMeshReference != nullptr ? new FRuntimeMeshComponentSceneProxy(this) : nullptr;
126 }
127 
128 UBodySetup* URuntimeMeshComponent::GetBodySetup()
129 {
130 #if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 21
131  return BodySetup;
132 #else
133  if (GetRuntimeMesh())
134  {
135  return GetRuntimeMesh()->BodySetup;
136  }
137 
138  return nullptr;
139 #endif
140 }
141 
142 
143 int32 URuntimeMeshComponent::GetNumMaterials() const
144 {
145  int32 RuntimeMeshSections = GetRuntimeMesh() != nullptr ? GetRuntimeMesh()->GetNumSections() : 0;
146 
147  return FMath::Max(Super::GetNumMaterials(), RuntimeMeshSections);
148 }
149 
150 void URuntimeMeshComponent::GetUsedMaterials(TArray<UMaterialInterface*>& OutMaterials, bool bGetDebugMaterials) const
151 {
152  if (URuntimeMesh* Mesh = GetRuntimeMesh())
153  {
154  Mesh->GetUsedMaterials(OutMaterials);
155  }
156 
157  Super::GetUsedMaterials(OutMaterials, bGetDebugMaterials);
158 }
159 
160 UMaterialInterface* URuntimeMeshComponent::GetMaterial(int32 ElementIndex) const
161 {
162  UMaterialInterface* Mat = Super::GetMaterial(ElementIndex);
163 
164  // Use default override material system
165  if (Mat != nullptr)
166  return Mat;
167 
168  // fallback to RM sections material
169  if (URuntimeMesh* Mesh = GetRuntimeMesh())
170  {
171  return Mesh->GetSectionMaterial(ElementIndex);
172  }
173 
174  // Had no RM/Section return null
175  return nullptr;
176 }
177 
178 UMaterialInterface* URuntimeMeshComponent::GetOverrideMaterial(int32 ElementIndex) const
179 {
180  return Super::GetMaterial(ElementIndex);
181 }
182 
183 int32 URuntimeMeshComponent::GetSectionIdFromCollisionFaceIndex(int32 FaceIndex) const
184 {
185  int32 SectionIndex = 0;
186 
187  if (URuntimeMesh* Mesh = GetRuntimeMesh())
188  {
189  SectionIndex = Mesh->GetSectionIdFromCollisionFaceIndex(FaceIndex);
190  }
191 
192  return SectionIndex;
193 }
194 
195 void URuntimeMeshComponent::GetSectionIdAndFaceIdFromCollisionFaceIndex(int32 FaceIndex, int32 & SectionIndex, int32 & SectionFaceIndex) const
196 {
197  if (URuntimeMesh* Mesh = GetRuntimeMesh())
198  {
199  Mesh->GetSectionIdAndFaceIdFromCollisionFaceIndex(FaceIndex, SectionIndex, SectionFaceIndex);
200  }
201 }
202 
203 UMaterialInterface* URuntimeMeshComponent::GetMaterialFromCollisionFaceIndex(int32 FaceIndex, int32& SectionIndex) const
204 {
205  UMaterialInterface* Result = nullptr;
206  SectionIndex = 0;
207 
208  if (URuntimeMesh* Mesh = GetRuntimeMesh())
209  {
210  Result = Mesh->GetMaterialFromCollisionFaceIndex(FaceIndex, SectionIndex);
211  }
212 
213  return Result;
214 }
215 
216 
217 
218 void URuntimeMeshComponent::Serialize(FArchive& Ar)
219 {
220  Super::Serialize(Ar);
221 
222  // This is a no-op serialization handler that can read all the old data
223  // but does nothing with it
225  {
227  //if (AActor* Actor = GetOwner())
228  //{
229  // if (!Actor->HasAnyFlags(RF_ClassDefaultObject))
230  // {
231  // Actor->RerunConstructionScripts();
232  // }
233  //}
234  }
235 }
236 
237 
238 
239 void URuntimeMeshComponent::PostLoad()
240 {
241  Super::PostLoad();
242 
243  if (RuntimeMeshReference)
244  {
245  RuntimeMeshReference->RegisterLinkedComponent(this);
246  }
247 }
248 
249 
250 #if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 22
251 
252 bool URuntimeMeshComponent::GetPhysicsTriMeshData(struct FTriMeshCollisionData* CollisionData, bool InUseAllTriData)
253 {
254  URuntimeMesh* RuntimeMesh = GetRuntimeMesh();
255  if (RuntimeMesh)
256  {
257  return RuntimeMesh->GetPhysicsTriMeshData(CollisionData, InUseAllTriData);
258  }
259 
260  return false;
261 }
262 
263 bool URuntimeMeshComponent::ContainsPhysicsTriMeshData(bool InUseAllTriData) const
264 {
265  URuntimeMesh* RuntimeMesh = GetRuntimeMesh();
266  if (RuntimeMesh)
267  {
268  return RuntimeMesh->ContainsPhysicsTriMeshData(InUseAllTriData);
269  }
270  return false;
271 }
272 
273 #endif
274 
275 #if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 21
276 
277 UBodySetup* URuntimeMeshComponent::CreateNewBodySetup()
278 {
279  UBodySetup* NewBodySetup = NewObject<UBodySetup>(this, NAME_None, (IsTemplate() ? RF_Public : RF_NoFlags));
280  NewBodySetup->BodySetupGuid = FGuid::NewGuid();
281 
282  return NewBodySetup;
283 }
284 
285 void URuntimeMeshComponent::FinishPhysicsAsyncCook(UBodySetup* FinishedBodySetup)
286 {
287  //SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_AsyncCollisionFinish);
288  check(IsInGameThread());
289 
290  int32 FoundIdx;
291  if (AsyncBodySetupQueue.Find(FinishedBodySetup, FoundIdx))
292  {
293  // The new body was found in the array meaning it's newer so use it
294  BodySetup = FinishedBodySetup;
295 
296  // Shift down all remaining body setups, removing any old setups
297  for (int32 Index = FoundIdx + 1; Index < AsyncBodySetupQueue.Num(); Index++)
298  {
299  AsyncBodySetupQueue[Index - (FoundIdx + 1)] = AsyncBodySetupQueue[Index];
300  AsyncBodySetupQueue[Index] = nullptr;
301  }
302  AsyncBodySetupQueue.SetNum(AsyncBodySetupQueue.Num() - (FoundIdx + 1));
303 
304  NewCollisionMeshReceived();
305  }
306 }
307 
308 void URuntimeMeshComponent::UpdateCollision(bool bForceCookNow)
309 {
310  //SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_CollisionUpdate);
311  check(IsInGameThread());
312  // HORU: workaround for a nullpointer
313  if (!GetRuntimeMesh())
314  return;
315  //check(GetRuntimeMesh());
316 
317  UWorld* World = GetWorld();
318  const bool bShouldCookAsync = !bForceCookNow && World && World->IsGameWorld() && GetRuntimeMesh()->bUseAsyncCooking;
319 
320  if (bShouldCookAsync)
321  {
322  UBodySetup* NewBodySetup = CreateNewBodySetup();
323  AsyncBodySetupQueue.Add(NewBodySetup);
324 
325  GetRuntimeMesh()->SetBasicBodySetupParameters(NewBodySetup);
326  GetRuntimeMesh()->CopyCollisionElementsToBodySetup(NewBodySetup);
327 
328  NewBodySetup->CreatePhysicsMeshesAsync(
329  FOnAsyncPhysicsCookFinished::CreateUObject(this, &URuntimeMeshComponent::FinishPhysicsAsyncCook, NewBodySetup));
330  }
331  else
332  {
333  AsyncBodySetupQueue.Empty();
334  UBodySetup* NewBodySetup = CreateNewBodySetup();
335 
336  // Change body setup guid
337  NewBodySetup->BodySetupGuid = FGuid::NewGuid();
338 
339  GetRuntimeMesh()->SetBasicBodySetupParameters(NewBodySetup);
340  GetRuntimeMesh()->CopyCollisionElementsToBodySetup(NewBodySetup);
341 
342  // Update meshes
343  NewBodySetup->bHasCookedCollisionData = true;
344  NewBodySetup->InvalidatePhysicsData();
345  NewBodySetup->CreatePhysicsMeshes();
346 
347  BodySetup = NewBodySetup;
348  NewCollisionMeshReceived();
349  }
350 }
351 
352 #endif
353 
354 bool URuntimeMeshComponent::IsAsyncCollisionCookingPending() const
355 {
356  return AsyncBodySetupQueue.Num() != 0;
357 }
virtual bool GetPhysicsTriMeshData(struct FTriMeshCollisionData *CollisionData, bool InUseAllTriData) override
Definition: RuntimeMesh.cpp:99
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
Definition: model-views.h:260
struct Index Index
Definition: sqlite3.c:11789
void RegisterLinkedComponent(URuntimeMeshComponent *NewComponent)
Definition: RuntimeMesh.cpp:85


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:41