网站查询工信部,国外网站制作有哪些,深圳市中心最繁华区,南昌网站建设公司效果《Electric Dreams》项目中提供了一些自定义节点和子图#xff08;文件位置:“/Content/PCG/Assets/PCGCustomNodes”#xff09;#xff0c;这些节点和子图在《Electric Dreams》被广泛使用#xff0c;对于理解《Electric Dreams》非常重要#xff0c;而且它们可以直接移… 《Electric Dreams》项目中提供了一些自定义节点和子图文件位置:“/Content/PCG/Assets/PCGCustomNodes”这些节点和子图在《Electric Dreams》被广泛使用对于理解《Electric Dreams》非常重要而且它们可以直接移植到新的项目中使用。所以写个博客分析一下 文章目录 前导文章Passthrough节点作用Execute with Context PointNormalToColor节点作用Point Loop BodyExecute with Context PointFromPCGVolume节点作用Execute with Context 前导文章
《虚幻引擎程序化资源生成框架PCG 之 UPCGBlueprintElement源码笔记一》 《虚幻引擎程序化资源生成框架PCG 之 UPCGBlueprintElement源码笔记二数据流》
Passthrough节点
作用
数据流的开关
Execute with Context 用Enabled控制是否将从Input输入进来的从Output输出当Enabled为false的时候输出的PCGDataCollection中的Tagged Data数组将会是一个空数组。
PointNormalToColor节点
作用
将Point法线存入Color属性
Point Loop Body
先看一下它的Point Loop Body Point Loop Body的逻辑就是将每一个Point的Up Vector存储在Color属性中然后把修改过的Point输出。
Execute with Context 注释见上图在PointLoopBody后面有一个Initialize from Data节点代码如下
void UPCGSpatialData::InitializeFromData(const UPCGSpatialData* InSource, const UPCGMetadata* InMetadataParentOverride, bool bInheritMetadata, bool bInheritAttributes)
{if (InSource TargetActor.IsExplicitlyNull()){TargetActor InSource-TargetActor;}if (!Metadata){Metadata NewObjectUPCGMetadata(this);}if (!bInheritMetadata || InMetadataParentOverride || InSource){const UPCGMetadata* ParentMetadata bInheritMetadata ? (InMetadataParentOverride ? InMetadataParentOverride : (InSource ? InSource-Metadata : nullptr)) : nullptr;Metadata-Initialize(ParentMetadata, bInheritAttributes);}else{UE_LOG(LogPCG, Warning, TEXT(InitializeFromData has both no source and no metadata override));}
}Initialize from Data做了两件事
将源Data中的TargetActor赋值给新PCGSpatialData的TargetActor用源Data的metadata初始化新PCGSpatialData的metadata
PointFromPCGVolume节点
作用
使用Context中Source的Component或者Component的几何信息(Transform和Bound)构造1个PCGPoint。
Execute with Context 我们先看一下GetComponent和GetOriginalComponent
UPCGComponent* UPCGBlueprintHelpers::GetComponent(FPCGContext Context)
{return Context.SourceComponent.Get();
}UPCGComponent* UPCGBlueprintHelpers::GetOriginalComponent(FPCGContext Context)
{if (Context.SourceComponent.IsValid() CastAPCGPartitionActor(Context.SourceComponent-GetOwner()) CastAPCGPartitionActor(Context.SourceComponent-GetOwner())-GetOriginalComponent(Context.SourceComponent.Get())){return CastAPCGPartitionActor(Context.SourceComponent-GetOwner())-GetOriginalComponent(Context.SourceComponent.Get());}else{return Context.SourceComponent.Get();}
}再看看它是如何获取GetActorLocalBoundsPCG的
UPCGBlueprintHelpers::GetActorLocalBoundsPCG
FBox UPCGBlueprintHelpers::GetActorLocalBoundsPCG(AActor* InActor, bool bIgnorePCGCreatedComponents)
{return PCGHelpers::GetActorLocalBounds(InActor, bIgnorePCGCreatedComponents);
}PCGHelpers::GetActorLocalBounds
FBox GetActorLocalBounds(const AActor* InActor, bool bIgnorePCGCreatedComponents){// Specialized version of CalculateComponentsBoundingBoxInLocalScape that skips over PCG generated components// This is to ensure stable bounds and no timing issues (cleared ISMs, etc.)FBox Box(EForceInit::ForceInit);const bool bNonColliding true;const bool bIncludeFromChildActors true;if (InActor){const FTransform ActorToWorld InActor-GetTransform();const FTransform WorldToActor ActorToWorld.Inverse();InActor-ForEachComponentUPrimitiveComponent(bIncludeFromChildActors, [bNonColliding, bIgnorePCGCreatedComponents, WorldToActor, Box](const UPrimitiveComponent* InPrimComp){if ((bNonColliding || InPrimComp-IsCollisionEnabled()) (!bIgnorePCGCreatedComponents || !InPrimComp-ComponentTags.Contains(DefaultPCGTag))){const FTransform ComponentToActor InPrimComp-GetComponentTransform() * WorldToActor;Box InPrimComp-CalcBounds(ComponentToActor).GetBox();}});}else{UE_LOG(LogPCG, Error, TEXT(Actor is invalid in GetActorLocalBounds));}return Box;}所谓LocalBounds就是把所属Actor的所有PrimitiveComponent叠加起来获得最大的FBox