Use 'duration' instead of 'nloops' in blends.

This commit is contained in:
Steven Robertson 2012-04-22 15:41:51 -07:00
parent 83e8eb465a
commit 1dcdd31973
3 changed files with 22 additions and 14 deletions

View File

@ -204,6 +204,8 @@ class GenomePacker(object):
times, knots = np.empty((2, len(self.genome), width), 'f4') times, knots = np.empty((2, len(self.genome), width), 'f4')
times.fill(1e9) times.fill(1e9)
# TODO: do a nicer job of finding the value of scale
scale = gnm.get('time', {}).get('duration', 1)
for idx, path in enumerate(self.genome): for idx, path in enumerate(self.genome):
attr = gnm attr = gnm
for name in path: for name in path:
@ -211,7 +213,7 @@ class GenomePacker(object):
attr = resolve_spec(specs.anim, path).default attr = resolve_spec(specs.anim, path).default
break break
attr = attr[name] attr = attr[name]
attr = SplineEval.normalize(attr) attr = SplineEval.normalize(attr, scale)
times[idx,:len(attr[0])] = attr[0] times[idx,:len(attr[0])] = attr[0]
knots[idx,:len(attr[1])] = attr[1] knots[idx,:len(attr[1])] = attr[1]
return times, knots return times, knots

View File

@ -98,7 +98,7 @@ def blend(src, dst, edit={}):
opts.update(d.get('blend', {})) opts.update(d.get('blend', {}))
opts = Wrapper(opts, specs.blend) opts = Wrapper(opts, specs.blend)
blended = merge_nodes(specs.node, src, dst, edit, opts.nloops) blended = merge_nodes(specs.node, src, dst, edit, opts.duration)
name_map = sort_xforms(src['xforms'], dst['xforms'], opts.xform_sort, name_map = sort_xforms(src['xforms'], dst['xforms'], opts.xform_sort,
explicit=zip(*opts.xform_map)) explicit=zip(*opts.xform_map))
@ -111,11 +111,12 @@ def blend(src, dst, edit={}):
blended['xforms'][bxf_key] = blend_xform( blended['xforms'][bxf_key] = blend_xform(
src['xforms'].get(sxf_key), src['xforms'].get(sxf_key),
dst['xforms'].get(dxf_key), dst['xforms'].get(dxf_key),
xf_edits, opts.nloops) xf_edits, opts.duration)
if 'final_xform' in src or 'final_xform' in dst: if 'final_xform' in src or 'final_xform' in dst:
blended['final_xform'] = blend_xform(src.get('final_xform'), blended['final_xform'] = blend_xform(src.get('final_xform'),
dst.get('final_xform'), edit.get('final_xform'), 0, True) dst.get('final_xform'), edit.get('final_xform'),
opts.duration, True)
# TODO: write 'info' section # TODO: write 'info' section
# TODO: palflip # TODO: palflip
@ -144,7 +145,7 @@ def split_node_val(spl, val):
return val, 0 return val, 0
return val return val
def tospline(spl, src, dst, edit, loops): def tospline(spl, src, dst, edit, duration):
sp, sv = split_node_val(spl, src) # position, velocity sp, sv = split_node_val(spl, src) # position, velocity
dp, dv = split_node_val(spl, dst) dp, dv = split_node_val(spl, dst)
@ -163,8 +164,11 @@ def tospline(spl, src, dst, edit, loops):
# Periodic extension: compute an appropriate number of loops based on # Periodic extension: compute an appropriate number of loops based on
# the angular velocities at the endpoints, and extend the destination # the angular velocities at the endpoints, and extend the destination
# position by the appropriate number of periods. # position by the appropriate number of periods.
avg_vel = round(float(sv + dv) * loops / spl.period) sign = lambda x: 1. if x >= 0 else -1.
dp = dp % spl.period + avg_vel * spl.period
movement = duration * (sv + dv) / (2.0 * spl.period)
angdiff = ((dp - sp) / spl.period) % (sign(movement))
dp = sp + (round(movement - angdiff) + angdiff) * spl.period
# Endpoint override: allow adjusting the number of loops as calculated # Endpoint override: allow adjusting the number of loops as calculated
# above by locking to the nearest value with the same mod (i.e. the # above by locking to the nearest value with the same mod (i.e. the
@ -183,14 +187,14 @@ def trace(k):
print k, print k,
return k return k
def merge_nodes(sp, src, dst, edit, loops): def merge_nodes(sp, src, dst, edit, duration):
if isinstance(sp, dict): if isinstance(sp, dict):
src, dst, edit = [x or {} for x in src, dst, edit] src, dst, edit = [x or {} for x in src, dst, edit]
return dict([(k, merge_nodes(sp[k], src.get(k), return dict([(k, merge_nodes(sp[k], src.get(k),
dst.get(k), edit.get(k), loops)) dst.get(k), edit.get(k), duration))
for k in set(src.keys() + dst.keys() + edit.keys()) if k in sp]) for k in set(src.keys() + dst.keys() + edit.keys()) if k in sp])
elif isinstance(sp, spectypes.Spline): elif isinstance(sp, spectypes.Spline):
return tospline(sp, src, dst, edit, loops) return tospline(sp, src, dst, edit, duration)
elif isinstance(sp, spectypes.List): elif isinstance(sp, spectypes.List):
if isinstance(sp.type, spectypes.Palette): if isinstance(sp.type, spectypes.Palette):
if src is not None: src = [[0] + src] if src is not None: src = [[0] + src]
@ -199,12 +203,12 @@ def merge_nodes(sp, src, dst, edit, loops):
else: else:
return edit if edit is not None else dst if dst is not None else src return edit if edit is not None else dst if dst is not None else src
def blend_xform(sxf, dxf, edits, loops, isfinal=False): def blend_xform(sxf, dxf, edits, duration, isfinal=False):
if sxf is None: if sxf is None:
sxf = padding_xform(dxf, isfinal) sxf = padding_xform(dxf, isfinal)
if dxf is None: if dxf is None:
dxf = padding_xform(sxf, isfinal) dxf = padding_xform(sxf, isfinal)
return merge_nodes(specs.xform, sxf, dxf, edits, loops) return merge_nodes(specs.xform, sxf, dxf, edits, duration)
# If xin contains any of these, use the inverse identity # If xin contains any of these, use the inverse identity
hole_variations = ('spherical ngon julian juliascope polar ' hole_variations = ('spherical ngon julian juliascope polar '

View File

@ -70,8 +70,10 @@ time = (
}) })
blend = ( blend = (
{ 'nloops': scalar(2) { 'duration': scalar(2, d='The base duration of the animation. This value '
, 'duration': scalar(2) 'affects the periodic extension of angular parameters (values are '
'extended to minimize deviation from average velocity), and also '
'sets the default value for `time.duration` in an animation.')
, 'xform_sort': enum('weightflip weight natural color') , 'xform_sort': enum('weightflip weight natural color')
, 'xform_map': list_(list_(String('xfid'), d='A pair of src, dst IDs')) , 'xform_map': list_(list_(String('xfid'), d='A pair of src, dst IDs'))
}) })