虚幻引擎程序化资源生成框架PCG 之 UPCGBlueprintElement源码笔记(二)数据流

news2024/11/16 22:01:10

PCG节点处理的是数据流,也就是点云,点云到底是啥?笼统地说就是一个个携带着信息的点组成的集合。但是在具体是使用过程中,我们还得了解这些”携带着信息的点“是如何被层层包装起来的。本文中老王就和大家一边拆解源代码一边做实验,尝试着深入理解一下PCG中的数据流。如有错误,敬请指正!

文章目录

  • 1. FPCGDataCollection
  • 2. FPCGTaggedData
  • 3. UPCGData
    • 3.1 UPCGSpatialData
      • 3.1.1 UPCGPointData
      • 3.1.2 UPCGSpatialDataWithPointCache
  • 4. UPCGMetadata
  • 5. FPCGPoint
  • 6. 小结

在这里插入图片描述

1. FPCGDataCollection

ExecuteExecute with Context共同的输入参数,是Input,它的类型是FPCGDataCollection,我们先看一下它源代码中最核心的部分:

USTRUCT(BlueprintType)
struct PCG_API FPCGDataCollection
{
	GENERATED_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Data)
	TArray<FPCGTaggedData> TaggedData;
}

一个TaggedData的数组,每一个TaggedData,对应着这个节点的一个输入连接,我们可以写个简单的代码试验一下:

在这里插入图片描述
在这里插入图片描述

LogBlueprintUserMessages: [BP_CustomNode_C_20] Tagged Data 数量:3

接下来我们看一下FPCGTaggedData的内容。

2. FPCGTaggedData

我们先看一下FPCGTaggedData源代码中最核心的部分:

USTRUCT(BlueprintType)
struct PCG_API FPCGTaggedData
{
	GENERATED_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Data)
	TObjectPtr<const UPCGData> Data = nullptr;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Data)
	TSet<FString> Tags;
};

如上文所述每个FPCGTaggedData对应着一条输入连接,每一条输入连接可能来自一个Actor、一个Spline、一个Landscape以及上一级节点的加工,那么每一条输入就会携带者原始Actor的Tag或者后添加上去的Tag。因此FPCGTaggedData包含最重要的两部分信息就是UPCGData的指针和Tag的集合。

我们再看一下什么是UPCGData

3. UPCGData

UPCGData是PCG中各种类型信息的基类

在这里插入图片描述

UCLASS(BlueprintType, ClassGroup = (Procedural))
class PCG_API UPCGData : public UObject
{
	GENERATED_BODY()
public:
	/** Unique ID for this object instance. */
	UPROPERTY(Transient)
	uint64 UID = 0;
private:
	/** Serves unique ID values to instances of this object. */
	static inline std::atomic<uint64> UIDCounter{ 1 };
}

UPCGData最核心的部分就是让每一个UPCGData都有一个全局唯一的UID,也就是说无论你的UPCGData是在何时生成(获取)的,它的UID都是全局唯一的。从上面的类图可以看到,在PCG中,我们经常使用的Data类型,不仅都派生自UPCGData,它们实际也都派生自UPCGSpatialData

3.1 UPCGSpatialData

空间相关的UPCGData

UCLASS(Abstract, BlueprintType, ClassGroup = (Procedural))
class PCG_API UPCGSpatialData : public UPCGData
{
	GENERATED_BODY()
	// Not accessible through blueprint to make sure the constness is preserved
	UPROPERTY(VisibleAnywhere, Category = Metadata)
	TObjectPtr<UPCGMetadata> Metadata = nullptr;
}

相对于UPCGData,每个UPCGSpatialData多了一个UPCGMetadataUPCGMetadata的作用就是允许用户自定义特性Attributes

UPCGSpatialData类有两个大的派生分支UPCGPointDataUPCGSpatialDataWithPointCache

3.1.1 UPCGPointData

UCLASS(BlueprintType, ClassGroup = (Procedural))
class PCG_API UPCGPointData : public UPCGSpatialData
{
	GENERATED_BODY()
	UPROPERTY()
	TArray<FPCGPoint> Points;
}

UPCGPointData中最重要的就是包含FPCGPoint数组,也就是说一个UPCGPointData对着一组Point

3.1.2 UPCGSpatialDataWithPointCache

UCLASS(Abstract, ClassGroup = (Procedural))
class PCG_API UPCGSpatialDataWithPointCache : public UPCGSpatialData
{
	GENERATED_BODY()
	UPROPERTY(Transient)
	mutable TArray<TObjectPtr<const UPCGPointData>> CachedBoundedPointData;
}

UPCGSpatialDataWithPointCache包含了一个UPCGPointData数组(间接包含了若干个FPCGPoint数组)

4. UPCGMetadata

注意:UPCGMetadata并不派生自UPCGData

先看一下核心代码:

UCLASS(BlueprintType)
class PCG_API UPCGMetadata : public UObject
{
	GENERATED_BODY()

	UPROPERTY()
	TObjectPtr<const UPCGMetadata> Parent;
	UPROPERTY()
	TSet<TWeakObjectPtr<const UPCGMetadata>> OtherParents;

	TMap<FName, FPCGMetadataAttributeBase*> Attributes;
}

UPCGMetadata也就是元数据,包含着Attributes的名称和值的Map,以及这些Attributes的来源,加上针对Attributes的各种操作。

在官方的文档中,自定义的特性叫做Attribute,而Point原生的属性叫做PropertyProperty直接定义在FPCGPoint中。

5. FPCGPoint

USTRUCT(BlueprintType)
struct PCG_API FPCGPoint
{
	GENERATED_BODY()
public:
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Properties)
	FTransform Transform;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Properties)
	float Density = 1.0f;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Properties)
	FVector BoundsMin = -FVector::One();

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Properties)
	FVector BoundsMax = FVector::One();

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Properties)
	FVector4 Color = FVector4::One();

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Properties, meta = (ClampMin = "0", ClampMax = "1"))
	float Steepness = 0.5f;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Properties)
	int32 Seed = 0;

	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Properties|Metadata")
	int64 MetadataEntry = -1;
};

FPCGPoint中除了属性Property的定义,还有一个int64类型的MetadataEntry,这个MetadataEntry应该就对应着PointMetadata(也就是Attribute)的关联方式。但是具体的算法还需要进一步研究。

	/** Adds a unique entry key to the metadata */
	UFUNCTION(BlueprintCallable, Category = "PCG|Metadata")
	int64 AddEntry(int64 ParentEntryKey = -1);
int64 UPCGMetadata::AddEntry(int64 ParentEntry)
{
	FWriteScopeLock ScopeLock(ItemLock);
	return ParentKeys.Add(ParentEntry) + ItemKeyOffset;
}

6. 小结

  • ExecuteInput是一个FPCGDataCollection,它包含多个FPCGTaggedData
  • 每个FPCGTaggedData对应一个输入源
  • FPCGTaggedData夹带着一串Tag和一个UPCGData(多数时候实际是其派生类UPCGSpatialData
  • 每个UPCGSpatialData(UPCGPointDataUPCGSpatialDataWithPointCache)对应着一组Point
  • 每个Point已包含固有属性(Property)通过int64MetadataEntry关联到自己的特性(Attribute

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/734686.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

以太网数据链路层相关技术(六)

目录 一、概述 二、MAC地址 2.1 概述 2.2 MAC地址的意义 三、共享介质型网络与非共享介质网络 四、VLAN技术 一、概述 在各设备之间的数据传输时&#xff0c;物理层和数据链路层是必不可少的。其中&#xff0c;物理层的通信媒介包括双绞线电缆、同轴电缆、光纤、电波以及…

Springcloud基础(4)-Ribbon负载均衡

负载均衡 1. Ribbon简单描述2. 在SpringCloud中查看相关处理源码3. ribbon的默认策略&#xff0c;懒加载3. 实操中的相关问题 1. Ribbon简单描述 Spring Cloud Ribbon 是一套基于 Netflix Ribbon 实现的客户端负载均衡和服务调用工具。Ribbon是Netflix发布的开源项目&#xff0…

MySQL第四天作业 单表查询和多表查询

单表查询 创建表 CREATE TABLE emp (empno int(4) NOT NULL,ename varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,job varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,mgr int(4) NULL DEFAULT NULL,hiredate d…

【电子学会】2023年05月图形化一级 -- 舞蹈演出

舞蹈演出 1. 准备工作 &#xff08;1&#xff09;删除小猫角色&#xff1b; &#xff08;2&#xff09;添加角色Ballerina&#xff0c;为角色添加声音Bossa Nova&#xff1b; &#xff08;3&#xff09;添加背景Theater和Concert。 2. 功能实现 &#xff08;1&#xff09…

STC89C52---定时器,中断

目录 一:定时器 1:简历 2:定时器/计数器0/1和相关寄存器 A:介绍 B: 相关寄存器 C:基本原理 3:定时器/计数器控制寄存器TCON 4:定时器/计数器工作模式寄存器TMOD (1)门控制 (2):使用STC-iSP软件生成配置 (2):使用STC-iSP软件定时器 二:中断 1:简历 B:中断寄存器 2…

【电子学会】2023年05月图形化四级 -- 还原轨迹

还原轨迹 1. 准备工作 &#xff08;1&#xff09;删除小猫&#xff1b; &#xff08;2&#xff09;从角色库添加“Butterfly 1”角色&#xff1b; &#xff08;3&#xff09;保留白色背景。 2. 功能实现 &#xff08;1&#xff09;点击绿旗&#xff0c;清除舞台&#xff…

利用Python实现网站内容监控及邮件提醒

目录 一、开启POP3/SMTP服务 二、利用SMTP库实现邮件发送 三、利用requests库监控网页关键字 四、常见问题 一、开启POP3/SMTP服务 以QQ邮箱为例&#xff1a;进入邮箱->设置->账户->开启POP3/SMTP等服务->获取授权码 ①首先进入QQ邮箱后点击设置 ② 点击邮箱…

【机器学习核心总结】什么是梯度下降

什么是梯度下降 根据已有数据的分布来预测可能的新数据&#xff0c;这是回归 希望有一条线将数据分割成不同类别&#xff0c;这是分类 无论回归还是分类&#xff0c;我们的目的都是让搭建好的模型尽可能的模拟已有的数据 除了模型的结构&#xff0c;决定模型能否模拟成功的关键…

IDEA+spring+spring mvc+mybatis+bootstrap+jquery+Mysql运动会管理系统

IDEAspringspring mvcmybatisbootstrapjqueryMysql运动会管理系统 一、系统介绍1.环境配置 二、系统展示1. 管理员登录2.修改密码3.运动会开幕信息4.运动会广播信息5. 比赛项目信息6.比赛成绩信息7.运动器材信息8.学生信息9.教师信息10.班级信息11. 院系信息12.开幕管理13.广播…

LVS + keepalived

一、keepalived概述1.1 keepalived 服务重要功能1.1.1 管理LVS负载均衡器软件1.1.2 支持故障自动切换&#xff08;failover&#xff09;1.1.3 实现LVS集中节点的健康检查&#xff08;health checking&#xff09;1.1.4 实现 LVS 负载调度器、节点服务器的高可用性&#xff08;H…

Hcip第四次作业

要求&#xff1a; 1.如图连接&#xff0c;合理规划IP地址&#xff0c;所有路由器各自创建一个loopback接口 2.R1再创建三个接口IP地址为201.1.1.1/24、201.1.2.1/24、201.1.3.1/24 R5再创建三个接口IP地址为202.1.1.1/24、202.1.2.1/24、202.1.3.1/24 R7再创建三个接口IP地址为…

运维开发面试题第一期

1.tail -f和tail -F的区别是什么? tail -f 根据文件描述符进行追踪&#xff0c;当文件改名或被删除&#xff0c;追踪停止。 tail -F 根据文件名进行追踪&#xff0c;并保持重试&#xff0c;即该文件被删除或改名后&#xff0c;如果再次创建相同的文件名&#xff0c;会继续…

【通览一百个大模型】CodeX(OpenAI)

【通览一百个大模型】CodeX&#xff08;OpenAI&#xff09; 作者&#xff1a;王嘉宁&#xff0c;本文章内容为原创&#xff0c;仓库链接&#xff1a;https://github.com/wjn1996/LLMs-NLP-Algo 订阅专栏【大模型&NLP&算法】可获得博主多年积累的全部NLP、大模型和算法干…

01 |「沟通技巧」

前言 沟通是一个程序员需要具备的技能。 文章目录 前言一、学会沟通1. 为什么需要具备沟通能力2. 如何具备良好的沟通能力 二、沟通实践 一、学会沟通 1. 为什么需要具备沟通能力 程序员的工作能力一部分是需求的开发&#xff0c;另一部分是调试解决 Bug 的能力&#xff1b;快…

算法导论机考复习(数据处理)

素数筛选 求所有小于n的素数 #include<bits/stdc.h> using namespace std; const int N1000; int prim[N]; int n; int main() {while(cin>>n){//初始化2到n都是素数for(int i2;i<n;i){prim[i]1;}//从2到n把所有的是当前数的倍数的数都设置为0//不能设置自己为…

硬盘或者U盘提示需要格式化的解决办法

插入硬盘之后提示&#xff1a; 使用驱动器 G:中的光盘之前需要将其格式化 是否要将其格式化? 如下图所示 顿时慌了啊&#xff0c;里面还有比较重要的东西呢&#xff0c;这一下子完蛋&#xff1f; 遇事找某宝&#xff0c;上面估计有这种技术服务。果然有这一类的技术服务&…

数据库作业——select查询操作

数据库作业 创建数据库 mysql> create table worker( -> 部门号 int(11) not null, -> 职工号 int(11) primary key not null,-> 工作时间 date not null,-> 工资…

Vue--》Vue3打造可扩展的项目管理系统后台的完整指南(十一)

今天开始使用 vue3 + ts 搭建一个项目管理的后台,因为文章会将项目的每一个地方代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的GithHub上,大家可以自行去进行下载运行,希望本文章对有帮助的朋友们能多多关注本专栏…

RabbitMQ ---- 消息队列

RabbitMQ ---- 消息队列 1. MQ 的相关概念1.1 什么是 MQ1.2 为什么要用 MQ1.3 MQ 的分类1.4 MQ 的选择 2. RabbitMQ2.1 RabbitMQ 的概念2.2 四大核心概念2.3 RabbitMQ 核心部分2.4 各个名词介绍2.5 安装 1. MQ 的相关概念 1.1 什么是 MQ MQ(message queue)&#xff0c;从字面…

03-2_Qt 5.9 C++开发指南_Qt全局定义、容器类、容器类的迭代器、Qt类库的模块

本篇简要介绍Qt全局定义中的数据类型、函数、宏定义&#xff1b;容器类中&#xff1a;顺序容器类、关联容器类&#xff1b;容器类的迭代器&#xff1b;Qt类库的模块。 文章目录 1.Qt全局定义1.1 数据类型定义1.2 函数1.3 宏定义1.3.1 QT_VERSION1.3.2 QT_VERSION_CHECK1.3.3 Q…