1#include "dynamic_mesh.h"
3#include <cgv/math/ftransform.h>
14 blend_shapes.push_back(bs);
15 return uint32_t(blend_shapes.size() - 1);
20 blend_shape_data.push_back(d);
25 blend_shape_indices.push_back(i);
30 const auto& bs = blend_shapes[bi];
32 case blend_shape_mode::direct:
36 case blend_shape_mode::indexed:
37 for (
idx_type i = bs.blend_shape_index_range[0]; i < bs.blend_shape_index_range[1]; ++i)
38 if (blend_shape_indices[i] == vi)
41 case blend_shape_mode::range_indexed:
42 for (
idx_type i = bs.blend_shape_index_range[0]; i < bs.blend_shape_index_range[1]; i+=2)
43 if (blend_shape_indices[i] <= vi && vi < blend_shape_indices[i+1])
52 const auto& bs = blend_shapes[bi];
54 case blend_shape_mode::direct:
55 return blend_shape_data[bi*this->get_nr_positions()+vi];
56 case blend_shape_mode::indexed:
57 for (
idx_type i = bs.blend_shape_index_range[0]; i < bs.blend_shape_index_range[1]; ++i)
58 if (blend_shape_indices[i] == vi)
59 return blend_shape_data[i];
61 case blend_shape_mode::range_indexed:
62 for (
idx_type off = 0, i = bs.blend_shape_index_range[0]; i < bs.blend_shape_index_range[1];
63 off += blend_shape_indices[i+1]-blend_shape_indices[i], i+=2)
64 if (blend_shape_indices[i] <= vi && vi < blend_shape_indices[i+1])
65 return blend_shape_data[off + vi- blend_shape_indices[i]];
73 return blend_shapes.size();
81void dynamic_mesh<T>::begin_vertex_weight_vertex()
83 vertex_weight_index_begins.push_back(uint32_t(vertex_weight_data.size()));
88 switch (weight_mode) {
89 case vertex_weight_mode::dense:
90 return uint32_t(vi * get_nr_joints());
91 case vertex_weight_mode::sparse:
92 return vertex_weight_index_begins[vi];
93 case vertex_weight_mode::fixed:
94 return uint32_t(vi * max_nr_weights_per_vertex);
101 switch (weight_mode) {
102 case vertex_weight_mode::dense:
103 return uint32_t((vi+1)*get_nr_joints());
104 case vertex_weight_mode::sparse:
105 return uint32_t(vi >= vertex_weight_index_begins.size() ? vertex_weight_data.size() : vertex_weight_index_begins[vi]);
106 case vertex_weight_mode::fixed:
107 return uint32_t((vi+1)*max_nr_weights_per_vertex);
114 switch (weight_mode) {
115 case vertex_weight_mode::dense:
116 return vertex_weight_data[vi * get_nr_joints() + ji];
118 for (
idx_type i = vertex_weight_begin(vi); i < vertex_weight_end(vi); ++i)
119 if (vertex_weight_indices[i] == ji)
120 return vertex_weight_data[i];
129 vertex_weight_data.push_back(w);
134 vertex_weight_indices.push_back(i);
139 return vertex_weight_data.size();
144 return vertex_weight_indices.size();
149 return idx_type(joint_parents.size());
153 const vec3_type& translation,
const std::vector<vec3_type>& target_spin_vectors)
const
155 std::vector<mat3_type> target_rotations;
156 for (
const auto& sv : target_spin_vectors)
157 target_rotations.push_back(cgv::math::rotate3s<T>(sv));
158 return compute_joint_transformations(reference_joint_locations, translation, target_rotations);
162 const vec3_type& translation,
const std::vector<mat3_type>& target_rotations)
const
165 std::vector<mat4_type> Is, Ts;
166 mat4_type I = cgv::math::identity4<float>();
168 t = reference_joint_locations.front();
170 Ts.push_back(pose4(target_rotations.front(), t + translation));
172 for (ji = 1; ji < target_rotations.size(); ++ji) {
173 t = reference_joint_locations[ji] - reference_joint_locations[joint_parents[ji]];
175 Ts.push_back(pose4(target_rotations[ji], t));
178 for (ji = 1; ji < target_rotations.size(); ++ji) {
179 Is[ji] = Is[joint_parents[ji]] * Is[ji];
180 Ts[ji] = Ts[joint_parents[ji]] * Ts[ji];
183 for (ji = 0; ji < target_rotations.size(); ++ji)
184 Ts[ji] = Ts[ji] * inverse(Is[ji]);
194 this->positions = reference_positions;
195 if (use_parallel_implementation) {
199 std::vector<const vec3_type*> bs_ptrs;
200 int n = this->get_nr_positions();
201 for (
size_t bi = blend_shape_offset; bi < weights.size() + blend_shape_offset; ++bi) {
202 const auto& bs = blend_shapes[bi];
203 assert(bs.mode == blend_shape_mode::direct);
204 assert(bs.blend_shape_data_range[1] - bs.blend_shape_data_range[0] == n);
205 bs_ptrs.push_back(&blend_shape_data[bs.blend_shape_data_range[0]]);
208#pragma omp parallel for
209 for (
int vi = 0; vi < n; ++vi) {
211 for (
int wi = 0; wi < weights.size(); ++wi)
212 p += weights[wi]*bs_ptrs[wi][vi];
213 this->position(vi) += p;
217 for (
idx_type bi = blend_shape_offset, wi = 0; wi < weights.size(); ++wi, ++bi) {
218 const auto& bs = blend_shapes[bi];
220 case blend_shape_mode::direct:
221 for (
int j=0, i = bs.blend_shape_data_range[0]; i < int(bs.blend_shape_data_range[1]); ++i, ++j)
222 this->positions[j] += weights[wi] * blend_shape_data[i];
224 case blend_shape_mode::indexed:
225 for (uint32_t i = bs.blend_shape_data_range[0], j = bs.blend_shape_index_range[0]; i < bs.blend_shape_data_range[1]; ++i, ++j)
226 this->positions[blend_shape_indices[j]] += weights[wi] * blend_shape_data[i];
228 case blend_shape_mode::range_indexed:
229 for (uint32_t i = bs.blend_shape_data_range[0], j = bs.blend_shape_index_range[0]; j < bs.blend_shape_index_range[1]; j += 2)
230 for (uint32_t k = blend_shape_indices[j]; k < blend_shape_indices[j + 1]; ++k, ++i)
231 this->positions[k] += weights[wi] * blend_shape_data[i];
240 return intermediate_positions;
246 return joint_parents;
251 return joint_parents;
256 reference_positions = this->positions;
261 intermediate_positions = this->positions;
266 this->positions = intermediate_positions;
272 std::vector<vec3_type> tmp;
273 if (mode == lbs_source_mode::position)
274 tmp = this->positions;
275 const std::vector<vec3_type>& P = mode == lbs_source_mode::position ? tmp : (
276 mode == lbs_source_mode::intermediate ? intermediate_positions : reference_positions);
277 switch (weight_mode) {
278 case vertex_weight_mode::dense:
279 for (
size_t pi = 0, wi = 0; pi < P.size(); ++pi) {
282 for (
unsigned ji = 0; ji < joint_parents.size(); ++ji, ++wi)
283 q += vertex_weight_data[wi] * (joint_matrices[ji] * p);
287 case vertex_weight_mode::sparse:
288 for (
size_t pi = 0; pi < P.size(); ++pi) {
291 size_t beg = vertex_weight_index_begins[pi];
292 size_t end = pi+1 < P.size() ? vertex_weight_index_begins[pi+1] : vertex_weight_indices.size();
293 for (
size_t wi = beg; wi < end; ++wi)
294 q += vertex_weight_data[wi] * (joint_matrices[vertex_weight_indices[wi]] * p);
298 case vertex_weight_mode::fixed:
299 for (
size_t pi = 0; pi < P.size(); ++pi) {
302 size_t beg = vertex_weight_index_begins[pi];
303 size_t end = pi + 1 < P.size() ? vertex_weight_index_begins[pi + 1] : vertex_weight_indices.size();
304 for (
size_t wi = beg; wi < end; ++wi)
305 q += vertex_weight_data[wi] * (joint_matrices[vertex_weight_indices[wi]] * p);
complete implementation of method actions that only call one method when entering a node
fvec< T, N > & col(unsigned j)
reference a column of the matrix as a vector
A vector with zero based index.