载入中...
搜索中...
未找到
MeshTangent.cpp
浏览该文件的文档.
1#include <cmath>
2#include <new>
3#include "graphics/Mesh.h"
4
5namespace eve::graphics {
6Result<void> Mesh::validateVegetationFactors(std::span<const float> values) const {
7 if (!values.empty()) {
8 if (gpuVertexCount <= 0 || values.size() != size_t(gpuVertexCount) * 5)
10 DiagnosticCode::InvalidArgument, "vegetation factor stream must contain five values per mesh vertex"));
11 for (size_t i = 0; i < values.size(); ++i)
12 if (!std::isfinite(values[i]) || (i % 5 < 3 && (values[i] < 0 || values[i] > 1)))
15 "vegetation factors must be unit values and detail UVs must be finite"));
16 }
17 return Result<void>::success();
18}
21 if (!valid) return valid;
22 vegetationFactors_.swap(values);
23 return Result<void>::success();
24}
26 if (values.empty()) return Result<void>::success();
27 if (gpuVertexCount <= 0 || values.size() != size_t(gpuVertexCount) * 9)
29 DiagnosticCode::InvalidArgument, "vegetation deformation stream must contain nine values per mesh vertex"));
30 for (size_t i = 0; i < values.size(); i += 9) {
31 for (size_t component = 0; component < 9; ++component)
32 if (!std::isfinite(values[i + component]))
34 DiagnosticCode::InvalidArgument, "vegetation deformation factors must be finite"));
35 for (size_t component = 3; component <= 6; ++component)
36 if (values[i + component] < 0 || values[i + component] > 1)
38 DiagnosticCode::InvalidArgument, "vegetation deformation masks must be unit values"));
39 if (values[i + 7] < 0 || values[i + 8] < 0)
41 DiagnosticCode::InvalidArgument, "vegetation deformation bounds must be nonnegative"));
42 }
43 return Result<void>::success();
44}
47 if (!valid) return valid;
48 vegetationDeformationFactors_.swap(values);
49 return Result<void>::success();
50}
51Result<void> Mesh::validateMotionHighlights(std::span<const float> values) const {
52 if (!values.empty()) {
53 if (gpuVertexCount <= 0 || values.size() != size_t(gpuVertexCount))
55 "motion highlight stream must match mesh vertex count"));
56 for (float value : values)
57 if (!std::isfinite(value) || value < 0)
59 "motion highlights must be finite and nonnegative"));
60 }
61 return Result<void>::success();
62}
65 if (!valid) return valid;
66 motionHighlights_.swap(values);
67 return Result<void>::success();
68}
69Result<void> Mesh::validateTangentFrame(std::span<const float> tangents, std::span<const float> bitangents) const {
70 auto invalid = [] {
73 "tangent frame must contain finite independent XYZ vectors for every mesh vertex"));
74 };
75 if (tangents.empty() && bitangents.empty()) {
76 return Result<void>::success();
77 }
78 if (gpuVertexCount <= 0 || tangents.size() != size_t(gpuVertexCount) * 3 || bitangents.size() != tangents.size())
79 return invalid();
80 for (size_t i = 0; i < tangents.size(); i += 3) {
81 double tt = 0, bb = 0, tb = 0;
82 for (unsigned c = 0; c < 3; ++c) {
83 const double t = tangents[i + c], b = bitangents[i + c];
84 if (!std::isfinite(t) || !std::isfinite(b)) return invalid();
85 tt += t * t;
86 bb += b * b;
87 tb += t * b;
88 }
89 if (tt <= 1e-20 || bb <= 1e-20 || tt * bb - tb * tb <= tt * bb * 1e-12) return invalid();
90 }
91 return Result<void>::success();
92}
93Result<void> Mesh::adoptTangentFrame(std::vector<float>&& tangents, std::vector<float>&& bitangents) {
94 if (&tangents == &bitangents)
96 Diagnostic::error(DiagnosticCode::InvalidArgument, "tangent frame buffers must be distinct"));
97 auto valid = validateTangentFrame(tangents, bitangents);
98 if (!valid) return valid;
99 importedTangents_.swap(tangents);
100 importedBitangents_.swap(bitangents);
101 return Result<void>::success();
102}
103Result<void> Mesh::setTangentFrame(std::span<const float> tangents, std::span<const float> bitangents) {
104 auto valid = validateTangentFrame(tangents, bitangents);
105 if (!valid) return valid;
106 try {
107 std::vector<float> t(tangents.begin(), tangents.end()), b(bitangents.begin(), bitangents.end());
108 importedTangents_.swap(t);
109 importedBitangents_.swap(b);
110 return Result<void>::success();
111 } catch (const std::bad_alloc&) {
112 return Result<void>::failure(Diagnostic::error(DiagnosticCode::Failed, "tangent frame allocation failed"));
113 }
114}
115} // namespace eve::graphics
double value
std::map< std::string, Var > values
std::int32_t c
bool valid
MeleePoint3 b
Definition MeleeHit.cpp:41
float tb
float t
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
Result< void > adoptVegetationFactors(std::vector< float > &&values)
Validate and take ownership of interleaved vegetation variation/occlusion pairs.
int gpuVertexCount
Vertex count of the GPU buffer (morph CPU base may be empty).
Definition Mesh.h:30
Result< void > validateMotionHighlights(std::span< const float > values) const
Validate an optional per-vertex motion-highlight stream without mutation.
Result< void > adoptVegetationDeformationFactors(std::vector< float > &&values)
Validate and atomically take ownership of a TVE rest-deformation stream. Failure preserves the mesh a...
Result< void > validateVegetationDeformationFactors(std::span< const float > values) const
Validate optional TVE rest-deformation data without mutation. Nine floats per vertex are pivot XYZ,...
Result< void > adoptTangentFrame(std::vector< float > &&tangents, std::vector< float > &&bitangents)
Validate then take owning frame buffers without allocating on success.
Result< void > validateVegetationFactors(std::span< const float > values) const
Validate optional interleaved vegetation variation/occlusion pairs without mutation.
Result< void > adoptMotionHighlights(std::vector< float > &&values)
Validate and transfer an owning motion-highlight stream without allocating on success.
Result< void > setTangentFrame(std::span< const float > tangents, std::span< const float > bitangents)
Atomically copy authored tangent and bitangent XYZ streams, or clear both with empty spans.
Result< void > validateTangentFrame(std::span< const float > tangents, std::span< const float > bitangents) const
Validate a frame against current vertex count without mutation or allocation on success.
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition Animation.h:25