Skip to content

Coordinate frames

The tables below summarise each frame. For explanations and worked examples, see the Coordinate frames guide.

FrameOriginAxes / unitsRead withSet with
RegionSouth-west corner of the region, height 0+X east, +Y north, +Z up; metres, 0–256 horizontallyllGetPos (unattached), llGetRootPosition, llGetRootRotation, llGetRot (except an attachment root), llDetectedPos, llCastRay, OBJECT_POS, PRIM_POSITION and PRIM_ROTATION (always region, also for children and attachments)llSetRegionPos, llSetPos on an unattached root
Global (grid)South-west corner of the gridRegion axes; metresllGetRegionCorner + region positionConvert to region first
Local (child prims)The root primThe root’s axes; metresllGetLocalPos, llGetLocalRot, PRIM_POS_LOCAL, PRIM_ROT_LOCALllSetPos on a child, llSetLocalRot, PRIM_POS_LOCAL, PRIM_ROT_LOCAL
AttachmentThe attach pointThe attach point’s axes; metresllGetLocalPos, llGetLocalRot in the attachment rootllSetPos, llSetLocalRot on the attachment root
Avatar (in an attachment)The wearerRegion axesllGetPos (wearer’s region position), llGetRootRotation (wearer’s region rotation)Not settable
HUD (screen)Each HUD attach point, on screen+X into the screen, +Y left, +Z up; about 1 unit tall (Z −0.5 to +0.5), width depends on aspect ratiollGetLocalPos, llGetLocalRotllSetPos, llSetLocalRot
Object axes (local flag)—FALSE: region axes; TRUE: the object’s axes—llApplyImpulse, llSetForce, llSetTorque, llSetAngularVelocity, llApplyRotationalImpulse
CameraRegion frame (the avatar’s region for CAMERA_POSITION and CAMERA_FOCUS)Region axes; metresllGetCameraPos, llGetCameraRotCAMERA_POSITION, CAMERA_FOCUS
Camera (follow)The avatar’s positionRelative to the avatar; metres—CAMERA_FOCUS_OFFSET (ZERO_VECTOR looks at the avatar’s llGetPos), CAMERA_DISTANCE, CAMERA_PITCH
Prim-local offsetsThe primThe prim’s axes; metres—llSitTarget offset and rotation, llSetLinkCamera eye and at

llTargetOmega spins a root around a region axis (an attachment around the attachment’s axis) and a child around its own local axis. Seated avatars are links after the last prim, positioned relative to the root.

Region and global coordinatesA grid of regions seen from above at an angle. One region is outlined, with its +X (east), +Y (north) and +Z (up) axes at its south-west corner and a ruler along X from 0 to 256 metres. A dashed line from the grid origin to that corner is labelled llGetRegionCorner(). An object inside the region is at llGetPos() <180, 150, 24>; its global position is the region corner plus llGetPos().+Y north+Z up0m64m128m192m256mgrid <0,0,0>llGetRegionCorner()llGetPos() <180, 150, 24>global = corner + llGetPos()this regionneighbour
Region coordinates run 0–256 m from the region's south-west corner. Global coordinates add llGetRegionCorner(), the corner's position on the grid.
Root and child primsA root prim above the region grid, rotated 35 degrees around Z, with its own grid and axes. A child prim sits at llGetLocalPos() <2.6, 1.2, 1.0>, drawn as dashed steps along the root's red X, green Y and blue Z axes. A ruler in metres runs along the root's X axis. A dashed line from the region origin to the root is labelled llGetRootPosition().region <0,0,0>0m1m2m3mllGetRootPosition()rootchildllGetLocalPos() <2.6, 1.2, 1.0>
llGetLocalPos() is measured along the root's own axes (the dashed steps), not the region's. The faint lines are the axes running through each frame.
// Child local to region
vector regionPos = llGetRootPosition() + llGetLocalPos() * llGetRootRotation();
rotation regionRot = llGetLocalRot() * llGetRootRotation();
// Region to child local
vector localPos = (regionPos - llGetRootPosition()) / llGetRootRotation();
rotation localRot = regionRot / llGetRootRotation();
// Region to global, and back
vector globalPos = llGetRegionCorner() + llGetPos();
vector backToRegion = globalPos - llGetRegionCorner();
// Velocity from region axes to the object's axes
vector localVel = llGetVel() / llGetRot();
  • llSetRot on a child is offset by the root rotation; use llSetLocalRot(globalRot / llGetRootRotation()) or PRIM_ROT_LOCAL instead
  • llSetPos is local on a child, region on an unattached root, and relative to the attach point on an attachment root
  • llGetLocalPos on an unattached root returns the region position
  • PRIM_POSITION with LINK_SET mixes frames (root in region or attachment coordinates, children local); use LINK_ROOT
  • llGetRot on an attachment root reports the avatar’s rotation; use llGetLocalRot
  • An avatar’s facing is only accurate seated or in mouselook
  • Animations are invisible to the simulator: there is no skeleton to read
  • No member access on a function return: assign llGetPos() to a variable before reading .z
HUD attachment frameThe viewer window as a rectangle with the eight HUD attach points: TOP_LEFT, TOP_CENTER, TOP_RIGHT, CENTER_1 and CENTER_2 in the middle, BOTTOM_LEFT, BOTTOM and BOTTOM_RIGHT. At the centre, +Y points left, +Z points up and +X points into the screen. The window is about 1 unit tall, from Z −0.5 to +0.5.viewer windowTOP_LEFTTOP_CENTERTOP_RIGHTCENTER_1 / CENTER_2BOTTOM_LEFTBOTTOMBOTTOM_RIGHT+Y left+Z up+X into the screenZ +0.5Z 0Z −0.5
Each HUD attach point is its own origin in the same frame. The camera looks along +X, so +X points into the screen; the window is about 1 unit tall and its width depends on the aspect ratio.
FunctionFrameNotes
llDetectedTouchSTFace, [0, 1], origin bottom-leftUnaffected by the texture
llDetectedTouchUVTexture coordinatesChange with repeats and rotation; vertical flipped on glTF mesh
llDetectedTouchPosRegionMetres
llDetectedTouchNormal, llDetectedTouchBinormalRegion axesSurface normal and the +T tangent
Blinn-Phong (PRIM_TEXTURE, PRIM_NORMAL, PRIM_SPECULAR)PBR (PRIM_GLTF_*)
OriginBottom-leftTop-left
V directionUpDown
PivotCentreTop-left corner
Positive rotationCounter-clockwiseClockwise
OrderRotate, scale, offsetScale, rotate, offset
OffsetFrom the centreFrom the top-left corner
RepeatsPer face (default mapping) or per half metre (planar)The same

Converting Blinn-Phong to PBR: rotation becomes -rotation, the V offset changes sign, and the scale is only exact at multiples of 90°. Source: the viewer’s texture transform code (llface.cpp, textureUtilV.glsl, llgltfmaterial.cpp). Not yet tested in-world: whether PRIM_GLTF_* values from LSL reach the viewer unchanged, and which way the texture visibly turns. LSL functions for the conversion are in the guide’s Texture transforms section.

Blinn-Phong and PBR texture transformsTwo texture squares seen from above. Blinn-Phong: the origin 0,0 is at the bottom-left, +U right and +V up; the pivot is the centre, positive rotation is counter-clockwise, offsets are from the centre, and the order is rotate, then scale, then offset. PBR (glTF): the origin is at the top-left, +U right and +V down; the pivot is the top-left corner, positive rotation is clockwise, the V offset has the opposite sign, and the order is scale, then rotate, then offset.Blinn-Phong: PRIM_TEXTURE+U+V up0,0+rot counter-clockwisepivot: centreoffset from the centreorderrotatescale→offset→PBR (glTF): PRIM_GLTF_*+U+V down0,0+rot clockwisepivot: corneroffset V: −Blinn-Phong valueorderscalerotate→offset→
Rotation and V offset have opposite signs, the pivot moves from the centre to the top-left corner, and scale and rotation swap order, so a rotated, non-uniform repeat only converts exactly at multiples of 90°.