56 const float deform_mat[4][4],
61 float mat_accum[3][3],
62 const bool full_deform)
95 const bool full_deform)
108 weight * (1.0f -
blend),
114 &quats[index + 1], mats[index + 2].mat, co, weight *
blend, vec, dq, defmat, full_deform);
118 const float vec[3],
const float b1[3],
const float b2[3],
float rad1,
float rad2,
float rdist)
123 float hsqr, a,
l, rad;
144 dist_sq = (hsqr - (a * a));
148 rad = rad * rad2 + (1.0f - rad) * rad1;
162 if (rdist == 0.0f || dist_sq >=
l) {
166 a =
sqrtf(dist_sq) - rad;
167 return 1.0f - (a * a) / (rdist * rdist);
175 const bool full_deform)
178 float fac, contrib = 0.0;
180 if (bone ==
nullptr) {
190 if (contrib > 0.0f) {
210 const bool full_deform,
227 (*contrib) += weight;
271 float(*
const vert_coords)[3] = data->vert_coords;
272 float(*
const vert_deform_mats)[3][3] = data->vert_deform_mats;
273 float(*
const vert_coords_prev)[3] = data->vert_coords_prev;
274 const bool use_envelope = data->use_envelope;
275 const bool use_quaternion = data->use_quaternion;
276 const bool use_dverts = data->use_dverts;
277 const int armature_def_nr = data->armature_def_nr;
282 float sumvec[3], summat[3][3];
283 float *vec =
nullptr, (*smat)[3] =
nullptr;
284 float contrib = 0.0f;
285 float armature_weight = 1.0f;
286 float prevco_weight = 0.0f;
288 const bool full_deform = vert_deform_mats !=
nullptr;
290 if (use_quaternion) {
291 memset(&sumdq, 0,
sizeof(
DualQuat));
304 if (armature_def_nr != -1 && dvert) {
307 if (data->invert_vgroup) {
308 armature_weight = 1.0f - armature_weight;
312 if (vert_coords_prev) {
315 prevco_weight = 1.0f - armature_weight;
316 armature_weight = 1.0f;
321 if (vert_coords_prev) {
322 if (prevco_weight == 1.0f) {
327 co = vert_coords_prev[i];
330 if (armature_weight == 0.0f) {
341 if (use_dverts && dvert && dvert->
totweight) {
345 for (j = dvert->
totweight; j != 0; j--, dw++) {
347 if (index < data->defbase_len && (pchan = data->pchan_from_defbase[index])) {
348 float weight = dw->
weight;
362 if (deformed == 0 && use_envelope) {
363 for (pchan =
static_cast<const bPoseChannel *
>(data->ob_arm->pose->chanbase.first); pchan;
372 else if (use_envelope) {
373 for (pchan =
static_cast<const bPoseChannel *
>(data->ob_arm->pose->chanbase.first); pchan;
383 if (contrib > 0.0001f) {
384 if (use_quaternion) {
387 if (armature_weight != 1.0f) {
389 mul_v3m3_dq(dco, full_deform ? summat :
nullptr, dq);
395 mul_v3m3_dq(co, full_deform ? summat :
nullptr, dq);
401 mul_v3_fl(vec, armature_weight / contrib);
406 float pre[3][3], post[3][3], tmpmat[3][3];
412 if (!use_quaternion) {
413 mul_m3_fl(smat, armature_weight / contrib);
424 if (vert_coords_prev) {
425 float mw = 1.0f - prevco_weight;
426 vert_coords[i][0] = prevco_weight * vert_coords[i][0] + mw * co[0];
427 vert_coords[i][1] = prevco_weight * vert_coords[i][1] + mw * co[1];
428 vert_coords[i][2] = prevco_weight * vert_coords[i][2] + mw * co[2];
438 if (data->use_dverts || data->armature_def_nr != -1) {
439 if (data->me_target) {
441 if (data->dverts !=
nullptr) {
442 dvert = data->dverts + i;
448 else if (data->dverts && i < data->dverts_len) {
449 dvert = data->dverts + i;
485 float (*vert_coords)[3],
486 float (*vert_deform_mats)[3][3],
487 const int vert_coords_len,
488 const int deformflag,
489 float (*vert_coords_prev)[3],
490 const char *defgrp_name,
492 const Mesh *me_target,
501 bool use_dverts =
false;
502 int armature_def_nr = -1;
503 int cd_dvert_offset = -1;
506 if (arm->
edbo || (ob_arm->
pose ==
nullptr)) {
512 "Trying to evaluate influence of armature '%s' which needs Pose recalc!",
527 use_dverts = (cd_dvert_offset != -1);
529 else if (me_target) {
530 use_dverts = !me_target->deform_verts().is_empty();
532 else if (dverts.
size() == vert_coords_len) {
538 MEM_callocN(
sizeof(*pchan_from_defbase) * defbase_len,
"defnrToBone"));
547 if (pchan_from_defbase[i]) {
549 pchan_from_defbase[i] =
nullptr;
559 data.me_target = me_target;
560 data.vert_coords = vert_coords;
561 data.vert_deform_mats = vert_deform_mats;
562 data.vert_coords_prev = vert_coords_prev;
563 data.use_envelope = use_envelope;
564 data.use_quaternion = use_quaternion;
565 data.invert_vgroup = invert_vgroup;
566 data.use_dverts = use_dverts;
567 data.armature_def_nr = armature_def_nr;
568 data.dverts = dverts.
data();
569 data.dverts_len = dverts.
size();
570 data.pchan_from_defbase = pchan_from_defbase;
571 data.defbase_len = defbase_len;
572 data.bmesh.cd_dvert_offset = cd_dvert_offset;
575 invert_m4_m4(obinv, ob_target->object_to_world().ptr());
577 mul_m4_m4m4(data.postmat, obinv, ob_arm->object_to_world().ptr());
580 if (em_target !=
nullptr) {
600 settings.min_iter_per_thread = 32;
604 if (pchan_from_defbase) {
611 float (*vert_coords)[3],
612 float (*vert_deform_mats)[3][3],
615 float (*vert_coords_prev)[3],
616 const char *defgrp_name,
654 reinterpret_cast<float(*)[3]
>(vert_coords.
data()),
655 vert_deform_mats ?
reinterpret_cast<float(*)[3][3]
>(vert_deform_mats->data()) :
nullptr,
658 vert_coords_prev ?
reinterpret_cast<float(*)[3]
>(vert_coords_prev->data()) :
nullptr,
667 float (*vert_coords)[3],
668 float (*vert_deform_mats)[3][3],
671 float (*vert_coords_prev)[3],
672 const char *defgrp_name,
673 const Mesh *me_target)
677 const ID *id_target =
static_cast<const ID *
>(ob_target->
data);
683 if (me_target ==
nullptr) {
684 me_target =
static_cast<const Mesh *
>(ob_target->
data);
686 dverts = me_target->deform_verts();
709 float (*vert_coords)[3],
710 float (*vert_deform_mats)[3][3],
713 float (*vert_coords_prev)[3],
714 const char *defgrp_name,
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void BKE_pchan_bbone_deform_segment_index(const bPoseChannel *pchan, const float *co, int *r_index, float *r_blend_next)
Low-level operations for curves.
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void copy_m3_m3(float m1[3][3], const float m2[3][3])
void copy_m3_m4(float m1[3][3], const float m2[4][4])
void mul_m3_fl(float R[3][3], float f)
void zero_m3(float m[3][3])
void mul_m4_v3(const float M[4][4], float r[3])
void madd_m3_m3m3fl(float R[3][3], const float A[3][3], const float B[3][3], float f)
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
#define mul_m3_series(...)
void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq)
void add_weighted_dq_dq_pivot(DualQuat *dq_sum, const DualQuat *dq, const float pivot[3], float weight, bool compute_scale_matrix)
void normalize_dq(DualQuat *dq, float totweight)
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
struct MempoolIterData MempoolIterData
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
void BLI_task_parallel_mempool(struct BLI_mempool *mempool, void *userdata, TaskParallelMempoolFunc func, const TaskParallelSettings *settings)
BLI_INLINE void BLI_parallel_mempool_settings_defaults(TaskParallelSettings *settings)
#define CLOG_ERROR(clg_ref,...)
These structs are the foundation for all linked lists in the library system.
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
#define BM_elem_index_get(ele)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
constexpr int64_t size() const
constexpr T * data() const
constexpr const T * data() const
constexpr int64_t size() const
constexpr const char * c_str() const
draw_view in_light_buf[] float
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
float(* vert_deform_mats)[3][3]
bPoseChannel ** pchan_from_defbase
const MDeformVert * dverts
struct ArmatureUserdata::@75 bmesh
float(* vert_coords_prev)[3]
struct BLI_mempool * vpool
struct MDeformVert * dvert
struct MDeformVert * dvert
struct Mat4 * bbone_deform_mats
struct DualQuat deform_dual_quat
struct DualQuat * bbone_dual_quats
struct bPoseChannel * next
struct bPoseChannel_Runtime runtime