1. Home
  2. Systems
  3. Plugin Development
  4. LUA World Machine Plugin API
  1. Home
  2. Device Reference
  3. Utility Devices
  4. LUA World Machine Plugin API

LUA World Machine Plugin API

This feature was introduced in the “Hurricane Ridge” release

This article contains the currently supported API for interacting with World Machine from your Lua scripts within the Code device.

As the bindings are continually developed, this reference material will be updated to stay current.

Overview

This API reference is only for the Host script language. You will also need to write one or more kernels in your compute language to create a device.

All World Machine bindings are exposed in the ‘wm’ library. To use any of the top-level commands below, make sure you access them with the ‘wm’ prefix. For example, ‘wm.parameter()’.

Sandboxing

To allow for secure sharing of plugin devices between users, the Lua scripting session is sandboxed:

  • Your script has no access to the system or external data.
  • Your script cannot persist information outside of the device build process.
  • The compute kernels have no access to any other data than that provided via the scripting.
  • The lua math and string libraries are available. No other built-ins are provided.
  • The World Machine plugin API *is* accessible.

Future versions may relax the sandboxing for custom devices that are not shared with others.

Datatypes

A variety of custom datatypes are created by the World Machine library.

buffer: A raw collection of bytes. Can be used to supply general memory to your compute kernel, or when accessing the underlying data of an input such as a heightfield. Your kernel should accept this as a float* parameter (or other relevant type).

image: An Image datatype, as defined in OpenCL. This may be more convenient than accessing a raw buffer, and some API functions will only return images. The image will be a 2D four channel RGBA texture. Your kernel must access as an image2d_t parameter.

In addition, standard Lua datatypes are used:

value: This is a Lua built-in integer or floating point value. Your kernel can accept either and WM will convert as appropriate.

table: A Lua table, which is simply a collection of values.

string: A Lua string.

A few additional notes:

  • If a function takes a slot value, it should be provided an integer.
  • If a function takes a name, it should be provided a string.
  • The extended datatypes have reference semantics. For example, that means that assigning one buffer to a new buffer variable does not copy the buffer – they will both refer to the same object.

Definitions

Some values defined within the library are meant to be identifiers rather than be manipulated. Providing these values allows WM to know what kind of data you are referring to.

Packet types

You can pass these identifiers to createBuffer or createImage, among other places, to create the correct types. They are a table defined at ‘wm.packet’.


wm.packet.hf -- A single channel heightfield image

wm.packet.rgb -- A 3-channel rgb image.

Data types

These are values used to communicate how to interpret a raw buffer. They are a table defined at ‘wm.type’. These are unused in the current API.


wm.type.byte -- 8bit unsigned integer data

wm.type.int -- 32bit

wm.type.int64 -- 64bit

wm.type.float -- 32bit floating point

wm.type.vec2 -- float vector2

wm.type.vec3 -- float vector3

wm.type.vec4 -- float vector4

wm.type.half -- 16bit floating point

wm.type.half3 -- 3 x 16bit floats

Inputs

Functions to take data from the input ports on the device, as well as the current parameters. The slot should be a number starting at zero for the first input.

buffer wm.inputBuffer(slot)

image wm.inputImage(slot)

value wm.inputValue(slot)

image wm.mask()

value wm.parameter(name)

value wm.parm(name) -- A convenience short alias for the above

Inputs of either heightfield or bitmap type can be taken as images or buffers, using either of the first two functions above as needed. The returned result will be of the type shown and can be used or passed to other functions.

Note that if you take a bitmap input as a buffer, the data is 3 channels of 16bit floating point, which takes special consideration to access inside of an OpenCL compute kernel.

Creation

Create new memory buffers or images for use by your compute kernels.

  • If no type is specified, the default is a heightfield.
  • If no dimensions are specified, the current world render size is used.

The dims parameter is currently ignored! It is not currently possible to create images of a different size than the general context.

image wm.createImage(type, dims)

buffer wm.createBuffer(type, dims)

buffer wm.createRawBuffer(bytes)

Context Functions

Several functions are built-in to allow you to gain access to the build context your device is invoked within.

Worldspace

image wm.worldspace()

Generate a image containing the the xy world-space coordinates for this build, in the red and green channels. The blue and alpha channels are unused and set to zero.

The image values are unnormalized 32bit floats. They correspond exactly to the render extents defined in your project settings.

Note that the worldspace coordinates are in internal World Machine units instead of kilometers. Each unit corresponds to 8 kilometers.

This is very useful to allow your compute kernel to understand what point in the world each pixel corresponds to! You will often use this, or the devicespace() function, to easily access this information.

If you output this image directly as a bitmap, it would look like this:

Devicespace

image wm.devicespace()

Devicespace is the world-space coordinate transformed by the device’s placement. The placement includes rotation, translation, and any connected domain distortion input.

The RGBA image is divided into two pairs of channels. The image values are unnormalized 32bit floats with real numbers.

  • The RG channels contains the (X,Y) distorted coordinates
  • The BA channels contains the undistorted (X,Y) device coordinates.

It looks like this, visualized:

Generally you will only need the RG channels. Device space is very useful for generator-type devices that want to make a pattern or some other output that can be placed into the world.

World Context

Retrieve a table containing the current render extent information.

table wm.context()

The table has the following members:

int dimX, dimY — Dimensions in pixels of the render extent

float x0, y0, x1, y1 — World render extent corners

float originX, originY — Placement origin

float rotate2D — Placement rotation in degrees

Outputs

Send data to an output port.

wm.output(data, port)

The port should be a number, starting at zero for the first output.

The port configuration determines the acceptable datatype to send. For example, a heightfield output must contain a buffer or image. Possible types of your data include:

hf : image, buffer

rgb : image, buffer

text : string

param : value, string

Compute Kernels

To perform operations on the GPU, use the runKernel function in the wm library.

wm.runKernel(kernelname/kernelobject, arg1, arg2, ...)

The first parameter must be a string containing the name of the compute kernel, while the following arguments should be buffers, images, or values. The types must match the type defined in your kernel function.

Currently, there is no way to define the local workgroup size of a kernel.

Other Functions

Progress Reporting

wm.progress(percent)

wm.progress(current, total)

You can specify the build progress as a floating point value from 0..1 or as current, total as integers.

There is currently no way to check if the user has requested the build to cancel.

Updated on November 13, 2024
Was this article helpful?

Related Articles

Need Support?
Can't find the answer you're looking for?
Contact Support

Start the discussion at forum.world-machine.com

Historical Comments

Leave a Comment