# Anaglym Documentation

Anaglym exposes a Lua library named `ag` which contains functions for interfacing with the Engine. In addition to the `ag` library, there is a `std` library which contains a "standard library" of Lua functions that do not directly interface with the Anaglym engine. The library functions are documented below.

- Overview
  - Invocation
  - Colors
  - Coordinate Systems
- `ag` library
  - object creation functions
  - object member methods
  - joint member methods
  - sound member methods
- `std` library
- Lua Event Handlers
- Key Names

## Overview

### Anaglym Invocation

`anaglym` usage:

        anaglym [options] script-file

`anaglym` command-line options:

- `-w width` - specify the width in pixels of the window
- `-h height` - specify the height in pixels of the window
- `-f` - do not fullscreen window
- `-g` - do not grab mouse input
- `-s samples` - set multisample level (default 4)

### Colors

Unless otherwise noted, color values described in this document consist of red, green, and blue components. Each component is a real number that can range from 0.0 to 1.0.

### Coordinate Systems

Anaglym uses the OpenGL right-handed coordinate system for its 3D coordinates. The default orientation is such that the XY plane is horizontal (the "ground" plane). The Z axis extends positively into the "air" above the XY plane, and the default gravity vector pulls along the negative Z axis.

When 2D coordinates are used (with mouse cursor positions and overlay drawing routines), the origin is in the lower-left corner of the screen. The X axis increases positively toward the right edge of the screen. The Y axis increases positively toward the top of the screen. The upper-right pixel on the screen has coordinates (width-1, height-1).

## `ag` library

### callList

`ag.callList(display_list)`

This function invokes a display list created with `startList()`.

### clearEventHandler

`ag.clearEventHandler(event_name)`

This function removes a Lua callback function from being associated with the engine event specified. `event_name` should be a string containing an event name. See Lua event handlers for a list of events.

### clearWorld

`ag.clearWorld()`

This function removes all objects from the world.

### createAMotor

`motor = ag.createAMotor(obj1, obj2, axis0 [, axis1 [, axis2 ] ])`

This function creates an angular motor in the simulation. An angular motor supplies torque to the bodies it is connected to around the axes specified in order to control the relative angular velocities of the two objects around the axes. Up to three axes can be specified, but only one is required. `obj1` and `obj2` specify the two objects that are connected with the motor. One of `obj1` or `obj2` can be the number 0 to signify that the other object should be connected to the static environment.

Connecting two objects with an angular motor does not restrict their positions relative to one another. See createHinge().

Each axisn argument should be a table containing named parameters. All parameters are optional. Valid parameters:

- `x` - x coordinate of axis vector (default 1)
- `y` - y coordinate of axis vector (default 0)
- `z` - z coordinate of axis vector (default 0)
- `rel` - controls relative orientation of axis. Possible values:
  - 0 - axis is anchored to the static environment (default)
  - 1 - axis is anchored to the first body
  - 2 - axis is anchored to the second body
- `angle` - initial angle of the motor on this axis (default 0)
- `lo_stop` - minimum angle of the motor (default disabled)
- `hi_stop` - maximum angle of the motor (default disabled)
- `vel` - target angular velocity of the motor on this axis (default 0)
- `fmax` - maximum amount of force the motor will apply around this axis to try to reach a velocity of `vel` (default 0)
- `bounce` - bounciness of the motor stops (default 0)

The motor will only allow movement around each axis from the `lo_stop` to `hi_stop` angles. The motor will attempt to maintain relative angular velocities of `vel` around each axis. The maximum amount of force that the motor is allowed to apply in order to maintain this velocity is specified by the `fmax` axis parameter. Specifying a low `fmax` value will cause the motor to take a while to reach its target velocity, and will mean that other objects can slow down or stop the motor easily. In contrast, a very high `fmax` value will allow the motor to reach its target velocity more quickly and the motor will be harder to stop by collisions with other objects. The `bounce` parameter should range from 0 to 1, with 0 meaning a hard stop and 1 meaning full bounciness.

### createHinge

`hinge = ag.createHinge(obj1, obj2, anchor, axis)`

This function creates a hinge joint between two objects, keeping a single axis from each object aligned. The two objects can rotate around this axis independently. One of `obj1` or `obj2` can be the number 0 to signify that the other object should be connected to the static environment. `anchor` and `axis` should be Lua "arrays" (tables with integer indices starting at 1), with three elements each. `anchor` gives the coordinates of a point on the hinge. `axis` gives the direction vector of the hinge.

### doPhysics

`ag.doPhysics()`

This function invokes the physics processing part of the engine. It is invoked automatically every update step if the "AutoPhysics" mode is enabled; this mode is enabled by default. See setAutoPhysics for more information.

### drawArc

`ag.drawArc(r, g, b, x, y, radius, a1, a2)`

This function tells the engine to draw an arc to the screen. The color of the arc is specified by (r, g, b). `x` and `y` specify the coordinates of the center of the arc. The arc ranges from angle `a1` to `a2`, which are specified in degrees, going counter-clockwise from the East. `drawArc()` should normally be called from the `update_overlay` event handler.

### drawCircle

`ag.drawCircle(r, g, b, x, y, radius)`

This function tells the engine to draw a circle to the screen. The color of the circle is specified by (r, g, b). `x` and `y` specify the coordinates of the center of the circle. `drawCircle()` should normally be called from the `update_overlay` event handler.

### drawImage

`ag.drawImage(width, height, x, y, texture [, rot])`

This function tells the engine to draw an image to the screen. `width` and `height` specify the size of the image, in pixels. `x` and `y` specify the coordinates of the center of the image. The image to be drawn is specified by `texture`, which should be loaded by `ag.loadTexture()`. `drawImage()` should normally be called from the `update_overlay` event handler.

### drawLine

`ag.drawLine(r, g, b, x1, y1, x2, y2 [, width])`

This function tells the engine to draw a line to the screen. The color of the line is given by (r, g, b). The start and end coordinates of the line are (x1, y1) and (x2, y2). `width` is an optional parameter and defaults to 1 if not specified. It controls the width of the line to be drawn. `drawLine()` should normally be called from the `update_overlay` event handler.

### drawObjects

`ag.drawObjects()`

This function instructs the engine to draw all visible objects. It is invoked automatically every update step if the "AutoDrawObjects" mode is enabled; this mode is enabled by default. See setAutoDrawObjects for more information.

### drawPoint

`ag.drawPoint(size, r, g, b, x, y [, z])`

This function draws a point to the screen. The size of the point is given by `size`. The point will be antialiased. The color of the point is given by (r, g, b). The position of the point is given by (x, y, z). If not specified, `z` defaults to 0. This function can be called from either the `update_event` or the `update_overlay_event`.

### drawRect

`ag.drawRect(r, g, b, width, height, x, y [, rot])`

This function draws a rectangle to the screen. The color of the rectangle is given by (r, g, b). The size is given by `width` and `height`. The center of the rectangle is given by (x, y). `rot` is an optional parameter that defaults to 0.0. It specifies the rotation of the rectangle. `drawRect()` should normally be called from the `update_overlay` event handler.

### drawText

`ag.drawText(message, r, g, b, ptsize, x, y)`

This function draws the text `message`, which should be a string, to the screen at position (x, y), with color specified by (r, g, b), and with font size `ptsize`. It should normally be called from the `update_overlay` event handler.

### elapsedTime

`elapsed_msec = ag.elapsedTime()`

This function returns the number of milliseconds that have elapsed since the beginning of the program.

### endFrame

`ag.endFrame()`

This function signals the engine that all drawing is complete for the current update frame. It is invoked automatically if the "AutoEndFrame" mode is enabled; this mode is enabled by default. See setAutoEndFrame for more information.

### endList

`ag.endList()`

This function ends the creation of a display list created with `startList()`. Every call to `startList()` should have a corresponding call to `endList()`.

### exit

`ag.exit()`

This function instructs the engine to exit. Internally, this function enqueues an "exit" event on the event queue to be processed by the engine. This means that Lua code following the call to `exit()` will be executed and callbacks to other events may still be called. The engine should exit within one update step.

### fillArc

`ag.fillArc(r, g, b, x, y, radius, a1, a2)`

This function tells the engine to draw a filled-in arc to the screen. The color of the arc is specified by (r, g, b). `x` and `y` specify the coordinates of the center of the arc. The arc ranges from angle `a1` to `a2`, which are specified in degrees, going counter-clockwise from the East. `fillArc()` should normally be called from the `update_overlay` event handler.

### fillCircle

`ag.fillCircle(r, g, b, x, y, radius)`

This function tells the engine to draw a solid circle to the screen. The color of the circle is specified by (r, g, b). `x` and `y` specify the coordinates of the center of the circle. `fillCircle()` should normally be called from the `update_overlay` event handler.

### fillRect

`ag.fillRect(r, g, b, width, height, x, y [, rot])`

This function draws a solid, filled rectangle to the screen. The color of the rectangle is given by (r, g, b). The size is given by `width` and `height`. The center of the rectangle is given by (x, y). `rot` is an optional parameter that defaults to 0.0. It specifies the rotation of the rectangle. `fillRect()` should normally be called from the `update_overlay` event handler.

### getCamera

`eye_x, eye_y, eye_z, center_x, center_y, center_z, up_x, up_y, up_z = ag.getCamera()`

This function returns the camera position (eye coordinates), focus position (center coordinates), and up vector for the current camera settings.

### getTextSize

`width, height = ag.getTextSize(message, ptsize)`

This function returns the width and height, in pixels, that the text specified by `message`, which should be a string, would take when drawn to the screen using font size `ptsize`.

### getScreenSize

`width, height = ag.getScreenSize()`

This function returns the dimensions of the engine window, in pixels.

### import

`ag.import(lua_source_name)`

This function instructs the engine to import a Lua source file named `lua_source_name`, which should be a string specifying the name of the Lua library without the ".lua" extension. Source files are searched for relative to the folder containing the hosted script first, then relative to the engine library folder. The `import()` function can be used to load Lua code that is broken into separate source files, and to load libraries such as std.

### isKeyDown

`result = ag.isKeyDown(key)`

This function returns a boolean value for whether or not the key given by `key` is currently pressed or not. `key` should be a string corresponding to a key name. See Key Names for key names.

### loadModel

`object = ag.loadModel(model_name [, optargs])`

This function loads an object file and returns the object loaded. If the returned value is `nil`, loading of the object failed. `model_name` should be a string specifying the base name of the model file, without the ".obj" extension. Models are searched for relative to the folder containing the hosted script first, then relative to the engine library folder.

If specified, `optargs` should be a table of named parameters. Possible parameters are:

- `scale` - specify the scale of the model (default 1.0)
- `static` - boolean to indicate if the object is static
- `reference` - boolean to indicate if the object is a reference object

A static object can still be placed with setPosition() and setRotation(). A static object will participate in collision detection when physics computations are performed, however a static object will not be moved by any colliding objects. Static objects do not have a mass associated with them; they are considered to be a part of the environment.

A reference object will not be drawn and cannot participate in physics. A reference object is useful when one wishes to load a model some time before actually using it. You can instantiate a reference object into a normal object by calling the clone() method on the object.

### loadSound

`sound = ag.loadSound(sound_name)`

This routine loads a sound object from file `sound_name` and returns a Lua reference to the loaded sound. The `sound_name` should contain the file extension, since multiple formats are supported (.wav, .mp3, etc...).

### loadTexture

`texture = ag.loadTexture(texture_name)`

This function loads a texture file from the file system and returns a Lua reference to the loaded texture. `nil` is returned if loading the texture fails. The `texture_name` should contain the file extension, since multiple formats are supported (.jpg, .png, .bmp, etc...). Textures are searched for relative to the folder containing the hosted script first, then relative to the engine library folder.

### pickObjects

`objects = ag.pickObjects(x, y)`

This function allows for 3D object "picking." `x` and `y` should be the 2D screen coordinates of the "pick point." `pickObjects` returns a Lua array of the objects in the "pick line" (the line from the camera through the "pick point" on the screen. Upon error, `pickObjects` returns `nil`. For each object in the "pick line", the following properties are set:

- `pick_dist` - the distance to the object along the pick line
- `pick_pos` - the 3D coordinates of the pick point
- `pick_normal` - the normal of the object at the pick point

### pickOne

`obj_hit = ag.pickOne(x, y, obj)`

This function allows for 3D object "picking," but only tests the given object for intersection with the pick line and is thus much more efficient than pickObjects() if you only care about selecting on a given object. `x` and `y` should be the 2D screen coordinates of the "pick point." `obj` indicates which object to be tested. `pickOne` returns a boolean for whether or not the given object was hit by the "pick line." If the return value is `true`, then the following properties are set on `obj`:

- `pick_dist` - the distance to the object along the pick line
- `pick_pos` - the 3D coordinates of the pick point
- `pick_normal` - the normal of the object at the pick point

### print

`ag.print(args...)`

This function prints its arguments to the standard output. It is mainly used for debugging when developing Lua scripts. On Windows, this output stream may be redirected to a file (stdout.txt). Example usage:

    local x, y, z = my_obj:getPosition()
    ag.print("my_obj position: (", x, ", ", y, ", ", z, ")")

### println

`ag.println(args...)`

Identical to `print()` but automatically prints a newline ("\n") after printing the arguments.

### registerEventHandler

`ag.registerEventHandler(event_name, handler)`

This function registers a Lua callback function (`handler`) to be called when the engine event specified by `event_name` occurs. There can be only one registered handler per event, so if a previous Lua function was registered for `event_name`, it will be overwritten to call the new handler. `event_name` should be a string containing the name of the event. See Lua event handlers for a list of event names.

When the Lua script is initially loaded, any functions found that have names matching an event name with "_event" appended (ex. "mouse_motion_event" for the "mouse_motion" event) are registered automatically as handlers for their corresponding events.

### setAutoDrawObjects

`ag.setAutoDrawObjects(enable_flag)`

This function sets the "AutoDrawObjects" mode. `enable_flag` should be `true` or `false`. If AutoDrawObjects mode is enabled, then all visible objects in the engine will be drawn automatically every update step. If it is not enabled, one can call `ag.drawObjects()` to draw all visible objects in the scene. The AutoDrawObjects mode is initially enabled.

### setAutoEndFrame

`ag.setAutoEndFrame(enable_flag)`

This function sets the "AutoEndFrame" mode. `enable_flag` should be `true` or `false`. If AutoEndFrame mode is enabled, then `ag.endFrame()` will be invoked automatically after executing the update and update_overlay Lua callback functions. The AutoEndFrame mode is initially enabled.

### setAutoPhysics

`ag.setAutoPhysics(enable_flag)`

This function sets the "AutoPhysics" mode. `enable_flag` should be `true` or `false`. If AutoPhysics mode is enabled, then collision detection and physics processing are performed automatically on every update step. If it is not enabled, one can call `ag.doPhysics()` to perform physics updates. The AutoPhysics mode is initially enabled.

### setAutoStartFrame

`ag.setAutoStartFrame(enable_flag)`

This function sets the "AutoStartFrame" mode. `enable_flag` should be `true` or `false`. If AutoStartFrame mode is enabled, then `ag.startFrame()` will be invoked automatically prior to executing the update and update_overlay Lua callback functions. The AutoStartFrame mode is initially enabled.

### setCamera

`ag.setCamera(eye_x, eye_y, eye_z [, center_x, center_y, center_z [, up_x, up_y, up_z] ])`

This function sets the camera position (eye coordinates), focus point (center coordinates), and up vector. If the center coordinates or up vector are not specified, their values are unchanged from the previous invocation of `setCamera()`. The default center point is (0, 0, 0). The default up vector is (0, 0, 1).

### setCursorVisible

`ag.setCursorVisible(visible)`

This function sets whether the mouse cursor is visible or not. `visible` should be a boolean value. When the cursor is visible, the absolute x and y coordinates passed to mouse event handlers are meaningful.

### setGravity

`ag.setGravity(gx, gy, gz)`

This function sets the gravity vector to (gx, gy, gz). The default gravity vector is (0, 0, -9.81).

### startFrame

`ag.startFrame()`

This function instructs the engine to begin drawing a frame. It is not necessary to call this function if the "AutoStartFrame" mode is enabled. See ag.setAutoStartFrame().

### startList

`displaylist = ag.startList()`

This function instructs the engine to start a display list. Any `draw*()` functions called between `startList()` and `endList()` will be stored in the display list for efficient execution. The display list can be called with `callList()`.

## Object creation functions

The following functions can be used to create "managed" objects. These objects are "managed" by the Lua script (as opposed to having all of their attributes defined in a model file). The properties of managed objects, such as the color, texture, position, and rotation, can be controlled by using the object member methods.

### `createBox`

`obj = ag.createBox(width, depth, height [, optargs])`

This function creates a managed object which is a box with dimensions given by (width, depth, height). The center of the box is initially located at the origin.

If specified, `optargs` should be a table containing named parameters. Valid parameters:

- `static` - boolean to indicate if the object is static
- `reference` - boolean to indicate if the object is a reference object

### `createCapsule`

`obj = ag.createCapsule(radius, length [, optargs])`

This function creates a capsule managed object. A capsule is like a cylinder, but has a half-sphere "capping" each end of the cylinder. `radius` specifies the radius of the cylinder (and caps). `length` specifies the length of the straight part of the capsule (not including the caps). The capsule is oriented with its axis along the Z axis and its center point at the origin.

If specified, `optargs` should be a table containing named parameters. Valid parameters:

- `static` - boolean to indicate if the object is static
- `reference` - boolean to indicate if the object is a reference object

### `createPlane`

1) `obj = ag.createPlane(a, b, c, d [, optargs])`

2) `obj = ag.createPlane(x, y, z, rot_x, rot_y, rot_z [, optargs])`

The `createPlane()` function creates a managed plane object. All planes are static and are not moved as a result of physics collisions (other objects can still bounce off them). In the four-argument form, the plane is created with equation `ax + by + cz = d`. (a, b, c) specifies the normal vector for the plane. In the six-argument form, the plane is created by specifying a point on the plane, with coordinates (x, y, z), and the Euler rotation angles around the x, y, and z axis. Specifying no rotation would use the default plane normal of (0, 0, 1). If you would like to create a plane by specifying a point on the surface and the surface normal, see the std.createPlanePointNormal() function.

If specified, `optargs` should be a table containing named parameters. Valid parameters:

- `reference` - boolean to indicate if the object is a reference object

### `createSphere`

`obj = ag.createSphere(radius [, optargs])`

This function creates a managed sphere object with the radius given. The center of the sphere is initially located at the origin.

If specified, `optargs` should be a table containing named parameters. Valid parameters:

- `static` - boolean to indicate if the object is static
- `reference` - boolean to indicate if the object is a reference object

## Object member methods

### addForce

`obj:addForce(xf, yf, zf)`

This function adds a one-time force to `obj` with a force vector (xf, yf, zf).

### addForceRel

`obj:addForceRel`

This function adds a one-time force to `obj` with a force vector (xf, yf, zf) which is relative to the local reference frame of `obj`.

### addTorque

`obj:addTorque(xr, yr, zr)`

This function adds torque (a rotational force) to `obj`. The torque vector around global x, y, and z axes is given by (xr, yr, zr).

### addTorqueRel

`obj:addTorqueRel(xr, yr, zr)`

This function adds torque (a rotational force) to `obj`. The torque vector around `obj`'s local x, y, and z axes is given by (xr, yr, zr).

### clone

`new_obj = obj:clone()`

This function makes a copy of the object in the engine. This is more efficient than creating a new object in whatever manner was used to create `obj`. `new_obj` will have all of its own parameters - position, rotation, color, texture, etc... However, these parameter values will be instantiated with the corresponding values from `obj` at the time of cloning. One should call `new_obj:setPosition()` in order to place `new_obj` somewhere where it is not intersecting with other objects in order to pacify the physics engine. The new object created will be a regular (non-reference) object, regardless of whether `obj` was a regular or reference object.

### destroy

`obj:destroy()`

This function destroys the object in the engine. `obj` should not be used after this method is called.

### draw

`obj:draw()`

This function will draw `obj` to the screen. It is called automatically by `ag.drawObjects()`, so calling it is only required if the "AutoDrawObjects" mode is disabled, and `ag.drawObjects()` is not called.

### getAABB

`minx, miny, minz, maxx, maxy, maxz = obj:getAABB()`

This function returns the coordinates of the axis-aligned box bounding `obj`.

### getMass

`mass = obj:getMass()`

This function returns the mass of `obj`.

### getPosition

`x, y, z = obj:getPosition()`

This function returns the coordinates (x, y, z) of the object. Normally, the center-of-mass of the object is located at its local origin. The coordinates of the object's local origin are returned by this call, so these coordinates will be the coordinates of the object's center-of-mass.

### getSize

`sx, sy, sz = obj:getSize()`

This function returns the axis-aligned size of `obj`.

### setColor

`obj:setColor(r, g, b)`

This function sets the color of the object. The parameters correspond to the red, green, and blue components of the object color. Each component should be between 0.0 and 1.0.

### setMass

`obj:setMass(new_mass)`

This function sets the mass of `obj` to `new_mass`.

### setPosition

`obj:setPosition(x, y, z)`

This function sets the coordinates for the object's center-of-mass (local origin) to (x, y, z).

### setRotation

`obj:setRotation(xr, yr, zr)`

This function sets the object's rotation as specified by Euler angles (xr, yr, zr).

### setTexture

`obj:setTexture(tex)`

This function sets the texture of `obj` to `tex`. `tex` should be a Lua reference to a texture loaded with ag.loadTexture().

### setTextureScale

`obj:setTextureScale(scale)`

This function sets the "texture scale" for `obj`. Currently, texture scaling is only supported for boxes and planes. `scale` actually scales the texture coordinates. Hence a scale of 4 would appear to shrink the texture by a factor of 4 and tile the texture 16 times where it normally would have once.

### setTransparency

`obj:setTransparency(t)`

This function sets the transparency of the object. `t` should be between 0.0 and 1.0, with 1.0 being fully transparent. Note that the object will only render transparent if it is created with the optional ''enable_blending'' attribute set to ''true.'' This does incur a slight performance hit. This call has no effect when the object has a texture specified, as the transparency is taken from the texture in that case.

### setVisible

`obj:setVisible(visible_flag)`

This function sets the visibility of `obj` to `visible_flag`. If `visible_flag` is `true`, then the object will be drawn. Newly created objects are visible by default.

## Joint member methods

### setAMotorAxis

`joint:setAMotorAxis(anum, rel, x, y, z)`

Set axis parameters of the AMotor joint. See ag.createAMotor() for more information.

### setAMotorNumAxes

`joint:setAMotorNumAxes(num)`

Set the number of axes of the AMotor joint. See ag.createAMotor() for more information.

### setAMotorAngle

`joint:setAMotorAngle(anum, angle)`

Set the angle of the specified of axis of the AMotor joint. See ag.createAMotor() for more information.

### setAMotorLoStop

`joint:setAMotorLoStop(anum, lostop)`

Set the low stop angle of the specified axis of the AMotor joint. See ag.createAMotor() for more information.

### setAMotorHiStop

`joint:setAMotorHiStop(anum, histop)`

Set the high stop angle of the specified axis of the AMotor joint. See ag.createAMotor() for more information.

### setAMotorVel

`joint:setAMotorVel(vel)`

Set the velocity of the AMotor joint. See ag.createAMotor() for more information.

### setAMotorFMax

`joint:setAMotorFMax(vel)`

Set the maximum force that the AMotor joint will apply to maintain its constraints. See ag.createAMotor() for more information.

### setAMotorBounce

`joint:setAMotorBounce(bounce)`

Set the bounciness of the AMotor joint. See ag.createAMotor() for more information.

## Sound member methods

### play

`snd:play()`

Begins playing the `snd` sound at the beginning.

### resume

`snd:resume()`

Begins playing the `snd` sound where it stopped after calling stop().

### stop

`snd:stop()`

Stops playing the `snd` sound at its current position.

### loop

`snd:loop(count)`

Begins playing the `snd` sound at the beginning and sets the loop count to `count`. `snd:loop(1)` is equivalent to `snd:play()`.

### loopForever

`snd:loopForever()`

Begins playing the `snd` sound at the beginning and sets the loop count to infinity. This routine is good for background music.

### getVolume

`snd:getVolume()`

Get the volume for the `snd` sound.

### setVolume

`snd:setVolume(vol)`

Set the volume for the `snd` sound to `snd`. `snd` should be between `0.0` and `1.0`.

## `std` library

The `std` Lua library supplies a set of Lua functions that may be useful to Lua scripts being executed. It is not imported by default. Import it like this:

    ag.import("std")

### createPlanePointNormal

`obj = std.createPlanePointNormal(x, y, z, nx, ny, nz)`

This function simply wraps `ag.createPlane()` allowing the user to specify a point on the plane with coordinates (x, y, z) and the surface normal of the plane (nx, ny, nz).

### crossProduct

`cp = std.crossProduct(vec1, vec2)`

This function returns the cross product of the two vectors `vec1` and `vec2`. The return value is a Lua array with indices 1 to 3. The indices of `vec1` and `vec2` should be from 1 to 3. This allows specifying a Lua array directly as a parameter to the function. For example:

    local z_axis = std.crossProduct({1, 0, 0}, {0, 1, 0})

### dotProduct

`dp = std.dotProduct(vec1, vec2)`

This function returns the dot product of the two vectors. The indices of `vec1` and `vec2` should be from 1 to 3. This allows specifying a Lua array directly as a parameter to the function.

### loadModelBounds

`obj = std.loadModelBounds(model_name, max_x, max_y, max_z)`

This function loads a model from the model file given by the string `model_name` (without extension). The scale used when loading the model is determined automatically. It is always a uniform scale. The scale is calculated to be the maximum value such that the model fits in the bounding box given by (max_x, max_y, max_z). To ignore an axis when calculating this scale, set its corresponding component to 0. For example:

`obj = std.loadModelBounds("pillar", 0, 0, 10)`

will load the "pillar" model and scale it (uniformly) so that its height is 10.

### pctx

`pixels_x = std.pctx(percent)`

This function returns the number of pixels corresponding to `percent` percent of the screen's X axis. `percent` should be between 0.0 and 1.0.

### pcty

`pixels_y = std.pcty(percent)`

This function returns the number of pixels corresponding to `percent` percent of the screen's Y axis. `percent` should be between 0.0 and 1.0.

## Lua Event Handlers

The following is a list of all events that the Anaglym engine handles:

- `update`
- `update_overlay`
- `key_down`
- `key_up`
- `mousebutton_down`
- `mousebutton_up`
- `mouse_motion`

Lua callback functions may be registered for each of these events.

When a Lua script is loaded, any defined function that matches the name of an engine event with "`_event`" appended will automatically be registered as a callback for that engine event. For example, a function named `key_up_event()` in a loaded Lua script will automatically be registered to receive `key_up` event notifications.

The prototypes for the Lua event handler callback functions follow.

### update

`function update_event()`

This function is called for every frame that is drawn on the screen. It could be called up to a few dozen times per second.

### update_overlay

`function update_overlay_event(width, height)`

This function is called immediately after the `update` function. During this event, the coordinate system is reset from the normal 3D system to a 2D system. The coordinates range from (0, 0) in the lower-left corner of the screen to (width, height) in the upper-right corner of the screen. In this mode, depth testing is disabled, so any graphics drawn will "overlay" whatever is currently on the screen. `width` and `height` contain the size of the Anaglym engine window, in pixels.

### key_down

`function key_down_event(key_name)`

This function is called when a key is initially pressed. `key_name` is a string containing the name of the key pressed. See Key Names for a list of key names.

### key_up

`function key_up_event(key_name)`

This function is called when a key is released. `key_name` is a string containing the name of the key released. See Key Names for a list of key names.

### mousebutton_down

`function mousebutton_down_event(button, x, y)`

This function is called when a mouse button is pressed. `button` contains the number of the button pressed (1: left, 2: middle, 3: right, 4: scroll wheel up, 5: scroll wheel down). The position of the cursor when the mouse button was pressed is at (x, y). This position is only meaningful when the cursor is shown. By default, it is hidden. Cursor visibility can be toggled with the F2 key.

### mousebutton_up

`function mousebutton_up_event(button, x, y)`

This function is called when a mouse button is released. `button` contains the number of the button released (1: left, 2: middle, 3: right, 4: scroll wheel up, 5: scroll wheel down). The position of the cursor when the mouse button was released is at (x, y). This position is only meaningful when the cursor is shown. By default, it is hidden. Cursor visibility can be toggled with the F2 key.

### mouse_motion

`function mouse_motion_event(x, y, xrel, yrel)`

This function is called when the mouse moves. (x, y) specifies the position that the cursor was moved to. This position is only meaningful when the cursor is shown. `xrel` and `yrel` contain the relative movement distance. These values are meaningful regardless of the cursor visibility state.

## Key Names

- `backspace`
- `tab`
- `clear`
- `return`
- `pause`
- `escape`
- `space`
- `exclaim`
- `quotedbl`
- `hash`
- `dollar`
- `ampersand`
- `quote`
- `leftparen`
- `rightparen`
- `asterisk`
- `plus`
- `comma`
- `minus`
- `period`
- `slash`
- `0`
- `1`
- `2`
- `3`
- `4`
- `5`
- `6`
- `7`
- `8`
- `9`
- `colon`
- `semicolon`
- `less`
- `equals`
- `greater`
- `question`
- `at`
- `leftbracket`
- `backslash`
- `rightbracket`
- `caret`
- `underscore`
- `backquote`
- `a`
- `b`
- `c`
- `d`
- `e`
- `f`
- `g`
- `h`
- `i`
- `j`
- `k`
- `l`
- `m`
- `n`
- `o`
- `p`
- `q`
- `r`
- `s`
- `t`
- `u`
- `v`
- `w`
- `x`
- `y`
- `z`
- `delete`
- `kp0`
- `kp1`
- `kp2`
- `kp3`
- `kp4`
- `kp5`
- `kp6`
- `kp7`
- `kp8`
- `kp9`
- `kp_period`
- `kp_divide`
- `kp_multiply`
- `kp_minus`
- `kp_plus`
- `kp_enter`
- `kp_equals`
- `up`
- `down`
- `right`
- `left`
- `insert`
- `home`
- `end`
- `pageup`
- `pagedown`
- `f1`
- `f2`
- `f3`
- `f4`
- `f5`
- `f6`
- `f7`
- `f8`
- `f9`
- `f10`
- `f11`
- `f12`
- `f13`
- `f14`
- `f15`
- `numlock`
- `capslock`
- `scrollock`
- `rshift`
- `lshift`
- `rctrl`
- `lctrl`
- `ralt`
- `lalt`
- `rmeta`
- `lmeta`
- `lsuper`
- `rsuper`
- `mode`
- `compose`
- `help`
- `print`
- `sysreq`
- `break`
- `menu`
- `power`
- `euro`
- `undo`
- `last`