Sinewav3 Plugin API

A Sinewav3 Plugin consists of:

  • At least one of the functions: setup and render
  • An optional function: destroy
  • Any number of optional setting groups

All of the above are created in the Sinewav3 Plugin editor.

Settings are defined and grouped by the developer, then exposed to the user for modification in the Project editor, both in list mode and while the visualizer runs. Consequently, it is important to watch for changes to Setting values not only in your Plugin's setup() function, but also in render().

Each function belonging to a Plugin has access to:

  • Its own setting values
  • Its own scene objects
  • Its own stored values
  • The modulation sources available to all plugins

All of this available via the VisualizerContext, passed to each Plugin function as the argument named context.

VisualizerContext

The Plugin developer's primary interface to the Sinewav3 visualizer

It solves several problems, including:

1) Your Plugin's setup(), render(), and destroy() methods are just anonymous functions that get invoked when required. They need a way to remember things.

2) The World that your Plugin is a part of may have any number of other Plugins actively manipulating objects in the Scene. You don't want them inadvertently affecting your objects though. Or vice versa.

3) Since the user may enter and exit multiple projects during a Sinewav3 session, we must be wary of memory leaks that occur when things aren't properly destroyed.

For these reasons, rather than permit working directly with the THREE.js Scene, the VisualizerContext acts as a mediator between your Plugin's code and the World it is a part of.

The benefits are:

You can store values and functions and make them available across function invocations, access and modify your own Scene objects, and if you register each Geometry, Material, or Object3D you create in setup() or render(), you can later recall them from the VisualizerContext by name. As a bonus, those registered items will be automatically disposed of by the visualizer, in most cases obviating the need for a destroy() function in your Plugin.

VisualizerContext
Instance Members
plugin
modulators
memory
scene_objects
dimension
getRenderer
getCamera()
getAmbient()
addToScene(object)
removeFromScene(object)
registerMaterial(name, material)
getMaterial(name)
registerTexture(name, texture)
getTexture(name)
registerGeometry(name, geometry)
getGeometry(name)
registerObject3D(name, object)
getObject3D(name)
registerFont(name, font)
getFont(name)
addMaterialToObject3D(object, material)
setSceneBackground(background)

PluginContext

The Plugin developer's interface to the Plugin's settings.

A reference to the PluginContext is available to all Plugins via the VisualizerContext as context.plugins.

Inside any of the Plugin's functions, you can read the settings and take appropriate action in response.

PluginContext
Instance Members
getSettingValue(group_name, setting_name)

ModulatorContext

The Plugin developer's interface to the modulation sources.

A reference to the ModulatorContext is available to all Plugins in a given world via the VisualizerContext as context.modulators.

Modulator values change over time and can be used to modulate various aspects of a Plugin's output.

For instance, rather than decide that an object's scale will be modulated by the audio's bass level as you might in a demo, in Sinewav3, you instead expose a Setting of type Modulator in your Plugin, allowing the user to decide whether to modulate that object's scale with the audio bass level or perhaps the overall volume, if that's more effective based on the audio track they are using.

Available modulation sources that naturally change include the audio bands and channels as well as the frame number.

Another modulation option is customized easers. By specifying the type of ease, beginning value, ending value, number of steps, and optional looping type, you get a customized closure that you can store and then call during each render invocation. An easer returns the next step between the start and end values each time it is called.

For instance, say you have a particle system that emits sparks which get bright (slowly, faster, then slowing again), then dim quickly before disappearing. Create two easers for each spark. Control the 'flash' of brightness using an 'exponential in/out' ease with no loop. When that easer returns the maximum value, remove it and dim the spark with the other easer - a non-looping 'ease out quint' going from the maximum value back to the minimum. When that easer returns the maximum value, you remove the particle from the scene and ditch its second easer.

See http://easings.net/ for examples of the supported types.

ModulatorContext
Instance Members
getModulatorValue(name)
getCurrentFrame()
getEaser(ease_type, start_val, end_val, steps, loop_type)