Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2018-04-25 18:59:08 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2018-04-26 19:11:58 +0300
commit918359269824a081c5e5819c44bc8461f59ebd37 (patch)
tree8475c029a831663bc31b863f226fa2267ece475d /source/blender/blenkernel/intern/anim_sys.c
parentc86be7345b5338544e32197ae7c852361f747a7c (diff)
Animation: Make it possible to keyframe to with copy-on-write
The issue was that every object tweak was doing a full copy of original datablock onto evaluated version, and was updating animation. This made it impossible to tweak properties which has keyframes. Proposed solution is to: - Always apply animation on frame change, and when object is explicitly tagged for animation update. This will store original DNA value of animated property in the f-curve. - When applying animation in other cases, we check original DNA value stored in f-curve with the actual original DNA property. If they differ, it means user started to tweak animated property, and we should skip animation. If the value is the same, we apply animation. This is just a first step towards proper final implementation, but seems to be the direction we want to take.
Diffstat (limited to 'source/blender/blenkernel/intern/anim_sys.c')
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c53
1 files changed, 46 insertions, 7 deletions
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index c1822bf086b..b8b585ba278 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -78,6 +78,8 @@
#include "atomic_ops.h"
+#include "DEG_depsgraph_query.h"
+
/* ***************************************** */
/* AnimData API */
@@ -1701,10 +1703,15 @@ bool BKE_animsys_execute_fcurve(PointerRNA *ptr, AnimMapper *remap, FCurve *fcu,
/* Evaluate all the F-Curves in the given list
* This performs a set of standard checks. If extra checks are required, separate code should be used
*/
-static void animsys_evaluate_fcurves(PointerRNA *ptr, ListBase *list, AnimMapper *remap, float ctime)
+static void animsys_evaluate_fcurves(PointerRNA *ptr, ListBase *list, AnimMapper *remap, float ctime, short recalc)
{
FCurve *fcu;
-
+
+ /* Pointer is expected to be an ID pointer, if it's not -- we are doomed. */
+ PointerRNA orig_ptr = *ptr;
+ orig_ptr.id.data = ((ID*)orig_ptr.id.data)->orig_id;
+ orig_ptr.data = orig_ptr.id.data;
+
/* calculate then execute each curve */
for (fcu = list->first; fcu; fcu = fcu->next) {
/* check if this F-Curve doesn't belong to a muted group */
@@ -1712,9 +1719,28 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr, ListBase *list, AnimMapper
/* check if this curve should be skipped */
if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
PathResolvedRNA anim_rna;
+ /* Read current value from original datablock. */
+ float dna_val;
+ if (animsys_store_rna_setting(&orig_ptr, remap, fcu->rna_path, fcu->array_index, &anim_rna)) {
+ if (!animsys_read_rna_setting(&anim_rna, &dna_val)) {
+ continue;
+ }
+ }
+ else {
+ continue;
+ }
if (animsys_store_rna_setting(ptr, remap, fcu->rna_path, fcu->array_index, &anim_rna)) {
+ const bool check_orig_dna = ((recalc & ADT_RECALC_CHECK_ORIG_DNA) != 0);
+ /* If we are tweaking DNA without changing frame, we don't write f-curves,
+ * since otherwise we will not be able to change properties which has animation.
+ */
+ if (check_orig_dna && fcu->orig_dna_val != dna_val) {
+ continue;
+ }
const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
animsys_write_rna_setting(&anim_rna, curval);
+ /* Store original DNA value f-curve was written for. */
+ fcu->orig_dna_val = dna_val;
}
}
}
@@ -1827,7 +1853,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *
}
/* Evaluate Action (F-Curve Bag) */
-void animsys_evaluate_action(PointerRNA *ptr, bAction *act, AnimMapper *remap, float ctime)
+static void animsys_evaluate_action_ex(PointerRNA *ptr, bAction *act, AnimMapper *remap, float ctime, short recalc)
{
/* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
if (act == NULL) return;
@@ -1836,7 +1862,12 @@ void animsys_evaluate_action(PointerRNA *ptr, bAction *act, AnimMapper *remap, f
action_idcode_patch_check(ptr->id.data, act);
/* calculate then execute each curve */
- animsys_evaluate_fcurves(ptr, &act->curves, remap, ctime);
+ animsys_evaluate_fcurves(ptr, &act->curves, remap, ctime, recalc);
+}
+
+void animsys_evaluate_action(PointerRNA *ptr, bAction *act, AnimMapper *remap, float ctime)
+{
+ animsys_evaluate_action_ex(ptr, act, remap, ctime, 0);
}
/* ***************************************** */
@@ -1875,7 +1906,7 @@ static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime)
RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
/* execute these settings as per normal */
- animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, NULL, ctime);
+ animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, NULL, ctime, 0);
}
/* analytically generate values for influence and time (if applicable)
@@ -2742,7 +2773,7 @@ void BKE_animsys_evaluate_animdata(Scene *scene, ID *id, AnimData *adt, float ct
}
/* evaluate Active Action only */
else if (adt->action)
- animsys_evaluate_action(&id_ptr, adt->action, adt->remap, ctime);
+ animsys_evaluate_action_ex(&id_ptr, adt->action, adt->remap, ctime, recalc);
/* reset tag */
adt->recalc &= ~ADT_RECALC_ANIM;
@@ -2921,7 +2952,15 @@ void BKE_animsys_eval_animdata(Depsgraph *depsgraph, ID *id)
* which should get handled as part of the dependency graph instead...
*/
DEG_debug_print_eval_time(__func__, id->name, id, ctime);
- BKE_animsys_evaluate_animdata(scene, id, adt, ctime, ADT_RECALC_ANIM);
+ short recalc = ADT_RECALC_ANIM;
+ const Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
+ /* If animation component is directly tagged for update, we always apply f-curves. */
+ if (((scene_eval->id.recalc & ID_RECALC_TIME) == 0) &&
+ (id->recalc & ID_RECALC_TIME) == 0)
+ {
+ recalc |= ADT_RECALC_CHECK_ORIG_DNA;
+ }
+ BKE_animsys_evaluate_animdata(scene, id, adt, ctime, recalc);
}
/* TODO(sergey): This is slow lookup of driver from CoW datablock.