UE4绘制简单三角形(二)
运行时动态生成StaticMesh
。主要参考Cesium for UE4
插件的相关源码。
Code
FStaticMeshBuildVertex
结构体FStaticMeshBuildVertex
的数据成员如下图,构成几何三角Mesh
顶点的基本数据。
The information used to build a static-mesh vertex.
FStaticMeshLODResources
Rendering resources needed to render an individual static mesh LOD.
渲染单独一个静态网格LOD所需的渲染资源,主要指顶点缓冲区、索引缓冲区等等渲染资源。
FStaticMeshSection
A set of static mesh triangles which are rendered with the same material.
共用一个材质的静态网格三角形集合。主要包含顶点的起始索引,三角形个数,以及材质索引等等。
示例
生成一个简单的三角形形。
UStaticMeshComponent* mesh = NewObject<UStaticMeshComponent>(this);
mesh->SetFlags(RF_Transient);
UStaticMesh* pStaticMesh = NewObject<UStaticMesh>(mesh);
mesh->SetStaticMesh(pStaticMesh);
pStaticMesh->NeverStream = true;
//静态网格MeshData,创建一个LOD资源
FStaticMeshRenderData* RenderData = new FStaticMeshRenderData();
RenderData->AllocateLODResources(1);
FStaticMeshLODResources& LODResources = RenderData->LODResources[0];
//设置索引数组
TArray<uint32> indices;
indices.SetNum(3);
indices[0]=0;
indices[1] = 1;
indices[2] = 2;
LODResources.IndexBuffer.SetIndices(
indices,
EIndexBufferStride::Type::AutoDetect);
LODResources.bHasDepthOnlyIndices = false;
LODResources.bHasReversedIndices = false;
LODResources.bHasReversedDepthOnlyIndices = false;
//LODResources.bHasAdjacencyInfo = false;
// 设置顶点数据
TArray<FStaticMeshBuildVertex> StaticMeshBuildVertices;
StaticMeshBuildVertices.SetNum(indices.Num());
FStaticMeshBuildVertex& vertex0 = StaticMeshBuildVertices[0];
vertex0.Position = FVector(0, 0, 0);
vertex0.Color= FColor(255, 0, 0);
vertex0.UVs[0]=FVector2D(0,0);
vertex0.TangentX = FVector(0, 1, 0);
vertex0.TangentY = FVector(1, 0, 0);
vertex0.TangentY = FVector(0, 0, 1);
FStaticMeshBuildVertex& vertex1 = StaticMeshBuildVertices[1];
vertex1.Position = FVector(100, 0, 0);
vertex1.Color = FColor(255, 0, 0);
vertex1.UVs[0] = FVector2D(1, 0);
vertex1.TangentX = FVector(0, 1, 0);
vertex1.TangentY = FVector(1, 0, 0);
vertex1.TangentY = FVector(0, 0, 1);
FStaticMeshBuildVertex& vertex2 = StaticMeshBuildVertices[2];
vertex2.Position = FVector(0, 100, 0);
vertex2.Color = FColor(255, 0, 0);
vertex2.UVs[0] = FVector2D(1, 0);
vertex2.TangentX = FVector(0, 1, 0);
vertex2.TangentY = FVector(1, 0, 0);
vertex2.TangentY = FVector(0, 0, 1);
LODResources.bHasColorVertexData = false;
//设置包围盒
FBoxSphereBounds BoundingBoxAndSphere;
BoundingBoxAndSphere.Origin = FVector(0, 0, 0);
BoundingBoxAndSphere.SphereRadius = 100.0f;
RenderData->Bounds = BoundingBoxAndSphere;
//顶点buffer LODResources.VertexBuffers.PositionVertexBuffer.Init(StaticMeshBuildVertices);
FColorVertexBuffer& ColorVertexBuffer =
LODResources.VertexBuffers.ColorVertexBuffer;
//ColorVertexBuffer.Init(StaticMeshBuildVertices);
//法线,切线,贴图坐标buffer LODResources.VertexBuffers.StaticMeshVertexBuffer.Init(
StaticMeshBuildVertices,1);
FStaticMeshLODResources::FStaticMeshSectionArray& Sections =
LODResources.Sections;
FStaticMeshSection& section = Sections.AddDefaulted_GetRef();
section.bEnableCollision = false;
section.NumTriangles = StaticMeshBuildVertices.Num() / 3;
section.FirstIndex = 0;
section.MinVertexIndex = 0;
section.MaxVertexIndex = StaticMeshBuildVertices.Num() - 1;
//section.bEnableCollision = true;
//section.bCastShadow = true;
pStaticMesh->RenderData = TUniquePtr<FStaticMeshRenderData>(RenderData);
UMaterial* Material = UMaterial::GetDefaultMaterial(MD_Surface);
Material->TwoSided = true;
//Material->Wireframe = true;
section.MaterialIndex = 0;
pStaticMesh->AddMaterial(Material);
pStaticMesh->InitResources();
pStaticMesh->CalculateExtendedBounds();
pStaticMesh->RenderData->ScreenSize[0].Default = 1.0f;
pStaticMesh->CreateBodySetup();
mesh->SetMobility(EComponentMobility::Movable);
mesh->SetupAttachment(this->RootComponent);
mesh->RegisterComponent();