# LScript v2.5 Release Notes

## New Features

      The Image Filter LScript architecture provides a new mechanism for accessing and
      modifying image pixel data.  The ImageFilter Object Agent is now passed to the process()
      function of an Image Filter script if it is the only argument defined.

            process: ifo
            {
                ...
            }

      The original process() interface continues to function within LScript v2.5 in order
      to support older scripts.  However, new scripts should be designed to employ this
      new interface mechanism.

      The following data members are exported by the ImageFilter Object Agent:

            width                                        (READ-ONLY)
                    the width, in pixels, of the current buffer

            height                                       (READ-ONLY)
                    the height, in pixels, of the current buffer

            frame                                        (READ-ONLY)
                    the current frame number for the main image

            start                                        (READ-ONLY)
                    the render start time for the main image

            end                                          (READ-ONLY)
                    the render end time for the main image

            red[]
                    the red-pixel buffer values for the image in
                    floating-point format.  indexing is in
                    [column,row] form.

            green[]
                    the green-pixel buffer values for the image in
                    floating-point format.  indexing is in
                    [column,row] form.

            blue[]
                    the blue-pixel buffer values for the image in
                    floating-point format.  indexing is in
                    [column,row] form.

            alpha[]
                    the alpha-pixel buffer values for the image in
                    floating-point format.  indexing is in
                    [column,row] form.

            special[]                                    (READ-ONLY)
                    the special buffer values. indexing is in
                    [column,row] form.

            luminous[]                                   (READ-ONLY)
                    the luminous buffer values. indexing is in
                    [column,row] form.

            diffuse[]                                    (READ-ONLY)
                    the diffuse buffer values. indexing is in
                    [column,row] form.

            specular[]                                   (READ-ONLY)
                    the specular buffer values. indexing is in
                    [column,row] form.

            mirror[]                                     (READ-ONLY)
                    the mirror buffer values. indexing is in
                    [column,row] form.

            trans[]                                      (READ-ONLY)
                    the trans buffer values. indexing is in
                    [column,row] form.

            rawred[]                                     (READ-ONLY)
                    the rawred buffer values. indexing is in
                    [column,row] form.

            rawgreen[]                                   (READ-ONLY)
                    the rawgreen buffer values. indexing is in
                    [column,row] form.

            rawblue[]                                    (READ-ONLY)
                    the rawblue buffer values. indexing is in
                    [column,row] form.

            shading[]                                    (READ-ONLY)
                    the shading buffer values. indexing is in
                    [column,row] form.

            shadow[]                                     (READ-ONLY)
                    the shadow buffer values. indexing is in
                    [column,row] form.

            geometry[]                                   (READ-ONLY)
                    the geometry buffer values. indexing is in
                    [column,row] form.

            depth[]                                      (READ-ONLY)
                    the depth buffer values. indexing is in
                    [column,row] form.

            diffshade[]                                  (READ-ONLY)
                    the diffshade buffer values. indexing is in
                    [column,row] form.

            specshade[]                                  (READ-ONLY)
                    the specshade buffer values. indexing is in
                    [column,row] form.

            motionx[]                                    (READ-ONLY)
                    the motionx buffer values. indexing is in
                    [column,row] form.

            motiony[]                                    (READ-ONLY)
                    the motiony buffer values. indexing is in
                    [column,row] form.

            reflectred[]                                 (READ-ONLY)
                    the reflectred buffer values. indexing is in
                    [column,row] form.

            reflectgreen[]                               (READ-ONLY)
                    the reflectgreen buffer values. indexing is in
                    [column,row] form.

            reflectblue[]                                (READ-ONLY)
                    the reflectblue buffer values. indexing is in
                    [column,row] form.

      The following methods are also available:

            copy(<left>,<top>,<right>,<bottom>)

                    creates a new image buffer using the image data contained
                    within the specified area (inclusive) in the current buffer.
                    a buffer identifier is returned for use with the select()
                    method.

            paste(<bufferid>,<left>,<top>)

                    pastes the image data contained in the specified buffer into
                    the currently selected buffer at the given left and top offsets.
                    bufferid must be a value returned by the copy()
                    method.

            select([<bufferid>])

                    selects an image buffer as the current working buffer.  all
                    data members and methods will function upon the selected
                    buffer after this call.  providing no arguments causes the
                    main image buffer to become current.

      Using the ImageFilter Object Agent to interface with the image data provides
      an increase in processing speed over the historical methods (bufferline(),
      processrgb(), etc.).

      Also note that pixel data accessed and altered using the ImageFilter Object
      Agent is done entirely in floating-point format.

      Using the ImageFilter Object Agent, the process() function of the
      "Black & White" Image Filter LScript provided with LightWave can be re-written
      as follows:

            process: ifo
            {
                for(i = 1;i <= ifo.height;++i)
                {
                    for(j = 1;j <= ifo.width;++j)
                    {
                        average = (ifo.red[j,i] + ifo.green[j,i] + ifo.blue[j,i]) / 3;

                        ifo.red[j,i] = average;
                        ifo.green[j,i] = average;
                        ifo.blue[j,i] = average;
                    }
                }
            }

      The following example uses the copy(), paste() and select() methods
      to swap the two vertical halves of an image:

            process: ifo
            {
                buf1 = ifo.copy(1,1,ifo.width / 2,ifo.height);
                buf2 = ifo.copy(ifo.width / 2,1,ifo.width,ifo.height);

                ifo.select(buf1);
                buf_width = ifo.width;
                ifo.select();

                ifo.paste(buf2,1,1);
                ifo.paste(buf1,buf_width,1);
            }
      Several new surface-related Object Agents are available in LScript, the first of which
      is the Surface Object Agent, from which all others are derived.  The Surface() constructor
      can be used to generate an Object Agent for an existing surface, or it can be used to
      create a new surface for an object.

      The constructor can be called with no arguments, and the first surface defined in the
      system will be returned.

      If called with an integer value, the surface in the system that corresponds to that
      index value will be returned.

      Provided a surface name, the constructor will return that surface if it is already
      defined in the system.  If it does not exist, a 'nil' value will be returned under Layout,
      and a new surface with that name will be generated for the current object under Modeler.

      Provided a Mesh Object Agent, a list of the surface names defined for that object will
      be returned.

      Under Layout, you can create a new surface for an object by providing the Mesh Object
      Agent to receive the surface as the first argument, and the name of the surface as the
      second.

      The following channel constants have been defined in LScript for use with the Surface
      Object Agent:

            SURFCOLR            Base Color              (vector)
            SURFLUMI            Luminosity              (number)
            SURFDIFF            Diffuse                 (number)
            SURFSPEC            Specularity             (number)
            SURFREFL            Reflectivity            (number)
            SURFTRAN            Transparency            (number)
            SURFTRNL            Translucency            (number)
            SURFRIND            IOR                     (number)
            SURFBUMP            Bump                    (number)
            SURFGLOS            Glossiness              (number)
            SURFBUF1            Special Buffer 1        (number)
            SURFBUF2            Special Buffer 2        (number)
            SURFBUF3            Special Buffer 3        (number)
            SURFBUF4            Special Buffer 4        (number)
            SURFSHRP            Diffuse Sharpness       (number)
            SURFSMAN            Smoothing Angle         (degrees)
            SURFRSAN            Reflection Seam Angle   (degrees)
            SURFTSAN            Refraction Seam Angle   (degrees)
            SURFRBLR            Reflection Blur         (number)
            SURFTBLR            Refraction Blur         (number)
            SURFCLRF            Color Filter            (number)
            SURFCLRH            Color Highlights        (number)
            SURFADTR            Additive Transparency   (number)
            SURFAVAL            Alpha Value             (number)
            SURFGVAL            Glow Value              (number)
            SURFLCOL            Line Color              (vector)
            SURFLSIZ            Line Size               (number)
            SURFSIDE            Sidedness               (integer)
            SURFGLOW            Glow                    (Boolean)
            SURFLINE            Render Outlines         (Boolean)
            SURFRIMG            Reflection Image        (Image Object Agent)
            SURFTIMG            Refraction Image        (Image Object Agent)
            SURFVCOL            Vertex Coloring         (number)

      The following data members are exported by the Surface Object Agent:

            name
                    the name of the surface

      The following methods are available:

            getValue(<channel>)

                    returns the specific value setting for the channel (whose type is
                    defined above).

            getEnvelope(<channel>)

                    returns the Envelope Object Agent associated with the specified
                    channel.  returns 'nil' if none exists.

            getTexture(<channel>)

                    returns the Texture Object Agent (documented below) associated
                    with the specified channel.  returns 'nil' if none exists.
      A Texture Object Agent can be generated from the Surface Object Agent (using its
      getTexture() method).  This Object Agent provides an interface to a texture assigned
      to a specific channel in a surface.  Textures have their own settings, including one or
      more layers that accumulate to represent the visual makeup of the surface.

      The following texture constants have been defined in LScript for use with the Texture
      Object Agent:

            TXTRIMAGE           Image Texture type
            TXTRPROCEDURE       Procedural Texture type
            TXTRGRADIENT        Gradient Texture type

      The following methods are exported by the Object Agent:

            setChannelGroup(<Channel Group Object Agent>)

                    sets the Texture's channel group using the provided Object Agent.
                    Envelopes created for parameters in the Texture's layers will
                    belong to this group.

            getChannelGroup()

                    returns the Channel Group Object Agent for the Texture.

            firstLayer()

                    returns the TextureLayer Object Agent (documented below) for the
                    first layer defined in the Texture.

            nextLayer(<TextureLayer Object Agent>)

                    returns the TextureLayer Object Agent that follows the
                    specified TextureLayer for the Texture.

            addLayer(<layer type>)

                    creates a new layer in the Texture of the specific type--one,
                    of TXTRIMAGE, TXTRPROCEDURE or TXTRGRADIENT--and returns the
                    TextureLayer Object Agent for it.
      A TextureLayer Object Agent is generated by the Texture Object Agent, and serves as
      proxy for the settings for the each layer defined in the Texture.

      The following channel constants have been defined in LScript for use with the
      TextureLayer Object Agent:

            TXLRPOSITION        Position                (vector)
            TXLRROTATION        Rotation                (vector)
            TXLRSIZE            Size                    (vector)
            TXLRFALLOFF         Falloff                 (vector)
            TXLRPROJECT         Projection              (constant)
            TXLRAXIS            Texture Axis            (integer)
            TXLRWWRAP           Width Wrap              (number)
            TXLRHWRAP           Height Wrap             (number)
            TXLRCOORD           Coordinate System       (integer: 1==object, 2==world)
            TXLRIMAGE           Image                   (Image Object Agent)
            TXLRVMAP            VMap                    (VMap Object Agent)
            TXLREFOBJ           Reference Object        (Layout Object Agent)
            TXLROPACITY         Opacity                 (number)
            TXLRANTIALIAS       Antialias               (Boolean)
            TXLRAAVALUE         Antialias Threshold     (number)
            TXLRPIXBLEND        Pixel Blending          (Boolean)
            TXLRWREPEAT         Width Repeat            (constant)
            TXLRHREPEAT         Height Repeat           (constant)

      The defined constants for a texture's TXLRPROJECT setting are:

            TXPJPLANAR
            TXPJCYLINDRICAL
            TXPJSPHERICAL
            TXPJCUBIC
            TXPJFRONT
            TXPJUVMAP

      The defined constants for a texture's TXLRWREPEAT and TXLRHREPEAT settings are:

            TXRPRESET
            TXRPREPEAT
            TXRPMIRROR
            TXRPEDGE

      The following data members are exported by the TextureLayer Object Agent:

            type
                    the type of the layer (TXTRIMAGE, TXTRPROCEDURE or TXTRGRADIENT)

      The following methods are available:

            getValue(<channel>)

                    retrieves the value of the specified channel in the layer.

            setValue(<channel>,<value>)

                    sets the the specified layer channel to the provided value.
      The following Layout Command Sequence functions have been incorporated into
      LScript:

            MotionBlurDOFPreview()
            BoneWeightShade()
            BoneXRay()
            Redraw()
            RedrawNow()
            RefreshNow()
            MatchGoalOrientation()
            KeepGoalWithinReach()
            LimitH()
            LimitP()
            LimitB()
            LimitDynamicRange()
            MorphMTSE()
            MorphSurfaces()
            MatteObject()
            UnseenByAlphaChannel()
            UnaffectedByFog()
            ShrinkEdgesWithDistance()
            UseMorphedPositions()
            FasterBones()
            BoneStrengthMultiply()
            BoneJointComp()
            BoneJointCompParent()
            BoneMuscleFlex()
            BoneMuscleFlexParent()
            ShadowMapFitCone()

            ItemVisibility(1-7)
            ItemColor(1-15)
            IndirectBounces(1-8)
            DepthBufferAA(true/false)
            AlertLevel(1-3)
            RayRecursionLimit(0-24)
            RenderThreads(1,2,4,8)
            MatteColor(r,g,b)
            PolygonSize(<float>)
            PolygonEdgeFlags(1,2,4,8,16)
            PolygonEdgeThickness(<silhouette>,<unshared>,<crease>,<surface>,<other>)
            PolygonEdgeZScale(0.0-1.0)
            BoneSource(<Object>)
            BoneMinRange(0.0-...)
            BoneMaxRange(0.0-...)
            BoneJointCompAmounts(<float>,<float>)
            BoneMuscleFlexAmounts(<float>,<float>)
            ShadowColor(r,g,b)
            ShadowMapFuzziness(<float>)
            ShadowMapAngle((0.5-89.5)
            IncludeObject(<Object>)
            ExcludeObject(<Object>)
            RegionPosition(<left>,<top>,<width>,<height>)

            FogType(1-4)
            FogMinDistance(<float>)
            FogMaxDistance(<float>)
            FogMinAmount(0.0-1.0)
            FogMaxAmount(0.0-1.0)

## Behavioral Changes

      The ChannelGroup() constructor was providing only top-level access to channel groups.
      This prevented a depth-based search of channel groups to find the correct channel.  Along
      with its other arguments, the ChannelGroup() constructor will now also accept an existing
      Channel Group Object Agent to allow for recursive processing of Channel Group chains.

      The following code illustrates:

            @warnings
            @script channel
            @version 2.5

            ChGroup;

            create: channel
            {
                // locate the channel group recursively
                ChGroup = nil;
                GetGroupName(channel.id,ChannelGroup());

                // was it found?
                if(ChGroup != nil)
                    info(ChGroup.name + "." + channel.name);
            }

            ...

            GetGroupName: cid, chgroup
            {
                if(ChGroup) return;

                while(chgroup)
                {
                    chchannel = chgroup.firstChannel();
                    while(chchannel)
                    {
                        if(chchannel.id == cid)
                        {
                            ChGroup = chgroup;
                            last;
                        }
                        chchannel = chgroup.nextChannel();
                    }

                    last if ChGroup;

                    GetGroupName(cid,ChannelGroup(chgroup));  // recursive call

                    chgroup = chgroup.next();
                }
            }
      The min() and max() functions, when provided vector arguments, now return the vector with the
      smaller or larger (respectively) magnitude (i.e., distance from the origin).
      The label component of the ctltext() control is now given a light drop shadow to highlight
      it from the other text in the control.
      The reqend() function call is now contextually tied to the UDF where its corresponding
      reqbegin() was called.  This means that you now cannot invoke reqend() for a requester
      anywhere other than where the requester was generated.  To terminate a requester from
      any other place (e.g., a callback UDF), use the reqabort() function.
      Initblocks can now be passed as arguments to other UDFs in a script.  They are
      converted into arrays at the receiving end.
      The range of values allowed for BoneFalloffType() has been expanded to 9 from 7 to allow
      access to the ^64 and ^128 exponent falloff types.
      The VMap Object Agent setValue() method (available only in Modeler LScript) now accepts
      a value of 'nil' for a point identifier.  When specified for a mapped point, the
      indicated point will be removed from the Vertex Map.
      The requpdate() function now accepts one or more Control Object Agent identifiers as
      arguments.  Only those identifiers provided will be refreshed by the update call if
      they are info or listbox types.  This change allows the update of ctlinfo() and
      ctllistbox() controls to be performed independently.
      setvalue() can now be used to alter the content of a ctltext() control.  You can provide
      individual string values, an array reference, or an initialization block of values.

      In addition, values can be directly assigned to the control by modifying the value data
      member.  You can assign a single string, an array of strings, or an initialization block
      to alter the control's display values.
      When resolving external references--such as @insert files or external Object
      Agents--LScript now automatically first checks the \NewTek\LScripts directory
      created by the LightWave installation program.  You should begin to incorporate
      all your external references into this location to avoid interactive file dialog
      prompts, or outright render failures under Screamernet, due to unresolved external
      references.
      The Channel Object Agent methods createKey(), getKeyValue() and setKeyValue() now
      automatically convert incoming values into radian measurement, and outgoing values
      into degrees, for an angle-based channel.
      The Object Agent constructors Mesh(), Light() and Camera(), now accept an object id
      under Layout.

## Bug Fixes

      The library command, when used with native-code shared libraries, was not processing
      the referenced disc file using the correct function.
      The file extension '.p' has been added as a valid native-code shared library type
      for the library command.
      The method used by LScript to locate an object's Channel Group entry was unnecessarily
      complex, resulting in the wrong identifier being assigned in certain cases.
      LScript's VMap handling system was not cognizant of the fact that a map could exist
      with zero elements per point defined (i.e., VMSELECT).
      The EditServer() CS function was causing a crash of Layout when used.
      Accessing an associative array element using a string index not previously assigned a
      value could potentially crash the application.  Now, a 'nil' value is returned.
      The ctltext() control was regarding the width/height setting of a ctlposition() call,
      resulting in potential display problems if either value was less than the actual
      dimensions of the control.
      The AddCamera() command was not properly allowing a camera name argument.
      The getWorldRotation() method was missing from LScript's method jump table, so was
      unrecognized when referenced.
      The WROTATION constant was not being defined in the script environment.
      The getTag() and setTag() Object methods were not behaving correctly.  This has
      been corrected.
      The timeout and countdown features of compiled scripts was not functioning across
      platforms.
      The ctlfilename() argument list would not allow the width argument (#3) to be
      omitted if you wanted only to specify the save/load flag argument (#4).
      Character strings assigned to an array created by the multiple-return values of
      a UDF called by a callback UDF (whew!) were not being locked, making them victims
      of the LScript garbage collector when the secondary UDF terminated.
      Sub-array references were not being correctly generated on-the-fly
      reqabort() was not functioning properly with non-modal windows.
      A context collision, most directly manfist when a Generic script was activated
      after an Image Filter is engaged, would cause a crash of the application.
      The getWorldRotation() method was returning the same values, regardless of the
      the object's rotation or parenting.
      The listbox and channel Requester controls were not functioning correctly under tabs.

## Experimental Features

This release of LScript includes what are considered "experimental" features. Roughly defined, these are features that are there solely for evaluation purposes; they are not officially supported. They may or may not be retained in the next release of LScript, or they may not exist in a subsequent release in their current form.

    ctledit()
    Diagnostic()
    Queue()
    mouse functions
    audio()
    Global CS