With
version 7.10, Terranim8or supports internal ASL scripts for the following
controller types: "visibility", "scale",
"position", "orientation", "color",
"fov", "active". The implementation of ASL keeps the
original syntax, but is limited to features used for controller scripts.
Variable and function names begin with a letter or an underscore character ‘_’ followed by any number of letters, digits and underscores. Upper case letters are distinct from lower case so that ‘Anim8or’ and ‘anim8or’ are unique names. In addition, user declared variables can begin with any alphanumeric character, or underscore ‘_’, but must be preceded by a dollar sign ‘$’ as in ‘$Anim8or’.
The types supported by Terranim8or’s ASL interpreter are:
A float is a 32 bit floating point value. A float constant is a number with either a decimal point or an exponent or both:
1.234
.7 10. 1e10
3.141e-4
An int is a 32-bit signed integer. Constants may be decimal or hexadecimal:
1234
1 0x1234 0xface
The type point2 is a vector of two floating point values. They are similar to the C struct:
typedef struct {
float x, y;
} point2;
Individual floating point values are referenced using member notation:
$myvar.x $myvar.y
Values are defined as a parenthesized list of two integer or floating point values:
(1.0, 7) (0, 0) (3.142,
1.732) ($ii, 7*$p)
Similarly the type point3 is a vector of three floating point values. They are similar to the C struct:
typedef struct {
float x, y, z;
} point3;
Individual floating point values are referenced using member notation:
$myvar.x $myvar.y $myvar.z
Values are defined as a parenthesized list of three integer or floating point values:
(1.0, 7, 9.999) (0, 0, 0) (3.142,
1.732, -1.414)
($loc.x, $loc.y*1.5, 0.0)
The type quaternion is a vector of four floating point values. They are used to represents a rotation or orientation in Anim8or.
typedef struct {
float x, y, z, w;
} quaternion;
Individual floating point values are referenced using member notation:
$q0.x
$q0.y $q0.z $q0.w
Quaternion values may be constructed from 4 scalar values:
(1.0, 7, 9.999, -1e8) (0, 0, 0, 0)
There are several predefined constants in ASL. General constants are listed below. Other values that are only meaningful as parameters to certain functions are listed later with those functions.
int true = 1
int false = 0
float PI = 3.1415926
Variables are declared similar to how they are in C. However there are some differences:
- Variables cannot be initialized in the declaration,
- Declaration don’t have to be grouped at the first. They can appear after executable statements,
- There are no scopes. A variable can
be used anywhere after it is declared.
int $i, $count;
float $size;
point3 $position;
ASL supports many of the operators fond in C..
- negation: int, float, point2, point3,
quaternion
! not: int, float
+ addition: int, float, point2, point3
- subtraction: int, float, point2,
point3
* multiplication: int, float,
point2/3*float,
float*point2/3,
quaternion*float
float*quaternion
/ division: int, float
% mod: int
< == <= comparisons: int,
float, string;
> != >= returns int with
value of 1 or 0
&& logical and: int,
float; returns int 1 if both
operands are non-zero
|| logical or: int, float;
returns int 1 if either
operand is non-zero
An expression is the simplest statement. Normally an expression statement will call a function that has some kind of a side effect such as setting an Objects location. Expression statements that don’t have side effects such as $i + 1 are NOT allowed. The same stands for Anim8or, though its ASL specification states the opposite!
An assignment statement sets the value of a variable to value of an expression. Numeric types simply copy the value of the expression to the variable:
int, float, point2, point3, quaternion,.
A compound statement is a list of zero or more statements enclosed in curly braces “{}”. They may be used anywhere a statement may be used:
{
$loc.x = sqrt($val);
$ii = $ii + 1;
}
An if statement evaluates a control expression. If the value is non-zero then the <then-statement> is executed next otherwisre the <else-statement> is executed if it is present. The syntax is the same as C’s:
if (<expr>)
<then-statement>
else
<else-statement>
As in C the “else” statement is optional:
if (<expr>)
<then-statement>
A while statement evaluates a control expression. If the value of <expr> is non-zero then it executes its subordinate <statement> and reevaluates the control expression. This continues until the expression evaluates to zero. The syntax is the same as in C:
while (<expr>)
<statement>
A for statement evaluates several control expressions and then executes its subordinate statement a number of times based on those values. For statements in ASL are not the same as those in C. The two general forms are:
for <var> = <init> to
<limit> do
<statement>
for <var> = <init> to
<limit step <step> do
<statement>
<var> can be either an int or float. The value of <init> is assigned to <var> and the values of <limit> and <step> expressions are cast to the type of <var> and saved. If <step> is not present a value of 1 or 1.0 is used. Then the value of <var> is compared to <limit>. If <step> is greater than or equal to zero and <var> is less than or equal to <limit>, or if <step> is less than zero and <var> is greater than or equal to <limit> the <statement> is executed after which <step> is added to <var>. This procedure repeats until the comparison fails.
There are predefined variables in ASL.
float time;
The current Scene time in seconds is stored in time. It is computed for 24 frames per second. You cannot set the value of time by assigning to it. It is read only.
int frame;
The current Scene frame number is stored in frame. You cannot set the value of frame by assigning to it. It is read only.
The following integer functions are supported:
int abs(int val); // absolute value
int min(int a, int b); //
minimum
int max(int a, int b); //
maximum
int clamp(int val, int min, int max);
// clamp val to min <= val <= max
The following floating point functions are supported:
float abs(float
val); // absolute value
float min(float a, float b); //
minimum
float max(float a, float b); //
maximum
float clamp(float val, float min, float max);
// clamp val to min <= val <= max
float floor(float val); // floor function
float ceil(float val); //
ceiling function
float fract(float val); // val
– floor(val)
float cos(float
val); // cosine
float sin(float val); // sine
float log(float val); //
natural logarithm
float exp(float val); // exp
float asin(float val); // arc
sine
float acos(float val); // arc
cosine
float sqrt(float val); //
square root
float tan(float val); //
tangent
float atan(float val); // arc
tangent
float log10(float val); //
logarithm base 10
float cosh(float val); //
hyperbolic cosine
float sinh(float val); //
hyperbolic sine
float tanh(float val); //
hyperbolic tangent
float pow(float val,
float pow); // val raised to power pow
float atan2(float a, float b); // arc
tangent of (a/b)
float lrp(float val,
float a, float b);
// linear interpolate between a
and b:
// if (val < 0.0) return a;
// else if (val > 1.0) return b;
// else return a*(1.0 – val) + b*val;
The following vector functions are supported:
float length(point2
val); // length of vector
float length(point3 val); //
length of vector
float length(quaternion val); //
length of quaternion
point2 normalize(point2 val); //
convert to unit length
point3 normalize(point3 val); //
convert to unit length
quaternion normalize(quaternion val); // to unit length
float dot(point3 a, point3 b); // dot
product of a and b
point3 cross(point3 a, point3 b); // cross product of a, b
The following special functions are supported:
quaternion
RPYtoQuaternion(float roll, float pitch, float yaw)
// Compute the primary unit
quaternion defined by
// applying a roll , then a pitch,
and finally a yaw
// specified in degrees.
The following functions support pseudo random number sequences
int irand(void); // 16b random value 0 to 65535
float frand(void); // float
random value -1.0 to 1.0
int randseed(int); // set new seed
and return current one
A useful property of Controller scripts is that they can refer to the value of other Controllers in Elements in the same Scene with the GetAttribute() functions:
int GetAttributeInt(string
elName, string ctrlName);
<ctrlName> := “visibility” | “active”
float GetAttributeFloat(string elName, string ctrlName);
<ctrlName> := “scale” | “fov”
point3 GetAttributePoint3(string elName, string ctrlName);
<ctrlName> := “position” | “color”
quaternion GetAttributeQuaternion(string elName,
string
ctrlName);
<ctrlName> := “orientation”
The type of the controller must match the type in the name of the GetAttribute() function. The parameters must be string constants, not variables or computed values.
Calling a GetAttribute() function in a script introduces a dependency on the order in which controller values must be computed. This is similar to what happens when one Element is set to face another element. You have to be careful to not create a circular dependency or Terranim8or won’t be able to decide what values to use. Terranim8or will warn you when this happens, however.