2019-12-27 09:26:59 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-10-01 20:41:42 -04:00
# pragma once
# include "CoreMinimal.h"
# include "Components/MeshComponent.h"
2019-10-31 17:12:21 -04:00
# include "InteractiveToolObjects.h"
2019-10-01 20:41:42 -04:00
# include "Changes/MeshVertexChange.h"
# include "Changes/MeshChange.h"
2019-12-19 18:07:47 -05:00
# include "Changes/MeshReplacementChange.h"
2020-04-23 18:02:05 -04:00
# include "MeshConversionOptions.h"
2021-06-10 18:37:34 -04:00
# include "DynamicMesh3.h" // todo replace with predeclaration (lots of fallout)
# include "UDynamicMesh.h"
2019-10-01 20:41:42 -04:00
# include "BaseDynamicMeshComponent.generated.h"
// predecl
2020-04-23 18:02:05 -04:00
struct FMeshDescription ;
2019-10-01 20:41:42 -04:00
class FMeshVertexChange ;
class FMeshChange ;
2021-03-09 19:33:56 -04:00
using UE : : Geometry : : FDynamicMesh3 ;
2019-10-01 20:41:42 -04:00
2020-04-18 18:42:59 -04:00
/**
* EMeshRenderAttributeFlags is used to identify different mesh rendering attributes , for things
* like fast - update functions
*/
enum class EMeshRenderAttributeFlags : uint8
{
None = 0 ,
2021-01-24 16:05:21 -04:00
Positions = 1 ,
VertexColors = 1 < < 1 ,
VertexNormals = 1 < < 2 ,
VertexUVs = 1 < < 3 ,
SecondaryIndexBuffers = 1 < < 4 ,
2020-04-18 18:42:59 -04:00
2021-01-24 16:05:21 -04:00
AllVertexAttribs = Positions | VertexColors | VertexNormals | VertexUVs
2020-04-18 18:42:59 -04:00
} ;
ENUM_CLASS_FLAGS ( EMeshRenderAttributeFlags ) ;
2019-10-01 20:41:42 -04:00
/**
* Tangent calculation modes
*/
UENUM ( )
2021-06-11 22:39:18 -04:00
enum class EDynamicMeshComponentTangentsMode : uint8
2019-10-01 20:41:42 -04:00
{
/** Tangents are not used/available, proceed accordingly (eg generate arbitrary orthogonal basis) */
NoTangents ,
2021-06-11 22:39:18 -04:00
/** Tangents will be automatically calculated on demand. Note that mesh changes due to tangents calculation will *not* be broadcast via MeshChange events! */
2019-10-01 20:41:42 -04:00
AutoCalculated ,
2021-06-11 22:39:18 -04:00
/** Tangents are externally provided via the FDynamicMesh3 AttributeSet */
ExternallyProvided
2019-10-01 20:41:42 -04:00
} ;
/**
2021-06-10 18:37:34 -04:00
* UBaseDynamicMeshComponent is a base interface for a UMeshComponent based on a UDynamicMesh .
2019-10-01 20:41:42 -04:00
*/
2021-06-10 18:37:34 -04:00
UCLASS ( Abstract , hidecategories = ( LOD , Physics , Collision ) , ClassGroup = Rendering )
class MODELINGCOMPONENTS_API UBaseDynamicMeshComponent :
public UMeshComponent ,
public IToolFrameworkComponent ,
public IMeshVertexCommandChangeTarget ,
public IMeshCommandChangeTarget ,
public IMeshReplacementCommandChangeTarget
2019-10-01 20:41:42 -04:00
{
GENERATED_UCLASS_BODY ( )
2021-06-10 18:37:34 -04:00
//===============================================================================================================
// UBaseDynamicMeshComponent API. Subclasses must implement these functions
//
public :
2020-04-23 18:02:05 -04:00
/**
2021-06-11 22:39:18 -04:00
* initialize the internal mesh from a DynamicMesh
2020-04-23 18:02:05 -04:00
*/
2021-06-11 22:39:18 -04:00
virtual void SetMesh ( UE : : Geometry : : FDynamicMesh3 & & MoveMesh )
2020-04-23 18:02:05 -04:00
{
unimplemented ( ) ;
}
/**
* @ return pointer to internal mesh
2021-06-10 18:37:34 -04:00
* @ warning avoid usage of this function , access via GetDynamicMesh ( ) instead
2020-04-23 18:02:05 -04:00
*/
virtual FDynamicMesh3 * GetMesh ( )
{
unimplemented ( ) ;
return nullptr ;
}
/**
* @ return pointer to internal mesh
*/
virtual const FDynamicMesh3 * GetMesh ( ) const
{
unimplemented ( ) ;
return nullptr ;
}
2021-06-11 22:39:18 -04:00
/**
* Allow external code to read the internal mesh .
*/
virtual void ProcessMesh ( TFunctionRef < void ( const UE : : Geometry : : FDynamicMesh3 & ) > ProcessFunc ) const
{
unimplemented ( ) ;
}
2021-06-10 18:37:34 -04:00
/**
* @ return the child UDynamicMesh
*/
UFUNCTION ( BlueprintCallable , Category = " Dynamic Mesh Component " )
virtual UDynamicMesh * GetDynamicMesh ( )
{
unimplemented ( ) ;
return nullptr ;
}
2019-10-01 20:41:42 -04:00
/**
* 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 ( ) ;
}
2019-12-19 18:07:47 -05:00
/**
* Apply a full mesh replacement change to the internal mesh ( implements IMeshReplacementCommandChangeTarget )
*/
virtual void ApplyChange ( const FMeshReplacementChange * Change , bool bRevert ) override
{
unimplemented ( ) ;
}
2021-06-10 18:37:34 -04:00
/**
* Apply a transform to the mesh
*/
2021-03-09 19:33:56 -04:00
virtual void ApplyTransform ( const UE : : Geometry : : FTransform3d & Transform , bool bInvert )
2020-04-23 18:02:05 -04:00
{
unimplemented ( ) ;
}
2019-12-19 18:07:47 -05:00
protected :
/**
* Subclass must implement this to notify allocated proxies of updated materials
*/
virtual void NotifyMaterialSetUpdated ( )
{
unimplemented ( ) ;
}
2021-06-10 18:37:34 -04:00
//===============================================================================================================
// Built-in Wireframe-on-Shaded Rendering support. The wireframe looks terrible but this is a convenient
// way to enable/disable it.
//
2019-12-19 18:07:47 -05:00
public :
2021-06-10 18:37:34 -04:00
/**
* if true , we always show the wireframe on top of the shaded mesh , even when not in wireframe mode
* @ todo : this should not be public , access via Set / Get once all usage is cleaned up
*/
UPROPERTY ( EditAnywhere , BlueprintReadWrite , Category = " Dynamic Mesh Component " )
bool bExplicitShowWireframe = false ;
2019-12-19 18:07:47 -05:00
2020-04-18 18:42:59 -04:00
/**
* Configure whether wireframe rendering is enabled or not
*/
2021-06-10 18:37:34 -04:00
UFUNCTION ( BlueprintCallable , Category = " Dynamic Mesh Component " )
virtual void SetEnableWireframeRenderPass ( bool bEnable ) { bExplicitShowWireframe = bEnable ; }
2020-04-18 18:42:59 -04:00
2019-12-19 18:07:47 -05:00
/**
2021-06-10 18:37:34 -04:00
* @ return true if wireframe rendering pass is enabled
2019-12-19 18:07:47 -05:00
*/
2021-06-10 18:37:34 -04:00
UFUNCTION ( BlueprintCallable , Category = " Dynamic Mesh Component " )
virtual bool GetEnableWireframeRenderPass ( ) const { return bExplicitShowWireframe ; }
2019-12-19 18:07:47 -05:00
2021-06-10 18:37:34 -04:00
//===============================================================================================================
// Override rendering material support. If an Override material is set, then it
// will be used during drawing of all mesh buffers except Secondary buffers.
2019-12-19 18:07:47 -05:00
//
2021-06-10 18:37:34 -04:00
public :
2019-12-19 18:07:47 -05:00
/**
* Set an active override render material . This should replace all materials during rendering .
*/
2021-06-10 18:37:34 -04:00
UFUNCTION ( BlueprintCallable , Category = " Dynamic Mesh Component " )
2019-12-19 18:07:47 -05:00
virtual void SetOverrideRenderMaterial ( UMaterialInterface * Material ) ;
/**
* Clear any active override render material
*/
2021-06-10 18:37:34 -04:00
UFUNCTION ( BlueprintCallable , Category = " Dynamic Mesh Component " )
2019-12-19 18:07:47 -05:00
virtual void ClearOverrideRenderMaterial ( ) ;
/**
* @ return true if an override render material is currently enabled for the given MaterialIndex
*/
2021-06-10 18:37:34 -04:00
UFUNCTION ( BlueprintCallable , Category = " Dynamic Mesh Component " )
2019-12-19 18:07:47 -05:00
virtual bool HasOverrideRenderMaterial ( int k ) const
{
return OverrideRenderMaterial ! = nullptr ;
}
/**
* @ return active override render material for the given MaterialIndex
*/
2021-06-10 18:37:34 -04:00
UFUNCTION ( BlueprintCallable , Category = " Dynamic Mesh Component " )
2019-12-19 18:07:47 -05:00
virtual UMaterialInterface * GetOverrideRenderMaterial ( int MaterialIndex ) const
{
return OverrideRenderMaterial ;
}
2021-06-10 18:37:34 -04:00
protected :
UPROPERTY ( )
TObjectPtr < UMaterialInterface > OverrideRenderMaterial = nullptr ;
2019-12-19 18:07:47 -05:00
2021-06-10 18:37:34 -04:00
//===============================================================================================================
// 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.
//
2019-12-19 18:07:47 -05:00
public :
/**
2021-06-10 18:37:34 -04:00
* Set an active secondary render material .
2019-12-19 18:07:47 -05:00
*/
2021-06-10 18:37:34 -04:00
UFUNCTION ( BlueprintCallable , Category = " Dynamic Mesh Component " )
2019-12-19 18:07:47 -05:00
virtual void SetSecondaryRenderMaterial ( UMaterialInterface * Material ) ;
/**
2021-06-10 18:37:34 -04:00
* Clear any active secondary render material
2019-12-19 18:07:47 -05:00
*/
2021-06-10 18:37:34 -04:00
UFUNCTION ( BlueprintCallable , Category = " Dynamic Mesh Component " )
2019-12-19 18:07:47 -05:00
virtual void ClearSecondaryRenderMaterial ( ) ;
/**
2021-06-10 18:37:34 -04:00
* @ return true if a secondary render material is set
2019-12-19 18:07:47 -05:00
*/
virtual bool HasSecondaryRenderMaterial ( ) const
{
return SecondaryRenderMaterial ! = nullptr ;
}
/**
2021-06-10 18:37:34 -04:00
* @ return active secondary render material
2019-12-19 18:07:47 -05:00
*/
2021-06-10 18:37:34 -04:00
UFUNCTION ( BlueprintCallable , Category = " Dynamic Mesh Component " )
2019-12-19 18:07:47 -05:00
virtual UMaterialInterface * GetSecondaryRenderMaterial ( ) const
{
return SecondaryRenderMaterial ;
}
2020-01-27 20:11:15 -05:00
/**
* Show / Hide the secondary triangle buffers . Does not invalidate SceneProxy .
*/
2021-06-10 18:37:34 -04:00
UFUNCTION ( BlueprintCallable , Category = " Dynamic Mesh Component " )
virtual void SetSecondaryBuffersVisibility ( bool bSetVisible ) ;
2020-01-27 20:11:15 -05:00
/**
* @ return true if secondary buffers are currently set to be visible
*/
2021-06-10 18:37:34 -04:00
UFUNCTION ( BlueprintCallable , Category = " Dynamic Mesh Component " )
2020-01-27 20:11:15 -05:00
virtual bool GetSecondaryBuffersVisibility ( ) const ;
2019-12-19 18:07:47 -05:00
protected :
2021-01-21 17:02:07 -04:00
UPROPERTY ( )
2021-06-10 18:37:34 -04:00
TObjectPtr < UMaterialInterface > SecondaryRenderMaterial = nullptr ;
2019-12-19 18:07:47 -05:00
2020-01-27 20:11:15 -05:00
bool bDrawSecondaryBuffers = true ;
2019-11-19 17:08:48 -05:00
2021-06-10 18:37:34 -04:00
//===============================================================================================================
// Standard Component interfaces
//
2019-12-19 18:07:47 -05:00
public :
2021-06-10 18:37:34 -04:00
// UMeshComponent Interface.
2019-12-19 18:07:47 -05:00
virtual int32 GetNumMaterials ( ) const override ;
virtual UMaterialInterface * GetMaterial ( int32 ElementIndex ) const override ;
2021-04-01 17:33:33 -04:00
virtual FMaterialRelevance GetMaterialRelevance ( ERHIFeatureLevel : : Type InFeatureLevel ) const override ;
2019-12-19 18:07:47 -05:00
virtual void SetMaterial ( int32 ElementIndex , UMaterialInterface * Material ) override ;
virtual void GetUsedMaterials ( TArray < UMaterialInterface * > & OutMaterials , bool bGetDebugMaterials = false ) const override ;
2021-06-10 18:37:34 -04:00
UPROPERTY ( )
TArray < TObjectPtr < UMaterialInterface > > BaseMaterials ;
2019-10-01 20:41:42 -04:00
} ;