src

algorithms.py

addKeyframes(insertedKeys: typing.List[Keyframe], nextKeys: typing.List[Keyframe]) -> (insertedKeys: typing.List[Keyframe], nextKeys: typing.List[Keyframe])

adds the two lists of keyframes together. check out the desmos graph to learn a bit more on how this works https://www.desmos.com/calculator/t7ullcvosp this is a mutating function

Parameters
  • insertedKeys (List[Keyframe]) – the keyframes that are already inserted on the object

  • nextKeys (List[Keyframe]) – the keyframes that will be inserted next (the upcoming note)

Raises

ValueError – if the insertedKeys’ first frame is bigger than nextKeys’ first frame

Return None

this function mutates the insertedKeys list

animateDampedOsc(time: float, period: float, amplitude: float, damp: float)

evaluates a dampaned oscillation curve based on parameters

Parameters
  • time (float) – the time at which you want to evaluate from (e.g., f(x))

  • period (float) – how long it takes for the oscillation to repeat one time

  • amplitude (float) – how large is each oscillation

  • damp (float) – damping of the oscillation (how much decrease of energy for each oscillation)

  • frameRate (float) – the framerate of the current scene

Return _type_

_description_

animateSine(time: float, startVal: float, endVal: float, duration: float) -> (time: float, startVal: float, endVal: float, duration: float)

evaluates a sine curve based on paramters interactive demo: https://www.desmos.com/calculator/kw2grve25z

Parameters
  • time (float) – the time at which you want to evaluate from (e.g., f(x))

  • startVal (float) – starting value (e.g., y-axis)

  • endVal (float) – ending value (e.g., y-axis)

  • duration (float) – how long the animation should last (e.g., x-axis)

Return float

the result of the evaluated animation (e.g., result of evaluating f(x))

genDampedOscKeyframes(period: float, amplitude: float, damp: float, frame=0) -> (period: float, amplitude: float, damp: float, frame=0)

generates keyframes that will generate the specified dampend oscillation Thanks to TheZacher5645 for helping figure out calculating the local extrema & derivative functions for v1 interactive demo (v2): https://www.desmos.com/calculator/qwmf2xkno3

Parameters
  • period (float) – how long it takes for the oscillation to repeat one time

  • amplitude (float) – how large is each oscillation

  • damp (float) – damping of the oscillation (how much decrease of energy for each oscillation)

  • frameRate (float) – the framerate of the current scene

Return List[Keyframe]

a list of keyframes of the min’s and max’s of the oscillation.

maxSimultaneousObjects(intervals: typing.List[typing.Tuple[float, float]]) -> (intervals: typing.List[typing.Tuple[float, float]])

gets the max simotaneous objects for List[Tuple[float, float]]`. :param intervals: List[Tuple[float, float]] :return int: max number of objects that are visible at any point in time

animation.py

class MIDIAnimatorNode

Bases: object

This class encompasses all Instrument classes (and its subclasses).

__init__()
addInstrument(instrumentType: str = None, midiTrack: midi.MIDITrack = None, objectCollection: bpy.types.Collection = None, custom=None, customVars: Dict = None)

adds an instrument to MIDIAnimator. This will create the class for you

Parameters
  • midiTrack (MIDITrack) – The MIDITrack object to create the instrument from

  • objectCollection (bpy.types.Collection) – The collection (bpy.types.Collection) of Blender objects to be animated.

  • custom (class(Instrument)) – a custom Instrument class that inherits from Instrument, defaults to None

  • customVars (Dict) – a dictionary of custom vars you would like to send to your custom class, defaults to None

Raises

ValueError – if instrumentType=”custom” and the customClass is None.

animate()

animate all of the tracks

instruments.py

class EvaluateInstrument

Bases: MIDIAnimator.src.instruments.Instrument

__init__(midiTrack: midi.MIDITrack, collection: bpy.types.Collection)

Takes an object with FCurves and duplicates it across the timeline.

Parameters
  • midiTrack (MIDITrack) – the MIDITrack object to animate from

  • collection (bpy.types.Collection) – the bpy.types.Collection of Blender objects to apply keyframes to

animate()

applys keyframe data to the objects from the MIDITrack

createNoteToObjectWpr()

takes the MIDI file and builds a dictionary with the key being note number, and the value being a ObjectWrapper (which gets its FCurves)

Raises

ValueError – if there is no note number on the object

static drawInstrument(context: bpy.types.Context, col: bpy.types.UILayout, blCol: bpy.types.Collection)

draws the UI for the instrument view

static drawObject(context: bpy.types.Context, col: bpy.types.UILayout, blObj: bpy.types.Object)

draws the UI for the object view

noteToWpr: Dict[int, bpy.types.Object]
preAnimate()

cleans all keyframes before the animation

static properties()

create properties for the instrument

class HiHatInstrument

Bases: MIDIAnimator.src.instruments.Instrument

EXCLUDE_NOTE_NUMBER = True
HANDLE_TYPE = 'ALIGNED'
HI_HAT_VERT_ANIMS = {'end': (KeyframeSeconds(seconds=0.4054, value=1), KeyframeSeconds(seconds=0.8108, value=0)), 'hat-down': (KeyframeSeconds(seconds=-0.10135, value=1), KeyframeSeconds(seconds=0, value=0)), 'hat-pedal': (KeyframeSeconds(seconds=-0.10135, value=1), KeyframeSeconds(seconds=0, value=0)), 'hat-pedal2': (KeyframeSeconds(seconds=-0.28378, value=0), KeyframeSeconds(seconds=-0.111485, value=1), KeyframeSeconds(seconds=0, value=0)), 'hat-up': (KeyframeSeconds(seconds=-0.16216, value=0), KeyframeSeconds(seconds=0, value=1)), 'none': ()}
TRANSITION_MATRIX = {'closed': {'closed': 'none', 'end': 'none', 'open': 'hat-up', 'pedal': 'hat-pedal2'}, 'open': {'closed': 'hat-down', 'end': 'end', 'open': 'none', 'pedal': 'hat-pedal'}, 'pedal': {'closed': 'none', 'end': 'none', 'open': 'hat-up', 'pedal': 'hat-pedal2'}, 'start': {'closed': 'none', 'end': 'none', 'open': 'hat-up', 'pedal': 'hat-pedal2'}}
__init__(midiTrack: midi.MIDITrack, collection: bpy.types.Collection)

Template Class

Parameters
  • midiTrack (MIDITrack) – the MIDITrack object to animate from

  • collection (bpy.types.Collection) – the bpy.types.Collection of Blender objects to apply keyframes to

animate()

this will keyframe the objects in self.objectCollection. this method is only called once

subclass should override this method

static drawInstrument(context: bpy.types.Context, col: bpy.types.UILayout, blCol: bpy.types.Collection)

draws the UI for the instrument view subclass should override this method, this method will not do anything if called

static drawObject(context: bpy.types.Context, col: bpy.types.UILayout, blObj: bpy.types.Object)

draws the UI for the object view subclass should override this method, this method will not do anything if called

evalHiHatVerticalMotion(curNote: midi.MIDINote, nextNote: midi.MIDINote, index: int) -> (curNote: midi.MIDINote, nextNote: midi.MIDINote, index: int)
hiHatNotes: List[MIDIAnimator.data_structures.midi.MIDINote]
preAnimate()

actions to take before the animation starts (cleaning keyframes, setting up objects, etc.) this method is called on class initalization.

subclass should override this method, this method will not do anything if called

static properties()

register properties for this instrument subclass should override this method, this method will not do anything if called

class Instrument

Bases: object

base class for MIDI instruments. These will handle all pre-animation and animation techniques.

EXCLUDE_NOTE_NUMBER = False
__init__(midiTrack: midi.MIDITrack, collection: bpy.types.Collection)

Base class for MIDI instruments. These will handle all pre-animation and animation techniques. You should not instance this class by itself. This class should be inherited.

Parameters
  • midiTrack (MIDITrack) – the MIDITrack object to animate from

  • collection (bpy.types.Collection) – the bpy.types.Collection of Blender objects to apply keyframes to

animate()

this will keyframe the objects in self.objectCollection. this method is only called once

subclass should override this method

collection: bpy.types.Collection
static drawInstrument(context: bpy.types.Context, col: bpy.types.UILayout, blCol: bpy.types.Collection)

draws the UI for the instrument view subclass should override this method, this method will not do anything if called

static drawObject(context: bpy.types.Context, col: bpy.types.UILayout, blObj: bpy.types.Object)

draws the UI for the object view subclass should override this method, this method will not do anything if called

static getFCurves(animationObject: bpy.types.Object, referenceObject: bpy.types.Object) -> (animationObject: bpy.types.Object, referenceObject: bpy.types.Object)

gets the FCurves on a Blender Object.

Parameters
  • animationObject (bpy.types.Object) – the object to keyframe

  • referenceObject (bpy.types.Object) – the object that holds the reference FCurves

Return List[Union[bpy.types.FCurve, ObjectShapeKey]]

returns a list of either bpy.types.FCurve`s and/or an `ObjectShapeKey.

midiTrack: MIDIAnimator.data_structures.midi.MIDITrack
preAnimate()

actions to take before the animation starts (cleaning keyframes, setting up objects, etc.) this method is called on class initalization.

subclass should override this method, this method will not do anything if called

static properties()

register properties for this instrument subclass should override this method, this method will not do anything if called

class InstrumentItem

Bases: object

InstrumentItem(identifier: ‘str’, name: ‘str’, description: ‘str’, cls: ‘Type[Instrument]’)

__init__(identifier: str, name: str, description: str, cls: typing.Type[instruments.Instrument]) -> (identifier: str, name: str, description: str, cls: typing.Type[instruments.Instrument])
cls: Type[MIDIAnimator.src.instruments.Instrument]
description: str
identifier: str
name: str
class Instruments

Bases: enum.Enum

custom = InstrumentItem(identifier='custom', name='Custom', description='Custom Instrument. Must pass the class via `MIDIAnimatorNode.addInstrument()`. See the docs for help.', cls=<class 'MIDIAnimator.src.instruments.Instrument'>)
evaluate = InstrumentItem(identifier='evaluate', name='Evaluate', description='Evaluate thing', cls=<class 'MIDIAnimator.src.instruments.EvaluateInstrument'>)
laser = InstrumentItem(identifier='laser', name='Laser', description='Laser', cls=<class 'MIDIAnimator.src.instruments.LaserInstrument'>)
projectile = InstrumentItem(identifier='projectile', name='Projectile', description='A projectile that is fired from the instrument', cls=<class 'MIDIAnimator.src.instruments.ProjectileInstrument'>)
class LaserInstrument

Bases: MIDIAnimator.src.instruments.Instrument

EXCLUDE_NOTE_NUMBER = True
__init__(midiTrack: midi.MIDITrack, collection: bpy.types.Collection)

Template Class

Parameters
  • midiTrack (MIDITrack) – the MIDITrack object to animate from

  • collection (bpy.types.Collection) – the bpy.types.Collection of Blender objects to apply keyframes to

animate()

this will keyframe the objects in self.objectCollection. this method is only called once

subclass should override this method

static drawInstrument(context: bpy.types.Context, col: bpy.types.UILayout, blCol: bpy.types.Collection)

draws the UI for the instrument view subclass should override this method, this method will not do anything if called

static drawObject(context: bpy.types.Context, col: bpy.types.UILayout, blObj: bpy.types.Object)

draws the UI for the object view subclass should override this method, this method will not do anything if called

preAnimate()

actions to take before the animation starts (cleaning keyframes, setting up objects, etc.) this method is called on class initalization.

subclass should override this method, this method will not do anything if called

static properties()

register properties for this instrument subclass should override this method, this method will not do anything if called

class MIDIAnimatorCollectionProperties

Bases: bpy.types.PropertyGroup

instrument_type: bpy.props.EnumProperty(items=[(item.value.identifier, item.value.name, item.value.description) for item in Instruments], name='Instrument Type', default='evaluate', options=set())
class MIDIAnimatorObjectProperties

Bases: bpy.types.PropertyGroup

note_number: bpy.props.StringProperty(name='Note Number', description='The note number of an object. Can be entered as a integer (MIDI Note Number, e.g. 60) or as a readable note (C3)', default='C3')
class MIDIAnimatorSceneProperties

Bases: bpy.types.PropertyGroup

quick_note_number_list: bpy.props.StringProperty(name='Note Number List', description='A list of note numbers. These will correspond to the objects in the selected collection', default='[]', options=set())
quick_obj_col: bpy.props.PointerProperty(type=bpy.types.Collection, name='Collection')
quick_sort_by_name: bpy.props.BoolProperty(name='Sort by Name', description='This will use a sorted list of objects by name instead of using `name_noteNumber`', default=False, options=set())
class ProjectileInstrument

Bases: MIDIAnimator.src.instruments.Instrument

__init__(midiTrack: midi.MIDITrack, objectCollection: bpy.types.Collection)

Pre-defined animation code that animates a projectile launching from a funnel. :param MIDITrack midiTrack: the MIDITrack object to animate from :param bpy.types.Collection objectCollection: the bpy.types.Collection of Blender objects (funnels) to apply keyframes to. These are the funnel objects (starting position for the projectiles).

animate()

generates projectiles with keyframes and adds them to the projectileCollection

Raises

ValueError – if the animation projectile object on the funnels do not have an reference curve (for the ball path)

createNoteToObjectWpr()

takes the MIDI file and builds a dictionary with the key being note number, and the value being a ObjectWrapper (which gets its FCurves)

Raises

ValueError – if there is no note number on the object

static drawInstrument(context: bpy.types.Context, col: bpy.types.UILayout, blCol: bpy.types.Collection)

draws the UI for the instrument view

static drawObject(context: bpy.types.Context, col: bpy.types.UILayout, blObj: bpy.types.Object)

draws the UI for the object view

static getFCurves(animationObject: bpy.types.Object, referenceObject: bpy.types.Object) -> (animationObject: bpy.types.Object, referenceObject: bpy.types.Object)

gets the FCurves on a Blender Object.

Parameters
  • animationObject (bpy.types.Object) – the object to keyframe

  • referenceObject (bpy.types.Object) – the object that holds the reference FCurves

Return List[Union[bpy.types.FCurve, ObjectShapeKey]]

returns a list of either bpy.types.FCurve`s and/or an `ObjectShapeKey.

noteToWpr: Dict[int, bpy.types.Object]
preAnimate()

deletes all old projectiles & their associated keyframes

static properties()

create properties for the instrument

Module contents