Files
UnrealEngineUWP/Engine/Source/Runtime/GeometryFramework/Public/Components/BaseDynamicMeshComponent.h

391 lines
12 KiB
C
Raw Normal View History

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Components/MeshComponent.h"
#include "InteractiveToolObjects.h"
#include "Changes/MeshVertexChange.h"
#include "Changes/MeshChange.h"
#include "Changes/MeshReplacementChange.h"
#include "MeshConversionOptions.h"
#include "DynamicMesh/DynamicMesh3.h" // todo replace with predeclaration (lots of fallout)
#include "UDynamicMesh.h"
#include "BaseDynamicMeshComponent.generated.h"
// predecl
struct FMeshDescription;
class FMeshVertexChange;
class FMeshChange;
class FBaseDynamicMeshSceneProxy;
using UE::Geometry::FDynamicMesh3;
/**
* EMeshRenderAttributeFlags is used to identify different mesh rendering attributes, for things
* like fast-update functions
*/
enum class EMeshRenderAttributeFlags : uint8
{
None = 0,
Positions = 1,
VertexColors = 1<<1,
VertexNormals = 1<<2,
VertexUVs = 1<<3,
SecondaryIndexBuffers = 1<<4,
AllVertexAttribs = Positions | VertexColors | VertexNormals | VertexUVs
};
ENUM_CLASS_FLAGS(EMeshRenderAttributeFlags);
/**
* Tangent calculation modes
*/
UENUM()
ModelingComponents: Clean up DynamicMeshComponent API. Update Component and Proxy handling of Tangents to use Attribute Overlay if available. Update affected Tools and also convert most of the affected Tools to use UE::ToolTarget helper functions. - Add UE::ToolTarget::CommitMaterialSetUpdate() and ::CommitDynamicMeshUpdate(). ::GetDynamicMeshCopy() can now return tangents if requested. - Add IMeshDescriptionProvider::CalculateAutoGeneratedAttributes(). Default implementation does nothing, UStaticMeshComponentToolTarget implementation initializes auto-generated MeshDescription attributes. Used in ::GetDynamicMeshCopy() to get tangents (but requires a MeshDescription copy). - Clean up handling of Tangents in Simple/OctreeDynamicMeshComponent. Add local MakeTangentsFunc() to generate the Tangents lambda, handle different cases and no-tangents fallbacks consistently. - UDynamicMesh: add optional info arguments to EditMesh() and ChangeInfo struct. Add support for deferring change events from Edit funcs. - Remove UBaseDynamicMeshComponent::InitializeMesh(), ::Bake() APIs, and add ::SetMesh(). Implement in Simple/Octree implementations, update all Tools that used those APIs. - Add USimpleDynamicMeshComponent::ProcessMesh(), EditMesh(). These are now the preferred ways to read/write mesh. - Update USimpleDynamicMeshComponent tangents handling. Externally-computed tangents are now taken directly from the FDynamicMesh3 attribute set. Autogenerated tangents are still computed and stored in an internal FMeshTangentsf, but this is no longer exposed for external updates. - Remove UPreviewMesh pass-through functions for Tangents access, InitializeMesh() and Bake(). Add ProcessMesh() - Update all affected Tools. In most cases these Tools have also been converted to use ModelingToolTargetUtil functions, instead of direct ToolTarget interface casting. #rb none #rnx #jira none #preflight 60c3e71d3e1b3c00015668af #ROBOMERGE-SOURCE: CL 16650666 in //UE5/Main/... #ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v833-16641396) [CL 16650707 by ryan schmidt in ue5-release-engine-test branch]
2021-06-11 22:42:32 -04:00
enum class EDynamicMeshComponentTangentsMode : uint8
{
/** Tangents are not used/available, proceed accordingly (eg generate arbitrary orthogonal basis) */
NoTangents,
ModelingComponents: Clean up DynamicMeshComponent API. Update Component and Proxy handling of Tangents to use Attribute Overlay if available. Update affected Tools and also convert most of the affected Tools to use UE::ToolTarget helper functions. - Add UE::ToolTarget::CommitMaterialSetUpdate() and ::CommitDynamicMeshUpdate(). ::GetDynamicMeshCopy() can now return tangents if requested. - Add IMeshDescriptionProvider::CalculateAutoGeneratedAttributes(). Default implementation does nothing, UStaticMeshComponentToolTarget implementation initializes auto-generated MeshDescription attributes. Used in ::GetDynamicMeshCopy() to get tangents (but requires a MeshDescription copy). - Clean up handling of Tangents in Simple/OctreeDynamicMeshComponent. Add local MakeTangentsFunc() to generate the Tangents lambda, handle different cases and no-tangents fallbacks consistently. - UDynamicMesh: add optional info arguments to EditMesh() and ChangeInfo struct. Add support for deferring change events from Edit funcs. - Remove UBaseDynamicMeshComponent::InitializeMesh(), ::Bake() APIs, and add ::SetMesh(). Implement in Simple/Octree implementations, update all Tools that used those APIs. - Add USimpleDynamicMeshComponent::ProcessMesh(), EditMesh(). These are now the preferred ways to read/write mesh. - Update USimpleDynamicMeshComponent tangents handling. Externally-computed tangents are now taken directly from the FDynamicMesh3 attribute set. Autogenerated tangents are still computed and stored in an internal FMeshTangentsf, but this is no longer exposed for external updates. - Remove UPreviewMesh pass-through functions for Tangents access, InitializeMesh() and Bake(). Add ProcessMesh() - Update all affected Tools. In most cases these Tools have also been converted to use ModelingToolTargetUtil functions, instead of direct ToolTarget interface casting. #rb none #rnx #jira none #preflight 60c3e71d3e1b3c00015668af #ROBOMERGE-SOURCE: CL 16650666 in //UE5/Main/... #ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v833-16641396) [CL 16650707 by ryan schmidt in ue5-release-engine-test branch]
2021-06-11 22:42:32 -04:00
/** Tangents will be automatically calculated on demand. Note that mesh changes due to tangents calculation will *not* be broadcast via MeshChange events! */
AutoCalculated,
ModelingComponents: Clean up DynamicMeshComponent API. Update Component and Proxy handling of Tangents to use Attribute Overlay if available. Update affected Tools and also convert most of the affected Tools to use UE::ToolTarget helper functions. - Add UE::ToolTarget::CommitMaterialSetUpdate() and ::CommitDynamicMeshUpdate(). ::GetDynamicMeshCopy() can now return tangents if requested. - Add IMeshDescriptionProvider::CalculateAutoGeneratedAttributes(). Default implementation does nothing, UStaticMeshComponentToolTarget implementation initializes auto-generated MeshDescription attributes. Used in ::GetDynamicMeshCopy() to get tangents (but requires a MeshDescription copy). - Clean up handling of Tangents in Simple/OctreeDynamicMeshComponent. Add local MakeTangentsFunc() to generate the Tangents lambda, handle different cases and no-tangents fallbacks consistently. - UDynamicMesh: add optional info arguments to EditMesh() and ChangeInfo struct. Add support for deferring change events from Edit funcs. - Remove UBaseDynamicMeshComponent::InitializeMesh(), ::Bake() APIs, and add ::SetMesh(). Implement in Simple/Octree implementations, update all Tools that used those APIs. - Add USimpleDynamicMeshComponent::ProcessMesh(), EditMesh(). These are now the preferred ways to read/write mesh. - Update USimpleDynamicMeshComponent tangents handling. Externally-computed tangents are now taken directly from the FDynamicMesh3 attribute set. Autogenerated tangents are still computed and stored in an internal FMeshTangentsf, but this is no longer exposed for external updates. - Remove UPreviewMesh pass-through functions for Tangents access, InitializeMesh() and Bake(). Add ProcessMesh() - Update all affected Tools. In most cases these Tools have also been converted to use ModelingToolTargetUtil functions, instead of direct ToolTarget interface casting. #rb none #rnx #jira none #preflight 60c3e71d3e1b3c00015668af #ROBOMERGE-SOURCE: CL 16650666 in //UE5/Main/... #ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v833-16641396) [CL 16650707 by ryan schmidt in ue5-release-engine-test branch]
2021-06-11 22:42:32 -04:00
/** Tangents are externally provided via the FDynamicMesh3 AttributeSet */
ExternallyProvided
};
/**
* UBaseDynamicMeshComponent is a base interface for a UMeshComponent based on a UDynamicMesh.
*/
UCLASS(Abstract, hidecategories = (LOD), ClassGroup = Rendering)
class GEOMETRYFRAMEWORK_API UBaseDynamicMeshComponent :
public UMeshComponent,
public IToolFrameworkComponent,
public IMeshVertexCommandChangeTarget,
public IMeshCommandChangeTarget,
public IMeshReplacementCommandChangeTarget
{
GENERATED_UCLASS_BODY()
//===============================================================================================================
// UBaseDynamicMeshComponent API. Subclasses must implement these functions
//
public:
/**
ModelingComponents: Clean up DynamicMeshComponent API. Update Component and Proxy handling of Tangents to use Attribute Overlay if available. Update affected Tools and also convert most of the affected Tools to use UE::ToolTarget helper functions. - Add UE::ToolTarget::CommitMaterialSetUpdate() and ::CommitDynamicMeshUpdate(). ::GetDynamicMeshCopy() can now return tangents if requested. - Add IMeshDescriptionProvider::CalculateAutoGeneratedAttributes(). Default implementation does nothing, UStaticMeshComponentToolTarget implementation initializes auto-generated MeshDescription attributes. Used in ::GetDynamicMeshCopy() to get tangents (but requires a MeshDescription copy). - Clean up handling of Tangents in Simple/OctreeDynamicMeshComponent. Add local MakeTangentsFunc() to generate the Tangents lambda, handle different cases and no-tangents fallbacks consistently. - UDynamicMesh: add optional info arguments to EditMesh() and ChangeInfo struct. Add support for deferring change events from Edit funcs. - Remove UBaseDynamicMeshComponent::InitializeMesh(), ::Bake() APIs, and add ::SetMesh(). Implement in Simple/Octree implementations, update all Tools that used those APIs. - Add USimpleDynamicMeshComponent::ProcessMesh(), EditMesh(). These are now the preferred ways to read/write mesh. - Update USimpleDynamicMeshComponent tangents handling. Externally-computed tangents are now taken directly from the FDynamicMesh3 attribute set. Autogenerated tangents are still computed and stored in an internal FMeshTangentsf, but this is no longer exposed for external updates. - Remove UPreviewMesh pass-through functions for Tangents access, InitializeMesh() and Bake(). Add ProcessMesh() - Update all affected Tools. In most cases these Tools have also been converted to use ModelingToolTargetUtil functions, instead of direct ToolTarget interface casting. #rb none #rnx #jira none #preflight 60c3e71d3e1b3c00015668af #ROBOMERGE-SOURCE: CL 16650666 in //UE5/Main/... #ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v833-16641396) [CL 16650707 by ryan schmidt in ue5-release-engine-test branch]
2021-06-11 22:42:32 -04:00
* initialize the internal mesh from a DynamicMesh
*/
ModelingComponents: Clean up DynamicMeshComponent API. Update Component and Proxy handling of Tangents to use Attribute Overlay if available. Update affected Tools and also convert most of the affected Tools to use UE::ToolTarget helper functions. - Add UE::ToolTarget::CommitMaterialSetUpdate() and ::CommitDynamicMeshUpdate(). ::GetDynamicMeshCopy() can now return tangents if requested. - Add IMeshDescriptionProvider::CalculateAutoGeneratedAttributes(). Default implementation does nothing, UStaticMeshComponentToolTarget implementation initializes auto-generated MeshDescription attributes. Used in ::GetDynamicMeshCopy() to get tangents (but requires a MeshDescription copy). - Clean up handling of Tangents in Simple/OctreeDynamicMeshComponent. Add local MakeTangentsFunc() to generate the Tangents lambda, handle different cases and no-tangents fallbacks consistently. - UDynamicMesh: add optional info arguments to EditMesh() and ChangeInfo struct. Add support for deferring change events from Edit funcs. - Remove UBaseDynamicMeshComponent::InitializeMesh(), ::Bake() APIs, and add ::SetMesh(). Implement in Simple/Octree implementations, update all Tools that used those APIs. - Add USimpleDynamicMeshComponent::ProcessMesh(), EditMesh(). These are now the preferred ways to read/write mesh. - Update USimpleDynamicMeshComponent tangents handling. Externally-computed tangents are now taken directly from the FDynamicMesh3 attribute set. Autogenerated tangents are still computed and stored in an internal FMeshTangentsf, but this is no longer exposed for external updates. - Remove UPreviewMesh pass-through functions for Tangents access, InitializeMesh() and Bake(). Add ProcessMesh() - Update all affected Tools. In most cases these Tools have also been converted to use ModelingToolTargetUtil functions, instead of direct ToolTarget interface casting. #rb none #rnx #jira none #preflight 60c3e71d3e1b3c00015668af #ROBOMERGE-SOURCE: CL 16650666 in //UE5/Main/... #ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v833-16641396) [CL 16650707 by ryan schmidt in ue5-release-engine-test branch]
2021-06-11 22:42:32 -04:00
virtual void SetMesh(UE::Geometry::FDynamicMesh3&& MoveMesh)
{
unimplemented();
}
/**
* @return pointer to internal mesh
* @warning avoid usage of this function, access via GetDynamicMesh() instead
*/
virtual FDynamicMesh3* GetMesh()
{
unimplemented();
return nullptr;
}
/**
* @return pointer to internal mesh
*/
virtual const FDynamicMesh3* GetMesh() const
{
unimplemented();
return nullptr;
}
ModelingComponents: Clean up DynamicMeshComponent API. Update Component and Proxy handling of Tangents to use Attribute Overlay if available. Update affected Tools and also convert most of the affected Tools to use UE::ToolTarget helper functions. - Add UE::ToolTarget::CommitMaterialSetUpdate() and ::CommitDynamicMeshUpdate(). ::GetDynamicMeshCopy() can now return tangents if requested. - Add IMeshDescriptionProvider::CalculateAutoGeneratedAttributes(). Default implementation does nothing, UStaticMeshComponentToolTarget implementation initializes auto-generated MeshDescription attributes. Used in ::GetDynamicMeshCopy() to get tangents (but requires a MeshDescription copy). - Clean up handling of Tangents in Simple/OctreeDynamicMeshComponent. Add local MakeTangentsFunc() to generate the Tangents lambda, handle different cases and no-tangents fallbacks consistently. - UDynamicMesh: add optional info arguments to EditMesh() and ChangeInfo struct. Add support for deferring change events from Edit funcs. - Remove UBaseDynamicMeshComponent::InitializeMesh(), ::Bake() APIs, and add ::SetMesh(). Implement in Simple/Octree implementations, update all Tools that used those APIs. - Add USimpleDynamicMeshComponent::ProcessMesh(), EditMesh(). These are now the preferred ways to read/write mesh. - Update USimpleDynamicMeshComponent tangents handling. Externally-computed tangents are now taken directly from the FDynamicMesh3 attribute set. Autogenerated tangents are still computed and stored in an internal FMeshTangentsf, but this is no longer exposed for external updates. - Remove UPreviewMesh pass-through functions for Tangents access, InitializeMesh() and Bake(). Add ProcessMesh() - Update all affected Tools. In most cases these Tools have also been converted to use ModelingToolTargetUtil functions, instead of direct ToolTarget interface casting. #rb none #rnx #jira none #preflight 60c3e71d3e1b3c00015668af #ROBOMERGE-SOURCE: CL 16650666 in //UE5/Main/... #ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v833-16641396) [CL 16650707 by ryan schmidt in ue5-release-engine-test branch]
2021-06-11 22:42:32 -04:00
/**
* Allow external code to read the internal mesh.
*/
virtual void ProcessMesh(TFunctionRef<void(const UE::Geometry::FDynamicMesh3&)> ProcessFunc) const
{
unimplemented();
}
/**
* @return the child UDynamicMesh
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual UDynamicMesh* GetDynamicMesh()
{
unimplemented();
return nullptr;
}
/**
* 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
*/
virtual void NotifyMeshUpdated()
{
unimplemented();
}
/**
* Apply a vertex deformation change to the internal mesh (implements IMeshVertexCommandChangeTarget)
*/
virtual void ApplyChange(const FMeshVertexChange* Change, bool bRevert) override
{
unimplemented();
}
/**
* Apply a general mesh change to the internal mesh (implements IMeshCommandChangeTarget)
*/
virtual void ApplyChange(const FMeshChange* Change, bool bRevert) override
{
unimplemented();
}
/**
* Apply a full mesh replacement change to the internal mesh (implements IMeshReplacementCommandChangeTarget)
*/
virtual void ApplyChange(const FMeshReplacementChange* Change, bool bRevert) override
{
unimplemented();
}
/**
* Apply a transform to the mesh
*/
virtual void ApplyTransform(const FTransform3d& Transform, bool bInvert)
{
unimplemented();
}
protected:
/**
* Subclass must implement this to return scene proxy if available, or nullptr
*/
virtual FBaseDynamicMeshSceneProxy* GetBaseSceneProxy()
{
unimplemented();
return nullptr;
}
/**
* Subclass must implement this to notify allocated proxies of updated materials
*/
virtual void NotifyMaterialSetUpdated()
{
unimplemented();
}
//===============================================================================================================
// Built-in Wireframe-on-Shaded Rendering support. The wireframe looks terrible but this is a convenient
// way to enable/disable it.
//
public:
/**
* If true, render the Wireframe on top of the Shaded Mesh
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dynamic Mesh Component|Rendering", meta = (DisplayName = "Wireframe Overlay") )
bool bExplicitShowWireframe = false;
/**
* Configure whether wireframe rendering is enabled or not
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual void SetEnableWireframeRenderPass(bool bEnable) { bExplicitShowWireframe = bEnable; }
/**
* @return true if wireframe rendering pass is enabled
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual bool GetEnableWireframeRenderPass() const { return bExplicitShowWireframe; }
//===============================================================================================================
// API for changing Rendering settings. Although some of these settings are available publicly
// on the Component (in some cases as public members), generally changing them requires more complex
// Rendering invalidation.
//
public:
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual void SetShadowsEnabled(bool bEnabled);
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual bool GetShadowsEnabled() const { return CastShadow; }
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual void SetViewModeOverridesEnabled(bool bEnabled);
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual bool GetViewModeOverridesEnabled() const { return bEnableViewModeOverrides; }
public:
/**
* This flag controls whether Editor View Mode Overrides are enabled for this mesh. For example, this controls hidden-line removal on the wireframe
* in Wireframe View Mode, and whether the normal map will be disabled in Lighting-Only View Mode, as well as various other things.
* Use SetViewModeOverridesEnabled() to control this setting in Blueprints/C++.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dynamic Mesh Component|Rendering", meta = (DisplayName = "View Mode Overrides") )
bool bEnableViewModeOverrides = true;
//===============================================================================================================
// Override rendering material support. If an Override material is set, then it
// will be used during drawing of all mesh buffers except Secondary buffers.
//
public:
/**
* Set an active override render material. This should replace all materials during rendering.
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual void SetOverrideRenderMaterial(UMaterialInterface* Material);
/**
* Clear any active override render material
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual void ClearOverrideRenderMaterial();
/**
* @return true if an override render material is currently enabled for the given MaterialIndex
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual bool HasOverrideRenderMaterial(int k) const
{
return OverrideRenderMaterial != nullptr;
}
/**
* @return active override render material for the given MaterialIndex
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual UMaterialInterface* GetOverrideRenderMaterial(int MaterialIndex) const
{
return OverrideRenderMaterial;
}
protected:
UPROPERTY()
TObjectPtr<UMaterialInterface> OverrideRenderMaterial = nullptr;
//===============================================================================================================
// Secondary Render Buffers support. This requires implementation in subclasses. It allows
// a subset of the mesh triangles to be moved to a separate set of render buffers, which
// can then have a separate material (eg to highlight faces), or be shown/hidden independently.
//
public:
/**
* Set an active secondary render material.
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual void SetSecondaryRenderMaterial(UMaterialInterface* Material);
/**
* Clear any active secondary render material
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual void ClearSecondaryRenderMaterial();
/**
* @return true if a secondary render material is set
*/
virtual bool HasSecondaryRenderMaterial() const
{
return SecondaryRenderMaterial != nullptr;
}
/**
* @return active secondary render material
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual UMaterialInterface* GetSecondaryRenderMaterial() const
{
return SecondaryRenderMaterial;
}
/**
* Show/Hide the secondary triangle buffers. Does not invalidate SceneProxy.
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual void SetSecondaryBuffersVisibility(bool bSetVisible);
/**
* @return true if secondary buffers are currently set to be visible
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual bool GetSecondaryBuffersVisibility() const;
protected:
UPROPERTY()
TObjectPtr<UMaterialInterface> SecondaryRenderMaterial = nullptr;
bool bDrawSecondaryBuffers = true;
//===============================================================================================================
// Raytracing support. Must be enabled for various rendering effects.
// However, note that in actual "dynamic" contexts (ie where the mesh is changing every frame),
// enabling Raytracing support has additional renderthread performance costs and does
// not currently support partial updates in the SceneProxy.
public:
/**
* Enable/disable Raytracing support on this Mesh, if Raytracing is currently enabled in the Project Settings.
* Use SetEnableRaytracing() to configure this flag in Blueprints/C++.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dynamic Mesh Component|Rendering")
bool bEnableRaytracing = true;
/**
* Enable/Disable raytracing support. This is an expensive call as it flushes
* the rendering queue and forces an immediate rebuild of the SceneProxy.
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual void SetEnableRaytracing(bool bSetEnabled);
/**
* @return true if raytracing support is currently enabled
*/
UFUNCTION(BlueprintCallable, Category = "Dynamic Mesh Component")
virtual bool GetEnableRaytracing() const;
protected:
virtual void OnRenderingStateChanged(bool bForceImmedateRebuild);
//===============================================================================================================
// Standard Component interfaces
//
public:
// UMeshComponent Interface.
virtual int32 GetNumMaterials() const override;
virtual UMaterialInterface* GetMaterial(int32 ElementIndex) const override;
virtual FMaterialRelevance GetMaterialRelevance(ERHIFeatureLevel::Type InFeatureLevel) const override;
virtual void SetMaterial(int32 ElementIndex, UMaterialInterface* Material) override;
virtual void GetUsedMaterials(TArray<UMaterialInterface*>& OutMaterials, bool bGetDebugMaterials = false) const override;
virtual void SetNumMaterials(int32 NumMaterials);
//~ UObject Interface.
#if WITH_EDITOR
void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
UPROPERTY()
TArray<TObjectPtr<UMaterialInterface>> BaseMaterials;
};