PyIgnition

https://github.com/animatinator/PyIgnition update for Python 3
Clone: git clone https://git.frombelow.net/PyIgnition.git
Log | Files | Refs | README

interpolate.py (2882B)


      1 ### EXESOFT PYIGNITION ###
      2 # Copyright David Barker 2010
      3 # 
      4 # Utility module for interpolating between keyframed values
      5 
      6 
      7 import math
      8 from constants import *
      9 
     10 
     11 def LinearInterpolate(val1, val2, t):
     12 	diff = val2 - val1
     13 	dist = float(diff) * t
     14 	
     15 	return val1 + dist
     16 
     17 def CosineInterpolate(val1, val2, t):
     18 	amplitude = float(val2 - val1) / 2.0
     19 	midpoint = float(val1 + val2) / 2.0
     20 	
     21 	return (amplitude * math.cos(math.pi * (1.0 - t))) + midpoint
     22 
     23 
     24 def LinearInterpolateKeyframes(curframe, key1, key2, val1, val2):
     25 	if key1 == key2:
     26 		return val2
     27 	
     28 	factor = float(curframe - key1) / float(key2 - key1)
     29 	
     30 	return LinearInterpolate(val1, val2, factor)
     31 
     32 def CosineInterpolateKeyframes(curframe, key1, key2, val1, val2):
     33 	if key1 == key2:
     34 		return val2
     35 	
     36 	factor = float(curframe - key1) / float(key2 - key1)
     37 	
     38 	return CosineInterpolate(val1, val2, factor)
     39 
     40 
     41 def InterpolateKeyframes(curframe, variables, keyframes):
     42 	if len(keyframes) == 1:
     43 		return keyframes[0].variables
     44 	
     45 	finalvariables = {}
     46 	
     47 	if not ('interpolationtype' in variables):
     48 		variables['interpolationtype'] = INTERPOLATIONTYPE_LINEAR
     49 	
     50 	keys = list(variables.keys())
     51 	
     52 	for i in range(len(keys)):  # Determine current keyframe and next one for this variable
     53 		key = keys[i]
     54 		curkeyframe = None
     55 		nextkeyframe = None
     56 		
     57 		for i in range(len(keyframes)):
     58 			try:
     59 				frame = keyframes[i]
     60 				if (frame.variables[key] != None):  # If the current keyframe has a keyed value for the current variable
     61 					if frame.frame <= curframe:  # If its frame is below or equal to the current, it is the current keyframe
     62 						curkeyframe = i
     63 					if (nextkeyframe == None) and (frame.frame > curframe):  # If this is the first keyframe with a frame higher than the current, it is the next keyframe
     64 						nextkeyframe = i
     65 			except KeyError:
     66 				pass
     67 		
     68 		if nextkeyframe == None or key == "interpolationtype":  # If there is no next key frame, maintain the value specified by the current one
     69 			finalvariables[key] = keyframes[curkeyframe].variables[key]  # (Also do this if it is an interpolation type variable; they should only change once their next keyframe has been reached
     70 		
     71 		else:  # Interpolate between the current and next keyframes
     72 			if keyframes[nextkeyframe].variables['interpolationtype'] == INTERPOLATIONTYPE_LINEAR:
     73 				finalvariables[key] = LinearInterpolateKeyframes(curframe, keyframes[curkeyframe].frame, keyframes[nextkeyframe].frame, keyframes[curkeyframe].variables[key], keyframes[nextkeyframe].variables[key])
     74 			elif keyframes[nextkeyframe].variables['interpolationtype'] == INTERPOLATIONTYPE_COSINE:
     75 				finalvariables[key] = CosineInterpolateKeyframes(curframe, keyframes[curkeyframe].frame, keyframes[nextkeyframe].frame, keyframes[curkeyframe].variables[key], keyframes[nextkeyframe].variables[key])
     76 	
     77 	return finalvariables