5 #include "CoreMinimal.h" 12 #include "RuntimeMesh.generated.h" 16 class URuntimeMeshComponent;
28 TWeakObjectPtr<URuntimeMesh>
Owner;
31 virtual void Tick(
float DeltaTime);
46 UCLASS(HideCategories = Object, BlueprintType)
47 class RUNTIMEMESHCOMPONENT_API
URuntimeMesh : public UObject, public IInterface_CollisionDataProvider
49 GENERATED_UCLASS_BODY()
56 UPROPERTY(EditAnywhere, Category =
"RuntimeMesh")
57 TArray<UMaterialInterface*> Materials;
61 bool bCollisionIsDirty;
67 TArray<TWeakObjectPtr<URuntimeMeshComponent>> LinkedComponents;
73 UPROPERTY(EditAnywhere, Category = "RuntimeMesh")
74 bool bUseComplexAsSimpleCollision;
81 UPROPERTY(EditAnywhere, Category = "RuntimeMesh")
82 bool bUseAsyncCooking;
87 UPROPERTY(EditAnywhere, Category = "RuntimeMesh")
88 bool bShouldSerializeMeshData;
91 UPROPERTY(EditAnywhere, Category = "RuntimeMesh")
96 UBodySetup* BodySetup;
100 TArray<UBodySetup*> AsyncBodySetupQueue;
104 UFUNCTION(BlueprintCallable, Category = "Components|RuntimeMesh")
105 bool ShouldSerializeMeshData()
107 return bShouldSerializeMeshData;
110 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
111 void SetShouldSerializeMeshData(
bool bShouldSerialize)
113 bShouldSerializeMeshData = bShouldSerialize;
117 UPROPERTY(BlueprintAssignable, Category =
"Components|RuntimeMesh")
118 FRuntimeMeshCollisionUpdatedDelegate CollisionUpdated;
129 check(IsInGameThread());
130 return Data->GetRenderProxy();
135 void CreateMeshSection(int32 SectionIndex,
bool bWantsHighPrecisionTangents,
bool bWantsHighPrecisionUVs, int32 NumUVs,
bool bWants32BitIndices,
bool bCreateCollision,
EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average)
137 check(IsInGameThread());
138 GetRuntimeMeshData()->CreateMeshSection(SectionIndex, bWantsHighPrecisionTangents, bWantsHighPrecisionUVs, NumUVs, bWants32BitIndices, bCreateCollision, UpdateFrequency);
141 template<
typename VertexType0,
typename IndexType>
142 FORCEINLINE
void CreateMeshSection(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<IndexType>& InTriangles,
bool bCreateCollision =
false,
145 check(IsInGameThread());
146 GetRuntimeMeshData()->CreateMeshSection<VertexType0, IndexType>(SectionIndex, InVertices0, InTriangles, bCreateCollision, UpdateFrequency, UpdateFlags);
149 template<
typename VertexType0,
typename IndexType>
150 FORCEINLINE
void CreateMeshSection(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<IndexType>& InTriangles,
const FBox& BoundingBox,
153 check(IsInGameThread());
154 GetRuntimeMeshData()->CreateMeshSection<VertexType0, IndexType>(SectionIndex, InVertices0, InTriangles, BoundingBox, bCreateCollision, UpdateFrequency, UpdateFlags);
157 template<
typename VertexType0,
typename VertexType1,
typename IndexType>
158 FORCEINLINE
void CreateMeshSectionDualBuffer(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<IndexType>& InTriangles,
bool bCreateCollision =
false,
161 check(IsInGameThread());
162 GetRuntimeMeshData()->CreateMeshSectionDualBuffer<VertexType0, VertexType1, IndexType>(SectionIndex, InVertices0,
163 InVertices1, InTriangles, bCreateCollision, UpdateFrequency, UpdateFlags);
166 template<
typename VertexType0,
typename VertexType1,
typename IndexType>
167 FORCEINLINE
void CreateMeshSectionDualBuffer(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<IndexType>& InTriangles,
const FBox& BoundingBox,
170 check(IsInGameThread());
171 GetRuntimeMeshData()->CreateMeshSectionDualBuffer<VertexType0, VertexType1, IndexType>(SectionIndex, InVertices0,
172 InVertices1, InTriangles, BoundingBox, bCreateCollision, UpdateFrequency, UpdateFlags);
175 template<
typename VertexType0,
typename VertexType1,
typename VertexType2,
typename IndexType>
176 FORCEINLINE
void CreateMeshSectionTripleBuffer(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<VertexType2>& InVertices2, TArray<IndexType>& InTriangles,
179 check(IsInGameThread());
180 GetRuntimeMeshData()->CreateMeshSectionTripleBuffer<VertexType0, VertexType1, VertexType2, IndexType>(SectionIndex,
181 InVertices0, InVertices1, InVertices2, InTriangles, bCreateCollision, UpdateFrequency, UpdateFlags);
184 template<
typename VertexType0,
typename VertexType1,
typename VertexType2,
typename IndexType>
185 FORCEINLINE
void CreateMeshSectionTripleBuffer(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<VertexType2>& InVertices2, TArray<IndexType>& InTriangles,
188 check(IsInGameThread());
189 GetRuntimeMeshData()->CreateMeshSectionTripleBuffer<VertexType0, VertexType1, VertexType2, IndexType>(SectionIndex,
190 InVertices0, InVertices1, InVertices2, InTriangles, BoundingBox, bCreateCollision, UpdateFrequency, UpdateFlags);
195 template<
typename VertexType0>
199 check(IsInGameThread());
200 GetRuntimeMeshData()->UpdateMeshSection<VertexType0>(SectionId, InVertices0, UpdateFlags);
203 template<
typename VertexType0>
207 check(IsInGameThread());
208 GetRuntimeMeshData()->UpdateMeshSection<VertexType0>(SectionId, InVertices0, BoundingBox, UpdateFlags);
211 template<
typename VertexType0,
typename IndexType>
212 FORCEINLINE
void UpdateMeshSection(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<IndexType>& InTriangles,
215 check(IsInGameThread());
216 GetRuntimeMeshData()->UpdateMeshSection<VertexType0, IndexType>(SectionId, InVertices0, InTriangles, UpdateFlags);
219 template<
typename VertexType0,
typename IndexType>
220 FORCEINLINE
void UpdateMeshSection(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<IndexType>& InTriangles,
223 check(IsInGameThread());
224 GetRuntimeMeshData()->UpdateMeshSection<VertexType0, IndexType>(SectionId, InVertices0, InTriangles, BoundingBox, UpdateFlags);
227 template<
typename VertexType0,
typename VertexType1>
231 check(IsInGameThread());
232 GetRuntimeMeshData()->UpdateMeshSectionDualBuffer<VertexType0, VertexType1>(SectionId, InVertices0, InVertices1, UpdateFlags);
235 template<
typename VertexType0,
typename VertexType1>
239 check(IsInGameThread());
240 GetRuntimeMeshData()->UpdateMeshSectionDualBuffer<VertexType0, VertexType1>(SectionId, InVertices0, InVertices1, BoundingBox, UpdateFlags);
243 template<
typename VertexType0,
typename VertexType1,
typename IndexType>
247 check(IsInGameThread());
248 GetRuntimeMeshData()->UpdateMeshSectionDualBuffer<VertexType0, VertexType1, IndexType>(SectionId, InVertices0, InVertices1, InTriangles, UpdateFlags);
251 template<
typename VertexType0,
typename VertexType1,
typename IndexType>
252 FORCEINLINE
void UpdateMeshSectionDualBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<IndexType>& InTriangles,
255 check(IsInGameThread());
256 GetRuntimeMeshData()->UpdateMeshSectionDualBuffer<VertexType0, VertexType1, IndexType>(SectionId, InVertices0, InVertices1, InTriangles, BoundingBox, UpdateFlags);
259 template<
typename VertexType0,
typename VertexType1,
typename VertexType2>
260 FORCEINLINE
void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<VertexType2>& InVertices2,
263 check(IsInGameThread());
264 GetRuntimeMeshData()->UpdateMeshSectionTripleBuffer<VertexType0, VertexType1, VertexType2>(SectionId, InVertices0, InVertices1, InVertices2, UpdateFlags);
267 template<
typename VertexType0,
typename VertexType1,
typename VertexType2>
268 FORCEINLINE
void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<VertexType2>& InVertices2,
271 check(IsInGameThread());
272 GetRuntimeMeshData()->UpdateMeshSectionTripleBuffer<VertexType0, VertexType1, VertexType2>(SectionId, InVertices0, InVertices1, InVertices2, BoundingBox, UpdateFlags);
275 template<
typename VertexType0,
typename VertexType1,
typename VertexType2,
typename IndexType>
276 FORCEINLINE
void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<VertexType2>& InVertices2,
279 check(IsInGameThread());
280 GetRuntimeMeshData()->UpdateMeshSectionTripleBuffer<VertexType0, VertexType1, VertexType2, IndexType>(SectionId, InVertices0, InVertices1, InVertices2, InTriangles, UpdateFlags);
283 template<
typename VertexType0,
typename VertexType1,
typename VertexType2,
typename IndexType>
284 FORCEINLINE
void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<VertexType2>& InVertices2,
287 check(IsInGameThread());
288 GetRuntimeMeshData()->UpdateMeshSectionTripleBuffer<VertexType0, VertexType1, VertexType2, IndexType>(SectionId, InVertices0, InVertices1, InVertices2, InTriangles, BoundingBox, UpdateFlags);
293 template<
typename VertexType0>
296 check(IsInGameThread());
297 GetRuntimeMeshData()->UpdateMeshSectionPrimaryBuffer<VertexType0>(SectionId, InVertices0, UpdateFlags);
300 template<
typename VertexType0>
303 check(IsInGameThread());
304 GetRuntimeMeshData()->UpdateMeshSectionPrimaryBuffer<VertexType0>(SectionId, InVertices0, BoundingBox, UpdateFlags);
307 template<
typename VertexType1>
310 check(IsInGameThread());
311 GetRuntimeMeshData()->UpdateMeshSectionSecondaryBuffer<VertexType1>(SectionId, InVertices1, UpdateFlags);
314 template<
typename VertexType2>
317 check(IsInGameThread());
318 GetRuntimeMeshData()->UpdateMeshSectionTertiaryBuffer<VertexType2>(SectionId, InVertices2, UpdateFlags);
321 template<
typename IndexType>
324 check(IsInGameThread());
325 GetRuntimeMeshData()->UpdateMeshSectionTriangles<IndexType>(SectionId, InTriangles, UpdateFlags);
330 FORCEINLINE
void CreateMeshSection(int32 SectionId,
const TSharedPtr<FRuntimeMeshBuilder>& MeshData,
bool bCreateCollision =
false,
333 check(IsInGameThread());
334 GetRuntimeMeshData()->CreateMeshSection(SectionId, MeshData, bCreateCollision, UpdateFrequency, UpdateFlags);
337 FORCEINLINE
void CreateMeshSectionByMove(int32 SectionId,
const TSharedPtr<FRuntimeMeshBuilder>& MeshData,
bool bCreateCollision =
false,
340 check(IsInGameThread());
341 GetRuntimeMeshData()->CreateMeshSectionByMove(SectionId, MeshData, bCreateCollision, UpdateFrequency, UpdateFlags);
344 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
348 check(IsInGameThread());
349 GetRuntimeMeshData()->CreateMeshSection(SectionId, MeshData->GetMeshBuilder(), bCreateCollision, UpdateFrequency);
355 check(IsInGameThread());
356 GetRuntimeMeshData()->UpdateMeshSection(SectionId, MeshData, UpdateFlags);
361 check(IsInGameThread());
362 GetRuntimeMeshData()->UpdateMeshSectionByMove(SectionId, MeshData, UpdateFlags);
365 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
368 check(IsInGameThread());
369 GetRuntimeMeshData()->UpdateMeshSection(SectionId, MeshData->GetMeshBuilder());
375 check(IsInGameThread());
376 return GetRuntimeMeshData()->BeginSectionUpdate(SectionId, UpdateFlags);
381 check(IsInGameThread());
382 return GetRuntimeMeshData()->GetSectionReadonly(SectionId);
388 FORCEINLINE
void CreateMeshSection(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<int32>& Triangles,
const TArray<FVector>& Normals,
389 const TArray<FVector2D>& UV0,
const TArray<FColor>& Colors,
const TArray<FRuntimeMeshTangent>& Tangents,
bool bCreateCollision =
false,
391 bool bUseHighPrecisionTangents =
false,
bool bUseHighPrecisionUVs =
true)
393 check(IsInGameThread());
394 GetRuntimeMeshData()->CreateMeshSection(SectionIndex, Vertices, Triangles, Normals, UV0, Colors, Tangents,
395 bCreateCollision, UpdateFrequency, UpdateFlags, bUseHighPrecisionTangents, bUseHighPrecisionUVs);
398 FORCEINLINE
void CreateMeshSection(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<int32>& Triangles,
const TArray<FVector>& Normals,
399 const TArray<FVector2D>& UV0,
const TArray<FVector2D>& UV1,
const TArray<FColor>& Colors,
const TArray<FRuntimeMeshTangent>& Tangents,
401 bool bUseHighPrecisionTangents =
false,
bool bUseHighPrecisionUVs =
true)
403 check(IsInGameThread());
404 GetRuntimeMeshData()->CreateMeshSection(SectionIndex, Vertices, Triangles, Normals, UV0, UV1, Colors, Tangents,
405 bCreateCollision, UpdateFrequency, UpdateFlags, bUseHighPrecisionTangents, bUseHighPrecisionUVs);
409 FORCEINLINE
void UpdateMeshSection(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<FVector>& Normals,
const TArray<FVector2D>& UV0,
412 check(IsInGameThread());
413 GetRuntimeMeshData()->UpdateMeshSection(SectionIndex, Vertices, Normals, UV0, Colors, Tangents, UpdateFlags);
416 FORCEINLINE
void UpdateMeshSection(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<FVector>& Normals,
const TArray<FVector2D>& UV0,
419 check(IsInGameThread());
420 GetRuntimeMeshData()->UpdateMeshSection(SectionIndex, Vertices, Normals, UV0, UV1, Colors, Tangents, UpdateFlags);
423 FORCEINLINE
void UpdateMeshSection(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<int32>& Triangles,
const TArray<FVector>& Normals,
426 check(IsInGameThread());
427 GetRuntimeMeshData()->UpdateMeshSection(SectionIndex, Vertices, Triangles, Normals, UV0, Colors, Tangents, UpdateFlags);
430 FORCEINLINE
void UpdateMeshSection(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<int32>& Triangles,
const TArray<FVector>& Normals,
433 check(IsInGameThread());
434 GetRuntimeMeshData()->UpdateMeshSection(SectionIndex, Vertices, Triangles, Normals, UV0, UV1, Colors, Tangents, UpdateFlags);
439 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh", meta = (DisplayName =
"Create Mesh Section", AutoCreateRefTerm =
"Normals,Tangents,UV0,UV1,Colors"))
440 void CreateMeshSection_Blueprint(int32 SectionIndex, const TArray<FVector>& Vertices, const TArray<int32>& Triangles, const TArray<FVector>& Normals,
441 const TArray<
FRuntimeMeshTangent>& Tangents, const TArray<FVector2D>& UV0, const TArray<FVector2D>& UV1, const TArray<FLinearColor>& Colors,
442 bool bCreateCollision = false,
bool bCalculateNormalTangent = false,
bool bShouldCreateHardTangents = false,
bool bGenerateTessellationTriangles = false,
445 check(IsInGameThread());
446 GetRuntimeMeshData()->CreateMeshSection_Blueprint(SectionIndex, Vertices, Triangles, Normals, Tangents, UV0, UV1, Colors,
447 bCreateCollision, bCalculateNormalTangent, bShouldCreateHardTangents, bGenerateTessellationTriangles, UpdateFrequency, bUseHighPrecisionTangents, bUseHighPrecisionUVs);
450 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh", meta = (DisplayName =
"Update Mesh Section", AutoCreateRefTerm =
"Triangles,Normals,Tangents,UV0,UV1,Colors"))
451 void UpdateMeshSection_Blueprint(int32 SectionIndex, const TArray<FVector>& Vertices, const TArray<int32>& Triangles, const TArray<FVector>& Normals,
452 const TArray<
FRuntimeMeshTangent>& Tangents, const TArray<FVector2D>& UV0, const TArray<FVector2D>& UV1, const TArray<FLinearColor>& Colors,
453 bool bCalculateNormalTangent = false,
bool bShouldCreateHardTangents = false,
bool bGenerateTessellationTriangles = false)
455 check(IsInGameThread());
456 GetRuntimeMeshData()->UpdateMeshSection_Blueprint(SectionIndex, Vertices, Triangles, Normals, Tangents, UV0, UV1, Colors,
457 bCalculateNormalTangent, bShouldCreateHardTangents, bGenerateTessellationTriangles);
460 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh", meta = (DisplayName =
"Create Mesh Section Packed", AutoCreateRefTerm =
"Normals,Tangents,UV0,UV1,Colors"))
462 bool bCreateCollision = false,
bool bCalculateNormalTangent = false,
bool bShouldCreateHardTangents = false,
bool bGenerateTessellationTriangles = false,
EUpdateFrequency UpdateFrequency =
EUpdateFrequency::Average,
463 bool bUseHighPrecisionTangents = false,
bool bUseHighPrecisionUVs = true)
465 check(IsInGameThread());
466 GetRuntimeMeshData()->CreateMeshSectionPacked_Blueprint(SectionIndex, Vertices, Triangles, bCreateCollision, bCalculateNormalTangent, bShouldCreateHardTangents,
467 bGenerateTessellationTriangles, UpdateFrequency, bUseHighPrecisionTangents, bUseHighPrecisionUVs);
470 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh", meta = (DisplayName =
"Update Mesh Section Packed", AutoCreateRefTerm =
"Triangles,Normals,Tangents,UV0,UV1,Colors"))
472 bool bCalculateNormalTangent = false,
bool bShouldCreateHardTangents = false,
bool bGenerateTessellationTriangles = false)
474 check(IsInGameThread());
475 GetRuntimeMeshData()->UpdateMeshSectionPacked_Blueprint(SectionIndex, Vertices, Triangles, bCalculateNormalTangent, bShouldCreateHardTangents, bGenerateTessellationTriangles);
483 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
484 void SetSectionTessellationTriangles(int32 SectionId, const TArray<int32>& Triangles)
486 check(IsInGameThread());
487 GetRuntimeMeshData()->SetSectionTessellationTriangles(SectionId, Triangles);
490 template<
typename IndexType>
493 check(IsInGameThread());
494 GetRuntimeMeshData()->SetSectionTessellationTriangles(SectionId, Triangles);
500 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
501 void ClearMeshSection(int32 SectionIndex)
503 check(IsInGameThread());
504 GetRuntimeMeshData()->ClearMeshSection(SectionIndex);
508 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
511 check(IsInGameThread());
512 GetRuntimeMeshData()->ClearAllMeshSections();
516 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
517 void SetSectionMaterial(int32 SectionId, UMaterialInterface* Material)
519 check(IsInGameThread());
520 if (SectionId >= Materials.Num())
522 Materials.SetNum(SectionId + 1);
525 Materials[SectionId] = Material;
527 if (DoesSectionExist(SectionId))
529 ForceProxyRecreate();
533 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
534 UMaterialInterface* GetSectionMaterial(int32 SectionId)
536 check(IsInGameThread());
537 if (Materials.IsValidIndex(SectionId))
539 return Materials[SectionId];
546 check(IsInGameThread());
551 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
552 FBox GetSectionBoundingBox(int32 SectionIndex)
554 check(IsInGameThread());
555 return GetRuntimeMeshData()->GetSectionBoundingBox(SectionIndex);
559 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
560 void SetMeshSectionVisible(int32 SectionIndex,
bool bNewVisibility)
562 check(IsInGameThread());
563 GetRuntimeMeshData()->SetMeshSectionVisible(SectionIndex, bNewVisibility);
567 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
568 bool IsMeshSectionVisible(int32 SectionIndex)
const 570 check(IsInGameThread());
571 return GetRuntimeMeshData()->IsMeshSectionVisible(SectionIndex);
576 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
577 void SetMeshSectionCastsShadow(int32 SectionIndex,
bool bNewCastsShadow)
579 check(IsInGameThread());
580 GetRuntimeMeshData()->SetMeshSectionCastsShadow(SectionIndex, bNewCastsShadow);
584 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
585 bool IsMeshSectionCastingShadows(int32 SectionIndex)
const 587 check(IsInGameThread());
588 return GetRuntimeMeshData()->IsMeshSectionCastingShadows(SectionIndex);
593 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
594 void SetMeshSectionCollisionEnabled(int32 SectionIndex,
bool bNewCollisionEnabled)
596 check(IsInGameThread());
597 GetRuntimeMeshData()->SetMeshSectionCollisionEnabled(SectionIndex, bNewCollisionEnabled);
601 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
602 bool IsMeshSectionCollisionEnabled(int32 SectionIndex)
604 check(IsInGameThread());
605 return GetRuntimeMeshData()->IsMeshSectionCollisionEnabled(SectionIndex);
610 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
611 int32 GetNumSections()
const 613 check(IsInGameThread());
614 return GetRuntimeMeshData()->GetNumSections();
618 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
619 bool DoesSectionExist(int32 SectionIndex)
const 621 check(IsInGameThread());
622 return GetRuntimeMeshData()->DoesSectionExist(SectionIndex);
626 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
627 int32 GetAvailableSectionIndex()
const 629 check(IsInGameThread());
630 return GetRuntimeMeshData()->GetAvailableSectionIndex();
635 check(IsInGameThread());
636 return GetRuntimeMeshData()->GetSectionIds();
642 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
643 void SetMeshCollisionSection(int32 CollisionSectionIndex, const TArray<FVector>& Vertices, const TArray<int32>& Triangles)
645 check(IsInGameThread());
646 GetRuntimeMeshData()->SetMeshCollisionSection(CollisionSectionIndex, Vertices, Triangles);
649 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
650 void ClearMeshCollisionSection(int32 CollisionSectionIndex)
652 check(IsInGameThread());
653 GetRuntimeMeshData()->ClearMeshCollisionSection(CollisionSectionIndex);
656 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
657 void ClearAllMeshCollisionSections()
659 check(IsInGameThread());
660 GetRuntimeMeshData()->ClearAllMeshCollisionSections();
665 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
666 int32 AddConvexCollisionSection(TArray<FVector> ConvexVerts)
668 check(IsInGameThread());
669 return GetRuntimeMeshData()->AddConvexCollisionSection(ConvexVerts);
672 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
673 void SetConvexCollisionSection(int32 ConvexSectionIndex, TArray<FVector> ConvexVerts)
675 check(IsInGameThread());
676 GetRuntimeMeshData()->SetConvexCollisionSection(ConvexSectionIndex, ConvexVerts);
679 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
680 void ClearConvexCollisionSection(int32 ConvexSectionIndex)
682 check(IsInGameThread());
683 GetRuntimeMeshData()->RemoveConvexCollisionSection(ConvexSectionIndex);
686 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
687 void ClearAllConvexCollisionSections()
689 check(IsInGameThread());
690 GetRuntimeMeshData()->ClearConvexCollisionSections();
695 check(IsInGameThread());
696 GetRuntimeMeshData()->SetCollisionConvexMeshes(ConvexMeshes);
701 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
704 check(IsInGameThread());
705 return GetRuntimeMeshData()->AddCollisionBox(NewBox);
708 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
711 check(IsInGameThread());
712 GetRuntimeMeshData()->RemoveCollisionBox(
Index);
715 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
718 check(IsInGameThread());
719 GetRuntimeMeshData()->ClearCollisionBoxes();
722 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
725 check(IsInGameThread());
726 GetRuntimeMeshData()->SetCollisionBoxes(NewBoxes);
730 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
733 check(IsInGameThread());
734 return GetRuntimeMeshData()->AddCollisionSphere(NewSphere);
737 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
740 check(IsInGameThread());
741 GetRuntimeMeshData()->RemoveCollisionSphere(
Index);
744 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
747 check(IsInGameThread());
748 GetRuntimeMeshData()->ClearCollisionSpheres();
751 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
754 check(IsInGameThread());
755 GetRuntimeMeshData()->SetCollisionSpheres(NewSpheres);
759 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
762 check(IsInGameThread());
763 return GetRuntimeMeshData()->AddCollisionCapsule(NewCapsule);
766 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
769 check(IsInGameThread());
770 GetRuntimeMeshData()->RemoveCollisionCapsule(
Index);
773 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
776 check(IsInGameThread());
777 GetRuntimeMeshData()->ClearCollisionCapsules();
780 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
783 check(IsInGameThread());
784 GetRuntimeMeshData()->SetCollisionCapsules(NewCapsules);
789 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
790 void CookCollisionNow();
792 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
793 void SetCollisionUseComplexAsSimple(
bool bNewValue)
795 check(IsInGameThread());
796 bUseComplexAsSimpleCollision = bNewValue;
797 MarkCollisionDirty();
800 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
801 bool IsCollisionUsingComplexAsSimple()
803 check(IsInGameThread());
804 return bUseComplexAsSimpleCollision;
807 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
808 void SetCollisionUseAsyncCooking(
bool bNewValue)
810 check(IsInGameThread());
811 bUseAsyncCooking = bNewValue;
814 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
815 bool IsCollisionUsingAsyncCooking()
817 check(IsInGameThread());
818 return bUseAsyncCooking;
821 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
824 check(IsInGameThread());
825 CollisionMode = NewMode;
828 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
831 check(IsInGameThread());
832 return CollisionMode;
838 return GetRuntimeMeshData()->GetLocalBounds();
843 check(IsInGameThread());
858 void RegisterLinkedComponent(URuntimeMeshComponent* NewComponent);
859 void UnRegisterLinkedComponent(URuntimeMeshComponent* ComponentToRemove);
861 template<
typename Function>
864 bool bShouldPurge =
false;
865 for (TWeakObjectPtr<URuntimeMeshComponent> MeshReference : LinkedComponents)
867 if (URuntimeMeshComponent* Mesh = MeshReference.Get())
878 LinkedComponents = LinkedComponents.FilterByPredicate([](
const TWeakObjectPtr<URuntimeMeshComponent>& MeshReference)
880 return MeshReference.IsValid();
888 OutMaterials.Append(Materials.FilterByPredicate([](UMaterialInterface* Mat) ->
bool { return Mat != nullptr; }));
892 virtual bool GetPhysicsTriMeshData(
struct FTriMeshCollisionData* CollisionData,
bool InUseAllTriData)
override;
893 virtual bool ContainsPhysicsTriMeshData(
bool InUseAllTriData)
const override;
897 virtual void Serialize(FArchive& Ar)
override;
902 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
903 UMaterialInterface* GetMaterialFromCollisionFaceIndex(int32 FaceIndex, int32& SectionIndex)
const;
905 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
906 int32 GetSectionIdFromCollisionFaceIndex(int32 FaceIndex)
const;
908 UFUNCTION(BlueprintCallable, Category =
"Components|RuntimeMesh")
909 void GetSectionIdAndFaceIdFromCollisionFaceIndex(int32 FaceIndex, int32& SectionIndex, int32& SectionFaceIndex)
const;
914 void MarkCollisionDirty();
916 #if ENGINE_MAJOR_VERSION >= 4 && ENGINE_MINOR_VERSION >= 21 918 UBodySetup* CreateNewBodySetup();
921 void CopyCollisionElementsToBodySetup(UBodySetup* Setup);
923 void SetBasicBodySetupParameters(UBodySetup* Setup);
925 void UpdateCollision(
bool bForceCookNow =
false);
927 #if ENGINE_MAJOR_VERSION >= 4 && ENGINE_MINOR_VERSION >= 21 928 void FinishPhysicsAsyncCook(
bool bSuccess, UBodySetup* FinishedBodySetup);
930 void FinalizeNewCookedData();
936 return GetRuntimeMeshData()->EnsureProxyCreated(InFeatureLevel);
940 void UpdateLocalBounds();
942 void ForceProxyRecreate();
944 void SendSectionCreation(int32 SectionIndex);
946 void SendSectionPropertiesUpdate(int32 SectionIndex);
950 friend class URuntimeMeshComponent;
FORCEINLINE void UpdateMeshSection(int32 SectionId, const TSharedPtr< FRuntimeMeshBuilder > &MeshData, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void SetSectionTessellationTriangles(int32 SectionId, const TArray< IndexType > &Triangles)
FORCEINLINE void UpdateMeshSectionPrimaryBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
virtual bool IsTickableInEditor() const
typedef void(APIENTRY *GLDEBUGPROC)(GLenum source
FORCEINLINE void UpdateMeshSection(int32 SectionId, TArray< VertexType0 > &InVertices0, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void UpdateMeshSection(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< IndexType > &InTriangles, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void CreateMeshSection(int32 SectionIndex, bool bWantsHighPrecisionTangents, bool bWantsHighPrecisionUVs, int32 NumUVs, bool bWants32BitIndices, bool bCreateCollision, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average)
FORCEINLINE void UpdateMeshSectionDualBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< IndexType > &InTriangles, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void UpdateMeshSectionPrimaryBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< VertexType2 > &InVertices2, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void UpdateMeshSection(int32 SectionIndex, const TArray< FVector > &Vertices, const TArray< FVector > &Normals, const TArray< FVector2D > &UV0, const TArray< FVector2D > &UV1, const TArray< FColor > &Colors, const TArray< FRuntimeMeshTangent > &Tangents, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void CreateMeshSection(int32 SectionIndex, TArray< VertexType0 > &InVertices0, TArray< IndexType > &InTriangles, const FBox &BoundingBox, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void CreateMeshSectionDualBuffer(int32 SectionIndex, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< IndexType > &InTriangles, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void UpdateMeshSection(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< IndexType > &InTriangles, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void CreateMeshSectionDualBuffer(int32 SectionIndex, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< IndexType > &InTriangles, const FBox &BoundingBox, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
TUniquePtr< FRuntimeMeshScopedUpdater > BeginSectionUpdate(int32 SectionId, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
virtual UWorld * GetTickableGameObjectWorld() const
FBoxSphereBounds GetLocalBounds() const
TSharedRef< FRuntimeMeshData, ESPMode::ThreadSafe > FRuntimeMeshDataRef
virtual void Tick(float DeltaTime)
FORCEINLINE void CreateMeshSectionByMove(int32 SectionId, const TSharedPtr< FRuntimeMeshBuilder > &MeshData, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void UpdateMeshSectionDualBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< IndexType > &InTriangles, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void CreateMeshSectionTripleBuffer(int32 SectionIndex, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< VertexType2 > &InVertices2, TArray< IndexType > &InTriangles, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void UpdateMeshSection(int32 SectionIndex, const TArray< FVector > &Vertices, const TArray< int32 > &Triangles, const TArray< FVector > &Normals, const TArray< FVector2D > &UV0, const TArray< FVector2D > &UV1, const TArray< FColor > &Colors, const TArray< FRuntimeMeshTangent > &Tangents, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
TArray< int32 > GetSectionIds() const
FORCEINLINE void CreateMeshSection(int32 SectionIndex, const TArray< FVector > &Vertices, const TArray< int32 > &Triangles, const TArray< FVector > &Normals, const TArray< FVector2D > &UV0, const TArray< FVector2D > &UV1, const TArray< FColor > &Colors, const TArray< FRuntimeMeshTangent > &Tangents, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None, bool bUseHighPrecisionTangents=false, bool bUseHighPrecisionUVs=true)
FORCEINLINE void UpdateMeshSectionTertiaryBuffer(int32 SectionId, TArray< VertexType2 > &InVertices2, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< VertexType2 > &InVertices2, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void GetUsedMaterials(TArray< UMaterialInterface * > &OutMaterials) const
FORCEINLINE void CreateMeshSection(int32 SectionIndex, TArray< VertexType0 > &InVertices0, TArray< IndexType > &InTriangles, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void CreateMeshSectionTripleBuffer(int32 SectionIndex, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< VertexType2 > &InVertices2, TArray< IndexType > &InTriangles, const FBox &BoundingBox, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
static const textual_icon check
TArray< UMaterialInterface * > GetMaterials()
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FRuntimeMeshCollisionUpdatedDelegate)
void DoForAllLinkedComponents(Function Func)
FORCEINLINE void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< VertexType2 > &InVertices2, TArray< IndexType > &InTriangles, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
TUniquePtr< FRuntimeMeshScopedUpdater > GetSectionReadonly(int32 SectionId)
UBodySetup * GetBodySetup()
FRuntimeMeshCollisionCookTickObject(TWeakObjectPtr< URuntimeMesh > InOwner)
FORCEINLINE void UpdateMeshSectionTriangles(int32 SectionId, TArray< IndexType > &InTriangles, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
TSharedPtr< FRuntimeMeshProxy, ESPMode::ThreadSafe > FRuntimeMeshProxyPtr
FORCEINLINE void UpdateMeshSection(int32 SectionId, TArray< VertexType0 > &InVertices0, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
virtual TStatId GetStatId() const
FORCEINLINE void UpdateMeshSectionDualBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
TWeakObjectPtr< URuntimeMesh > Owner
FORCEINLINE void UpdateMeshSectionSecondaryBuffer(int32 SectionId, TArray< VertexType1 > &InVertices1, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
virtual bool WantsNegXTriMesh() override
FRuntimeMeshProxyPtr GetRuntimeMeshRenderProxy() const
FORCEINLINE void UpdateMeshSection(int32 SectionIndex, const TArray< FVector > &Vertices, const TArray< int32 > &Triangles, const TArray< FVector > &Normals, const TArray< FVector2D > &UV0, const TArray< FColor > &Colors, const TArray< FRuntimeMeshTangent > &Tangents, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void UpdateMeshSectionDualBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void CreateMeshSection(int32 SectionId, const TSharedPtr< FRuntimeMeshBuilder > &MeshData, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
virtual void MarkChanged()
FORCEINLINE void UpdateMeshSectionByMove(int32 SectionId, const TSharedPtr< FRuntimeMeshBuilder > &MeshData, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void SetCollisionConvexMeshes(const TArray< TArray< FVector >> &ConvexMeshes)
ERuntimeMeshCollisionCookingMode
FORCEINLINE void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< VertexType2 > &InVertices2, TArray< IndexType > &InTriangles, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FORCEINLINE void CreateMeshSection(int32 SectionIndex, const TArray< FVector > &Vertices, const TArray< int32 > &Triangles, const TArray< FVector > &Normals, const TArray< FVector2D > &UV0, const TArray< FColor > &Colors, const TArray< FRuntimeMeshTangent > &Tangents, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None, bool bUseHighPrecisionTangents=false, bool bUseHighPrecisionUVs=true)
virtual bool IsTickable() const
FRuntimeMeshProxyPtr EnsureProxyCreated(ERHIFeatureLevel::Type InFeatureLevel)
FORCEINLINE void UpdateMeshSection(int32 SectionIndex, const TArray< FVector > &Vertices, const TArray< FVector > &Normals, const TArray< FVector2D > &UV0, const TArray< FColor > &Colors, const TArray< FRuntimeMeshTangent > &Tangents, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)