[docs]defspline_interpolator(keyframes,degree):"""N-th degree spline interpolator for keyframes. This is a general n-th degree spline interpolator to be used for any shape of keyframes data. Parameters ---------- keyframes: dict Keyframe data containing timestamps and values to form the spline curve. Data should be on the following format: {1: {'value': np.array([...])}, 2: {'value': np.array([...])}} Returns ------- function The interpolation function that take time and return interpolated value at that time. """iflen(keyframes)<(degree+1):raiseValueError(f"Minimum {degree+1} "f"keyframes must be set in order to use "f"{degree}-degree spline")timestamps=get_timestamps_from_keyframes(keyframes)values=get_values_from_keyframes(keyframes)distances=euclidean_distances(values)distances_sum=sum(distances)cumulative_dist_sum=np.cumsum([0]+distances)tck=splprep(values.T,k=degree,full_output=1,s=0)[0][0]definterpolate(t):t0=get_previous_timestamp(timestamps,t)t1=get_next_timestamp(timestamps,t)mi_index=np.where(timestamps==t0)[0][0]dt=get_time_tau(t,t0,t1)section=cumulative_dist_sum[mi_index]ts=(section+dt*distances[mi_index])/distances_sumreturnnp.array(splev(ts,tck))returninterpolate
[docs]defcubic_spline_interpolator(keyframes):"""Cubic spline interpolator for keyframes. This is a general cubic spline interpolator to be used for any shape of keyframes data. Parameters ---------- keyframes: dict Keyframe data containing timestamps and values to form the cubic spline curve. Returns ------- function The interpolation function that take time and return interpolated value at that time. See Also -------- spline_interpolator """returnspline_interpolator(keyframes,degree=3)
[docs]defstep_interpolator(keyframes):"""Step interpolator for keyframes. This is a simple step interpolator to be used for any shape of keyframes data. Parameters ---------- keyframes: dict Keyframe data containing timestamps and values to form the spline Returns ------- function The interpolation function that take time and return interpolated value at that time. """timestamps=get_timestamps_from_keyframes(keyframes)definterpolate(t):previous_t=get_previous_timestamp(timestamps,t,include_last=True)returnkeyframes.get(previous_t).get("value")returninterpolate
[docs]deflinear_interpolator(keyframes):"""Linear interpolator for keyframes. This is a general linear interpolator to be used for any shape of keyframes data. Parameters ---------- keyframes: dict Keyframe data to be linearly interpolated. Returns ------- function The interpolation function that take time and return interpolated value at that time. """timestamps=get_timestamps_from_keyframes(keyframes)is_single=len(keyframes)==1definterpolate(t):ifis_single:t=timestamps[0]returnkeyframes.get(t).get("value")t0=get_previous_timestamp(timestamps,t)t1=get_next_timestamp(timestamps,t)p0=keyframes.get(t0).get("value")p1=keyframes.get(t1).get("value")returnlerp(p0,p1,t0,t1,t)returninterpolate
[docs]defcubic_bezier_interpolator(keyframes):"""Cubic Bézier interpolator for keyframes. This is a general cubic Bézier interpolator to be used for any shape of keyframes data. Parameters ---------- keyframes : dict Keyframes to be interpolated at any time. Returns ------- function The interpolation function that take time and return interpolated value at that time. Notes ----- If no control points are set in the keyframes, The cubic Bézier interpolator will almost behave as a linear interpolator. """timestamps=get_timestamps_from_keyframes(keyframes)fortsintimestamps:# keyframe at timestampkf_ts=keyframes.get(ts)ifkf_ts.get("in_cp")isNone:kf_ts["in_cp"]=kf_ts.get("value")ifkf_ts.get("out_cp")isNone:kf_ts["out_cp"]=kf_ts.get("value")definterpolate(t):t0=get_previous_timestamp(timestamps,t)t1=get_next_timestamp(timestamps,t)k0=keyframes.get(t0)k1=keyframes.get(t1)p0=k0.get("value")p1=k0.get("out_cp")p2=k1.get("in_cp")p3=k1.get("value")dt=get_time_tau(t,t0,t1)val=((1-dt)**3*p0+3*(1-dt)**2*dt*p1+3*(1-dt)*dt**2*p2+dt**3*p3)returnvalreturninterpolate
[docs]defslerp(keyframes):"""Spherical based rotation keyframes interpolator. A rotation interpolator to be used for rotation keyframes. Parameters ---------- keyframes : dict Rotation keyframes to be interpolated at any time. Returns ------- function The interpolation function that take time and return interpolated value at that time. Notes ----- Rotation keyframes must be in the form of quaternions. """timestamps=get_timestamps_from_keyframes(keyframes)quat_rots=[]fortsintimestamps:quat_rots.append(keyframes.get(ts).get("value"))rotations=transform.Rotation.from_quat(quat_rots)# if only one keyframe specified, linear interpolator is used.iflen(timestamps)==1:returnlinear_interpolator(keyframes)slerp_interp=transform.Slerp(timestamps,rotations)min_t=timestamps[0]max_t=timestamps[-1]definterpolate(t):t=min_tift<min_telsemax_tift>max_telsetv=slerp_interp(t)q=v.as_quat()returnqreturninterpolate
[docs]defcolor_interpolator(keyframes,rgb2space,space2rgb):"""Custom-space color interpolator. Interpolate values linearly inside a custom color space. Parameters ---------- keyframes : dict Rotation keyframes to be interpolated at any time. rgb2space: function A functions that take color value in rgb and return that color converted to the targeted space. space2rgb: function A functions that take color value in the targeted space and returns that color in rgb space. Returns ------- function The interpolation function that take time and return interpolated value at that time. """timestamps=get_timestamps_from_keyframes(keyframes)space_keyframes={}is_single=len(keyframes)==1forts,keyframeinkeyframes.items():space_keyframes[ts]=rgb2space(keyframe.get("value"))definterpolate(t):ifis_single:t=timestamps[0]returnkeyframes.get(t).get("value")t0=get_previous_timestamp(timestamps,t)t1=get_next_timestamp(timestamps,t)c0=space_keyframes.get(t0)c1=space_keyframes.get(t1)space_color_val=lerp(c0,c1,t0,t1,t)returnspace2rgb(space_color_val)returninterpolate
[docs]defhsv_color_interpolator(keyframes):"""HSV interpolator for color keyframes See Also -------- color_interpolator """returncolor_interpolator(keyframes,rgb2hsv,hsv2rgb)
[docs]deflab_color_interpolator(keyframes):"""LAB interpolator for color keyframes See Also -------- color_interpolator """returncolor_interpolator(keyframes,rgb2lab,lab2rgb)
[docs]defxyz_color_interpolator(keyframes):"""XYZ interpolator for color keyframes See Also -------- color_interpolator """returncolor_interpolator(keyframes,rgb2xyz,xyz2rgb)
[docs]deftan_cubic_spline_interpolator(keyframes):"""Cubic spline interpolator for keyframes using tangents. glTF contains additional tangent information for the cubic spline interpolator. Parameters ---------- keyframes: dict Keyframe data containing timestamps and values to form the cubic spline curve. Returns ------- function The interpolation function that take time and return interpolated value at that time. """timestamps=get_timestamps_from_keyframes(keyframes)fortimeinkeyframes:data=keyframes.get(time)value=data.get("value")ifdata.get("in_tangent")isNone:data["in_tangent"]=np.zeros_like(value)ifdata.get("in_tangent")isNone:data["in_tangent"]=np.zeros_like(value)definterpolate(t):t0=get_previous_timestamp(timestamps,t)t1=get_next_timestamp(timestamps,t)dt=get_time_tau(t,t0,t1)time_delta=t1-t0p0=keyframes.get(t0).get("value")tan_0=keyframes.get(t0).get("out_tangent")*time_deltap1=keyframes.get(t1).get("value")tan_1=keyframes.get(t1).get("in_tangent")*time_delta# cubic spline equation using tangentst2=dt*dtt3=t2*dtreturn((2*t3-3*t2+1)*p0+(t3-2*t2+dt)*tan_0+(-2*t3+3*t2)*p1+(t3-t2)*tan_1)returninterpolate