RLS Studios
ProjectsPatreonCommunityDocsAbout
Join Patreon
BeamNG Modding Docs

Guides

Reference

Server CommandsGE UtilitiesGame Engine MainNavigation GraphScreenshot CaptureServerServer ConnectionSpawnpoint ManagerSimulation TimeVehicle SpawningSuspension Frequency Tester
Gameplay AchievementGameplay CityDiscoverForce FieldGarage ModeMarker InteractionParking SystemGameplay Playmode MarkersGameplay PoliceGameplay RallyGameplay Rally LoopGameplay Raw POIsGameplay Skidpad TestSpeed Trap LeaderboardsSpeed Traps and CamerasGameplay StatisticsTaxi Ride SystemTraffic SystemVehicle PerformanceWalking
Rally Audio ManagerRally Camera Path PlayerRally ClientRally Cut CaptureRally EnumsRally Extension HelperRally GeometryRally ManagerRecce ManagerRecce AppRecce SettingsRally Settings ManagerSnap-to-RoadTraffic Exclusion ZonesRally UtilityRally Vehicle CaptureRally Vehicle Tracker
Geo PacenotesDriveline Normals

UI

Resources

BeamNG Game Engine Lua Cheat SheetGE Developer RecipesMCP Server Setup

// RLS.STUDIOS=true

Premium Mods for BeamNG.drive. Career systems, custom vehicles, and immersive gameplay experiences.

Index

HomeProjectsPatreon

Socials

DiscordPatreon (RLS)Patreon (Vehicles)

© 2026 RLS Studios. All rights reserved.

Modding since 2024

API ReferenceGE Extensionsgameplayrallysnaproad

Geo Pacenotes

Measures pacenote corner geometry by fitting circles to driveline points. Calculates corner severity, direction, radius, arc length, and fit quality. Provides debug visualization with 3D arc prisms.

Measures pacenote corner geometry by fitting circles to driveline points. Calculates corner severity, direction, radius, arc length, and fit quality. Provides debug visualization with 3D arc prisms.


Exports

FunctionSignatureReturnsDescription
M.measurePartition(pn, focusPoints, skipAuto)nilMeasures corner geometry, stores in pn.measurements
M.autoSelectBestIntensityVariation(pn, focusPoints)value, fitValueAuto-selects best split point for two-circle fit
M.drawPacenoteMeasurement(center, radius, arcDistance, p1, p2, p3, clr, alpha, prefix, fitQuality, angleDegrees)nilDraws 3D arc, radius lines, and measurement text
M.calculateMiddlePoint(pn, startPos, endPos, partition)vec3Calculates midpoint using halfpoint or geometry
M.calculateCircleFromPoints2(p1, p2, p3)center, radius, arcDistanceFits a 2D circle through 3 points
M.intensityVariationOptionstable-Available split ratios: nil (none), 0.50 (50%)

How It Works

Measurement Modes

Single circle (default): Fits one circle through CS, halfpoint, and CE positions.

Two circles (intensity variation): Splits the corner at a percentage of total path length, fits separate circles to each segment. Used for compound corners.

Auto-Selection (autoSelectBestIntensityVariation)

  1. Tests single-circle fit first - if fit quality ≤ 0.009, uses single circle
  2. Otherwise tests all intensity variation options (none, 50%)
  3. Selects the option with lowest average fit quality (normalized RMSE)
  4. pn.intensityVariationAuto controls whether auto-selection runs (default: true)

Circle Fitting

Uses circle2DFrom3Points() from road architect utilities for 2D circle calculation, then calculates:

  • Radius/diameter: from center to first point
  • Arc distance: angle × radius
  • Fit quality: normalized RMSE of all points' distances from the circle (lower = better)
    • < 0.05 = excellent, 0.05-0.15 = good, > 0.15 = poor/compound

Corner Severity

After measurement, calculateAndStoreSeverityDirection():

  1. Finds nearest severity entry by diameter from text compositor config
  2. Validates hairpin classification (requires ≥45% of circumference)
  3. Detects direction via cross product (left/right/straight)
  4. Calculates diameter change between corners (opening/tightening)

Measurement Data Structure

pn.measurements = {
  corner1 = {
    center = vec3(...), radius = 25, diameter = 50,
    arcDistance = 40, angleDegrees = 92,
    straightLineDistance = 35, fitQuality = 0.03,
    pointsLength = 42, p1 = vec3(...), p2 = vec3(...), p3 = vec3(...),
    severity = { value = 3, ... }, direction = "left"
  },
  corner2 = { ... },  -- nil for single circle
  splitPoint = vec3(...),
  totalPointsLength = 80,
  diameterChange = { change = 10, changePercent = 20, isOpening = true, isTightening = false }
}

Debug Visualization

Draws 3D arc prisms, radius lines, and text labels showing length, diameter, angle, and fit quality using debugDrawer:drawSquarePrism().

local geoPacenotes = require('/lua/ge/extensions/gameplay/rally/snaproad/geoPacenotes')
geoPacenotes.measurePartition(pacenote, focusPoints)
-- Results stored in pacenote.measurements

See Also

  • normals - Snaproad Normal Vector Calculations - Related reference
  • Gameplay Systems Guide - Guide

Driveline Recording

Loads a recorded driveline file from a recce run and returns a `PointList`. A driveline is a series of timestamped position/orientation points captured during reconnaissance driving.

Driveline Normals

Calculates forward normal vectors for driveline points using adjacent point positions. Used for waypoint orientation and direction display.

On this page

ExportsHow It WorksMeasurement ModesAuto-Selection (autoSelectBestIntensityVariation)Circle FittingCorner SeverityMeasurement Data StructureDebug VisualizationSee Also