载入中...
搜索中...
未找到
SoftBodyModelCooker.cpp
浏览该文件的文档.
2
4
5#include <algorithm>
6#include <cmath>
7#include <set>
8
10namespace {} // namespace
11
13 const SoftBodyModelDefinition& definition) {
14 auto recipeValid = definition.validate();
15 if (!recipeValid) return eve::Result<SoftBodyModel>::failure(recipeValid.status());
16 if (definition.surfaceSampling != SoftBodySurfaceSampling::Vertices ||
17 definition.volumeSampling != SoftBodyVolumeSampling::None)
20 "only vertex surface sampling without volume voxels is implemented", "sampling"));
21 if (mesh.positions.empty() || mesh.positions.size() % 3 != 0)
24 "mesh positions must contain complete xyz vertices", "mesh.positions"));
25 const std::size_t vertexCount = mesh.positions.size() / 3;
26 if (mesh.indices.empty() || mesh.indices.size() % 3 != 0)
28 eve::DiagnosticCode::InvalidArgument, "mesh indices must contain complete triangles", "mesh.indices"));
29
31 model.sourceMesh = definition.sourceMesh;
32 model.particles.reserve(vertexCount);
33 model.surfaceBindings.reserve(vertexCount);
34 for (std::size_t index = 0; index < vertexCount; ++index) {
35 const float x = mesh.positions[index * 3];
36 const float y = mesh.positions[index * 3 + 1];
37 const float z = mesh.positions[index * 3 + 2];
38 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(z))
40 eve::DiagnosticCode::InvalidArgument, "mesh position must be finite", "mesh.positions"));
41 model.particles.push_back({x, y, z});
42 model.surfaceBindings.push_back({static_cast<std::uint32_t>(index)});
43 }
44 model.surfaceIndices = mesh.indices;
45
46 std::vector<std::set<std::uint32_t>> neighborhoods(vertexCount);
47 for (std::size_t triangle = 0; triangle < mesh.indices.size(); triangle += 3) {
48 const auto a = mesh.indices[triangle];
49 const auto b = mesh.indices[triangle + 1];
50 const auto c = mesh.indices[triangle + 2];
51 if (a >= vertexCount || b >= vertexCount || c >= vertexCount)
53 eve::DiagnosticCode::InvalidArgument, "mesh triangle index exceeds vertex count", "mesh.indices"));
54 if (a == b || b == c || a == c)
56 eve::DiagnosticCode::InvalidArgument, "mesh contains a degenerate index triangle", "mesh.indices"));
57 for (const auto center : {a, b, c}) {
58 neighborhoods[center].insert(a);
59 neighborhoods[center].insert(b);
60 neighborhoods[center].insert(c);
61 }
62 }
63 for (const auto& neighborhood : neighborhoods) {
64 if (neighborhood.size() < 3) continue;
66 cluster.particleIndices.assign(neighborhood.begin(), neighborhood.end());
67 model.clusters.push_back(std::move(cluster));
68 }
69 auto modelValid = model.validate();
70 if (!modelValid) return eve::Result<SoftBodyModel>::failure(modelValid.status());
72}
73
74} // namespace eve::physics::softbody_cook
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
int triangle
std::uint32_t vertexCount
std::int32_t c
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
Mesh * mesh
glm::mat4 model
uint32_t index
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
eve::Result< SoftBodyModel > cookSoftBodyModel(const eve::asset::CanonicalMeshData &mesh, const SoftBodyModelDefinition &definition)
Cook an owning canonical mesh snapshot into a validated soft-body model.
Owning CPU mesh snapshot; UV arrays are packed ST pairs indexed by source set number....
An overlapping shape-matching cluster stored by particle index.
std::vector< std::uint32_t > particleIndices
Versioned authoring recipe used to cook a mesh-backed SoftBodyModel.
Backend-neutral, owning result of deterministic soft-body cooking.