Common Commands

This section describes the commands available to both Layout and Modeler LScripts. These include commands and functions for math, variable conversions, string manipulations, system information, file input and output. The interface controls are discussed in the chapter that follows.

UDFs

Default value assignments can now be made on function argument parameters (much like C++).
These default value assignments will trigger if the value passed to the function in that position is 'nil'. Consider the following example:
main
testudf(,"Bob",,15.0,); }

testudf: p1 = -3.4,p2,p3 = "pretty",p4,p5
{
info(p1," ",p2," ",p3," ",p4," ",p5);> }

This example script would print:

-3.4 Bob pretty 15 (nil)

If you wish to provide for an actual 'nil' value in your function's processing, then you must either avoid using defaultvalue assignments for that parameter, or use 'nil' as the default value.

main
{
testudf(,"Bob",,15.0,);
}

testudf: p1,p2,p3 = "pretty",p4,p5
{
if(p1) // if 'p1' == nil, nothing will print
info(p1," ",p2," ",p3," ",p4," ",p5);
}

General Commands

effectedby
This function is used to inform Layout about the objects in the current scene to which your script has dependencies. This function is LScript's interface to the plug-in API's useItems system.

effectedby() can be called at anytime in your script, and accepts one or more character strings that represent the names of objects in the current scene whose parameters effect the script. These names can also be passed to effectedby() through an array reference.

This function has no actual impact on the execution of your script. Rather, it has impact on *when* your script is executed. Layout will use the information provided by effectedby() to determine when your script (i.e., the LScript plug-in) should be executed in response to some change in the indicated objects.

obj;

create
{
    obj = getfirstitem("MasterNull");

    // make sure process() is called
    // whenever "MasterNull" changes

    if(obj)
        effectedby("MasterNull");
}

process: ma, frame, time
{
    if(!obj) return;

    v = obj.param(POSITION,time);
    ma.set(POSITION,v + 1);

    v = obj.param(ROTATION,time);
    ma.set(ROTATION,v);

    v = obj.param(SCALING,time);
    ma.set(SCALING,v);
}
The effectedby() function can also be called in your options() function in response to some change to the operation of the script made by the user. For instance, you can allow the user to specify which object(s) will effect the script:

obj;

create
{
    obj = nil;
}

process: ma, frame, time
{
    . . .
}

options
{
    if(!reqbegin("Parent"))
        return;

    c1 = ctlallitems("Select master object",obj);

    if(reqpost())
    {
        object = getvalue(c1);

        if(object && (object.name != obj.name))
        {
            obj = object;
            effectedby(obj.name); // new dependencies!
        }
    }

    reqend();
}

spawn
The spawn command begins executing an external process. Normally, the external process runs entirely within this command. In this case, the spawn() command returns the execution result code for the specified process.

However, if the @asyncspawn pragma directive was declared in the script, then the spawn() command returns, upon success, the process id of the external process it launched. This process id is required as an argument to the other process control functions wait() and terminate().

// launch ScreamerNet II in parallel
snID = spawn(“lwsn -2 “,
getenv(“TMP”),”\\snii.job “,
getenv(“TMP”),”\\snii.rpl”);
if(snID == nil)
{
    error(“Cannot create ScreamerNet process”);

system

systemex
The system and systemex commands begins executing an external process. The external process runs entirely within this command. In this case, the spawn() command returns the execution result code for the specified process.

wait
The wait command is provided as a synchronization function for spawn(). When it is passed a process id (which is returned by spawn(), wait halts script execution until the specified external process terminates, and then returns the exit status of that process.

terminate
The terminate() command is another function in the process control suite of commands; terminate() causes Windows to terminate the specified process id.

terminate(snID); // shut down ScreamerNet

sleep
The sleep() command allows a script to pause for a specified number of milliseconds, and it releases the script’s (and Modeler’s) Windows time slice until the sleep time has expired. For the purposes of conversion, 1000 milliseconds is equal to one second.

sleep(1000); // sleep for 1 second

debug
The debug() command takes no arguments, and, when it is encountered, it establishes a session with the LSIDE LScript Debugger. This debugger is now internalized within the LightWave code, no external application is needed.

dump
dump() is a debug function; it lets the script developer dump all known internal script variables and their values to a specified text file. That text file, if it already exists, gets appended each time this function is called.

dump(“/myscript.var”);

The dump() command is not supported in the run-time environment. Scripts that contain this command will not compile successfully with the Script Compiler.

visitnodes(<objectagent>,<processUDF>)
This function attempts to simplify the process of iterating down through object parenting hierarchies.The function requires two arguments. The first argument is an Object Agent reference for an object type capable of containing children--Mesh, Light, Camera or Bone.

The second argument is a character string that identifies a UDF in the script that will be called by LScript for each child object found in the hierarchy. The UDF must accept two arguments, the parent Object Agent and the child Object Agent. Be aware that multiple calls may be made with the same parent identity if that parent manages more than one child.

generic
{
visitnodes(Mesh("MasterObject"),"process_node");
}

process_node: parent, child
{
info(parent.name," -> ",child.name);
}



System

time
The time() function returns, as multiple items, the hour, minute, second, and tick values for the current time. If a time value is provided as an argument (defined as the number of seconds that have elapsed since January 1st, 1900), then return values are relative to that time index. The hour is in 24-hour military form, so values range from 0 to 23. The minutes in seconds range from 0 to 59. The ‘tick’ value is the number of seconds that that have elapsed since January 1, 1900.

(h,m,s,t) = time();

date
The date() function returns, as multiple items, the day of the month, month, four-digit year, day of the week, and the day of the year (i.e., julian value), string value for the current month, and string value for the current day of the week. If a time index value is provided as an argument (defined as the number of seconds that have elapsed since January 1, 1900), then the date() return values are relative to that time index.

The day of the week begins at Sunday==1, and the day of the year runs from 1 to 365.

(d,m,y,w,j,sm,sw) = date();

getenv
Just like its C counterpart, the getenv function accepts a string argument—which is presumed to be an environment variable—and will return the current value of the variable. If no variable exists in the environment with the provided name, getenv() will return nil.

tempfile = getenv(“TMP”) + “/33j4ks.$$$”;

lscriptVersion
lscriptVersion() returns information about the version of the LScript system that is executing the script. It returns four elements in this order: a string representation of the LScript version (identical to that displayed by LScript in the title bar of the script-select file dialog); the major component of the version as an integer; the minor component of the version as an integer; the patch level of the version as an integer.

hostVersion
The hostVersion() function returns the host application’s version number as a floating-point value. It contains the major and minor values of the version—for example, 6.1.

hostBuild
The hostBuild() function returns the sub-version build value of the application as an integer. Because LightWave build numbers are linear and are never reset, this value is a more accurate means of determining application feature sets than the version number.

licenseId
The licenseld() function returns your dongle identification number.

dongleNum = licenseId();

platform
The LScript pre-processor has a testable condition called platform. This value is one of INTEL, ALPHA, SGI, MACINTOSH, MACUB (for LW >9.2), LINUX or SUN. It can be tested with either the ‘==’ or ‘!=’ equality operators.

@if platform == ALPHA
    info(“Alpha!”);
@end
@if platform == INTEL
    info(“Intel!”);
@end

platform
The platform() function returns the same values as the testable conditioned discussed above and can be used at run-time to determine the machine and operating system type.

x = platform();

runningUnder
The runningUnder function returns one of the following LAYOUT, MODELER, or SCREAMERNET).

app = runningUnder();

cloned
The new mechanism will correctly activate the source script on the target item. It will also copy certain global values from the original script into the corresponding values in the new activation. Due to their complexity, certain data types, such as Binary Blocks and internal Object Agents, are not duplicated in the target script.

The copy of values occurs only after the script is activated on the duplicated object, and its create() function has successfully completed. This may have some odd effects on your script, most obviously where the setdesc() function is concerned. If you call setdesc() in your create() function, the duplicated script may end up displaying values to the user that are not valid after the value copy has completed.

In order to combat this problem, LScript will look for a pre-defined function called cloned() in the duplicated script. This function, if it exists, will be invoked by LScript immediately following the duplication of global values from the original script. The cloned() function takes no aguments, and should return no values.

Activities involving data changes within your script should be centralized within this function. For instance, you could place a single call to setdesc() in this function, and then invoke the function whereever appropriate from within your script:

...
create
{
...
cloned(); // after initial operational values are established
}
cloned
{
// data values have changed...
setdesc("...");
}

options
{
...
cloned(); // after user has changed operational values
}
...