diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2015-05-20 13:14:55 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2015-05-20 13:14:55 +0300 |
commit | b75a56dcc1d8c9507f0e51801e634b88d9c3f3e7 (patch) | |
tree | afaf62acb8b29c999145c7ea4fe0c2a53d383a4d /source/blender/blenkernel | |
parent | 249625971432f5ee48f93dc627af3cdedb9c9f23 (diff) |
Fixed shape key reference data usage, for applying shape keys on top
of an animated base.
This is necessary for strand shape keys. The basis of the data comes
from the cached animation or simulation results, i.e. we can't use the
fixed basis key or the result would always become static.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_key.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cache_library.c | 26 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 32 |
3 files changed, 47 insertions, 13 deletions
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index 710e7f354a1..eb665f26965 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -73,7 +73,7 @@ float *BKE_key_evaluate_strands_ex( int *r_totelem, float *arr, size_t arr_size); float *BKE_key_evaluate_strands( struct Strands *strand, struct Key *key, struct KeyBlock *actkbs, bool lock_shape, - int *r_totelem); + int *r_totelem, bool use_motion_basis); struct Key *BKE_key_from_object(struct Object *ob); struct KeyBlock *BKE_keyblock_from_object(struct Object *ob); diff --git a/source/blender/blenkernel/intern/cache_library.c b/source/blender/blenkernel/intern/cache_library.c index 2caa0d46dd2..dbccbed7d45 100644 --- a/source/blender/blenkernel/intern/cache_library.c +++ b/source/blender/blenkernel/intern/cache_library.c @@ -1527,10 +1527,9 @@ static void strandskey_process(StrandsKeyCacheModifier *skmd, CacheProcessContex return; actkb = BLI_findlink(&skmd->key->block, skmd->shapenr); - shape = BKE_key_evaluate_strands(strands, skmd->key, actkb, skmd->flag & eStrandsKeyCacheModifier_Flag_ShapeLock, NULL); + shape = BKE_key_evaluate_strands(strands, skmd->key, actkb, skmd->flag & eStrandsKeyCacheModifier_Flag_ShapeLock, NULL, false); if (shape) { StrandsVertex *vert = strands->verts; - StrandsMotionState *state = strands->state; int totvert = strands->totverts; int i; @@ -1538,16 +1537,29 @@ static void strandskey_process(StrandsKeyCacheModifier *skmd, CacheProcessContex for (i = 0; i < totvert; ++i) { copy_v3_v3(vert->co, fp); ++vert; + fp += 3; + } + + MEM_freeN(shape); + } + + /* motion shape, if needed */ + if (strands->state) { + shape = BKE_key_evaluate_strands(strands, skmd->key, actkb, skmd->flag & eStrandsKeyCacheModifier_Flag_ShapeLock, NULL, true); + if (shape) { + StrandsMotionState *state = strands->state; + int totvert = strands->totverts; + int i; - if (state) { + float *fp = shape; + for (i = 0; i < totvert; ++i) { copy_v3_v3(state->co, fp); ++state; + fp += 3; } - fp += 3; + MEM_freeN(shape); } - - MEM_freeN(shape); } } @@ -1588,7 +1600,7 @@ KeyBlock *BKE_cache_modifier_strands_key_insert_key(StrandsKeyCacheModifier *skm KeyBlock *actkb = BLI_findlink(&skmd->key->block, skmd->shapenr); bool shape_lock = skmd->flag & eStrandsKeyCacheModifier_Flag_ShapeLock; int totelem; - float *data = BKE_key_evaluate_strands(strands, key, actkb, shape_lock, &totelem); + float *data = BKE_key_evaluate_strands(strands, key, actkb, shape_lock, &totelem, false); /* create new block with prepared data */ kb = BKE_keyblock_add_ctime(key, name, false); diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index d7308e30cfe..7b82cb1a9c8 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -770,7 +770,9 @@ void BKE_key_evaluate_relative_ex(const int start, int end, const int tot, char { KeyBlock *kb; int *ofsp, ofs[3], elemsize, b; - char *cp, *poin, *reffrom, *from, elemstr[8]; + char *poin, *reffrom, *from, *keyreffrom; + char *freekeyreffrom = NULL; + char elemstr[8]; int poinsize, keyblock_index; /* currently always 0, in future key_pointer_size may assign */ @@ -791,8 +793,10 @@ void BKE_key_evaluate_relative_ex(const int start, int end, const int tot, char if (mode == KEY_MODE_BEZTRIPLE) elemsize *= 3; /* step 1 init */ - if (!refdata) + keyreffrom = key_block_get_data(key, actkb, key->refkey, &freekeyreffrom); + if (!refdata) { cp_key(start, end, tot, basispoin, key, actkb, key->refkey, NULL, mode, NULL); + } /* step 2: do it */ @@ -818,8 +822,11 @@ void BKE_key_evaluate_relative_ex(const int start, int end, const int tot, char poin += start * poinsize; reffrom += key->elemsize * start; // key elemsize yes! from += key->elemsize * start; + keyreffrom += key->elemsize * start; + if (refdata) refdata += key->elemsize * start; for (b = start; b < end; b++) { + char *cp; weight = weights ? (*weights * icuval) : icuval; @@ -833,6 +840,11 @@ void BKE_key_evaluate_relative_ex(const int start, int end, const int tot, char switch (cp[1]) { case IPO_FLOAT: rel_flerp(3, (float *)poin, (float *)reffrom, (float *)from, weight); + if (refdata) { + float offset[3]; + sub_v3_v3v3(offset, (float *)keyreffrom, (float *)refdata); + madd_v3_v3fl((float *)poin, offset, weight); + } break; case IPO_BPOINT: rel_flerp(4, (float *)poin, (float *)reffrom, (float *)from, weight); @@ -856,6 +868,8 @@ void BKE_key_evaluate_relative_ex(const int start, int end, const int tot, char reffrom += elemsize; from += elemsize; + keyreffrom += elemsize; + if (refdata) refdata += elemsize; if (mode == KEY_MODE_BEZTRIPLE) b += 2; if (weights) weights++; @@ -866,6 +880,8 @@ void BKE_key_evaluate_relative_ex(const int start, int end, const int tot, char } } } + + if (freekeyreffrom) MEM_freeN(freekeyreffrom); } void BKE_key_evaluate_relative(const int start, int end, const int tot, char *basispoin, Key *key, KeyBlock *actkb, @@ -1551,7 +1567,7 @@ float *BKE_key_evaluate_strands_ex(Strands *strands, Key *key, KeyBlock *actkb, return (float *)out; } -float *BKE_key_evaluate_strands(Strands *strands, Key *key, KeyBlock *actkb, bool lock_shape, int *r_totelem) +float *BKE_key_evaluate_strands(Strands *strands, Key *key, KeyBlock *actkb, bool lock_shape, int *r_totelem, bool use_motion_basis) { size_t size = sizeof(float) * 3 * strands->totverts; float *data = MEM_mallocN(size, "strands shape key data"); @@ -1559,8 +1575,14 @@ float *BKE_key_evaluate_strands(Strands *strands, Key *key, KeyBlock *actkb, boo float *fp; int i; - for (i = 0, fp = data; i < strands->totverts; ++i, fp += 3) - copy_v3_v3(fp, strands->verts[i].co); + if (use_motion_basis && strands->state) { + for (i = 0, fp = data; i < strands->totverts; ++i, fp += 3) + copy_v3_v3(fp, strands->state[i].co); + } + else { + for (i = 0, fp = data; i < strands->totverts; ++i, fp += 3) + copy_v3_v3(fp, strands->verts[i].co); + } result = BKE_key_evaluate_strands_ex(strands, key, actkb, lock_shape, r_totelem, data, size); if (result != data) |