UE4尝试用C++修改已有StaticMesh的顶点数据

目标

之前的博客《UE4尝试用C++生成一个最简单的StaticMesh》是创建一个新的StaticMesh,本篇则是对一个已有的StaticMesh的顶点数据进行修改。思路上是获取StaticMesh的RawMesh,然后对其进行操作。

本篇内容具体包括:

  • 创建一个插件,其中包含能修改StaticMesh的顶点数据的功能。
  • 总结出通用的框架代码。

实验插件

Blank为模板创建插件
在这里插入图片描述
在插件模块的.Build.cs文件中添加RawMeshPrivateDependencyModuleNames列表中
在这里插入图片描述
接下来,我选择定义一个Actor来实现功能。因为Actor可以很方便被创建,且其UPROPERTY可以在Detail面板中有对应界面,这样我能更方便指定StaticMesh并提供按钮界面。

StaticMeshModifier.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"

#include"StaticMeshModifier.generated.h"

UCLASS()
class AStaticMeshModifier : public AActor
{
    
    
	GENERATED_UCLASS_BODY()

public:
	UPROPERTY(Category = "StaticMeshModifier", EditAnywhere)
		UStaticMesh* StaticMesh;

	UFUNCTION(Category = "StaticMeshModifier", CallInEditor)
		void Process();
};

StaticMeshModifier.cpp
当前所做的操作只是简单地将模型的最低点对齐到水平位置

#include "StaticMeshModifier.h"

#include "Engine/StaticMesh.h"
#include "RawMesh.h"

AStaticMeshModifier::AStaticMeshModifier(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
    
    
}


void AStaticMeshModifier::Process()
{
    
    
	//表明将要更改StaticMesh
	StaticMesh->PreEditChange(nullptr);

	//遍历所有LOD
	for (int LOD = 0; LOD < StaticMesh->SourceModels.Num(); LOD++)
	{
    
    
		//获得此LOD的SourceModel
		FStaticMeshSourceModel& SourceModel = StaticMesh->SourceModels[LOD];

		//获得RawMesh
		FRawMesh RawMesh;
		SourceModel.RawMeshBulkData->LoadRawMesh(RawMesh);

		//处理顶点数据,这里就是将模型的最低点对齐到水平位置
		{
    
    
			//最低点
			float MinZ = RawMesh.VertexPositions[0].Z;
			//找到最低点:
			for (int VertexId = 1; VertexId < RawMesh.VertexPositions.Num(); VertexId++)
			{
    
    
				if (RawMesh.VertexPositions[VertexId].Z < MinZ)
					MinZ = RawMesh.VertexPositions[VertexId].Z;
			}
			//对所有顶点进行偏移:
			for (int VertexId = 0; VertexId < RawMesh.VertexPositions.Num(); VertexId++)
				RawMesh.VertexPositions[VertexId].Z -= MinZ;
		}

		//保存RawMesh
		SourceModel.SaveRawMesh(RawMesh);
	}

	TArray< FText > BuildErrors;
	StaticMesh->Build(true, &BuildErrors);

	//表明修改结束StaticMesh
	StaticMesh->PostEditChange();
}

在这里插入图片描述


修改前:
在这里插入图片描述
使用时:

  1. 将StaticMeshModifier这个Actor拖到场景中
  2. 将待处理模型放到StaticMeshModifier细节面板中
  3. 点击Process按钮

在这里插入图片描述
修改后:
在这里插入图片描述

总结

代码框架:

//表明将要更改StaticMesh
StaticMesh->PreEditChange(nullptr);

//遍历所有LOD
for (int LOD = 0; LOD < StaticMesh->SourceModels.Num(); LOD++)
{
    
    
	//获得此LOD的SourceModel
	FStaticMeshSourceModel& SourceModel = StaticMesh->SourceModels[LOD];

	//获得RawMesh
	FRawMesh RawMesh;
	SourceModel.RawMeshBulkData->LoadRawMesh(RawMesh);

	//处理顶点数据
	{
    
    
		//在这里写修改的逻辑
	}

	//保存RawMesh
	SourceModel.SaveRawMesh(RawMesh);
}

TArray< FText > BuildErrors;
StaticMesh->Build(true, &BuildErrors);

//表明修改结束StaticMesh
StaticMesh->PostEditChange();

另外记得要在.Build.cs文件中将RawMeshPrivateDependencyModuleNames中。

对于FRawMesh的数据结构,可以参考《UE4实验观察FRawMesh的数据结构》

问题记录

我这里有时候会发现FRawMesh的数据是空的:
在这里插入图片描述
不过如果重新导入,则就能得到
在这里插入图片描述
关于“RawMesh数据是否能保证得到”的问题,待深入研究。

猜你喜欢

转载自blog.csdn.net/u013412391/article/details/114106966
今日推荐