UStaticMesh几何数据相关(UE5.2)

UStaticMesh相关类图

8f663eb4989e48579fd3d47252243c43.png

 

UStaticMesh的数据构成

 

UStaticMesh的FStaticMeshSourceModel

UStaticMesh的Mesh几何元数据来自于FStaticMeshSourceModel, 一级Lod就存在一个FStaticMeshSourceModel. FStaticMeshSourceModel几何数据大致包含以下几类:

Vertex(点), VertexInstance(顶点), Edge(边),   Triangle(三角形),   Polygon(多边形)

总体上概念和Houdini的一些几何概念相似,每种几何元素都可以附带属性,比如点的“Position”, 顶点的“Normal,UV”等等。

下面介绍下如何获取Mesh元数据和相关属性

void AMyActor::TestMeshInfo() const
{if(!Mesh)return;// SourceModelconst TArray<FStaticMeshSourceModel>& SourceModels = Mesh->GetSourceModels();for(int32 Index = 0; Index < SourceModels.Num(); Index++){FMeshDescription* MeshDesc = Mesh->GetMeshDescription(Index);if(MeshDesc){const FVertexArray& VertexArray =  MeshDesc->Vertices();// TVertexAttributesRef<FVector3f> VertexPositions = MeshDesc->VertexAttributes().GetAttributesRef<FVector3f>(MeshAttribute::Vertex::Position);TVertexAttributesRef<FVector3f> VertexPositions = MeshDesc->GetVertexPositions();//loop vertex postionfor(const FVertexID VertexID : VertexArray.GetElementIDs()){FVector3f& Pos = VertexPositions[VertexID];}UE_LOG(LogTemp, Warning, TEXT("Vertex num = %d"), VertexArray.Num());//loop vertex instance attributeconst FVertexInstanceArray& VertexInstanceArray = MeshDesc->VertexInstances();TVertexInstanceAttributesRef<FVector4f> VertexInstanceColors = MeshDesc->VertexInstanceAttributes().GetAttributesRef<FVector4f>(MeshAttribute::VertexInstance::Color);for(const FVertexInstanceID VertxInstanceId : VertexInstanceArray.GetElementIDs()){}UE_LOG(LogTemp, Warning, TEXT("VertexInstanceArray num = %d"), VertexInstanceArray.Num());//loop vertex edge attributeconst FEdgeArray& EdgeArray = MeshDesc->Edges();TEdgeAttributesRef<bool> EdgeHardness = MeshDesc->EdgeAttributes().GetAttributesRef<bool>(MeshAttribute::Edge::IsHard);for (FEdgeID EdgeID : EdgeArray.GetElementIDs()){}UE_LOG(LogTemp, Warning, TEXT("EdgeArray num = %d"), EdgeArray.Num());// loop triangle attributeconst FTriangleArray& TriangleArray = MeshDesc->Triangles();TTriangleAttributesRef<FVector3f> TriangleNormals = MeshDesc->TriangleAttributes().GetAttributesRef<FVector3f>(MeshAttribute::Triangle::Normal);for (FTriangleID TriangleID : TriangleArray.GetElementIDs()){}UE_LOG(LogTemp, Warning, TEXT("TriangleArray num = %d"), TriangleArray.Num());// loop polygonconst FPolygonArray& PolygonArray =  MeshDesc->Polygons();TPolygonAttributesRef<int32> PatchGroups = MeshDesc->PolygonAttributes().GetAttributesRef<int32>(MeshAttribute::Polygon::PolygonGroupIndex);UE_LOG(LogTemp, Warning, TEXT("PolygonArray num = %d"), PolygonArray.Num());}if(Mesh->GetRenderData()->LODResources.Num() > Index){TArray<FVector3f> Vertexs;auto& LodResource = Mesh->GetRenderData()->LODResources[Index];int32 VertexNum = LodResource.GetNumVertices();for(int32 I = 0; I < VertexNum; I++){Vertexs.Add(LodResource.VertexBuffers.PositionVertexBuffer.VertexPosition(I));}int32 TriangleNum = LodResource.GetNumTriangles();TArray<uint32> Indexs;for(int32 I = 0; I < TriangleNum; I++){Indexs.Add(LodResource.IndexBuffer.GetIndex(I * 3 + 0));Indexs.Add(LodResource.IndexBuffer.GetIndex(I * 3 + 1));Indexs.Add(LodResource.IndexBuffer.GetIndex(I * 3 + 2));}}}
}

 

 

如何填充数据生成一个UStaticMesh

主要是通过填充FMeshDescription的各种图元数据(Vertex, VertexInstance, Polygon, PolygonGroup等等)

void AMyActor::TestCreateStaticMesh()
{const FString ObjectName = "TestStaticMesh";const FString GameFoldPath = "/Game";const FString PackageName = FString::Printf(TEXT("%s/%s"), *GameFoldPath, *ObjectName);UPackage* Package = CreatePackage(*PackageName);UStaticMesh* MyMesh = NewObject<UStaticMesh>(Package, *ObjectName, RF_Standalone | RF_Public);FMeshDescription MeshDescription;FStaticMeshAttributes MeshAttribute(MeshDescription);MeshAttribute.Register();TArray<FDynamicMeshVertex> Vertices;Vertices.Add(FDynamicMeshVertex(FVector3f(500.0f, 500.0f, 200)));Vertices.Add(FDynamicMeshVertex(FVector3f(-500.0f, 500.0f, 200)));Vertices.Add(FDynamicMeshVertex(FVector3f(-500.0f, -500.0f, 200)));Vertices.Add(FDynamicMeshVertex(FVector3f(500.0f, -500.0f, 200)));TArray<int32> Indexs;Indexs.Add(0);Indexs.Add(3);Indexs.Add(1);Indexs.Add(1);Indexs.Add(3);Indexs.Add(2);MeshDescription.Empty();MeshDescription.ReserveNewVertices(Vertices.Num());MeshDescription.ReserveNewTriangles(Indexs.Num() / 3);MeshDescription.ReserveNewVertexInstances(Indexs.Num());TVertexAttributesRef<FVector3f> VertexPositions = MeshAttribute.GetVertexPositions();TVertexInstanceAttributesRef<FVector2f>	VertexInstanceUVs = MeshAttribute.GetVertexInstanceUVs();TVertexInstanceAttributesRef<FVector3f>	VertexInstanceNormals = MeshAttribute.GetVertexInstanceNormals();TVertexInstanceAttributesRef<FVector3f>	VertexInstanceTangents = MeshAttribute.GetVertexInstanceTangents();TPolygonGroupAttributesRef<FName> MaterialSlotNames = MeshAttribute.GetPolygonGroupMaterialSlotNames();TArray<UMaterialInterface*> MaterialInterfaces = {UMaterial::GetDefaultMaterial(MD_Surface)};for(int32 Index = 0; Index < MaterialInterfaces.Num(); Index++){FPolygonGroupID PolygonGroupID = MeshDescription.CreatePolygonGroup();FStaticMaterial StaticMaterial = MaterialInterfaces[Index];MaterialSlotNames[PolygonGroupID] = StaticMaterial.MaterialSlotName;}//create vertexfor(int32 Index = 0; Index < Vertices.Num(); Index++){FVertexID VertexId = MeshDescription.CreateVertex();VertexPositions.Set(VertexId, Vertices[Index].Position);}//create vertex instancefor(int32 Index = 0; Index < Indexs.Num(); Index++){FVertexInstanceID VertexInstanceId = FVertexInstanceID(Index);FVertexID VertexID = FVertexID(Indexs[Index]);MeshDescription.CreateVertexInstanceWithID(VertexInstanceId, VertexID);}// set vertex instance normal/tangent/uvFPolygonGroupID PolygonGroupID(0);TArray<FVertexInstanceID> InstanceIds;for(int32 Index = 0; Index < Indexs.Num(); Index++){FVertexInstanceID VertexInstanceId = FVertexInstanceID(Index);InstanceIds.Add(VertexInstanceId);const FDynamicMeshVertex& DynamicVertex = Vertices[Indexs[Index]];VertexInstanceUVs.Set(VertexInstanceId, DynamicVertex.TextureCoordinate[0]);VertexInstanceNormals.Set(VertexInstanceId, DynamicVertex.TangentX.ToFVector3f());VertexInstanceTangents.Set(VertexInstanceId, DynamicVertex.TangentZ.ToFVector3f());if(InstanceIds.Num() == 3){TArray<FEdgeID> EdgeIds;MeshDescription.CreatePolygon(PolygonGroupID, InstanceIds, &EdgeIds);InstanceIds.Empty();}}// create source model lod0 and commit mesh descconst int32 LodIndex = 0;if(!MyMesh->IsSourceModelValid(LodIndex)){FStaticMeshSourceModel& SourceModel = MyMesh->AddSourceModel();SourceModel.BuildSettings.bRecomputeNormals = false;SourceModel.BuildSettings.bRecomputeTangents = false;SourceModel.BuildSettings.bGenerateLightmapUVs = false;}MyMesh->CreateMeshDescription(LodIndex, MeshDescription);MyMesh->CommitMeshDescription(LodIndex);MyMesh->ImportVersion = EImportStaticMeshVersion::LastVersion;MyMesh->CreateBodySetup();MyMesh->GetBodySetup()->CollisionReponse = EBodyCollisionResponse::BodyCollision_Disabled;MyMesh->Build(true);MyMesh->PostEditChange();MyMesh->MarkPackageDirty();FAssetRegistryModule::AssetCreated(MyMesh);
}

4cf12657eaea4f30b908fbb25d410d6f.png

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】认识C++(上)

目录 从C到C命名空间同名冲突命名空间的定义命名空间的使用 C的输入和输出缺省参数&#xff08;默认参数&#xff09; 从C到C C语言的出现是计算机科学和工程史上的一个重要里程碑&#xff0c;许多现代计算机语言都受C语言的影响。C语言是面向过程的&#xff0c;结构化和模块化…

Windows Docker 部署 Etcd 键值存储系统

一、简介 etcd 是一个由 CoreOS 团队发起的开源项目&#xff0c;它用 Go 语言实现&#xff0c;是一个分布式、高可用的键值存储系统。etcd 采用 Raft 算法&#xff0c;确保了数据的强一致性和高可用性&#xff0c;即使集群中有部分节点发生故障&#xff0c;也能保持服务的正常…

2024深圳杯数学建模C题参考论文24页+完整代码数据解题

一、问题研究 24页参考论文&#xff1a; 【编译器识别】2024深圳杯C题24页参考论文1-3小问完整解题代码https://www.jdmm.cc/file/2710545/ 为了回答这些问题&#xff0c;我们需要进行一系列的编译实验、分析编译结果&#xff0c;并构建判别函数。以下是对这些问题的初步分析…

杨校老师项目之基于单片机STC89C52的智能环境监测系统【嵌入式】

获取全套资料&#xff1a; 有偿获取&#xff1a;mryang511688 技术&#xff1a;C语言、单片机等 摘要&#xff1a; 此设计可分为三个主要部分。此中的温度和湿度的检测功能&#xff0c;通过操纵单总线型温湿度传感器DHT11以数字形式显示&#xff0c;实现了切确测得温湿度的功能…

乡村振兴的农业科技创新:加大农业科技投入,推广农业科技成果,提升农业科技创新水平,推动美丽乡村农业现代化

一、引言 随着全球化和信息化时代的到来&#xff0c;农业作为国民经济的基础&#xff0c;其现代化进程日益受到关注。在乡村振兴战略的大背景下&#xff0c;农业科技创新成为推动乡村经济转型升级、实现农业现代化的关键力量。本文旨在探讨如何通过加大农业科技投入、推广农业…

[图解]EA从数据库逆向得到分析类模型-01

1 00:00:00,840 --> 00:00:02,400 今天&#xff0c;我们来说一下 2 00:00:02,670 --> 00:00:06,320 一个最近几天不止一个同学问的问题 3 00:00:06,490 --> 00:00:11,410 就是说&#xff0c;怎样把一个数据库 4 00:00:13,740 --> 00:00:16,720 转到分析类图 5 …

项目管理-案例重点知识(整合管理)

项目管理&#xff1a;每天进步一点点~ 活到老&#xff0c;学到老 ヾ(◍∇◍)&#xff89;&#xff9e; 何时学习都不晚&#xff0c;加油 一、整合管理 案例重点 重点内容&#xff1a; &#xff08;1&#xff09;项目章程内容和作用 &#xff08;2&#xff09;项目管理计划…

前端 performance api使用 —— mark、measure计算vue3页面echarts渲染时间

文章目录 ⭐前言&#x1f496;vue3系列文章 ⭐Performance api计算持续时间&#x1f496; mark用法&#x1f496; measure用法 ⭐计算echarts渲染的持续时间⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于 前端 performance api使用 —— mark、measure计…

vs2019 c++中模板 enable_if_t 的使用

&#xff08;1&#xff09; 该模板的定义如下&#xff1a; template <bool _Test, class _Ty void> struct enable_if {}; // no member "type" when !_Testtemplate <class _Ty> struct enable_if<true, _Ty> { // type is _Ty for _Testusing …

C++——动态规划

公共子序列问题 ~待补充 最长公共子序列 对于两个字符串A和B&#xff0c;A的前i位和B的前j位的最大公共子序列必然是所求解的一部分&#xff0c;设dp[i][j]为串A前i位和B串前j位的最长公共子序列的长度&#xff0c;则所求答案为dp[n][m]&#xff0c;其中n&#xff0c;m分别为…

C++ | Leetcode C++题解之第90题子集II

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> t;vector<vector<int>> ans;vector<vector<int>> subsetsWithDup(vector<int> &nums) {sort(nums.begin(), nums.end());int n nums.size();for (int mask …

楼宇智慧公厕建设新方案-集成更简单!成本价更低!

在当今的大厦和写字楼中&#xff0c;公厕面临着诸多痛点。 办公楼公厕常常存在厕位难找的问题&#xff0c;使用者不得不花费时间逐一查看&#xff0c;导致效率低下&#xff1b;环境质量也令人担忧&#xff0c;异味、脏污等情况时有发生&#xff0c;影响使用者的心情和健康&…