diff options
-rw-r--r-- | intern/opencolorio/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_armature.h | 11 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 159 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature_update.c | 9 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 2 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_rotation.h | 10 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_action_types.h | 6 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_types.h | 9 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_vec_types.h | 9 |
9 files changed, 32 insertions, 184 deletions
diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt index da0956cee86..4d95c1b701b 100644 --- a/intern/opencolorio/CMakeLists.txt +++ b/intern/opencolorio/CMakeLists.txt @@ -24,6 +24,7 @@ set(INC ../guardedalloc ../../source/blender/blenlib ../../source/blender/gpu + ../../source/blender/makesdna ) set(INC_SYS diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 50457c5b3f0..e171eec023f 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -335,17 +335,6 @@ void BKE_pose_eval_proxy_copy_bone(struct Depsgraph *depsgraph, struct Object *object, int pchan_index); -/* BBOne deformation cache. - * - * The idea here is to pre-calculate deformation queternions, matricies and such - * used by armature_deform_verts(). - */ -struct ObjectBBoneDeform; -struct ObjectBBoneDeform *BKE_armature_cached_bbone_deformation_get(struct Object *object); -void BKE_armature_cached_bbone_deformation_free_data(struct Object *object); -void BKE_armature_cached_bbone_deformation_free(struct Object *object); -void BKE_armature_cached_bbone_deformation_update(struct Object *object); - #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 91c760223aa..6cbc9901b0b 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -932,17 +932,6 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, /* ************ Armature Deform ******************* */ -typedef struct bPoseChanDeform { - DualQuat *dual_quat; -} bPoseChanDeform; - -/* Definition of cached object bbone deformations. */ -typedef struct ObjectBBoneDeform { - DualQuat *dualquats; - bPoseChanDeform *pdef_info_array; - int num_pchan; -} ObjectBBoneDeform; - static void allocate_bbone_cache(bPoseChannel *pchan, int segments) { bPoseChannel_Runtime *runtime = &pchan->runtime; @@ -1171,12 +1160,8 @@ float distfactor_to_bone( } } -static float dist_bone_deform(bPoseChannel *pchan, - const bPoseChanDeform *pdef_info, - float vec[3], - DualQuat *dq, - float mat[3][3], - const float co[3]) +static float dist_bone_deform( + bPoseChannel *pchan, float vec[3], DualQuat *dq, float mat[3][3], const float co[3]) { Bone *bone = pchan->bone; float fac, contrib = 0.0; @@ -1194,7 +1179,8 @@ static float dist_bone_deform(bPoseChannel *pchan, if (bone->segments > 1 && pchan->runtime.bbone_segments == bone->segments) b_bone_deform(pchan, co, fac, vec, dq, mat); else - pchan_deform_accumulate(pdef_info->dual_quat, pchan->chan_mat, co, fac, vec, dq, mat); + pchan_deform_accumulate( + &pchan->runtime.deform_dual_quat, pchan->chan_mat, co, fac, vec, dq, mat); } } @@ -1202,7 +1188,6 @@ static float dist_bone_deform(bPoseChannel *pchan, } static void pchan_bone_deform(bPoseChannel *pchan, - const bPoseChanDeform *pdef_info, float weight, float vec[3], DualQuat *dq, @@ -1218,33 +1203,12 @@ static void pchan_bone_deform(bPoseChannel *pchan, if (bone->segments > 1 && pchan->runtime.bbone_segments == bone->segments) b_bone_deform(pchan, co, weight, vec, dq, mat); else - pchan_deform_accumulate(pdef_info->dual_quat, pchan->chan_mat, co, weight, vec, dq, mat); + pchan_deform_accumulate( + &pchan->runtime.deform_dual_quat, pchan->chan_mat, co, weight, vec, dq, mat); (*contrib) += weight; } -typedef struct ArmatureBBoneDefmatsData { - bPoseChanDeform *pdef_info_array; - DualQuat *dualquats; - bool use_quaternion; -} ArmatureBBoneDefmatsData; - -static void armature_bbone_defmats_cb(void *userdata, Link *iter, int index) -{ - ArmatureBBoneDefmatsData *data = userdata; - bPoseChannel *pchan = (bPoseChannel *)iter; - - if (!(pchan->bone->flag & BONE_NO_DEFORM)) { - bPoseChanDeform *pdef_info = &data->pdef_info_array[index]; - const bool use_quaternion = data->use_quaternion; - - if (use_quaternion) { - pdef_info->dual_quat = &data->dualquats[index]; - mat4_to_dquat(pdef_info->dual_quat, pchan->bone->arm_mat, pchan->chan_mat); - } - } -} - void armature_deform_verts(Object *armOb, Object *target, const Mesh *mesh, @@ -1256,10 +1220,8 @@ void armature_deform_verts(Object *armOb, const char *defgrp_name, bGPDstroke *gps) { - const bPoseChanDeform *pdef_info = NULL; bArmature *arm = armOb->data; bPoseChannel *pchan, **defnrToPC = NULL; - int *defnrToPCIndex = NULL; MDeformVert *dverts = NULL; bDeformGroup *dg; float obinv[4][4], premat[4][4], postmat[4][4]; @@ -1288,20 +1250,6 @@ void armature_deform_verts(Object *armOb, mul_m4_m4m4(postmat, obinv, armOb->obmat); invert_m4_m4(premat, postmat); - /* Use pre-calculated bbone deformation. - * - * TODO(sergey): Make this code robust somehow when there are dependency - * cycles involved. */ - ObjectBBoneDeform *bbone_deform = BKE_armature_cached_bbone_deformation_get(armOb); - if (bbone_deform == NULL || bbone_deform->pdef_info_array == NULL) { - CLOG_ERROR(&LOG, - "Armature does not have bbone cache %s, " - "usually happens due to a dependency cycle.\n", - armOb->id.name + 2); - return; - } - const bPoseChanDeform *pdef_info_array = bbone_deform->pdef_info_array; - /* get the def_nr for the overall armature vertex group if present */ armature_def_nr = defgroup_name_index(target, defgrp_name); @@ -1340,19 +1288,10 @@ void armature_deform_verts(Object *armOb, if (use_dverts) { defnrToPC = MEM_callocN(sizeof(*defnrToPC) * defbase_tot, "defnrToBone"); - defnrToPCIndex = MEM_callocN(sizeof(*defnrToPCIndex) * defbase_tot, "defnrToIndex"); /* TODO(sergey): Some considerations here: * - * - Make it more generic function, maybe even keep together with chanhash. * - Check whether keeping this consistent across frames gives speedup. - * - Don't use hash for small armatures. */ - GHash *idx_hash = BLI_ghash_ptr_new("pose channel index by name"); - int pchan_index = 0; - for (pchan = armOb->pose->chanbase.first; pchan != NULL; - pchan = pchan->next, ++pchan_index) { - BLI_ghash_insert(idx_hash, pchan, POINTER_FROM_INT(pchan_index)); - } for (i = 0, dg = target->defbase.first; dg; i++, dg = dg->next) { defnrToPC[i] = BKE_pose_channel_find_name(armOb->pose, dg->name); /* exclude non-deforming bones */ @@ -1360,12 +1299,8 @@ void armature_deform_verts(Object *armOb, if (defnrToPC[i]->bone->flag & BONE_NO_DEFORM) { defnrToPC[i] = NULL; } - else { - defnrToPCIndex[i] = POINTER_AS_INT(BLI_ghash_lookup(idx_hash, defnrToPC[i])); - } } } - BLI_ghash_free(idx_hash, NULL, NULL); } } } @@ -1440,7 +1375,6 @@ void armature_deform_verts(Object *armOb, if (index >= 0 && index < defbase_tot && (pchan = defnrToPC[index])) { float weight = dw->weight; Bone *bone = pchan->bone; - pdef_info = pdef_info_array + defnrToPCIndex[index]; deformed = 1; @@ -1457,7 +1391,7 @@ void armature_deform_verts(Object *armOb, acum_weight += weight; } - pchan_bone_deform(pchan, pdef_info, weight, vec, dq, smat, co, &contrib); + pchan_bone_deform(pchan, weight, vec, dq, smat, co, &contrib); /* if acumulated weight limit exceed, exit loop */ if ((target->type == OB_GPENCIL) && (acum_weight >= 1.0f)) { @@ -1468,18 +1402,16 @@ void armature_deform_verts(Object *armOb, /* if there are vertexgroups but not groups with bones * (like for softbody groups) */ if (deformed == 0 && use_envelope) { - pdef_info = pdef_info_array; - for (pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next, pdef_info++) { + for (pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) { if (!(pchan->bone->flag & BONE_NO_DEFORM)) - contrib += dist_bone_deform(pchan, pdef_info, vec, dq, smat, co); + contrib += dist_bone_deform(pchan, vec, dq, smat, co); } } } else if (use_envelope) { - pdef_info = pdef_info_array; - for (pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next, pdef_info++) { + for (pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) { if (!(pchan->bone->flag & BONE_NO_DEFORM)) - contrib += dist_bone_deform(pchan, pdef_info, vec, dq, smat, co); + contrib += dist_bone_deform(pchan, vec, dq, smat, co); } } @@ -1533,8 +1465,6 @@ void armature_deform_verts(Object *armOb, if (defnrToPC) MEM_freeN(defnrToPC); - if (defnrToPCIndex) - MEM_freeN(defnrToPCIndex); } /* ************ END Armature Deform ******************* */ @@ -2724,70 +2654,3 @@ bPoseChannel *BKE_armature_splineik_solver_find_root(bPoseChannel *pchan, } return rootchan; } - -/* ****************************** BBone cache ****************************** */ - -ObjectBBoneDeform *BKE_armature_cached_bbone_deformation_get(Object *object) -{ - return object->runtime.cached_bbone_deformation; -} - -void BKE_armature_cached_bbone_deformation_free_data(Object *object) -{ - ObjectBBoneDeform *bbone_deform = BKE_armature_cached_bbone_deformation_get(object); - if (bbone_deform == NULL) { - return; - } - /* Free arrays. */ - MEM_SAFE_FREE(bbone_deform->pdef_info_array); - MEM_SAFE_FREE(bbone_deform->dualquats); - /* Tag that we've got no data, so we are safe for sequential calls to - * data free. */ - bbone_deform->num_pchan = 0; -} - -void BKE_armature_cached_bbone_deformation_free(Object *object) -{ - ObjectBBoneDeform *bbone_deform = BKE_armature_cached_bbone_deformation_get(object); - if (bbone_deform == NULL) { - return; - } - BKE_armature_cached_bbone_deformation_free_data(object); - MEM_freeN(bbone_deform); - object->runtime.cached_bbone_deformation = NULL; -} - -void BKE_armature_cached_bbone_deformation_update(Object *object) -{ - BLI_assert(object->type == OB_ARMATURE); - BLI_assert(object->pose != NULL); - bPose *pose = object->pose; - const int totchan = BLI_listbase_count(&pose->chanbase); - const bool use_quaternion = true; - /* Make sure cache exists. */ - ObjectBBoneDeform *bbone_deform = BKE_armature_cached_bbone_deformation_get(object); - if (bbone_deform == NULL) { - bbone_deform = MEM_callocN(sizeof(*bbone_deform), "bbone deform cache"); - object->runtime.cached_bbone_deformation = bbone_deform; - } - /* Make sure arrays are allocateds at the proper size. */ - BKE_armature_cached_bbone_deformation_free_data(object); - DualQuat *dualquats = NULL; - if (use_quaternion) { - dualquats = MEM_calloc_arrayN(sizeof(DualQuat), totchan, "dualquats"); - } - bPoseChanDeform *pdef_info_array = MEM_calloc_arrayN( - sizeof(bPoseChanDeform), totchan, "bPoseChanDeform"); - /* Calculate deofrmation matricies. */ - ArmatureBBoneDefmatsData data = { - .pdef_info_array = pdef_info_array, - .dualquats = dualquats, - .use_quaternion = use_quaternion, - }; - BLI_task_parallel_listbase(&pose->chanbase, &data, armature_bbone_defmats_cb, totchan > 1024); - /* Store pointers. */ - bbone_deform->dualquats = dualquats; - atomic_cas_ptr( - (void **)&bbone_deform->pdef_info_array, bbone_deform->pdef_info_array, pdef_info_array); - bbone_deform->num_pchan = totchan; -} diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index bf33b1c7c50..0f1ebc70b5b 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -618,8 +618,6 @@ void BKE_pose_eval_init(struct Depsgraph *depsgraph, Scene *UNUSED(scene), Objec } BLI_assert(pose->chan_array != NULL || BLI_listbase_is_empty(&pose->chanbase)); - - BKE_armature_cached_bbone_deformation_free_data(object); } void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph, Scene *scene, Object *object) @@ -714,6 +712,9 @@ void BKE_pose_bone_done(struct Depsgraph *depsgraph, struct Object *object, int if (pchan->bone) { invert_m4_m4(imat, pchan->bone->arm_mat); mul_m4_m4m4(pchan->chan_mat, pchan->pose_mat, imat); + if (!(pchan->bone->flag & BONE_NO_DEFORM)) { + mat4_to_dquat(&pchan->runtime.deform_dual_quat, pchan->bone->arm_mat, pchan->chan_mat); + } } if (DEG_is_active(depsgraph) && armature->edbo == NULL) { bPoseChannel *pchan_orig = pchan->orig_pchan; @@ -798,7 +799,6 @@ static void pose_eval_done_common(struct Depsgraph *depsgraph, Object *object) bPose *pose = object->pose; UNUSED_VARS_NDEBUG(pose); BLI_assert(pose != NULL); - BKE_armature_cached_bbone_deformation_update(object); BKE_object_eval_boundbox(depsgraph, object); } static void pose_eval_cleanup_common(Object *object) @@ -838,8 +838,6 @@ void BKE_pose_eval_proxy_init(struct Depsgraph *depsgraph, Object *object) DEG_debug_print_eval(depsgraph, __func__, object->id.name, object); BLI_assert(object->pose->chan_array != NULL || BLI_listbase_is_empty(&object->pose->chanbase)); - - BKE_armature_cached_bbone_deformation_free_data(object); } void BKE_pose_eval_proxy_done(struct Depsgraph *depsgraph, Object *object) @@ -877,5 +875,6 @@ void BKE_pose_eval_proxy_copy_bone(struct Depsgraph *depsgraph, Object *object, BLI_assert(pchan != NULL); BLI_assert(pchan_from != NULL); BKE_pose_copyesult_pchan_result(pchan, pchan_from); + copy_dq_dq(&pchan->runtime.deform_dual_quat, &pchan_from->runtime.deform_dual_quat); BKE_pchan_bbone_segments_cache_copy(pchan, pchan_from); } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 303d63d6a8b..77086d9c6ac 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -444,7 +444,6 @@ void BKE_object_free_derived_caches(Object *ob) object_update_from_subsurf_ccg(ob); BKE_object_free_derived_mesh_caches(ob); - BKE_armature_cached_bbone_deformation_free(ob); if (ob->runtime.mesh_eval != NULL) { Mesh *mesh_eval = ob->runtime.mesh_eval; @@ -3886,7 +3885,6 @@ void BKE_object_runtime_reset_on_copy(Object *object, const int UNUSED(flag)) runtime->mesh_deform_eval = NULL; runtime->curve_cache = NULL; runtime->gpencil_cache = NULL; - runtime->cached_bbone_deformation = NULL; } /* diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h index cde3f282427..7a4ac14970f 100644 --- a/source/blender/blenlib/BLI_math_rotation.h +++ b/source/blender/blenlib/BLI_math_rotation.h @@ -27,6 +27,8 @@ * \ingroup bli */ +#include "DNA_vec_types.h" + #ifdef __cplusplus extern "C" { #endif @@ -215,14 +217,6 @@ void rotate_eulO(float eul[3], const short order, char axis, float angle); /******************************* Dual Quaternions ****************************/ -typedef struct DualQuat { - float quat[4]; - float trans[4]; - - float scale[4][4]; - float scale_weight; -} DualQuat; - void copy_dq_dq(DualQuat *r, const DualQuat *dq); void normalize_dq(DualQuat *dq, float totw); void add_weighted_dq_dq(DualQuat *r, const DualQuat *dq, float weight); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index fd3409b266c..01f1dc42c44 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -31,6 +31,7 @@ #include "DNA_listBase.h" #include "DNA_ID.h" #include "DNA_view2d_types.h" +#include "DNA_vec_types.h" #include "DNA_userdef_types.h" /* ThemeWireColor */ struct Collection; @@ -183,8 +184,11 @@ struct DualQuat; struct Mat4; typedef struct bPoseChannel_Runtime { + /* Cached dual quaternion for deformation. */ + struct DualQuat deform_dual_quat; + + /* B-Bone shape data: copy of the segment count for validation. */ int bbone_segments; - char _pad[4]; /* Rest and posed matrices for segments. */ struct Mat4 *bbone_rest_mats; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index dc23a6a1ee2..781a2216029 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -118,11 +118,6 @@ typedef struct LodLevel { int obhysteresis; } LodLevel; -/* Forward declaration for cache bbone deformation information. - * - * TODO(sergey): Consider moving it to more appropriate place. */ -struct ObjectBBoneDeform; - struct CustomData_MeshMasks; /* Not saved in file! */ @@ -166,10 +161,6 @@ typedef struct Object_Runtime { /** Runtime grease pencil drawing data */ struct GpencilBatchCache *gpencil_cache; - - struct ObjectBBoneDeform *cached_bbone_deformation; - - void *_pad1; } Object_Runtime; typedef struct Object { diff --git a/source/blender/makesdna/DNA_vec_types.h b/source/blender/makesdna/DNA_vec_types.h index 06e6d881d0e..72a6056e239 100644 --- a/source/blender/makesdna/DNA_vec_types.h +++ b/source/blender/makesdna/DNA_vec_types.h @@ -83,4 +83,13 @@ typedef struct rctf { float ymin, ymax; } rctf; +/** dual quaternion. */ +typedef struct DualQuat { + float quat[4]; + float trans[4]; + + float scale[4][4]; + float scale_weight; +} DualQuat; + #endif |