[Bf-blender-cvs] [9c1a961dc42] master: Keyframing: refactor insertion code to allow property-global NLA tweaks.
Alexander Gavrilov
noreply at git.blender.org
Mon Jan 14 17:35:38 CET 2019
Commit: 9c1a961dc423d2eb19b875564bb4bb3c0b297ca5
Author: Alexander Gavrilov
Date: Tue Jan 8 18:49:38 2019 +0300
Branches: master
https://developer.blender.org/rB9c1a961dc423d2eb19b875564bb4bb3c0b297ca5
Keyframing: refactor insertion code to allow property-global NLA tweaks.
Supporting a strip blending type that treats quaternions as a unit
also means being able to adjust all sub-channels as a unit when
inserting keyframes. This requires refactoring keyframe insertion
code to retrieve array property values for all channels at once,
before iterating over the indices being inserted.
===================================================================
M source/blender/blenkernel/BKE_animsys.h
M source/blender/blenkernel/intern/anim_sys.c
M source/blender/editors/animation/keyframing.c
M source/blender/editors/interface/interface_anim.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 7cdb62712e8..b49eb182981 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -177,7 +177,7 @@ void BKE_fcurves_main_cb(struct Main *bmain, ID_FCurve_Edit_Callback func, void
typedef struct NlaKeyframingContext NlaKeyframingContext;
struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *cache, struct Depsgraph *depsgraph, struct PointerRNA *ptr, struct AnimData *adt, float ctime);
-bool BKE_animsys_nla_remap_keyframe_value(struct NlaKeyframingContext *context, struct PointerRNA *prop_ptr, struct PropertyRNA *prop, int index, float *r_value);
+bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context, struct PointerRNA *prop_ptr, struct PropertyRNA *prop, float *values, int count, int index, bool *r_force_all);
void BKE_animsys_free_nla_keyframing_context_cache(struct ListBase *cache);
/* ************************************* */
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 5ec3b931f09..8928ecbb5e2 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -3106,16 +3106,22 @@ NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
}
/**
- * Apply correction from the NLA context to the value about to be keyframed.
+ * Apply correction from the NLA context to the values about to be keyframed.
*
* @param context Context to use (may be NULL).
* @param prop_ptr Property about to be keyframed.
- * @param index Array index within the property.
- * @param[in,out] r_value Value to correct.
- * @return False if correction fails due to a division by zero.
+ * @param[in,out] values Array of property values to adjust.
+ * @param count Number of values in the array.
+ * @param index Index of the element about to be updated, or -1.
+ * @param[out] r_force_all Set to true if all channels must be inserted. May be NULL.
+ * @return False if correction fails due to a division by zero, or null r_force_all when all channels are required.
*/
-bool BKE_animsys_nla_remap_keyframe_value(struct NlaKeyframingContext *context, struct PointerRNA *prop_ptr, struct PropertyRNA *prop, int index, float *r_value)
+bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context, struct PointerRNA *prop_ptr, struct PropertyRNA *prop, float *values, int count, int index, bool *r_force_all)
{
+ if (r_force_all != NULL) {
+ *r_force_all = false;
+ }
+
/* No context means no correction. */
if (context == NULL || context->strip.act == NULL) {
return true;
@@ -3143,18 +3149,26 @@ bool BKE_animsys_nla_remap_keyframe_value(struct NlaKeyframingContext *context,
NlaEvalChannelKey key = { .ptr = *prop_ptr, .prop = prop, };
NlaEvalData *nlaeval = &context->nla_channels;
NlaEvalChannel *nec = nlaevalchan_verify_key(nlaeval, NULL, &key);
- int real_index = nlaevalchan_validate_index(nec, index);
- if (real_index < 0) {
- return true;
+ if (nec->base_snapshot.length != count) {
+ BLI_assert(!"invalid value count");
+ return false;
}
- /* Invert the blending operation to compute the desired key value. */
+ /* Invert the blending operation to compute the desired key values. */
NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_find_channel(&nlaeval->eval_snapshot, nec);
- float old_value = nec_snapshot->values[real_index];
+ float *old_values = nec_snapshot->values;
+
+ for (int i = 0; i < count; i++) {
+ if (ELEM(index, i, -1)) {
+ if (!nla_invert_blend_value(blend_mode, old_values[i], values[i], influence, &values[i])) {
+ return false;
+ }
+ }
+ }
- return nla_invert_blend_value(blend_mode, old_value, *r_value, influence, r_value);
+ return true;
}
/**
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 02d5e2cb28a..84d911681b3 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -425,6 +425,9 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag)
fcu->totvert++;
}
+ else {
+ return -1;
+ }
}
/* no keyframes already, but can only add if...
* 1) keyframing modes say that keyframes can only be replaced, so adding new ones won't know
@@ -678,42 +681,73 @@ static short new_key_needed(FCurve *fcu, float cFrame, float nValue)
/* ------------------ RNA Data-Access Functions ------------------ */
/* Try to read value using RNA-properties obtained already */
-static float setting_get_rna_value(Depsgraph *depsgraph, PointerRNA *ptr, PropertyRNA *prop, int index, const bool get_evaluated)
+static float *setting_get_rna_values(Depsgraph *depsgraph, PointerRNA *ptr, PropertyRNA *prop, const bool get_evaluated, float *buffer, int buffer_size, int *r_count)
{
- PointerRNA ptr_eval = *ptr;
- float value = 0.0f;
+ BLI_assert(buffer_size >= 1);
+
+ float *values = buffer;
+ PointerRNA ptr_eval;
if (get_evaluated) {
DEG_get_evaluated_rna_pointer(depsgraph, ptr, &ptr_eval);
+ ptr = &ptr_eval;
}
- switch (RNA_property_type(prop)) {
- case PROP_BOOLEAN:
- if (RNA_property_array_check(prop))
- value = (float)RNA_property_boolean_get_index(&ptr_eval, prop, index);
- else
- value = (float)RNA_property_boolean_get(&ptr_eval, prop);
- break;
- case PROP_INT:
- if (RNA_property_array_check(prop))
- value = (float)RNA_property_int_get_index(&ptr_eval, prop, index);
- else
- value = (float)RNA_property_int_get(&ptr_eval, prop);
- break;
- case PROP_FLOAT:
- if (RNA_property_array_check(prop))
- value = RNA_property_float_get_index(&ptr_eval, prop, index);
- else
- value = RNA_property_float_get(&ptr_eval, prop);
- break;
- case PROP_ENUM:
- value = (float)RNA_property_enum_get(&ptr_eval, prop);
- break;
- default:
- break;
+ if (RNA_property_array_check(prop)) {
+ int length = *r_count = RNA_property_array_length(ptr, prop);
+ bool *tmp_bool;
+ int *tmp_int;
+
+ if (length > buffer_size) {
+ values = MEM_malloc_arrayN(sizeof(float), length, __func__);
+ }
+
+ switch (RNA_property_type(prop)) {
+ case PROP_BOOLEAN:
+ tmp_bool = MEM_malloc_arrayN(sizeof(*tmp_bool), length, __func__);
+ RNA_property_boolean_get_array(ptr, prop, tmp_bool);
+ for (int i = 0; i < length; i++) {
+ values[i] = (float)tmp_bool[i];
+ }
+ MEM_freeN(tmp_bool);
+ break;
+ case PROP_INT:
+ tmp_int = MEM_malloc_arrayN(sizeof(*tmp_int), length, __func__);
+ RNA_property_int_get_array(ptr, prop, tmp_int);
+ for (int i = 0; i < length; i++) {
+ values[i] = (float)tmp_int[i];
+ }
+ MEM_freeN(tmp_int);
+ break;
+ case PROP_FLOAT:
+ RNA_property_float_get_array(ptr, prop, values);
+ break;
+ default:
+ memset(values, 0, sizeof(float) * length);
+ }
+ }
+ else {
+ *r_count = 1;
+
+ switch (RNA_property_type(prop)) {
+ case PROP_BOOLEAN:
+ *values = (float)RNA_property_boolean_get(ptr, prop);
+ break;
+ case PROP_INT:
+ *values = (float)RNA_property_int_get(ptr, prop);
+ break;
+ case PROP_FLOAT:
+ *values = RNA_property_float_get(ptr, prop);
+ break;
+ case PROP_ENUM:
+ *values = (float)RNA_property_enum_get(ptr, prop);
+ break;
+ default:
+ *values = 0.0f;
+ }
}
- return value;
+ return values;
}
/* ------------------ 'Visual' Keyframing Functions ------------------ */
@@ -869,8 +903,10 @@ static bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
* In the event that it is not possible to perform visual keying, try to fall-back
* to using the default method. Assumes that all data it has been passed is valid.
*/
-static float visualkey_get_value(Depsgraph *depsgraph, PointerRNA *ptr, PropertyRNA *prop, int array_index)
+static float *visualkey_get_values(Depsgraph *depsgraph, PointerRNA *ptr, PropertyRNA *prop, float *buffer, int buffer_size, int *r_count)
{
+ BLI_assert(buffer_size >= 4);
+
const char *identifier = RNA_property_identifier(prop);
float tmat[4][4];
int rotmode;
@@ -888,7 +924,9 @@ static float visualkey_get_value(Depsgraph *depsgraph, PointerRNA *ptr, Property
/* Loc code is specific... */
if (strstr(identifier, "location")) {
- return ob_eval->obmat[3][array_index];
+ copy_v3_v3(buffer, ob_eval->obmat[3]);
+ *r_count = 3;
+ return buffer;
}
copy_m4_m4(tmat, ob_eval->obmat);
@@ -907,58 +945,162 @@ static float visualkey_get_value(Depsgraph *depsgraph, PointerRNA *ptr, Property
/* Loc code is specific... */
if (strstr(identifier, "location")) {
/* only use for non-connected bones */
- if ((pchan->bone->parent == NULL) || !(pchan->bone->flag & BONE_CONNECTED))
- return tmat[3][array_index];
+ if ((pchan->bone->parent == NULL) || !(pchan->bone->flag & BONE_CONNECTED)) {
+ copy_v3_v3(buffer, tmat[3]);
+ *r_count = 3;
+ return buffer;
+ }
}
}
else {
- return setting_get_rna_value(depsgraph, ptr, prop, array_index, true);
+ return setting_get_rna_values(depsgraph, ptr, prop, true, buffer, buffer_size, r_count);
}
/* Rot/Scale code are common! */
if (strstr(identifier, "rotation_euler")) {
- float eul[3];
+ mat4_to_eulO(buffer, rotmode, tmat);
- mat4_to_eulO(eul, rotmode, tmat);
- return eul[array_index];
+ *r_count = 3;
+ return buffer;
}
else if (strstr(identifier, "rotation_quaternion")) {
- float mat3[3][3], quat[4];
+ float mat3[3][3];
copy_m3_m4(mat3, tmat);
- mat3_to_quat_is_ok(quat, mat3);
+ mat3_to_quat_is_ok(buffer, mat3);
- return quat[array_index];
+ *r_count = 4;
+ return buffer;
}
else if (strstr(identifier, "rotation_axis_angle")) {
- float axis[3], angle;
-
- mat4_to_axis_angle(axis, &angle, tmat);
-
/* w = 0, x,y,z = 1,2,3 */
- if (array_index == 0)
- return angle;
- else
- return axis[array_index - 1];
+ mat4_to_axis_angle(buffer + 1, buffer, tmat);
+
+ *r_count = 4;
+ return buffer;
}
else if (strstr(identifier, "scale")) {
- float scale[3];
-
- mat4_to_size(scale, tmat);
+ mat4_to_size(buffer, tmat);
- return scale[array_index];
+ *r_count = 3;
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list