84 if (fcu && fcu->
bezt) {
97 FCurve **fcurves = alloca(
sizeof(*fcurves) * fkc_len);
99 for (
int i = 0; i < fkc_len; i++) {
100 if (fcurves[i] && fcurves[i]->bezt) {
101 fkc[i].
fcurve = fcurves[i];
115 const float *keyed_frames,
116 int keyed_frames_len)
124 for (
int frame_index = 0; frame_index < keyed_frames_len; frame_index++) {
125 const float evaltime = keyed_frames[frame_index];
136 while (frame_index < keyed_frames_len) {
137 const float evaltime = keyed_frames[frame_index];
138 const float bezt_time = roundf(bezt->
vec[1][0]);
147 if (bezt == bezt_end) {
153 while (frame_index < keyed_frames_len) {
167 char path_xform[256];
170 const int path_xform_prefix_len =
SNPRINTF(path_xform,
"pose.bones[\"%s\"]", pchan_name_esc);
171 char *path_xform_suffix = path_xform + path_xform_prefix_len;
172 const int path_xform_suffix_len =
sizeof(path_xform) - path_xform_prefix_len;
191 } fkc_pchan = {{{
NULL}}};
193 #define FCURVE_ASSIGN_VALUE(id, path_test_suffix, index) \
194 BLI_strncpy(path_xform_suffix, path_test_suffix, path_xform_suffix_len); \
195 action_flip_pchan_cache_fcurve_assign_value(&fkc_pchan.id, index, path_xform, fcache)
197 #define FCURVE_ASSIGN_ARRAY(id, path_test_suffix) \
198 BLI_strncpy(path_xform_suffix, path_test_suffix, path_xform_suffix_len); \
199 action_flip_pchan_cache_fcurve_assign_array( \
200 fkc_pchan.id, ARRAY_SIZE(fkc_pchan.id), path_xform, fcache)
210 #undef FCURVE_ASSIGN_VALUE
211 #undef FCURVE_ASSIGN_ARRAY
214 #define FCURVE_CHANNEL_LEN (sizeof(fkc_pchan) / sizeof(struct FCurve_KeyCache))
216 int fcurve_array_len = 0;
221 fcurve_array[fcurve_array_len++] = fkc->
fcurve;
226 if (fcurve_array_len == 0) {
231 int keyed_frames_len;
233 fcurve_array, fcurve_array_len, &keyed_frames_len);
245 float flip_mtx[4][4];
252 if (!
STREQ(pchan_name_flip, pchan->
name)) {
256 float arm_mat_inv[4][4];
261 for (
int frame_index = 0; frame_index < keyed_frames_len; frame_index++) {
268 #define READ_VALUE_FLT(id) \
269 if (fkc_pchan.id.fcurve_eval != NULL) { \
270 pchan_temp.id = fkc_pchan.id.fcurve_eval[frame_index]; \
274 #define READ_VALUE_INT(id) \
275 if (fkc_pchan.id.fcurve_eval != NULL) { \
276 pchan_temp.id = floorf(fkc_pchan.id.fcurve_eval[frame_index] + 0.5f); \
280 #define READ_ARRAY_FLT(id) \
281 for (int i = 0; i < ARRAY_SIZE(pchan_temp.id); i++) { \
282 READ_VALUE_FLT(id[i]); \
294 #undef READ_ARRAY_FLT
295 #undef READ_VALUE_FLT
296 #undef READ_VALUE_INT
298 float chan_mat[4][4];
316 const float unit_x[3] = {1.0f, 0.0f, 0.0f};
317 const bool is_x_axis_orthogonal = (pchan_flip ==
NULL) &&
319 if (is_x_axis_orthogonal) {
321 float extra_mat[4][4] = {
322 {-1.0f, 0.0f, 0.0f, 0.0f},
323 {0.0f, 1.0f, 0.0f, 0.0f},
324 {0.0f, 0.0f, -1.0f, 0.0f},
325 {0.0f, 0.0f, 0.0f, 1.0f},
333 #define WRITE_VALUE_FLT(id) \
334 if (fkc_pchan.id.fcurve_eval != NULL) { \
335 BezTriple *bezt = fkc_pchan.id.bezt_array[frame_index]; \
336 if (bezt != NULL) { \
337 const float delta = pchan_temp.id - bezt->vec[1][1]; \
338 bezt->vec[0][1] += delta; \
339 bezt->vec[1][1] += delta; \
340 bezt->vec[2][1] += delta; \
345 #define WRITE_ARRAY_FLT(id) \
346 for (int i = 0; i < ARRAY_SIZE(pchan_temp.id); i++) { \
347 WRITE_VALUE_FLT(id[i]); \
360 #undef WRITE_ARRAY_FLT
361 #undef WRITE_VALUE_FLT
365 for (
int i = 0; i < fcurve_array_len; i++) {
387 const char *path_pose_prefix =
"pose.bones[\"";
388 const int path_pose_prefix_len = strlen(path_pose_prefix);
396 if (!
STRPREFIX(fcu->rna_path, path_pose_prefix)) {
400 const char *name_esc = fcu->rna_path + path_pose_prefix_len;
409 const size_t name_esc_len = (size_t)(name_esc_end - name_esc);
414 if (
UNLIKELY(name_len >=
sizeof(name))) {
421 if (!
STREQ(name_flip, name)) {
424 char *path_flip =
BLI_sprintfN(
"pose.bones[\"%s%s", name_flip_esc, name_esc_end);
426 fcu->rna_path = path_flip;
428 if (fcu->grp !=
NULL) {
442 if (!
STREQ(name_flip, agrp->name)) {
443 STRNCPY(agrp->name, name_flip);
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
void BKE_pchan_to_mat4(const struct bPoseChannel *pchan, float r_chanmat[4][4])
void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, const float mat[4][4], bool use_compat)
struct FCurvePathCache * BKE_fcurve_pathcache_create(ListBase *list)
float evaluate_fcurve_only_curve(struct FCurve *fcu, float evaltime)
float * BKE_fcurves_calc_keyed_frames(struct FCurve **fcurve_array, int fcurve_array_len, int *r_frames_len)
void BKE_fcurve_pathcache_destroy(struct FCurvePathCache *fcache)
void BKE_fcurve_handles_recalc_ex(struct FCurve *fcu, eBezTriple_Flag handle_sel_flag)
int BKE_fcurve_pathcache_find_array(struct FCurvePathCache *fcache, const char *rna_path, struct FCurve **fcurve_result, int fcurve_result_len)
struct FCurve * BKE_fcurve_pathcache_find(struct FCurvePathCache *fcache, const char rna_path[], int array_index)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void unit_m4(float m[4][4])
bool invert_m4_m4(float R[4][4], const float A[4][4])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
size_t size_t char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, size_t src_maxncpy) ATTR_NONNULL()
#define STRNCPY(dst, src)
#define SNPRINTF(dst, format,...)
const char * BLI_str_escape_find_quote(const char *str) ATTR_NONNULL()
size_t size_t char size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL()
size_t BLI_string_flip_side_name(char *r_name, const char *from_name, bool strip_number, size_t name_len)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_COPY_ON_WRITE
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
#define READ_VALUE_FLT(id)
#define WRITE_ARRAY_FLT(id)
static void action_flip_pchan_cache_fcurve_assign_value(struct FCurve_KeyCache *fkc, int index, const char *path, struct FCurvePathCache *fcache)
void BKE_action_flip_with_pose(struct bAction *act, struct Object *ob_arm)
static void action_flip_pchan_cache_init(struct FCurve_KeyCache *fkc, const float *keyed_frames, int keyed_frames_len)
#define READ_VALUE_INT(id)
#define FCURVE_ASSIGN_ARRAY(id, path_test_suffix)
#define FCURVE_CHANNEL_LEN
static void action_flip_pchan_rna_paths(struct bAction *act)
static void action_flip_pchan_cache_fcurve_assign_array(struct FCurve_KeyCache *fkc, int fkc_len, const char *path, struct FCurvePathCache *fcache)
#define WRITE_VALUE_FLT(id)
#define READ_ARRAY_FLT(id)
static void action_flip_pchan(Object *ob_arm, const bPoseChannel *pchan, struct FCurvePathCache *fcache)
#define FCURVE_ASSIGN_VALUE(id, path_test_suffix, index)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_mallocN)(size_t len, const char *str)