进入RuntimeGeometryDemo最外层文件夹后,右键单击Windows资源管理器中的RuntimeGeometryDemo.uproject,然后从上下文菜单中选择“Generate Visual Studio project files”项目文件。这将生成RuntimeGeometryDemo.sln。你也可以直接在编辑器中打开.uproject(它会要求编译),但我想大概率你是需要参考下本教程的C++代码的。
UCLASS(Abstract)
class RUNTIMEGEOMETRYUTILS_API ADynamicMeshBaseActor : public AActor
{
protected:
/** The SourceMesh used to initialize the mesh Components in the various subclasses */
FDynamicMesh3 SourceMesh;
};
这个Actor并没有显示网格的能力,它需要一个组件。我将创建三个Actor子类分别对应三种组件:
UCLASS()
class RUNTIMEGEOMETRYUTILS_API ADynamicSMCActor : public ADynamicMeshBaseActor
{
UPROPERTY(VisibleAnywhere)
UStaticMeshComponent* MeshComponent = nullptr;
};
UCLASS()
class RUNTIMEGEOMETRYUTILS_API ADynamicPMCActor : public ADynamicMeshBaseActor
{
UPROPERTY(VisibleAnywhere)
UProceduralMeshComponent* MeshComponent = nullptr;
};
UCLASS()
class RUNTIMEGEOMETRYUTILS_API ADynamicSDMCActor : public ADynamicMeshBaseActor
{
UPROPERTY(VisibleAnywhere)
USimpleDynamicMeshComponent* MeshComponent = nullptr;
};
protected:
/**
* Called when the SourceMesh has been modified. Subclasses override this function to
* update their respective Component with the new SourceMesh.
*/
virtual void OnMeshEditedInternal();
/**
* Call EditMesh() to safely modify the SourceMesh owned by this Actor.
* Your EditFunc will be called with the Current SourceMesh as argument,
* and you are expected to pass back the new/modified version.
* (If you are generating an entirely new mesh, MoveTemp can be used to do this without a copy)
*/
virtual void EditMesh(TFunctionRef<void(FDynamicMesh3&)> EditFunc);
void ADynamicMeshBaseActor::CopyFromMesh(ADynamicMeshBaseActor* OtherMesh, bool bRecomputeNormals)
{
// the part where we generate a new mesh
FDynamicMesh3 TmpMesh;
OtherMesh->GetMeshCopy(TmpMesh);
// apply our normals setting
if (bRecomputeNormals)
{
RecomputeNormals(TmpMesh);
}
这是一个很简单的函数,但关键是,你基本上可以剪切和粘贴此函数,重命名它,并在“the part where we generate a new mesh”插入任何几何处理代码,你将有权在蓝图中访问该操作。进行网格编辑的其他蓝图API 函数正是这样做的。一个有用的练习是添加Remesh()函数,通过从Command-Line Geometry Processing Tutorial中将相关的网格重建的代码拷贝黏贴过来。
自UE4.26预览版5起,默认物理系统已切换回二进制版本的PhysX。如果你自己从源代码来构建,你仍然可以启用Chaos,并尝试未来即将推出的所有新功能。然而,这一改变导致的一个结果是UProceduralMesh组件的运行时物理烘焙再次可用。因此,我已经添加了一个碰撞模式的属性到ADynamicMeshBaseActor,包含“Complex as Simple(将复杂模型转换为简单碰撞体)”与”Complex as Simple Async(复杂模型异步转换为简单碰撞体)”两个选项。这些选项目前只会对ADynamicPMCActor产生影响,而对SMC或SDMC没有影响。它可能也可以对SMC起作用, 我自己还没有试过(也许你能自己搞定,然后给我发一个PullRequest!)
虽然你可以直接在你的项目中使用ADynamicMeshBaseActor和RuntimeGeometryutils插件,但我觉这些更多的应该被视作一种指南,来帮助你建立自己的版本。如果你正在研发涉及存储运行时创建的内容的游戏或应用,我鼓励你花一些时间思考如何组织你的数据。在此演示中将源网格存储在Actor使得我后续的实现非常方便,但如果我构建的是真实内容,我就会将这些源网格的所有权从 Actor 转移到一些更集中的位置,例如UGameInstance子系统。你可能觉得这看起来像“可以放在稍后再去做的事儿”,但如果你基于当前的设计开发了很多蓝图或游戏功能,那之后的重构会显得非常繁琐(我最初将ADynamicMeshBaseActor放在Game目录中,后来为了能将.h/.cpp文件正确的移动到插件目录中而不破坏已有的功能,我花了一个下午来学习UE的Redirector……)