diff options
author | Joshua Leung <aligorith@gmail.com> | 2008-01-27 06:21:24 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2008-01-27 06:21:24 +0300 |
commit | 8c59520060009d08d50b79e2a37734e77fd6aebe (patch) | |
tree | e4989001053626ef8d267c0cc063b112b4147a78 /source | |
parent | 4213dac345f053cb5674143d719276e742bc69da (diff) |
== Action Editor Drawing - Optimisations (Part 2 out of ?) ==
Keyframes are now checked for whether they are visible or not before they are prepared for drawing. This should provide some improvements for large data-sets...
In general there don't appear to be any major issues, although in a few situations, long-keyframes may end up appearing/disappearing.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/include/BDR_drawaction.h | 16 | ||||
-rw-r--r-- | source/blender/src/drawaction.c | 70 | ||||
-rw-r--r-- | source/blender/src/drawarmature.c | 9 | ||||
-rw-r--r-- | source/blender/src/editaction.c | 6 | ||||
-rw-r--r-- | source/blender/src/poselib.c | 2 | ||||
-rw-r--r-- | source/blender/src/transform_conversions.c | 4 |
6 files changed, 70 insertions, 37 deletions
diff --git a/source/blender/include/BDR_drawaction.h b/source/blender/include/BDR_drawaction.h index 1753f4ecf42..72b3de1e54d 100644 --- a/source/blender/include/BDR_drawaction.h +++ b/source/blender/include/BDR_drawaction.h @@ -68,6 +68,12 @@ typedef struct ActKeyBlock { } ActKeyBlock; +/* Inclusion-Range Limiting Struct (optional) */ +typedef struct ActKeysInc { + struct Object *ob; /* if present, used to find action-scaled time */ + float start, end; /* frames (global-time) to only consider keys between */ +} ActKeysInc; + /* ******************************* Methods ****************************** */ /* Action Generics */ @@ -81,11 +87,11 @@ void draw_action_channel(struct gla2DDrawInfo *di, struct bAction *act, float yp void draw_object_channel(struct gla2DDrawInfo *di, struct Object *ob, float ypos); /* Keydata Generation */ -void icu_to_keylist(struct IpoCurve *icu, ListBase *keys, ListBase *blocks); -void ipo_to_keylist(struct Ipo *ipo, ListBase *keys, ListBase *blocks); -void agroup_to_keylist(struct bActionGroup *agrp, ListBase *keys, ListBase *blocks); -void action_to_keylist(struct bAction *act, ListBase *keys, ListBase *blocks); -void ob_to_keylist(struct Object *ob, ListBase *keys, ListBase *blocks); +void icu_to_keylist(struct IpoCurve *icu, ListBase *keys, ListBase *blocks, ActKeysInc *aki); +void ipo_to_keylist(struct Ipo *ipo, ListBase *keys, ListBase *blocks, ActKeysInc *aki); +void agroup_to_keylist(struct bActionGroup *agrp, ListBase *keys, ListBase *blocks, ActKeysInc *aki); +void action_to_keylist(struct bAction *act, ListBase *keys, ListBase *blocks, ActKeysInc *aki); +void ob_to_keylist(struct Object *ob, ListBase *keys, ListBase *blocks, ActKeysInc *aki); #endif /* BDR_DRAWACTION_H */ diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c index 3339385d565..87c9d886a6e 100644 --- a/source/blender/src/drawaction.c +++ b/source/blender/src/drawaction.c @@ -816,8 +816,7 @@ static void draw_channel_strips(void) /* Draw keyframes * 1) Only channels that are visible in the Action Editor get drawn/evaluated. * This is to try to optimise this for heavier data sets - * 2) Keyframes which are out of view horizontally could be disregarded (probably as - * option - 'drop-frames' or so). Todo... + * 2) Keyframes which are out of view horizontally are disregarded */ y = 0.0; for (ale= act_data.first; ale; ale= ale->next) { @@ -1241,12 +1240,15 @@ static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, fl glDisable(GL_BLEND); } +#define INIT_AKI_DATA {((G.saction && NLA_ACTION_SCALED)? OBACT : NULL), G.v2d->cur.xmin - 10, G.v2d->cur.xmax + 10} + void draw_object_channel(gla2DDrawInfo *di, Object *ob, float ypos) { ListBase keys = {0, 0}; ListBase blocks = {0, 0}; + ActKeysInc aki = INIT_AKI_DATA; - ob_to_keylist(ob, &keys, &blocks); + ob_to_keylist(ob, &keys, &blocks, &aki); draw_keylist(di, &keys, &blocks, ypos); BLI_freelistN(&keys); @@ -1257,8 +1259,9 @@ void draw_ipo_channel(gla2DDrawInfo *di, Ipo *ipo, float ypos) { ListBase keys = {0, 0}; ListBase blocks = {0, 0}; + ActKeysInc aki = INIT_AKI_DATA; - ipo_to_keylist(ipo, &keys, &blocks); + ipo_to_keylist(ipo, &keys, &blocks, &aki); draw_keylist(di, &keys, &blocks, ypos); BLI_freelistN(&keys); @@ -1269,8 +1272,9 @@ void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, float ypos) { ListBase keys = {0, 0}; ListBase blocks = {0, 0}; + ActKeysInc aki = INIT_AKI_DATA; - icu_to_keylist(icu, &keys, &blocks); + icu_to_keylist(icu, &keys, &blocks, &aki); draw_keylist(di, &keys, &blocks, ypos); BLI_freelistN(&keys); @@ -1281,8 +1285,9 @@ void draw_agroup_channel(gla2DDrawInfo *di, bActionGroup *agrp, float ypos) { ListBase keys = {0, 0}; ListBase blocks = {0, 0}; + ActKeysInc aki = INIT_AKI_DATA; - agroup_to_keylist(agrp, &keys, &blocks); + agroup_to_keylist(agrp, &keys, &blocks, &aki); draw_keylist(di, &keys, &blocks, ypos); BLI_freelistN(&keys); BLI_freelistN(&blocks); @@ -1291,27 +1296,28 @@ void draw_agroup_channel(gla2DDrawInfo *di, bActionGroup *agrp, float ypos) void draw_action_channel(gla2DDrawInfo *di, bAction *act, float ypos) { ListBase keys = {0, 0}; + ActKeysInc aki = INIT_AKI_DATA; - action_to_keylist(act, &keys, NULL); + action_to_keylist(act, &keys, NULL, &aki); draw_keylist(di, &keys, NULL, ypos); BLI_freelistN(&keys); } /* --------------- Conversion: data -> keyframe list ------------------ */ -void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks) +void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks, ActKeysInc *aki) { bConstraintChannel *conchan; if (ob) { /* Add object keyframes */ if (ob->ipo) - ipo_to_keylist(ob->ipo, keys, blocks); + ipo_to_keylist(ob->ipo, keys, blocks, aki); /* Add constraint keyframes */ - for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next){ + for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next) { if(conchan->ipo) - ipo_to_keylist(conchan->ipo, keys, blocks); + ipo_to_keylist(conchan->ipo, keys, blocks, aki); } /* Add object data keyframes */ @@ -1319,7 +1325,24 @@ void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks) } } -void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks) +static short bezt_in_aki_range (ActKeysInc *aki, BezTriple *bezt) +{ + /* when aki == NULL, we don't care about range */ + if (aki == NULL) + return 1; + + /* if nla-scaling is in effect, apply appropriate scaling adjustments */ + if (aki->ob) { + float frame= get_action_frame_inv(aki->ob, bezt->vec[1][0]); + return IN_RANGE(frame, aki->start, aki->end); + } + else { + /* check if in range */ + return IN_RANGE(bezt->vec[1][0], aki->start, aki->end); + } +} + +void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks, ActKeysInc *aki) { BezTriple *bezt; ActKeyColumn *ak; @@ -1331,8 +1354,11 @@ void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks) bezt= icu->bezt; for (v=0; v<icu->totvert; v++, bezt++) { - add_bezt_to_keycolumnslist(keys, bezt); - if (blocks) add_bezt_to_keyblockslist(blocks, icu, v); + /* only if keyframe is in range (optimisation) */ + if (bezt_in_aki_range(aki, bezt)) { + add_bezt_to_keycolumnslist(keys, bezt); + if (blocks) add_bezt_to_keyblockslist(blocks, icu, v); + } } /* update the number of curves that elements have appeared in */ @@ -1355,17 +1381,17 @@ void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks) } } -void ipo_to_keylist(Ipo *ipo, ListBase *keys, ListBase *blocks) +void ipo_to_keylist(Ipo *ipo, ListBase *keys, ListBase *blocks, ActKeysInc *aki) { IpoCurve *icu; if (ipo) { for (icu= ipo->curve.first; icu; icu= icu->next) - icu_to_keylist(icu, keys, blocks); + icu_to_keylist(icu, keys, blocks, aki); } } -void agroup_to_keylist(bActionGroup *agrp, ListBase *keys, ListBase *blocks) +void agroup_to_keylist(bActionGroup *agrp, ListBase *keys, ListBase *blocks, ActKeysInc *aki) { bActionChannel *achan; bConstraintChannel *conchan; @@ -1375,18 +1401,18 @@ void agroup_to_keylist(bActionGroup *agrp, ListBase *keys, ListBase *blocks) for (achan= agrp->channels.first; achan && achan!=agrp->channels.last; achan= achan->next) { /* firstly, add keys from action channel's ipo block */ if (achan->ipo) - ipo_to_keylist(achan->ipo, keys, blocks); + ipo_to_keylist(achan->ipo, keys, blocks, aki); /* then, add keys from constraint channels */ for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) { if (conchan->ipo) - ipo_to_keylist(conchan->ipo, keys, blocks); + ipo_to_keylist(conchan->ipo, keys, blocks, aki); } } } } -void action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks) +void action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks, ActKeysInc *aki) { bActionChannel *achan; bConstraintChannel *conchan; @@ -1396,12 +1422,12 @@ void action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks) for (achan= act->chanbase.first; achan; achan= achan->next) { /* firstly, add keys from action channel's ipo block */ if (achan->ipo) - ipo_to_keylist(achan->ipo, keys, blocks); + ipo_to_keylist(achan->ipo, keys, blocks, aki); /* then, add keys from constraint channels */ for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) { if (conchan->ipo) - ipo_to_keylist(conchan->ipo, keys, blocks); + ipo_to_keylist(conchan->ipo, keys, blocks, aki); } } } diff --git a/source/blender/src/drawarmature.c b/source/blender/src/drawarmature.c index abe22a1804d..52f5f4e8954 100644 --- a/source/blender/src/drawarmature.c +++ b/source/blender/src/drawarmature.c @@ -2111,7 +2111,7 @@ static void draw_pose_paths(Object *ob) if (act) { achan= get_action_channel(act, pchan->name); if (achan) - ipo_to_keylist(achan->ipo, &keys, NULL); + ipo_to_keylist(achan->ipo, &keys, NULL, NULL); } /* Draw slightly-larger yellow dots at each keyframe */ @@ -2257,17 +2257,18 @@ static void draw_ghost_poses_keys(Base *base) bArmature *arm= ob->data; bPose *posen, *poseo; ListBase keys= {NULL, NULL}; + ActKeysInc aki = {0, 0, 0}; ActKeyColumn *ak, *akn; float start, end, range, colfac, i; int cfrao, flago, ipoflago; - start = arm->ghostsf; - end = arm->ghostef; + aki.start= start = arm->ghostsf; + aki.end= end = arm->ghostef; if (end <= start) return; /* get keyframes - then clip to only within range */ - action_to_keylist(act, &keys, NULL); + action_to_keylist(act, &keys, NULL, &aki); range= 0; for (ak= keys.first; ak; ak= akn) { akn= ak->next; diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index 1c091ed39d9..2cc905f1147 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -682,20 +682,20 @@ static void *get_nearest_action_key (float *selx, short *sel, short *ret_type, b case ALE_IPO: { Ipo *ipo= (Ipo *)ale->key_data; - ipo_to_keylist(ipo, &act_keys, NULL); + ipo_to_keylist(ipo, &act_keys, NULL, NULL); } break; case ALE_ICU: { IpoCurve *icu= (IpoCurve *)ale->key_data; - icu_to_keylist(icu, &act_keys, NULL); + icu_to_keylist(icu, &act_keys, NULL, NULL); } break; } } else if (ale->type == ACTTYPE_GROUP) { bActionGroup *agrp= (bActionGroup *)ale->data; - agroup_to_keylist(agrp, &act_keys, NULL); + agroup_to_keylist(agrp, &act_keys, NULL, NULL); } /* loop through keyframes, finding one that was clicked on */ diff --git a/source/blender/src/poselib.c b/source/blender/src/poselib.c index 44277e17804..468c68021ed 100644 --- a/source/blender/src/poselib.c +++ b/source/blender/src/poselib.c @@ -218,7 +218,7 @@ void poselib_validate_act (bAction *act) } /* determine which frames have keys */ - action_to_keylist(act, &keys, NULL); + action_to_keylist(act, &keys, NULL, NULL); /* for each key, make sure there is a correspnding pose */ for (ak= keys.first; ak; ak= ak->next) { diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 12419c94c0f..5d3ab77ab45 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -3002,9 +3002,9 @@ short autokeyframe_cfra_can_key(Object *ob) /* get keyframes that object has (bone anim is stored on ob too) */ if (ob->action) - action_to_keylist(ob->action, &keys, NULL); + action_to_keylist(ob->action, &keys, NULL, NULL); else if (ob->ipo) - ipo_to_keylist(ob->ipo, &keys, NULL); + ipo_to_keylist(ob->ipo, &keys, NULL, NULL); else return 0; |