[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