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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to