我很难在 UE 中从 C++ 级别做相当简单的事情。 目标很简单。我希望能够显示一个立方体。我想手动指定顶点、面和法线。用 C++ 对其进行硬编码,创建网格并显示。但我还是做不到。
此存储库中提供了该项目的完整代码。请查看 AMyActor::RegenerateMeshByHand 方法。 https://github.com/stryku/BareBonesDynamicMesh/blob/forum-question/Source/BareBonesDynamicMesh/MyActor.cpp#L154
我有一个简单的项目,只有一个从 AActor 派生的 MyActor。我创建了一个 UDynamicMeshComponent 并将其设置为我的根组件。 在 PostLoad() 中,我尝试创建 UE::Geometry::FDynamicMesh3 网格并将其设置在我的根组件中。
一切正常,网格已设置,但看起来不太好。其他每个面的法线都混乱了,因此立方体的一半面是不可见的。它们只能“从内部”看到,因为只有在这个视图中,法线才面向相机(我认为)。
当我调用 mesh.CheckValidity() 时,我得到 false,所以我一定做错了什么。
我尝试了另一件事:在 Blender 中创建一个立方体,导出到 OBJ 文件,看看里面有什么,然后从代码中执行相同的操作。并且它有效(在 ReverseOrientation 和 InitializeOverlayToPerTriangleNormals 之后)!显示完整的立方体,所有法线都很好。 所以,我很困惑。
当然我错过了引擎明显需要的东西。有人知道出了什么问题吗?
该方法的完整代码(如果有人喜欢的话):
UE::Geometry::FDynamicMesh3 AMyActor::RegenerateMeshByHand() {
UE::Geometry::FDynamicMesh3 mesh;
mesh.EnableAttributes();
UE::Geometry::FDynamicMeshNormalOverlay *normalsOverlay =
mesh.Attributes()->PrimaryNormals();
const std::array vertices{FVector3d(-1, -1, -1), FVector3d(1, -1, -1),
FVector3d(-1, -1, 1), FVector3d(1, -1, 1),
FVector3d(-1, 1, -1), FVector3d(1, 1, -1),
FVector3d(-1, 1, 1), FVector3d(1, 1, 1)};
const std::array normals{FVector3f(0, -1, 0), FVector3f(0, 1, 0),
FVector3f(-1, 0, 0), FVector3f(1, 0, 0),
FVector3f(0, 0, -1), FVector3f(0, 0, 1)};
int32 id;
UE::Geometry::EMeshResult result;
for (auto vertex : vertices) {
mesh.AppendVertex(vertex * 100);
}
for (auto normal : normals) {
normalsOverlay->AppendElement(normal);
normalsOverlay->AppendElement(normal);
normalsOverlay->AppendElement(normal);
}
// Face 0, 1. Normal 0
id = mesh.AppendTriangle(0, 1, 2);
result = normalsOverlay->SetTriangle(id, {0, 1, 2});
id = mesh.AppendTriangle(3, 1, 2);
result = normalsOverlay->SetTriangle(id, {0, 1, 2});
// Face 2, 3. Normal 1
id = mesh.AppendTriangle(4, 5, 6);
result = normalsOverlay->SetTriangle(id, {1 * 3, 1 * 3 + 1, 1 * 3 + 2});
id = mesh.AppendTriangle(7, 5, 6);
result = normalsOverlay->SetTriangle(id, {1 * 3, 1 * 3 + 1, 1 * 3 + 2});
// Face 4, 5. Normal 2
id = mesh.AppendTriangle(4, 6, 0);
result = normalsOverlay->SetTriangle(id, {2 * 3, 2 * 3 + 1, 2 * 3 + 2});
id = mesh.AppendTriangle(2, 6, 0);
result = normalsOverlay->SetTriangle(id, {2 * 3, 2 * 3 + 1, 2 * 3 + 2});
// Face 6, 7. Normal 3
id = mesh.AppendTriangle(1, 5, 3);
result = normalsOverlay->SetTriangle(id, {3 * 3, 3 * 3 + 1, 3 * 3 + 2});
id = mesh.AppendTriangle(7, 5, 3);
result = normalsOverlay->SetTriangle(id, {3 * 3, 3 * 3 + 1, 3 * 3 + 2});
// Face 8, 9. Normal 4
id = mesh.AppendTriangle(0, 1, 4);
result = normalsOverlay->SetTriangle(id, {4 * 3, 4 * 3 + 1, 4 * 3 + 2});
id = mesh.AppendTriangle(5, 1, 4);
result = normalsOverlay->SetTriangle(id, {4 * 3, 4 * 3 + 1, 4 * 3 + 2});
// Face 10, 11. Normal 5
id = mesh.AppendTriangle(2, 3, 6);
result = normalsOverlay->SetTriangle(id, {5 * 3, 5 * 3 + 1, 5 * 3 + 2});
id = mesh.AppendTriangle(7, 3, 6);
result = normalsOverlay->SetTriangle(id, {5 * 3, 5 * 3 + 1, 5 * 3 + 2});
// Why is this false?
const auto validityResult =
mesh.CheckValidity({}, UE::Geometry::EValidityCheckFailMode::ReturnOnly);
return mesh;
}
必须调用ReverseOrientation。会有帮助