Math module

Fixed-point trigonometry, matching the engine's own tables. Using these rather than Lua's math library guarantees a script places things exactly where the engine would. trx.math.Angle says what an angle is here.

Constants

  • trx.math.DEG_1 = 182 (trx.math.Angle)
    One degree. Multiply by it to say an angle in degrees: 45 * trx.math.DEG_1.

  • trx.math.DEG_45 = 8192 (trx.math.Angle)
    A 45-degree turn.

  • trx.math.DEG_90 = 16384 (trx.math.Angle)
    A quarter turn. A full turn is four of these.

  • trx.math.WALL_L = 1024 (trx.math.Distance)
    The size of one sector. Level geometry is laid out on this grid, so it is the step to take to move an item a sector over.

Structures

  • trx.math.Angle (integer)

    An angle in the engine's own units, where 65536 is a full turn rather than 2 pi. An angle counts in cycles, so one past the end of a turn wraps round to name the same direction: adding a half turn to a rotation always works. trx.math.DEG_1 converts from degrees.

  • trx.math.Distance (integer)

    A length in the units the engine measures the world in, where one sector is trx.math.WALL_L. Y grows downwards, so a greater Y is further down.

  • trx.math.Vec3

    A point or a direction in the world.

    Properties:

  • trx.math.Rot

    An orientation, as three angles about the world axes.

    Properties:

  • trx.math.Box

    An axis-aligned box. Whether it is placed in the world or in something's own frame is for the call that hands it over to say.

    Properties:

  • trx.math.Color

    A color, as three channels counted 0 to 255.

    Assigning one takes either a color or the hex text a color is written as, so "33e5ff" and { r = 51, g = 229, b = 255 } say the same thing. A channel may also be written on its own, and a color read off something the engine owns writes that change straight back to it.

    Some colors the engine keeps are stored as fractions rather than bytes, and those carry more precision than the hex text shows: a channel of one may read back as 191.25.

    Properties:

    • b: number. The blue channel.
    • g: number. The green channel.
    • hex: string. The color as six hex digits, which is how a setting and a data file spell one. Writing it takes a leading # as well.
    • r: number. The red channel.

    Operators:

    • color .. color. A color joins text as its hex, whichever side of the .. it is on.
    • color == color. Two colors are equal when their channels are.
    • tostring(color). The color as its hex text.

Functions

  • trx.math.color(value, [g], [b])
    Builds a color, out of three channels or out of hex text. The color it hands back belongs to the caller: assign it somewhere for the engine to take it.

    Parameters:

    • value (string or number). The hex text, or the red channel.
    • g (number, optional). The green channel, where the first argument was the red one.
    • b (number, optional). The blue channel.

    Returns: trx.math.Color.

    Example:

    local gold = trx.math.color("ffbf20")
    local teal = trx.math.color(51, 229, 255)
    
  • trx.math.sin(angle)
    Sine of an angle.

    Parameters:

    Returns: number. A value in [-1, 1].

  • trx.math.cos(angle)
    Cosine of an angle.

    Parameters:

    Returns: number. A value in [-1, 1].

  • trx.math.atan(z, x)
    Angle of the vector (x, z).

    Parameters:

    Returns: trx.math.Angle.

    Example:

    -- face an item towards Lara
    local angle = trx.math.atan(lara.pos.z - pos.z, lara.pos.x - pos.x)
    
  • trx.math.round_to_sector(value)
    Snaps a position back to the corner of the sector it stands in, the way the level's own geometry is laid out. A whole position keeps its height: a sector is a column, and rounding it is about the ground plan rather than how far up the position sits. A single coordinate rounds on its own, which is what an axis at a time needs.

    The corner is always the one to the west and the south, on both sides of the origin, so two positions in the same sector always answer with the same corner.

    Parameters:

    Returns: trx.math.Vec3 or trx.math.Distance. The corner of the sector, in whichever of the two came in.

    Example:

    -- a zone over the sector Lara stands on, a sector tall.
    -- y grows downwards, so the ceiling of the box is the lesser y.
    local corner = trx.math.round_to_sector(trx.lara.item.pos)
    trx.zones.box(corner, {
      x = corner.x + trx.math.WALL_L,
      y = corner.y - trx.math.WALL_L,
      z = corner.z + trx.math.WALL_L,
    })
    
  • trx.math.from_sectors(value)
    Says a length in sectors, which is how a level is laid out, in the units the engine measures the world in. A part of a sector is a length of its own, so 0.5 is half a sector.

    Parameters:

    • value (number). A length in sectors.

    Returns: trx.math.Distance. The same length.

    Example:

    -- how far the uzis reach, eight sectors out
    trx.weapons.get(trx.catalog.weapons.uzis).target_dist =
      trx.math.from_sectors(8)
    
  • trx.math.to_sectors(value)
    Says a length in sectors, which is what it reads as on a level's own grid. A length that is not a whole number of sectors reads as a fraction.

    Parameters:

    Returns: number. The same length in sectors.

    Example:

    local sectors = trx.math.to_sectors(trx.lara.item.pos.y)