197 lines
11 KiB
C++
197 lines
11 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Engine/EngineTypes.h"
|
|
#include "Engine/HitResult.h"
|
|
#include "MeshPaintTypes.h"
|
|
|
|
class FMeshPaintParameters;
|
|
class UVertexColorImportOptions;
|
|
class UTexture2D;
|
|
class UStaticMeshComponent;
|
|
class UStaticMesh;
|
|
class USkeletalMesh;
|
|
class IMeshPaintGeometryAdapter;
|
|
class UPaintBrushSettings;
|
|
class FEditorViewportClient;
|
|
class UMeshComponent;
|
|
class USkeletalMeshComponent;
|
|
class UViewportInteractor;
|
|
class FViewport;
|
|
class FPrimitiveDrawInterface;
|
|
class FSceneView;
|
|
|
|
struct FStaticMeshComponentLODInfo;
|
|
|
|
enum class EMeshPaintColorViewMode : uint8;
|
|
|
|
/** Parameters for paint actions, stored together for convenience */
|
|
struct FPerVertexPaintActionArgs
|
|
{
|
|
IMeshPaintGeometryAdapter* Adapter;
|
|
FVector CameraPosition;
|
|
FHitResult HitResult;
|
|
const UPaintBrushSettings* BrushSettings;
|
|
EMeshPaintAction Action;
|
|
};
|
|
|
|
/** Delegates used to call per-vertex/triangle actions */
|
|
DECLARE_DELEGATE_TwoParams(FPerVertexPaintAction, FPerVertexPaintActionArgs& /*Args*/, int32 /*VertexIndex*/);
|
|
DECLARE_DELEGATE_ThreeParams(FPerTrianglePaintAction, IMeshPaintGeometryAdapter* /*Adapter*/, int32 /*TriangleIndex*/, const int32[3] /*Vertex Indices*/);
|
|
|
|
class MESHPAINT_API MeshPaintHelpers
|
|
{
|
|
public:
|
|
/** Removes vertex colors associated with the object */
|
|
static void RemoveInstanceVertexColors(UObject* Obj);
|
|
|
|
/** Removes vertex colors associated with the static mesh component */
|
|
static void RemoveComponentInstanceVertexColors(UStaticMeshComponent* StaticMeshComponent);
|
|
|
|
/** Propagates per-instance vertex colors to the underlying Static Mesh for the given LOD Index */
|
|
static bool PropagateColorsToRawMesh(UStaticMesh* StaticMesh, int32 LODIndex, FStaticMeshComponentLODInfo& ComponentLODInfo);
|
|
|
|
/** Retrieves the Vertex Color buffer size for the given LOD level in the Static Mesh */
|
|
static uint32 GetVertexColorBufferSize(UMeshComponent* MeshComponent, int32 LODIndex, bool bInstance);
|
|
|
|
/** Retrieves the vertex positions from the given LOD level in the Static Mesh */
|
|
static TArray<FVector> GetVerticesForLOD(const UStaticMesh* StaticMesh, int32 LODIndex);
|
|
|
|
/** Retrieves the vertex colors from the given LOD level in the Static Mesh */
|
|
static TArray<FColor> GetColorDataForLOD(const UStaticMesh* StaticMesh, int32 LODIndex);
|
|
|
|
/** Retrieves the per-instance vertex colors from the given LOD level in the StaticMeshComponent */
|
|
static TArray<FColor> GetInstanceColorDataForLOD(const UStaticMeshComponent* MeshComponent, int32 LODIndex);
|
|
|
|
/** Sets the specific (LOD Index) per-instance vertex colors for the given StaticMeshComponent to the supplied Color array */
|
|
static void SetInstanceColorDataForLOD(UStaticMeshComponent* MeshComponent, int32 LODIndex, const TArray<FColor>& Colors);
|
|
|
|
/** Sets the specific (LOD Index) per-instance vertex colors for the given StaticMeshComponent to a single Color value */
|
|
static void SetInstanceColorDataForLOD(UStaticMeshComponent* MeshComponent, int32 LODIndex, const FColor FillColor, const FColor MaskColor);
|
|
|
|
/** Fills all vertex colors for all LODs found in the given mesh component with Fill Color */
|
|
static void FillStaticMeshVertexColors(UStaticMeshComponent* MeshComponent, int32 LODIndex, const FColor FillColor, const FColor MaskColor);
|
|
static void FillSkeletalMeshVertexColors(USkeletalMeshComponent* MeshComponent, int32 LODIndex, const FColor FillColor, const FColor MaskColor);
|
|
|
|
/** Sets all vertex colors for a specific LOD level in the SkeletalMesh to FillColor */
|
|
static void SetColorDataForLOD(USkeletalMesh* SkeletalMesh, int32 LODIndex, const FColor FillColor, const FColor MaskColor);
|
|
|
|
static void ApplyFillWithMask(FColor& InOutColor, const FColor& MaskColor, const FColor& FillColor);
|
|
|
|
/** Helper function to import Vertex Colors from a Texture to the specified MeshComponent (makes use of SImportVertexColorsOptions Widget) */
|
|
static void ImportVertexColorsFromTexture(UMeshComponent* MeshComponent);
|
|
|
|
/** Checks whether or not the given Viewport Client is a VR editor viewport client */
|
|
static bool IsInVRMode(const FEditorViewportClient* ViewportClient);
|
|
|
|
/** Forces the Viewport Client to render using the given Viewport Color ViewMode */
|
|
static void SetViewportColorMode(EMeshPaintColorViewMode ColorViewMode, FEditorViewportClient* ViewportClient);
|
|
|
|
/** Sets whether or not the level viewport should be real time rendered move or viewport as parameter? */
|
|
static void SetRealtimeViewport(bool bRealtime);
|
|
|
|
/** Forces the component to render LOD level at LODIndex instead of the view-based LOD level ( X = 0 means do not force the LOD, X > 0 means force the lod to X - 1 ) */
|
|
static void ForceRenderMeshLOD(UMeshComponent* Component, int32 LODIndex);
|
|
|
|
/** Clears all texture overrides for this component. */
|
|
static void ClearMeshTextureOverrides(const IMeshPaintGeometryAdapter& GeometryInfo, UMeshComponent* InMeshComponent);
|
|
|
|
/** Applies vertex color painting found on LOD 0 to all lower LODs. */
|
|
static void ApplyVertexColorsToAllLODs(IMeshPaintGeometryAdapter& GeometryInfo, UMeshComponent* InMeshComponent);
|
|
|
|
/** Applies the vertex colors found in LOD level 0 to all contained LOD levels in the StaticMeshComponent */
|
|
static void ApplyVertexColorsToAllLODs(IMeshPaintGeometryAdapter& GeometryInfo, UStaticMeshComponent* StaticMeshComponent);
|
|
|
|
/** Applies the vertex colors found in LOD level 0 to all contained LOD levels in the SkeletalMeshComponent */
|
|
static void ApplyVertexColorsToAllLODs(IMeshPaintGeometryAdapter& GeometryInfo, USkeletalMeshComponent* SkeletalMeshComponent);
|
|
|
|
/** Returns the number of Mesh LODs for the given MeshComponent */
|
|
static int32 GetNumberOfLODs(const UMeshComponent* MeshComponent);
|
|
|
|
/** OutNumLODs is set to number of Mesh LODs for the given MeshComponent and returns true, or returns false of given mesh component has no valid LODs */
|
|
static bool TryGetNumberOfLODs(const UMeshComponent* MeshComponent, int32& OutNumLODs);
|
|
|
|
/** Returns the number of Texture Coordinates for the given MeshComponent */
|
|
static int32 GetNumberOfUVs(const UMeshComponent* MeshComponent, int32 LODIndex);
|
|
|
|
/** Checks whether or not the mesh components contains per lod colors (for all LODs)*/
|
|
static bool DoesMeshComponentContainPerLODColors(const UMeshComponent* MeshComponent);
|
|
|
|
/** Retrieves the number of bytes used to store the per-instance LOD vertex color data from the static mesh component */
|
|
static void GetInstanceColorDataInfo(const UStaticMeshComponent* StaticMeshComponent, int32 LODIndex, int32& OutTotalInstanceVertexColorBytes);
|
|
|
|
/** Given arguments for an action, and an action - retrieves influences vertices and applies Action to them */
|
|
static bool ApplyPerVertexPaintAction(FPerVertexPaintActionArgs& InArgs, FPerVertexPaintAction Action);
|
|
|
|
static bool GetPerVertexPaintInfluencedVertices(FPerVertexPaintActionArgs& InArgs, TSet<int32>& InfluencedVertices);
|
|
|
|
/** Given the adapter, settings and view-information retrieves influences triangles and applies Action to them */
|
|
static bool ApplyPerTrianglePaintAction(IMeshPaintGeometryAdapter* Adapter, const FVector& CameraPosition, const FVector& HitPosition, const UPaintBrushSettings* Settings, FPerTrianglePaintAction Action);
|
|
|
|
/** Applies vertex painting to InOutvertexColor according to the given parameters */
|
|
static bool PaintVertex(const FVector& InVertexPosition, const FMeshPaintParameters& InParams, FColor& InOutVertexColor);
|
|
|
|
/** Applies Vertex Color Painting according to the given parameters */
|
|
static void ApplyVertexColorPaint(const FMeshPaintParameters &InParams, const FLinearColor &OldColor, FLinearColor &NewColor, const float PaintAmount);
|
|
|
|
/** Applies Vertex Blend Weight Painting according to the given parameters */
|
|
static void ApplyVertexWeightPaint(const FMeshPaintParameters &InParams, const FLinearColor &OldColor, const float PaintAmount, FLinearColor &NewColor);
|
|
|
|
/** Generate texture weight color for given number of weights and the to-paint index */
|
|
static FLinearColor GenerateColorForTextureWeight(const int32 NumWeights, const int32 WeightIndex);
|
|
|
|
/** Computes the Paint power multiplier value */
|
|
static float ComputePaintMultiplier(float SquaredDistanceToVertex2D, float BrushStrength, float BrushInnerRadius, float BrushRadialFalloff, float BrushInnerDepth, float BrushDepthFallof, float VertexDepthToBrush);
|
|
|
|
/** Checks whether or not a point is influenced by the painting brush according to the given parameters*/
|
|
static bool IsPointInfluencedByBrush(const FVector& InPosition, const FMeshPaintParameters& InParams, float& OutSquaredDistanceToVertex2D, float& OutVertexDepthToBrush);
|
|
|
|
static bool IsPointInfluencedByBrush(const FVector2D& BrushSpacePosition, const float BrushRadiusSquared, float& OutInRangeValue);
|
|
|
|
template<typename T>
|
|
static void ApplyBrushToVertex(const FVector& VertexPosition, const FMatrix& InverseBrushMatrix, const float BrushRadius, const float BrushFalloffAmount, const float BrushStrength, const T& PaintValue, T& InOutValue);
|
|
|
|
public:
|
|
struct FPaintRay
|
|
{
|
|
FVector CameraLocation;
|
|
FVector RayStart;
|
|
FVector RayDirection;
|
|
UViewportInteractor* ViewportInteractor;
|
|
};
|
|
|
|
static bool RetrieveViewportPaintRays(const FSceneView* View, FViewport* Viewport, FPrimitiveDrawInterface* PDI, TArray<FPaintRay>& OutPaintRays);
|
|
protected:
|
|
/** Imports vertex colors from a Texture to the specified Static Mesh according to user-set options */
|
|
static void ImportVertexColorsToStaticMesh(UStaticMesh* StaticMesh, const UVertexColorImportOptions* Options, UTexture2D* Texture);
|
|
|
|
/** Imports vertex colors from a Texture to the specified Static Mesh Component according to user-set options */
|
|
static void ImportVertexColorsToStaticMeshComponent(UStaticMeshComponent* StaticMeshComponent, const UVertexColorImportOptions* Options, UTexture2D* Texture);
|
|
|
|
/** Imports vertex colors from a Texture to the specified Skeletal Mesh according to user-set options */
|
|
static void ImportVertexColorsToSkeletalMesh(USkeletalMesh* SkeletalMesh, const UVertexColorImportOptions* Options, UTexture2D* Texture);
|
|
|
|
/** Helper function to retrieve vertex color from a UTexture given a UVCoordinate */
|
|
static FColor PickVertexColorFromTextureData(const uint8* MipData, const FVector2D& UVCoordinate, const UTexture2D* Texture, const FColor ColorMask);
|
|
};
|
|
|
|
template<typename T>
|
|
void MeshPaintHelpers::ApplyBrushToVertex(const FVector& VertexPosition, const FMatrix& InverseBrushMatrix, const float BrushRadius, const float BrushFalloffAmount, const float BrushStrength, const T& PaintValue, T& InOutValue)
|
|
{
|
|
const FVector BrushSpacePosition = InverseBrushMatrix.TransformPosition(VertexPosition);
|
|
const FVector2D BrushSpacePosition2D(BrushSpacePosition.X, BrushSpacePosition.Y);
|
|
|
|
float InfluencedValue = 0.0f;
|
|
if (IsPointInfluencedByBrush(BrushSpacePosition2D, BrushRadius * BrushRadius, InfluencedValue))
|
|
{
|
|
float InnerBrushRadius = BrushFalloffAmount * BrushRadius;
|
|
float PaintStrength = MeshPaintHelpers::ComputePaintMultiplier(BrushSpacePosition2D.SizeSquared(), BrushStrength, InnerBrushRadius, BrushRadius - InnerBrushRadius, 1.0f, 1.0f, 1.0f);
|
|
|
|
const T OldValue = InOutValue;
|
|
InOutValue = FMath::LerpStable(OldValue, PaintValue, PaintStrength);
|
|
}
|
|
}
|
|
|