Recording GML

July 09, 2011

Recording GML basics

To record GML, you can use a GmlRecorder object.
The simplest constructor of this object takes a single argument which is a 3D vector giving information about the drawing surface.
For instance, if you’re drawing on a flat screen which size is 800×600, creating a new GmlRecorder will look like this:

import gml4u.brushes.*;
import gml4u.recording.*;
import gml4u.test.*;
import gml4u.utils.*;
import gml4u.drawing.*;
import gml4u.events.*;
import gml4u.model.*;

// Declare a GML recorder object
GmlRecorder recorder;

void setup() {
	Vec3D screen = new Vec3D(800, 600, 0);
	recorder = new GmlRecorder(screen);
}

The recorder has 3 different methods that you have to use to record a stroke.
When the drawing of a stroke starts, you have to call the beginStroke method which takes a single argument being a unique ID that you will use when adding points and at the end of the stroke.
Having an ID allows you to draw several strokes in the meantime when needed without messing up points and strokes

recorder.beginStroke(666);

When adding points to a stroke, you need to use a minim of two arguments.
First argument is the unique ID we mentionned above.
Second argument is the coordinates of the point, which have to fit within 0 and 1.
Each value between 0 and 1 has to be the ratio of the point’s coordinates on each axis.
If you screen vector is 800x600x100 and the current coordinates of your point are 400,400, 25, then your point coordinates will be 0.5, 0.66, 0.25

recorder.addPoint(666, new Vec3D(0.5, 0.66, 0.25));

When the drawing of the stroke ends, just call this method with the ID

recorder.endStroke(666);

The recorder handles a Gml object and a temporary stroke list in parallel.
When a stroke ends, it is moved from the temporary list to the Gml object.

Alternatively, you can use the endStrokes() method which will stop all recordings in one shot:

recorder.endStrokes();

Advanced beginStroke

If you intend to work with several layers, you can call the beginStroke method with an extra parameter to store this info along with the stroke information.

recorder.beginStroke(666, 1);

Note: there is a third parameter that you can use which will be covered when we’ll talk about brushes later on.

Advanced GmlPoints

The recorder also has addPoint methods which will accept more complex GmlPoint
addPoint(int sessionID, Vec3D v, final float time);
Takes a 3rd argument to store time information

addPoint(int sessionID, Vec3D v, final float time, final float pressure, final Vec3D rotation, final Vec3D direction);
Takes even more arguments

  • Time
  • Pressure: think spray can of flow pen
  • Rotation: orientation of the tool (ie: spray can)
  • Direction: direction of the tool (between two points)

The recorder also includes several useful methods:


recorder.clear()
// Removes all strokes, the Gml ones and the temporary ones.


recorder.removeLastStroke(layer)
// Removes the last stroke from the given layer


recorder.getStrokes()
// Retrieves a list of GmlStrokes (both Gml strokes and temporary strokes)


recorder.getGml()
// Returns a copy of the Gml object used by the recorder


recorder.setGml(gml);
// Will replace the recorder's gml file with this one.
// Can be used to continue drawing from an existing Gml file.

Optimizing recording

Your recording device may send way more points than needed to render a stroke correctly.
If you want to limit the number of points, you may add limitations to the GmlRecorder by adding two extra arguments:


float minimumStrokeLength = 0.01f; // Default value when omitted
float minimumPointsDistance = 0.001f; // Default value when omitted
recorder = new GmlRecorder(screen, minimumStrokeLength, minimumPointsDistance);

By doing so:
When a stroke ends, it will only be recorded in the Gml object if longer than the value you defined.
When adding a point to a stroke, it will only be added if the distance between this point and the last point of the stroke is greater than the value you defined.

These values can be adjusted afterward by calling these two methods with a float argument
recorder.setMinStrokeLength();
recorder.setMinPointsDistance();

Recording with devices

It is handy to use a protocol like OSC or TUIO for recording purpose.
Once you have your recorder understanding such protocol, it means that you can interface with any device or installation which can send OSC or TUIO messages.
It also means that you’ll be able to record several strokes in the meantime.

You can check the two examples provided with the library

  • GmlOscRecorder
  • GmlTuioRecorder

| Tags: , | More: Tutorials, Updates