Introduction | Tutorial | Messages | Graphical Interface | Scripts | Reference | Command Index | News |
Scripting Principles
Scripts customize how objects behave and many other things such as send and receive messages and even build an entire graphical view. When the graphical view of a score is visible in the main workspace, the script of the score is in the scripts tab of the property inspector. A script may be few or many lines of code which may include few or many function definitions - almost any type of Javascript code. The Script tab is not only the place to see scripts - it's a syntax highlighting code editor. You can not only edit the script, you can execute all or parts part of of it from within the editor. When you run some script code the effects will immedately happen in the graphics view and usually as response text below the editor.
Note to Geosonix 1 users: Unlike GX1 (and Iannix from which GX1 was forked) GX2 does not have separate script files. The advantage of this is that scripts are always saved with the graphical view in the .score file (structured as XML). A score's scripts will be always and available when a score is opened. This makes it a lot easier for you to organize your work and easier to store or share score files in one neat package.
A great thing about the script editor is that it includes a REPL, or "read-eval-print loop". A REPL is an interactive interactive programming environment where a user can type commands or scripts, instantly evaluate them, and see the result. In GX2 the textual output is directly below below the editor. What's special about a REPL is that you don't have to execute all the code every time. Code in the REPL editor can be executed as a single line of code, arbitrary selected code, a single function, or the entire script. There are buttons just below the REPL for you execute: a single line of code, a function, a block of any selected code, or all the code. There are convenient keyboard shortcuts that make it easy for you run code as you work with it. The button names include reminders of the keyboard shortcuts. The entire script is also auto executed when a score file is loaded but auto execution can be suppressed if needed.
Learning JavaScript
If you wish to learn more Javascript for more advanced scripting there are many books, online tutorials and reference msterials available to help you. Also, feel free to inquire on the GeoSonix forum for further information on the conventions used in writing JavaScript, or for tips in writing GeoSonix scripts.
Here is a link to the complete language reference of QtScript, the version of Javascript used in GeoSonix: QtScript.
GeoSonix Scripting
The GeoSonix scripting language is JavaScript with a additional predefined commands, objects and variables. You can use scripts to automatically build scores as well as to build tools to help you build scores. You can also embed small scripts in message definitions to remap score parameters in real time, or transform them in more complex ways before messages are sent. See the Functions Index for an index to available commands and the Reference for more detail. For more information on embedding JavaScript in messages see JavaScript in Scripts.
Commands are callable like native JavaScript functions. For Example this command sets the display zoom factor to 125 percent:
zoom(125);
This command sets the x, y and z position of the most recently created object to be the values of the variables center_x, center_y and zero, respectively:
setPosition(center_x, center_y, 0);
If the position of an object which is not the most recently created needs to be set the object must be referred to by the ID given when it was created. For example this would set the position of the object with ID=110 to be x=3, y=6, z=5:
setPosition(101, 3, 6, 5);
In general any command that sets of property of an object needs the object's ID to be specified unless the object is the one most recently created in the script. Of course very often properties are set for an object just after it is created, so often the ID can be omitted.
More generally under certain conditions certain parameters can be omitted from scripting commands, and GeoSonix will supply the most appropriate value. Any parameters shown bracketed in the Reference , as in <param>, can be omitted under the conditions described in the documentation.
Other examples:
- Clear the score:
clear();
- Add a trigger and give it an ID based on the value of the script variable
myID:
addTrigger(myID);
- Set the group of the trigger to be "foo":
setGroup("foo");
Note that the ID is omitted because the trigger was just previously created. - Set the position of the trigger to be x=1, y=3, z=0:
setPosition(1, 3, 0);
Again the ID can be omitted because the trigger it the most recently created object. - Set the message for the trigger:
setMessage("1, osc://127.0.0.1:57120/trigger trigger_id trigger_xPos trigger_yPos cursor_id");
Note that the message must be enclosed in quotes because it is passed to the setMessage function as a text string. - Scale the trigger to half its default size:
setSize(0.5);
Remember the «;
» at the end of each line is required by the syntax of JavaScript.
Also, if the characters "//" are encountered in a line in a script, all text from there to the end of the line is ignored. Thus "//" can be used to precede comments that have no effect on the operation of the script. For example see the example script below for a number of uses of "//" to precede comments.
Creating your own functions
Example: This function provides a random number between parameters
min
and max
.
function randomFloat(min, max) {
return Math.random() * (max-min) + min;
}
Creating your own libraries of functions
GeoSonix provides the ability to predefine libraries of frequently used functions
for use in writing scripts. Files of type <name>.js
in the Tools
folder are scanned during GeoSonix startup and variables, classes and function
definitons are made available for use in scripts. Note that if a library file is
edited while GeoSonix is running, GeoSonix must be restarted for the changes to take
effect.
Predefined helper variables and functions
GeoSonix includes a library of helper functions defined in the file "JavaScriptLibrary.js".
The library includes the following functions:
Useful Constants
E
: the mathematical constant eLN2
: the natural logarithm of 2LN10
: the natural logarithm of 10LOG2E
: the base 2 logarithm of eLOG10E
: the logarithm to the base 10 of ePI
: the constant PITWO_PI
: two times PITHIRD_PI
: Pi over 3QUARTER_PI
: Pi over 4HALF_PI
: Pi over 2SQRT1_2
: one over the square root of twoSQRT2
: the square root of two
Math Functions:
abs(x)
: the absolute value of xacos(x)
: the arccosine of xasin(x)
: the arcsine of xatan(x)
: the arctangent of xatan2(x,y)
: the arctangent of x divided by yceil(x)
: the next higher integer above xcos(x)
: cosine of xexp(x)
: e to the power xfloor(x)
: the next lower integer below xlog(x)
: logarithm to the base 2 of xmin(x,y)
: the minimum of x and ymax(x,y)
: the maximum of x and ypow(x,y)
: x raised to the power yround(x)
: x rounded nearest integer, higher or lowersin(x)
: the sine of xsqrt(x)
: the square root of xsq(x)
: x squaredtan(x)
: the tangent of xdegrees(x)
: the radian angle x converted into degreesradians(x)
: the degree angle x converted into radiansrandom(low, high)
: returns a random number between low and highconstrain(x, min, max)
: values of x below min and above max are discardeddist(x1, y1, z1, x2, y2, z2)
: the distance between the points(x1, y1, z1)
and(x2, y2, z2)
Data Scaling Functions
- Scale x to cover the range from low to high, assuming x ranges between 0.0 and
1.0:
range(x, low, high)
: - Scale x to cover the range from low to high, assuming x ranges between 0.0 and
1.0,
withmid
being returned as the value for x=0.5:
rangeMid(x, low, mid, high)
- Scale x to cover the range from
low2
tohigh2
, assuming x ranges betweenlow1
andhigh1
:
map(x, low1, high1, low2, high2)
Curve Plotting
GeoSonix provides the plot()
function to help you plot 2D or 3D
parametric curves based on mathematical functions, either using cartesian or polar
coordinates.
A parametric curve is defined as a function of one independent parameter (usually denoted t) that defines the values of the plotting coordinates as a function of t. For cartesian type plot (i.e. in terms of x, y, x) you must provide functions to define the values of x and y optionally z. as a function of t. For a polar type plot, you must provide functions of t to define r (the radius), theta (the angle) and optionally phi (the angle above or below the plane). In GeoSonix the functions must define the coordinates for values of t ranging from 0.0 to 1.0.
Cartesian Curve Plotting
To plot a curve you need to define in JavaScript the functions fx(t), fY(t), fZ(t) that give each of x, y and z as a function of t, where t runs from 0 to 1. Then you pass those functions as well as the number to give to the first point, to the fuction plot(numberOfPoints, fX, fY, fZ)
For example the following JavaScript code fragment defines x to be 2*t, y to be 3 *t*t, and z to be always zero. Then it passed the three fuction definitions to the plot function, also telling the function plot 100 points. This happens to be the equation for a parabola. A script containing this code is provided in the example function "Learn - Simple Parabola" in the Tutorial Scripts project.
fx = function(t) {return 2*t}; fy = function(t) {return 3*t*t}; fz = function(t) {return 0}; plot(100, fx,fy,fz);
The general form of the plot function is as follows:
plot(nPts, fX, fY, fZ, iStart, x0, y0, z0)
nPts is the number of points to plot; fX, fY and fZ are the functions of x, y and z; iStart is the number of the first point to plot (defaults to 1); and x0, y0, z0 are the coordinates to locate the curve, which defaults to an offset of 0, 0, 0.
Polar Coordinate Curve Plotting
Polar curve plotting is very similar to certesian curve plotting except you provide functions of fTheta(t), fR(t) and fPhi(t), where theta is the clockwise angle from the x axis, r is the distance from the origin, and phi is the angle above or below the x, t plane.
The following code fragment defines fTheta to be two pi times 20 times t; fR to be 3 times t; and fPhi to be always zero. Then it passes them to the function plotPolar requesting that 300 point be plotted. The result is a spiral. A complete script to demonstrate this example is provided as "Learn - Simple Spiral" n the Tutorial Scripts project.
fTheta = function(t) {return TWO_PI * 20 * t}; fR = function(t) {return 3*t}; fPhi = function(t) {return 0}; plotPolar(300, fTheta, fR, fPhi);
The general form of the plot function is as follows:
plotPolar(nPts, fTheta, fR, fPhi, iStart, theta0, r0 ,phi0 )
nPts is the number of points to plot; fTheta, fR and fPhi are the functions of theta, r and phi; iStart is the number of the first point to plot (defaults to 1); and theta0, r0, phi0 are the coordinates to locate the curve, which defaults to an offset of 0, 0, 0.
For an example of the interesting and crazy curves you can easily create with parametric equations, try duplicating (with the context menu) the "Learn - Simple Spiral" example in the GeoSonix Inspector Example scripts. Now open the script with the context menu and change
fPhi = function(t) {return 0}; to fPhi = function(t) {return sin(20*t)};
Execute the script by double clicking on it. Now hold down the Alt key and drag the mouse on the score view to see the wavy 3D curve you created. Start the cursor running to see it undulate over the curve.
Drawing Curves with Straight Line and Cubic Bezier Segments
The GeoSonix setPointAt() function allows scripts to create 2D and 3D paths from a sequence of straight line and curved (cubic Bezier) segments.
Creating a Curve
You start a new curve with:
addCurve(id);
This creates a curve object with the specified ID. The curve has not yet been given any points. The location of a new object defaults to (0,0,0).
The setPointAt Function
The setPointAt function is used to add points to or change points on a curve.
There are several behaviors of the setPointAt() function depending the parameters
passed to it:
- To set the first point of the path:
setPointAt(id, 0, x, y, <z>);
which defines point number 0 as x, y (and optionally z for a 3D path). - To add a straight line segment to the path:
setPointAt(id, pNum, x, y, <z>);
where pNum is the point number which should always be the previous pNum+1. - To change the endpoint of a straight line segment in an existing path:
setPointAt(id, pNum, x, y, <z>);
where pNum is the the number of the point to change. - To add a curved segment and define its curvature:
setPointAt(id, pNum, x, y, <z>, dxStart, dyStart, <dzStart>, dxEnd, dyEnd, <dzEnd>);
where the end point of the segment is x, y and optionally z. The the segment starts tangent to a line from the start point, (the end of the previous segment) to the point(xStart+dxStart, yStart+dyStart, <zStart+dZstart>)
. The segment ends tangent to a line from the end point(x, y, <z>)
to the point(x+dxEnd, y+dyEnd, <z+dyEnd>)
. Note that the start point would be the point(x, y, <z>)
in the previous call to setPointAt. - To change a previously defined curved segment:
setPointAt(id, pNum, x, y, <z>, dxStart, dyStart, <dzStart>, dxEnd, dyEnd, <dzEnd>)
where pNum is the number of a previously defined point and the other parameters are as defined above.
As usual, optional parameters are indicated above by bracketing them between <...>.
All forms of setPointAt
specify the location of the point as x y
<z>. The forms that specify Bezier segments include two other points, cx1 cy1
<cz1> and cx2 cy2 <cz2>, that describe the curvature. The direction of
the curve leaving its start point is tangent to the line from the start point to the
first control point cx1 cy1 <cz1>. The direction of the curve arriving its end
point is tangent to the line from the control point cx2 cy2 <cz2> to the end
point x y <z>.
Example of Creating a Curve With 2D and 3D Segments
The following is the code of the example "Learn - Curve points" that can be found in the Inspector script browser. It creates a path with with five segments and five points. The first segment is a 2D straight line, the next is a 2D Bezier, the next is a 3D straight line, and the fourth segment is a 3D Bezier. Run the example script to see what the curve looks like. To see its shape in 3D hold down the Alt key and drag the mouse on the score area. You can reset the viewing angle by running the "Reset orientation" script in the Tools section of the script browser.
clear(); rotate( 0, -70, -10); center(); zoom(); //Create a curve addCurve(1000); //Point number 0 //Location x0 = -2, y0 = 1 //run("setPointAt current 0 -2 1"); setPointAt("current", 0, -2, 1,0); //Draw a 2D straight segment from point number 0, to //point number 1, which is at (x1,y1) = (-2,3) //run("setPointAt current 1 -2 3"); setPointAt("current", 1, -2, 3,0); //Draw a 2D bezier segment from point number 1, to //point number 2, which is at (x2,y2) = (2,3) //Segment start is tangent to a line from (x1,y1) to (x1+2, y1+2) //Segment end is tangent to a line from (x2,y2) to (x2+0,x2+3) setPointBezierAt("current", 2, 2, 3,0, +2, +2,0, +0,+3,0 ); //Draw a 3D Straight segment from point number 2, to //point number 3, which is at (x3,y3,z3) = (0,2,1) setPointAt("current", 3, 0,2, 1); //Draw a 3D bezier segment from point number 3, to //point number 4, which is at (x4,y4,z4) = (-2,-1,0) //Start tangent to a line from (x3,y3,z3) to (x3+0,y3-1,z3+2) //End tangent to a line from (x4,y4,z4) to (x4+4,x4+0,z4+0) run("setPointAt current 4 -2 -1 0 +0 -1 +2 +4 +0 +0"); //Add a cursor on the curve run("add cursor 1"); run("setCurve current lastCurve"); run("setSpeed current auto 10");
External Control of Geosonix using MIDI
As discussed above, any script may contain an onCreate function to define a score. Most of the example scripts contain only an onCreate function to build the score.
However, a script may also contain a function called onMessage(protocol, host, port, destination, param) that is called each time Geosonix receives an external message (midi, osc, etc.)
In the onMessage function, provide JavaScript code that maps message parameters to Geosonix commands.