55
66namespace scene {
77
8- WeightBuffer::WeightBuffer (size_t n_verts) :
9- n_verts (n_verts),
10- joint_idxs (std::make_unique<u16 []>(MAX_WEIGHTS_PER_VERTEX * n_verts)),
11- weights (std::make_unique<f32 []>(MAX_WEIGHTS_PER_VERTEX * n_verts))
12- {}
13-
14- void WeightBuffer::addWeight (u32 vertex_id, u16 joint_id, f32 weight)
8+ void WeightBuffer::VertexWeights::addWeight (u16 joint_id, f32 weight)
159{
16- assert (vertex_id < n_verts);
17- assert (weight >= 0 .f );
18- f32 *weights = getWeights (vertex_id);
19- f32 *min_weight = std::min_element (weights, weights + MAX_WEIGHTS_PER_VERTEX);
10+ assert (weight >= 0 .0f );
11+ auto min_weight = std::min_element (strengths.begin (), strengths.end ());
2012 if (*min_weight > weight)
2113 return ;
2214
2315 *min_weight = weight;
24- getJointIndices (vertex_id)[min_weight - weights ] = joint_id;
16+ joint_ids[ std::distance (strengths. begin (), min_weight) ] = joint_id;
2517}
2618
27- void WeightBuffer::skinVertex (u32 vertex_id, core::vector3df &pos, core::vector3df &normal,
19+ void WeightBuffer::addWeight (u32 vertex_id, u16 joint_id, f32 weight)
20+ {
21+ weights[vertex_id].addWeight (joint_id, weight);
22+ }
23+
24+ void WeightBuffer::VertexWeights::skinVertex (core::vector3df &pos, core::vector3df &normal,
2825 const std::vector<core::matrix4> &joint_transforms) const
2926{
30- const u16 *joint_idxs = getJointIndices (vertex_id);
31- const f32 *weights = getWeights (vertex_id);
32- f32 total_weight = 0 .f ;
27+ f32 total_weight = 0 .0f ;
3328 core::vector3df skinned_pos;
3429 core::vector3df skinned_normal;
3530 for (u16 i = 0 ; i < MAX_WEIGHTS_PER_VERTEX; ++i) {
36- u16 joint_id = joint_idxs[i];
37- f32 weight = weights[i];
38- if (weight <= 0 .f )
39- continue ;
31+ u16 joint_id = joint_ids[i];
32+ f32 weight = strengths[i];
4033
4134 const auto &transform = joint_transforms[joint_id];
4235 core::vector3df transformed_pos = pos;
@@ -45,15 +38,20 @@ void WeightBuffer::skinVertex(u32 vertex_id, core::vector3df &pos, core::vector3
4538 skinned_normal += weight * transform.rotateAndScaleVect (normal);
4639 total_weight += weight;
4740 }
48- if (core::equals (total_weight, 0 .f ))
41+ if (core::equals (total_weight, 0 .0f ))
4942 return ;
5043
5144 pos = skinned_pos;
5245 // Need to renormalize normal after potentially scaling
5346 normal = skinned_normal.normalize ();
5447}
5548
56- // / @note src and dst can be the same buffer
49+ void WeightBuffer::skinVertex (u32 vertex_id, core::vector3df &pos, core::vector3df &normal,
50+ const std::vector<core::matrix4> &joint_transforms) const
51+ {
52+ return weights[vertex_id].skinVertex (pos, normal, joint_transforms);
53+ }
54+
5755void WeightBuffer::skin (IVertexBuffer *dst,
5856 const std::vector<core::matrix4> &joint_transforms) const
5957{
@@ -71,24 +69,24 @@ void WeightBuffer::skin(IVertexBuffer *dst,
7169 dst->setDirty ();
7270}
7371
74- // / Normalizes weights so that they sum to 1.0 per vertex,
75- // / stores which vertices are animated.
7672void WeightBuffer::finalize ()
7773{
74+ // Normalizes weights so that they sum to 1.0 per vertex,
75+ // stores which vertices are animated.
7876 assert (!animated_vertices.has_value ());
7977 animated_vertices.emplace ();
80- for (u32 i = 0 ; i < n_verts ; ++i) {
81- auto *weights_i = getWeights (i) ;
82- f32 total_weight = std::accumulate (weights_i, weights_i + MAX_WEIGHTS_PER_VERTEX , 0 .0f );
78+ for (u32 i = 0 ; i < size () ; ++i) {
79+ auto &strengths = weights[i]. strengths ;
80+ f32 total_weight = std::accumulate (strengths. begin (), strengths. end () , 0 .0f );
8381 if (core::equals (total_weight, 0 .0f )) {
84- std::fill (weights_i, weights_i + MAX_WEIGHTS_PER_VERTEX , 0 .0f );
82+ std::fill (strengths. begin (), strengths. end () , 0 .0f );
8583 continue ;
8684 }
8785 animated_vertices->emplace_back (i);
8886 if (core::equals (total_weight, 1 .0f ))
8987 continue ;
90- for (u16 j = 0 ; j < MAX_WEIGHTS_PER_VERTEX; ++j )
91- weights_i[j] /= total_weight;
88+ for (auto &strength : strengths )
89+ strength /= total_weight;
9290 }
9391 animated_vertices->shrink_to_fit ();
9492}
0 commit comments