Optimize action constraint by avoid memory allocation
This commit is contained in:
@@ -144,6 +144,8 @@ void BKE_pose_channels_remove(
|
|||||||
struct Object *ob,
|
struct Object *ob,
|
||||||
bool (*filter_fn)(const char *bone_name, void *user_data), void *user_data);
|
bool (*filter_fn)(const char *bone_name, void *user_data), void *user_data);
|
||||||
|
|
||||||
|
void BKE_pose_free_data_ex(struct bPose *pose, bool do_id_user);
|
||||||
|
void BKE_pose_free_data(struct bPose *pose);
|
||||||
void BKE_pose_free(struct bPose *pose);
|
void BKE_pose_free(struct bPose *pose);
|
||||||
void BKE_pose_free_ex(struct bPose *pose, bool do_id_user);
|
void BKE_pose_free_ex(struct bPose *pose, bool do_id_user);
|
||||||
void BKE_pose_copy_data(struct bPose **dst, struct bPose *src, const bool copy_constraints);
|
void BKE_pose_copy_data(struct bPose **dst, struct bPose *src, const bool copy_constraints);
|
||||||
|
@@ -824,26 +824,35 @@ void BKE_pose_channels_free(bPose *pose)
|
|||||||
BKE_pose_channels_free_ex(pose, true);
|
BKE_pose_channels_free_ex(pose, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BKE_pose_free_data_ex(bPose *pose, bool do_id_user)
|
||||||
|
{
|
||||||
|
/* free pose-channels */
|
||||||
|
BKE_pose_channels_free_ex(pose, do_id_user);
|
||||||
|
|
||||||
|
/* free pose-groups */
|
||||||
|
if (pose->agroups.first)
|
||||||
|
BLI_freelistN(&pose->agroups);
|
||||||
|
|
||||||
|
/* free IK solver state */
|
||||||
|
BIK_clear_data(pose);
|
||||||
|
|
||||||
|
/* free IK solver param */
|
||||||
|
if (pose->ikparam)
|
||||||
|
MEM_freeN(pose->ikparam);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BKE_pose_free_data(bPose *pose)
|
||||||
|
{
|
||||||
|
BKE_pose_free_data_ex(pose, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes and deallocates all data from a pose, and also frees the pose.
|
* Removes and deallocates all data from a pose, and also frees the pose.
|
||||||
*/
|
*/
|
||||||
void BKE_pose_free_ex(bPose *pose, bool do_id_user)
|
void BKE_pose_free_ex(bPose *pose, bool do_id_user)
|
||||||
{
|
{
|
||||||
if (pose) {
|
if (pose) {
|
||||||
/* free pose-channels */
|
BKE_pose_free_data_ex(pose, do_id_user);
|
||||||
BKE_pose_channels_free_ex(pose, do_id_user);
|
|
||||||
|
|
||||||
/* free pose-groups */
|
|
||||||
if (pose->agroups.first)
|
|
||||||
BLI_freelistN(&pose->agroups);
|
|
||||||
|
|
||||||
/* free IK solver state */
|
|
||||||
BIK_clear_data(pose);
|
|
||||||
|
|
||||||
/* free IK solver param */
|
|
||||||
if (pose->ikparam)
|
|
||||||
MEM_freeN(pose->ikparam);
|
|
||||||
|
|
||||||
/* free pose */
|
/* free pose */
|
||||||
MEM_freeN(pose);
|
MEM_freeN(pose);
|
||||||
}
|
}
|
||||||
@@ -1415,7 +1424,13 @@ void what_does_obaction(Object *ob, Object *workob, bPose *pose, bAction *act, c
|
|||||||
|
|
||||||
workob->pose = pose; /* need to set pose too, since this is used for both types of Action Constraint */
|
workob->pose = pose; /* need to set pose too, since this is used for both types of Action Constraint */
|
||||||
if (pose) {
|
if (pose) {
|
||||||
BKE_pose_channels_hash_make(pose);
|
/* This function is most likely to be used with a temporary pose with a single bone in there.
|
||||||
|
* For such cases it makes no sense to create hash since it'll only waste CPU ticks on memory
|
||||||
|
* allocation and also will make lookup slower.
|
||||||
|
*/
|
||||||
|
if (pose->chanbase.first != pose->chanbase.last) {
|
||||||
|
BKE_pose_channels_hash_make(pose);
|
||||||
|
}
|
||||||
if (pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
|
if (pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
|
||||||
BKE_pose_update_constraint_flags(pose);
|
BKE_pose_update_constraint_flags(pose);
|
||||||
}
|
}
|
||||||
|
@@ -2143,29 +2143,26 @@ static void actcon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintT
|
|||||||
}
|
}
|
||||||
else if (cob->type == CONSTRAINT_OBTYPE_BONE) {
|
else if (cob->type == CONSTRAINT_OBTYPE_BONE) {
|
||||||
Object workob;
|
Object workob;
|
||||||
bPose *pose;
|
bPose pose = {0};
|
||||||
bPoseChannel *pchan, *tchan;
|
bPoseChannel *pchan, *tchan;
|
||||||
|
|
||||||
/* make a temporary pose and evaluate using that */
|
|
||||||
pose = MEM_callocN(sizeof(bPose), "pose");
|
|
||||||
|
|
||||||
/* make a copy of the bone of interest in the temp pose before evaluating action, so that it can get set
|
/* make a copy of the bone of interest in the temp pose before evaluating action, so that it can get set
|
||||||
* - we need to manually copy over a few settings, including rotation order, otherwise this fails
|
* - we need to manually copy over a few settings, including rotation order, otherwise this fails
|
||||||
*/
|
*/
|
||||||
pchan = cob->pchan;
|
pchan = cob->pchan;
|
||||||
|
|
||||||
tchan = BKE_pose_channel_verify(pose, pchan->name);
|
tchan = BKE_pose_channel_verify(&pose, pchan->name);
|
||||||
tchan->rotmode = pchan->rotmode;
|
tchan->rotmode = pchan->rotmode;
|
||||||
|
|
||||||
/* evaluate action using workob (it will only set the PoseChannel in question) */
|
/* evaluate action using workob (it will only set the PoseChannel in question) */
|
||||||
what_does_obaction(cob->ob, &workob, pose, data->act, pchan->name, t);
|
what_does_obaction(cob->ob, &workob, &pose, data->act, pchan->name, t);
|
||||||
|
|
||||||
/* convert animation to matrices for use here */
|
/* convert animation to matrices for use here */
|
||||||
BKE_pchan_calc_mat(tchan);
|
BKE_pchan_calc_mat(tchan);
|
||||||
copy_m4_m4(ct->matrix, tchan->chan_mat);
|
copy_m4_m4(ct->matrix, tchan->chan_mat);
|
||||||
|
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
BKE_pose_free(pose);
|
BKE_pose_free_data(&pose);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* behavior undefined... */
|
/* behavior undefined... */
|
||||||
|
Reference in New Issue
Block a user