载入中...
搜索中...
未找到
Mesh.cpp
浏览该文件的文档.
1#include "graphics/Mesh.h"
2
3#include "graphics/Graphics.h"
4
5#include <algorithm>
6#include <cmath>
7
8namespace eve::graphics {
9
10void Mesh::computeBounds(const float *posXYZ, int vertexCount) {
11 boundsCx = 0.f;
12 boundsCy = 0.f;
13 boundsCz = 0.f;
14 boundsRadius = 0.f;
15 if (!posXYZ || vertexCount <= 0) return;
16
17 const size_t n = size_t(vertexCount);
18 glm::vec3 c(0.f);
19 for (size_t i = 0; i < n; ++i) {
20 c.x += posXYZ[i * 3u + 0u];
21 c.y += posXYZ[i * 3u + 1u];
22 c.z += posXYZ[i * 3u + 2u];
23 }
24 c /= float(n);
25 boundsCx = c.x;
26 boundsCy = c.y;
27 boundsCz = c.z;
28
29 float r = 0.f;
30 for (size_t i = 0; i < n; ++i) {
31 const float dx = posXYZ[i * 3u + 0u] - c.x;
32 const float dy = posXYZ[i * 3u + 1u] - c.y;
33 const float dz = posXYZ[i * 3u + 2u] - c.z;
34 const float d = std::sqrt(dx * dx + dy * dy + dz * dz);
35 if (d > r) r = d;
36 }
37 // Degenerate (single-point) meshes still get a tiny non-zero sphere so
38 // hasBounds() stays meaningful and the culler never drops point geometry.
39 boundsRadius = r > 0.f ? r : 1e-4f;
40}
41
42void Mesh::drawOcclusion(Graphics *gfx, const glm::mat4 &matrix) const {
43 if (!gfx || !getCastOcclusion()) return;
44 const float x = matrix[3][0];
45 const float y = matrix[3][1];
46 const float w = std::sqrt(matrix[0][0] * matrix[0][0] + matrix[0][1] * matrix[0][1]);
47 const float h = std::sqrt(matrix[1][0] * matrix[1][0] + matrix[1][1] * matrix[1][1]);
48 if (w <= 0.f || h <= 0.f) return;
49 gfx->drawOcclusionSolid(x, y, w, h);
50}
51
53 basePos_.clear();
54 baseNrm_.clear();
55 baseUv_.clear();
56 morphs_.clear();
57 morphWeights_.clear();
58 morphDirty_ = false;
59}
60
61void Mesh::initMorphBase(int vertexCount, const float *posXYZ, const float *nrmXYZ,
62 const float *uvST) {
64 if (vertexCount <= 0 || !posXYZ) return;
65 const size_t n = size_t(vertexCount);
66 basePos_.assign(posXYZ, posXYZ + n * 3);
67 if (nrmXYZ)
68 baseNrm_.assign(nrmXYZ, nrmXYZ + n * 3);
69 else
70 baseNrm_.assign(n * 3, 0.f);
71 if (uvST)
72 baseUv_.assign(uvST, uvST + n * 2);
73 else
74 baseUv_.assign(n * 2, 0.f);
75}
76
77bool Mesh::addMorphTarget(const std::string &name, const float *deltaPosXYZ) {
78 if (name.empty() || !deltaPosXYZ || basePos_.empty()) return false;
79 if (hasMorph(name)) return false;
80 MorphTarget t;
81 t.name = name;
82 t.deltaPos.assign(deltaPosXYZ, deltaPosXYZ + basePos_.size());
83 morphs_.push_back(std::move(t));
84 morphWeights_[name] = 0.f;
85 morphDirty_ = true;
86 return true;
87}
88
89bool Mesh::addMorphTargetAbsolute(const std::string &name, const float *absPosXYZ) {
90 if (name.empty() || !absPosXYZ || basePos_.empty()) return false;
91 if (hasMorph(name)) return false;
92 MorphTarget t;
93 t.name = name;
94 t.deltaPos.resize(basePos_.size());
95 for (size_t i = 0; i < basePos_.size(); ++i)
96 t.deltaPos[i] = absPosXYZ[i] - basePos_[i];
97 morphs_.push_back(std::move(t));
98 morphWeights_[name] = 0.f;
99 morphDirty_ = true;
100 return true;
101}
102
103int Mesh::getVertexCount() const { return int(basePos_.size() / 3); }
104
105int Mesh::getMorphCount() const { return int(morphs_.size()); }
106
107std::string Mesh::getMorphName(int index) const {
108 if (index < 0 || size_t(index) >= morphs_.size()) return {};
109 return morphs_[size_t(index)].name;
110}
111
112bool Mesh::hasMorph(const std::string &name) const {
113 return morphWeights_.find(name) != morphWeights_.end();
114}
115
116bool Mesh::setMorphWeight(const std::string &name, float weight) {
117 auto it = morphWeights_.find(name);
118 if (it == morphWeights_.end()) return false;
119 if (weight < 0.f) weight = 0.f;
120 if (weight > 1.f) weight = 1.f;
121 if (std::fabs(it->second - weight) > 1e-6f) {
122 it->second = weight;
123 morphDirty_ = true;
124 }
125 return true;
126}
127
128float Mesh::getMorphWeight(const std::string &name) const {
129 auto it = morphWeights_.find(name);
130 return it == morphWeights_.end() ? 0.f : it->second;
131}
132
134 for (auto &kv : morphWeights_) {
135 if (kv.second != 0.f) {
136 kv.second = 0.f;
137 morphDirty_ = true;
138 }
139 }
140}
141
142void Mesh::computeMorphedPositions(std::vector<float> &outPos, std::vector<float> &outNrm) const {
143 outPos = basePos_;
144 outNrm = baseNrm_;
145 if (outPos.empty()) return;
146 for (const MorphTarget &t : morphs_) {
147 auto it = morphWeights_.find(t.name);
148 const float w = (it == morphWeights_.end()) ? 0.f : it->second;
149 if (std::fabs(w) < 1e-8f) continue;
150 for (size_t i = 0; i < outPos.size() && i < t.deltaPos.size(); ++i)
151 outPos[i] += t.deltaPos[i] * w;
152 }
153}
154
155} // namespace eve::graphics
int y
Definition Grass.cpp:135
float u
Definition Grass.cpp:234
int x
Definition Grass.cpp:135
glm::vec3 n
Definition Grass.cpp:64
int h
int w
uint32_t c
const char * name
Definition RockMesh.cpp:21
int d
bool getCastOcclusion() const
When false, skipped by Graphics::drawOcclusion / volumetric occluder passes.
Definition Drawable.h:27
virtual void drawOcclusionSolid(float x, float y, float w, float h)
Definition Graphics.cpp:856
void initMorphBase(int vertexCount, const float *posXYZ, const float *nrmXYZ=nullptr, const float *uvST=nullptr)
Capture base pose (xyz packed). Optional normals/uvs (same vertex count).
Definition Mesh.cpp:61
void clearMorphData()
Definition Mesh.cpp:52
void computeBounds(const float *posXYZ, int vertexCount)
Compute the bounding sphere (centroid + max radius) from positions.
Definition Mesh.cpp:10
bool setMorphWeight(const std::string &name, float weight)
Definition Mesh.cpp:116
bool addMorphTarget(const std::string &name, const float *deltaPosXYZ)
Definition Mesh.cpp:77
bool hasMorph(const std::string &name) const
Definition Mesh.cpp:112
float boundsCx
Model-space bounding sphere used for view/cascade frustum culling. Computed from vertex positions at ...
Definition Mesh.h:29
void drawOcclusion(Graphics *gfx, const glm::mat4 &matrix) const override
Screen-space black proxy for volumetric occlusion. Interprets matrix as 2D affine (translation + scal...
Definition Mesh.cpp:42
float getMorphWeight(const std::string &name) const
Definition Mesh.cpp:128
bool addMorphTargetAbsolute(const std::string &name, const float *absPosXYZ)
Absolute morph (Assimp aiAnimMesh style): stored as delta from base.
Definition Mesh.cpp:89
void clearMorphWeights()
Definition Mesh.cpp:133
int getMorphCount() const
Definition Mesh.cpp:105
std::string getMorphName(int index) const
Definition Mesh.cpp:107
float boundsRadius
Definition Mesh.h:32
int getVertexCount() const
Definition Mesh.cpp:103
void computeMorphedPositions(std::vector< float > &outPos, std::vector< float > &outNrm) const
Bake current weights into outPos / outNrm (xyz packed).
Definition Mesh.cpp:142
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition AnimTrail.h:6