// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "Components/BaseDynamicMeshComponent.h" #include "UDynamicMesh.h" #include "DynamicMesh/DynamicMeshOctree3.h" #include "Util/IndexSetDecompositions.h" #include "OctreeDynamicMeshComponent.generated.h" #define UE_API MODELINGCOMPONENTS_API // predecl struct FMeshDescription; /** internal FPrimitiveSceneProxy defined in OctreeDynamicMeshSceneProxy.h */ class FOctreeDynamicMeshSceneProxy; class FBaseDynamicMeshSceneProxy; /** * UOctreeDynamicMeshComponent is a mesh component similar to UProceduralMeshComponent, * except it bases the renderable geometry off an internal FDynamicMesh3 instance. * The class generally has the same capabilities as UDynamicMeshComponent. * * A FDynamicMeshOctree3 is available to dynamically track the triangles of the mesh * (however the client is responsible for updating this octree). * Based on the Octree, the mesh is partitioned into chunks that are stored in separate * RenderBuffers in the FOctreeDynamicMeshSceneProxy. * Calling NotifyMeshUpdated() will result in only the "dirty" chunks being updated, * rather than the entire mesh. * * (So, if you don't need this capability, and don't want to update an Octree, use UDynamicMeshComponent!) */ UCLASS(MinimalAPI, hidecategories = (LOD, Physics, Collision), editinlinenew, ClassGroup = Rendering) class UOctreeDynamicMeshComponent : public UBaseDynamicMeshComponent { GENERATED_UCLASS_BODY() public: /** * initialize the internal mesh from a DynamicMesh */ UE_API virtual void SetMesh(UE::Geometry::FDynamicMesh3&& MoveMesh) override; /** * @return pointer to internal mesh */ virtual FDynamicMesh3* GetMesh() override { return MeshObject->GetMeshPtr(); } /** * @return pointer to internal mesh */ virtual const FDynamicMesh3* GetMesh() const override { return MeshObject->GetMeshPtr(); } virtual void ProcessMesh(TFunctionRef ProcessFunc) const { MeshObject->ProcessMesh(ProcessFunc); } UE::Geometry::FDynamicMeshOctree3* GetOctree() { return Octree.Get(); } /** * Apply transform to internal mesh. Invalidates RenderProxy. * @param bInvert if true, inverse tranform is applied instead of forward transform */ UE_API virtual void ApplyTransform(const FTransform3d& Transform, bool bInvert) override; // // change tracking/etc // /** * Call this if you update the mesh via GetMesh() * @todo should provide a function that calls a lambda to modify the mesh, and only return const mesh pointer */ UE_API virtual void NotifyMeshUpdated() override; /** * Apply a vertex deformation change to the internal mesh */ UE_API virtual void ApplyChange(const FMeshVertexChange* Change, bool bRevert) override; /** * Apply a general mesh change to the internal mesh */ UE_API virtual void ApplyChange(const FMeshChange* Change, bool bRevert) override; /** * Apply a general mesh replacement change to the internal mesh */ UE_API virtual void ApplyChange(const FMeshReplacementChange* Change, bool bRevert) override; /** * This delegate fires when a FCommandChange is applied to this component, so that * parent objects know the mesh has changed. */ FSimpleMulticastDelegate OnMeshChanged; /** * If this function is set, we will use these colors instead of vertex colors */ TFunction TriangleColorFunc = nullptr; protected: /** * This is called to tell our RenderProxy about modifications to the material set. * We need to pass this on for things like material validation in the Editor. */ UE_API virtual void NotifyMaterialSetUpdated(); private: virtual FBaseDynamicMeshSceneProxy* GetBaseSceneProxy() override { return (FBaseDynamicMeshSceneProxy*)GetCurrentSceneProxy(); } FOctreeDynamicMeshSceneProxy* GetCurrentSceneProxy() { return (FOctreeDynamicMeshSceneProxy*)SceneProxy; } //~ Begin UPrimitiveComponent Interface. UE_API virtual FPrimitiveSceneProxy* CreateSceneProxy() override; //~ End UPrimitiveComponent Interface. //~ Begin USceneComponent Interface. UE_API virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const override; //~ Begin USceneComponent Interface. UPROPERTY() TObjectPtr MeshObject; FDelegateHandle MeshObjectChangedHandle; UE_API void OnMeshObjectChanged(UDynamicMesh* ChangedMeshObject, FDynamicMeshChangeInfo ChangeInfo); FDelegateHandle PreMeshChangeHandle; UE_API void OnPreMeshObjectChanged(UDynamicMesh* ChangedMeshObject, FDynamicMeshChangeInfo ChangeInfo); TUniquePtr Octree; TUniquePtr OctreeCut; UE::Geometry::FArrayIndexSetsDecomposition TriangleDecomposition; struct FCutCellIndexSet { UE::Geometry::FDynamicMeshOctree3::FCellReference CellRef; int32 DecompSetID; }; TArray CutCellSetMap; int32 SpillDecompSetID; UE_API FColor GetTriangleColor(int TriangleID); //friend class FCustomMeshSceneProxy; public: //UFUNCTION(BlueprintCallable, Category = "DynamicMesh") virtual UDynamicMesh* GetDynamicMesh() override { return MeshObject; } UFUNCTION(BlueprintCallable, Category = "DynamicMesh") UE_API void SetDynamicMesh(UDynamicMesh* NewMesh); }; #undef UE_API