113 lines
3.6 KiB
C++
113 lines
3.6 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "GetGroomAssetNode.h"
|
|
#include "GroomEdit.h"
|
|
#include "GroomInstance.h"
|
|
#include "GroomCollectionFacades.h"
|
|
#include "Dataflow/DataflowInputOutput.h"
|
|
#include "Dataflow/DataflowObjectInterface.h"
|
|
|
|
#include UE_INLINE_GENERATED_CPP_BY_NAME(GetGroomAssetNode)
|
|
|
|
namespace UE::Groom::Private
|
|
{
|
|
template<typename FacadeType>
|
|
FORCEINLINE const UGroomAsset* BuildGroomCollection(Dataflow::FContext& Context, const UGroomAsset* NodeGroom, FManagedArrayCollection& GroomCollection, FEditableGroom& EditGroom)
|
|
{
|
|
const UGroomAsset* GroomAsset = NodeGroom;
|
|
if (!GroomAsset)
|
|
{
|
|
if (const Dataflow::FEngineContext* EngineContext = Context.AsType<Dataflow::FEngineContext>())
|
|
{
|
|
GroomAsset = Cast<UGroomAsset>(EngineContext->Owner);
|
|
}
|
|
}
|
|
|
|
if (GroomAsset)
|
|
{
|
|
ConvertFromGroomAsset(const_cast<UGroomAsset*>(GroomAsset), &EditGroom, false, false, false);
|
|
|
|
TArray<FVector3f> PointRestPositions;
|
|
TArray<int32> ObjectCurveOffsets;
|
|
TArray<int32> CurvePointOffsets;
|
|
TArray<FString> ObjectGroupNames;
|
|
|
|
uint32 GroupIndex = 0;
|
|
for(FEditableGroomGroup& GroomGroup : EditGroom.Groups)
|
|
{
|
|
|
|
for( const typename FacadeType::FEditableType& EditType : FacadeType::GetEditableGroom(GroomGroup))
|
|
{
|
|
for(auto& GuidePoint : EditType.ControlPoints)
|
|
{
|
|
PointRestPositions.Add(GuidePoint.Position);
|
|
}
|
|
CurvePointOffsets.Add(PointRestPositions.Num());
|
|
}
|
|
ObjectCurveOffsets.Add(CurvePointOffsets.Num());
|
|
|
|
const FString GroupName = GroomAsset->GetName() + TEXT("_") + FacadeType::GroupPrefix.ToString();
|
|
ObjectGroupNames.Add(GroupName);
|
|
++GroupIndex;
|
|
}
|
|
FacadeType CurvesFacade(GroomCollection);
|
|
CurvesFacade.InitGroomCollection(PointRestPositions, CurvePointOffsets, ObjectCurveOffsets, ObjectGroupNames);
|
|
|
|
const FString GroomName = GroomAsset->GetName();
|
|
|
|
return GroomAsset;
|
|
}
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
void FGetGroomAssetDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA<FManagedArrayCollection>(&Collection))
|
|
{
|
|
FManagedArrayCollection GroomCollection;
|
|
FEditableGroom EditGroom;
|
|
const UGroomAsset* LocalGroom = nullptr;
|
|
if(CurvesType == EGroomCollectionType::Guides)
|
|
{
|
|
LocalGroom = UE::Groom::Private::BuildGroomCollection<UE::Groom::FGroomGuidesFacade>(
|
|
Context, GroomAsset, GroomCollection, EditGroom);
|
|
}
|
|
else if(CurvesType == EGroomCollectionType::Strands)
|
|
{
|
|
LocalGroom = UE::Groom::Private::BuildGroomCollection<UE::Groom::FGroomStrandsFacade>(
|
|
Context, GroomAsset, GroomCollection, EditGroom);
|
|
}
|
|
|
|
if(LocalGroom)
|
|
{
|
|
TArray<int32> ObjectPointSamples, CurveStrandIndices;
|
|
const TArray<FHairGroupsPhysics>& GroupsPhysics = LocalGroom->GetHairGroupsPhysics();
|
|
for(const FHairGroupsPhysics& GroupPhysics : GroupsPhysics)
|
|
{
|
|
ObjectPointSamples.Add(static_cast<uint8>(GroupPhysics.StrandsParameters.StrandsSize));
|
|
}
|
|
|
|
UE::Groom::FGroomGuidesFacade GuidesFacade(GroomCollection);
|
|
if(GroomCollection.NumElements(UE::Groom::FGroomGuidesFacade::ObjectsGroup) == 0)
|
|
{
|
|
GroomCollection.AddElements(ObjectPointSamples.Num(), UE::Groom::FGroomGuidesFacade::ObjectsGroup);
|
|
}
|
|
GuidesFacade.SetObjectPointSamples(ObjectPointSamples);
|
|
}
|
|
SetValue(Context, MoveTemp(GroomCollection), &Collection);
|
|
}
|
|
}
|
|
|
|
TArray<UE::Dataflow::FRenderingParameter> FGetGroomAssetDataflowNode::GetRenderParametersImpl() const
|
|
{
|
|
if(CurvesType == EGroomCollectionType::Guides)
|
|
{
|
|
return { {TEXT("GuidesRender"), FName("FGroomCollection"), {TEXT("Collection")}}};
|
|
}
|
|
else
|
|
{
|
|
return { {TEXT("StrandsRender"), FName("FGroomCollection"), {TEXT("Collection")}}};
|
|
}
|
|
}
|