|
Now that we have seen a very simple script in action, we need to look at the our toolchest for writing scripts. The next set of tools we will consider are the basic building blocks for programming a script, and will be used in every non-tribial scipt you write. 3.1. Comments
Commmenting your scripts is a good idea, and will help when you update and modify the script, or when you adapt parts of it into other scripts. Unless the meaning is obvious, you should add comments:
• at the start of the script to explain the purpose of the script • before every global variable to describe what it holds • before every global function to describe what it does • sprinked through your script wherever the code solves a problem that took you more than a few minutes to figure out. LSL uses Java/C++ style single line comments.
// This script toggles a the rotation of an object // g_is_rotating stores the current state of the rotation. TRUE is // rotating, FALSE otherwise. integer g_is_rotating = FALSE; default { // toggle state during the touch handler touch(integer num) { if(g_is_rotating) { // turn off rotation llTargetOmega(<0,0,1%gt;, 0, 0); g_is_rotating = FALSE; } else { // rotate around the positive z axis - up. llTargetOmega(<0,0,1>, 4, 1); g_is_rotating = TRUE; } } }
3.2. Arithmetic Operations
Most of the common arithmetic operations are supported in lsl, and follow the C/Java syntax.
3.2.1. Assignment
The most common arithmetic operation is assignment, denoted with the ’=’ sign. Loosely translated, it means, take what you find on the right hand side of the equal sign and assign it to the left hand side. Any expression that evaluates to a basic type can be used as the right hand side of an assignment, but the left hand side must be a normal variable.
All basic types support assignment ’=’, equality ’==’ and inequality ’!=’ operators.
// variables to hold a information about the target key g_target; vector g_target_postion; float g_target_distance; // function that demonstrates assignment set_globals(key target, vector pos) { g_target = target; g_target_position = pos; // assignment from the return value of a function vector my_pos = llGetPos(); g_target_distance = llVecDist(g_target_position, my_pos); }
3.2.2. Binary Arithmetic Operators
Binary arithmetic operators behave like a funtion call that accepts two parameters of the same type, and then return that type; however, the syntax is slightly different.
Table 3-1. Binary Arithmetic Operators | Operator | Meaning | | + | Addition | | - | Subtraction | | * | Multiplication | | / | Division | | % | Modulo (remainder) | | ^ | Exclusive OR | Where noted, each type may have a special interpretation of a binary arithmetic operator. See the lsl types section for more details.
3.2.3. Boolean Operators Table 3-2. Boolean Operators
| Operator | Meaning | | < | Operator returns TRUE if the left hand side is less than the right hand side. | | > | Operator returns TRUE if the left hand side is greater than the right hand side. | | <= | Operator returns TRUE if the left hand side is less than or equal to the right hand sid. | | >= | Operator returns TRUE if the left hand side than or equal to the right hand sid. | | && | Operator returns TRUE if the left hand side and right hand side are both true. | | || | Operator returns TRUE if either the left hand or right hand side are true. | | ! | Unary operator returns the logical negation of the expression to the right. | 3.2.4. Bitwise Operators
Table 3-3. Bitwise Operators | Operator | Meaning | | & | Returns the bitwise and of the left and right hand side. | | | | Returns the bitwise or of the left and right hand side. | | ~ | Unary operator returns the bitwise complement of the expression to the right. | 3.3. Types
Variables, return values, and parameters have type information. LSL provides a small set of basic types that are used througout the language.
LSL Types
integer A signed, 32-bit integer value with valid range from -2147483648 to 2147483647. float An IEEE 32-bit floating point value with values ranging from 1.175494351E-38 to 3.402823466E+38.
key A unique identifier that can be used to reference objects and agents in Second Life.
vector 3 floats that are used together as a single item. A vector can be used to represent a 3 dimensional position, direction, velocity, force, impulse, or a color. Each component can be accessed via ’.x’, ’.y’, and ’.z’.
Table 3-4. Vector Arithmetic Operators | Operator | Meaning | | + | Add two vectors together | | - | Subract one vector from another | | * | Vector dot product | | % | Vector dot product | rotation 4 floats that are used together as a single item to represent a roation. This data is interpreted as a quaternion.
Each compnent can be accessed via ’.x’, ’.y’, ’.z’, and ’.w’. Table 3-5. Rotation Arithmetic Operators | Operator | Meaning | | + | Add two rotations together | | - | Subract one rotation from another | | * | Rotate the first rotation by the second | | / | Rotate the first rotation by the inverse of the second | list A heterogeneous list of the other data types. Lista are created via comma separated values of the other data
types enclosed by ’[’ and ’]’. string StringVar = "Hello, Carbon Unit"; list MyList = [ 1234, ZERO_ROTATION, StringVar ]; Yields the list: [ 1234, <0,0,0,1>, "Hello, Carbon Unit" ] Lists can be combined with other lists. For example: MyList = 3.14159 + MyList; Yields the list: [ 3.14159, 1234, <0,0,0,1>, "Hello, Carbon Unit" ] And similarly, MyList = MyList + MyList; Yields: [ 3.14159, 1234, <0,0,0,1>, "Hello, Carbon Unit", 3.14159, 1234, <0,0,0,1>, "Hello, Carbon Unit" ] Library functions exist used to copy data from lists, sort lists, copy/remove sublists. 3.3.1. Type Conversion Type conversion can either occur implicitly or explicitly. Explicit type casts are accomplished using C syntax:
float foo_float = 1.0; integer foo_int = (integer)foo_float; 3.3.1.1. Implicit Casting LSL only supports two implicit type casts: integer to float and string to key. Thus, any place you see a float specified you can supply an integer, and any place you see a key specified, you can supply a string.
3.3.1.2. Explicit Casting
LSL supports the following explicit casts: • Integer to String • Float to Integer • Float to String • Vector to String • Rotation to String Chapter 3. Basics • Integer to List • Float to List • Key to List • String to List • Vector to List • Rotation to List • String to Integer • String to Float • String to Vector • String to Rotation 3.4. Global Functions Global functions are also declared much like Java/C, with the exception that no ’void’ return value exists.
Instead, if no return value is needed, just don?t specify one:
make_physical_and_spin(vector torque) { // double the torque vector double_torque = 2.0*torque; llSetState(STATUS_PHYSICS, TRUE); llApplyTorque(double_torque); } 3.5. Global Variables
Global variables and functions are accessible from anywhere in the file. Global variables are declared much like Java or C, although only one declaration may be made per line:
vector gStartPosition;
Global variables may also be initialized if desired, although uninitialized global and local variables are initialized to legal zero values:
vector gStartPosition = <10.0,10.0,10.0>
3.6. Local Variables Local variables are scoped below their declaration within the block of code they are declared in and may be declared within any block of code. Thus the following code is legal and will work like C:
integer test_function() { // Test vector that we can use anywhere in the function vector test = <1,2,3>; integer j; for (j = 0; j < 10; j++) { // This vector is a different variable than the one declared above // This IS NOT good coding practice vector test = <j, j, j>; } // this test fails if (test == <9,9,9>) { // never reached } }
|