box3dvehicleplugin
A car made of box3d rows from one description, driven by throttle, brake and steer.
Putting it in a scene
List it after box3d and before render3d. The scene's sim lists the box3dvehicle kind from #plugins/box3dvehicle/box3dvehicle.sim.ts, and the scene has one box3dvehicle row for each car. The row holds the car's controls. On its first step the plugin spawns the car's parts as box3d rows: a chassis, a wheel for each corner, and a wheel joint from each wheel to the chassis. The row then holds their ids. The actor entry's pos and rot say where the car is made, and the plugin takes them off the row once it has. Name the plugin in world.box3d.mods.kinds, so box3d is handed the parts' entries and the scene's world.box3d lists none of them.
"world": {
"box3d": { "subStepCount": 4, "static": [], "kinds": {}, "mods": { "ground": "terrain3d", "kinds": ["box3dvehicle"] } },
"box3dvehicle": {
"chassis": "chassis", "wheel": "wheel", "joint": "wheelJoint",
"hit": { "speed": 3, "damage": 5 },
"mods": { "gravity": "box3d", "land": "terrain3d", "bodies": "hitscan3d", "strike": "hitscan3d" },
"vehicles": {
"buggy": {
"body": { "length": 3.6, "width": 1.8, "height": 0.7, "mass": 1100, "center": [0, -0.15, 0], "friction": 0.4,
"cabin": { "at": -0.2, "length": 1.8, "width": 1.5, "top": 1.2, "topWidth": 1.3, "height": 0.6 } },
"bodies": {},
"axles": [
{ "at": 1.2, "track": 1.6, "mount": 0.1,
"wheel": { "radius": 0.4, "width": 0.3, "mass": 25, "friction": 1.2, "rollingResistance": 0.01 },
"spring": { "stiffness": 40000, "length": 0.35, "travel": 0.3, "sag": 0.12 },
"damper": { "bump": 2500, "rebound": 3500 },
"bumpStop": { "length": 0.06, "stiffness": 80000 }, "antiRoll": 8000, "driven": false, "steered": true },
{ "at": -1.2, "driven": true, "steered": false, … }
],
"engine": { "spinSpeed": 60, "spinTorque": 400, "brakeTorque": 900, "coastTorque": 30 },
"steering": { "angle": 0.5, "hertz": 8, "dampingRatio": 1, "maxTorque": 3000 },
"look": {
"paint": { "body": 12597547, "cabin": 12597547, "trim": 2236962, "glass": 8956671, "light": 16774608, "tail": 13369344, "amber": 16750848,
"tyre": 1710618, "rim": 8421504, "chrome": 14540253, "seat": 3355443, "hook": 13369344, "spring": 13369344, "damper": 3355443, "arm": 5592405 },
"segments": 24, "spokes": 6, "rim": 0.6, "coils": 6, "coilRadius": 0.05, "wire": 0.012, "arm": 0.025,
"lock": 1.6,
"points": {
"seat": [-0.3, 0.45, -0.38],
"gripL": { "at": [0.25, 0.75, -0.55], "part": "steer", "turn": [0, 0, 0, 1] }
}
}
}
}
}
},
"prefabs": {
"box3dvehicle": { "vehicle": "buggy", "throttle": 0, "brake": 0, "steer": 0 }
}
The rear axle in the example repeats the front axle's other keys. A car is driven by whatever writes its throttle, brake, steer and gear: a rule writing them onto the row, or a seat through the car's acts. A rule that makes a car in a step makes it with vehicle, which spawns the row with its parts made. What a car does while nobody drives it is up to the game.
The car's forward is its chassis's +x, up is +y, and left is −z. A car's wheels are listed axle after axle, the left wheel (−z) then the right (+z).
Properties
Read from world.box3dvehicle. A child scene inherits it from the manager scene.
The fleet
| Setting | Meaning |
|---|---|
.chassis, .wheel, .joint | The kinds of the parts' rows, the same for every car. box3d is handed their entries by this plugin's kinds mod. |
.vehicles | Vehicle name to vehicle (below): the cars the scene can make. |
.hit | Optional. { speed, damage }: a chassis moving at speed m/s or faster hits the bodies its box meets, each struck for damage for each m/s it moves (see Hitting bodies). With no hit, or no bodies and strike mods, no car hits anything. |
.mods | { gravity, land, grip, drag, bodies, strike } (see Mods). |
Hitting bodies
Each step, every body the bodies mod hands that the chassis's box reaches, while the chassis moves at hit.speed m/s or faster, is struck through the strike mod, once a step, on its part nearest the box. The box is the body's length, height and width, without the cabin. A capsule is met as itself, and a cylinder as the segment up its middle with its radius round it. The chassis must be moving toward the body, unless the body stands inside the box, in which case it is struck whichever way the chassis moves. The body's row's hit act is handed { damage, by, part, point, dir, what: "body", speed }: damage is hit.damage times the chassis's speed in m/s, by the chassis's id, point where on the body the box met it, dir the unit way the chassis moves, and speed its speed. hitscan3d's bodies leaves out a body lying off, so a body that goes off once it is struck, as one lying dead, is not struck again.
A vehicle
One entry of .vehicles. The body, the wheels, the joints and the drawing are all made from it. Lengths are metres, masses kilograms, angles radians.
| Key | Meaning |
|---|---|
body | The chassis (below). |
bodies | box3d body fields that every part of the car takes, such as enableContactRecycling. Not shapes or mass. |
axles | The wheels, a pair for each axle (below). |
engine | One of three engines (below). |
steering | { angle, hertz, dampingRatio, maxTorque }: angle is a steered wheel's target at steer 1, and the other three tune its steering joint. |
pedal | { stop }, in m/s: the speed below which the one pedal of a car that picks its own forward gear changes its way (see Driving). Required for such a car when it is driven by pedal. |
look | How the page draws the car (below). |
body
| Key | Meaning |
|---|---|
length, height, width | The chassis is a box length along x, height along y and width along z, centred on the chassis's origin. |
mass, center | The mass in kg and the centre of mass in the chassis's frame. The inertia is that of a uniform box of the body's size and mass, cabin or none. |
friction | The chassis's friction. |
cabin | Optional. A four-sided hull on the body's top: length long and width wide at its base, top long and topWidth wide at its roof, height high, its middle at along x. A body with no cabin is its box alone. |
axles
A list with one entry for each axle. Each makes two wheels.
| Key | Meaning |
|---|---|
at | Where the axle is along the chassis's x. |
track | The distance between its two wheels' centres. |
mount | The height of the springs' top mounts in the chassis's frame. Each mount is straight above its wheel's inner face, track / 2 − wheel.width / 2 out. |
wheel | { radius, width, mass, friction, rollingResistance }. The wheel rolls as a ball of its radius and grips by Coulomb friction, its friction times the load on it. Its width places its mount, sets how it spins, and is drawn, but grips no harder. A hard tyre has a low friction and rollingResistance, a soft one a high. |
spring | { stiffness, length, travel, sag }. stiffness is in N/m. length is how far below its mount the wheel's inner face hangs at full droop. travel is how far it can be pushed up from there. sag is how far it is pushed in when the car stands still on flat ground. Each spring is preloaded to carry, at sag, its share of the chassis's weight in the scene's gravity. |
damper | { bump, rebound } in N·s/m: the damping when the spring is pushed in and when it is pulled out. |
bumpStop | { length, stiffness }. The last length of the travel pushes back harder: stiffness N/m more at its start, growing to twice that at full travel. |
antiRoll | N/m on the difference between the axle's two compressions. The more pushed-in wheel is pushed down that much more and the other that much less. |
driven, steered | Whether the throttle turns the axle's wheels, and whether the steering steers them. Driving the front, the rear or every axle makes front, rear or four-wheel drive. A steered axle behind the middle of the wheelbase turns its wheels the other way, as a combine's rear wheels do, so a positive steer turns every car left. A petrol engine's torque is shared equally among the driven wheels, so the layout moves the push, not how much there is. |
engine
| Engine | Keys |
|---|---|
| Direct drive. Each driven wheel has a motor of its own. | spinSpeed rad/s, a driven wheel's motor speed at throttle 1. spinTorque N·m, its motor torque while the throttle is held. brakeTorque N·m, each wheel's motor torque at brake 1, holding it at no spin. coastTorque N·m, each wheel's torque holding it at no spin while neither is held, as an engine's drag does. At 0 the wheels roll free. |
| Petrol, through a manual gearbox. | curve: [rpm, N·m] points of the torque at full throttle, joined by straight lines with the ends held. idle, launch (the rpm the clutch slips at, full throttle, pulling away) and redline (the limiter), all rpm. revRate: rpm/s, revving in neutral. friction: [N·m, N·m per 1000 rpm], the engine braking. gears: ratios, first gear up. reverse, final and efficiency. brakeTorque as above. automatic, optional: { up: [light, full], down: [light, full] }, so that the gearbox picks the forward gear itself. The box shifts up once the rpm the driven wheels turn the engine at in the gear reaches up, and down once it falls to down. Each is the throttle's share of the way from its light-throttle rpm to its full-throttle one, so a car pressed hard holds a gear longer and a floored throttle kicks down. |
| Electric motor, through one reduction. | torque N·m up to the speed where it makes power W, then that power, to its redline rpm. ratio and efficiency. regen: N·m braking it with the throttle shut. brakeTorque as above. |
A petrol or electric car's row carries gear: −1 is reverse, 0 neutral, and for petrol 1 and up are the gears. For an electric car, and for a petrol car with automatic, any forward gear is drive. Each step the plugin writes rpm and torque on the row. On such a car a throttle below 0 is the brake pedal. On a direct-drive car it drives the wheels backwards.
look
Colours are numbers, 0xRRGGBB.
| Key | Meaning |
|---|---|
paint | The colour of each part, by name: body, cabin, trim, glass, light, tail, amber, tyre, rim, chrome, seat, hook, spring, damper, arm. light, tail and amber glow in their own colour. |
finish | Optional. For any paint name, { roughness, metalness, clearcoat?, clearcoatRoughness?, sheen?, sheenRoughness?, opacity? }. A clearcoat is for lacquered paint, a sheen for vinyl, and an opacity below 1 for glass and lenses, which are then drawn see-through. |
segments | Sides of every round part. |
spokes, rim | The steel wheel has spokes ribs on its outer face, and as many lug nuts round its hub. rim is its radius as a share of the tyre's. |
tread | Optional. { blocks, depth, angle }: blocks chevron lugs round the tyre, depth deep, each half turned angle across it. |
coils, coilRadius, wire | The coil spring drawn between chassis and wheel: its turns, its radius, and the thickness of its wire. It stretches to the gap between the mount and the wheel, so it squashes as the wheel is pushed in. |
arm | The thickness of the suspension arms. |
inboard | Optional, metres. The spring and damper are drawn that far in toward the body, out of the tyre. Only the drawing moves. |
fenders | Optional. { gap, thickness, flare, round, ease, square }: a fender over each axle's wheels, a band thickness thick gap over the wheel's top at rest, reaching flare past the wheel's outer face, its edges rounded round. Over an axle within ease of the nose it is a flat wing that eases down over ease metres to the axle's height. Over any other it is an arch round the wheel, a superellipse of power square (2 is round, higher is squarer). |
bumpers | Optional. { depth, height, overhang, round, bolts, hooks? }: a steel bar across the front and the back, overhang past each side, with bolts bolt heads across each. With hooks, a tow hook either side of the front one, hooks from the middle. |
grille | Optional. { slots, width, height, depth, paint }: a panel depth thick in the paint paint across the nose, with slots rounded slots cut in it, and holes for the headlights. |
lights | Optional (see below). |
spare | Optional. { lift }: the last axle's wheel on the back, lift above the body's top, on a bracket. |
exhaust | Optional. A list of tailpipes, each { at, dir, pipe, effect, rev? }: a pipe pipe round ending at at along dir, both in the chassis's frame, and particle3d's effect thrown from it. rev is another effect thrown beside it while the throttle is held. A trail is left where it is thrown. List particle3d after this plugin. |
dust | Optional. { effect, clear, speed }: particle3d's effect thrown from under each wheel while its lowest point is within clear metres of the land's height there and it goes faster than speed m/s across it, or its tread slides over it faster than that, spinning or locked. It needs a land mod and particle3d. Where the land's spray(x, z) gives an effect's name, that effect is thrown instead, and false throws nothing. |
tracks | Optional. { colour, opacity, skid, slide, clear, step, life, max, lift }: the track each tyre leaves on the land, a ribbon its wheel's width laid lift metres over the land's height, a piece every step metres while the wheel's lowest point is within clear metres of the land. A piece is colour at opacity (or the land's mark(x, z) where it has one), plus skid while the tread slides faster than slide m/s, at most 1. A piece of no opacity is not laid and breaks the track. Each fades over life seconds, and a wheel keeps its last max pieces. It needs a land mod. |
open | Optional. An open jeep built round the cabin (see below). It needs the body to have a cabin. |
model | Optional. { asset, at?, scale? }: the loader catalogue's model entry asset drawn on the chassis in place of the body, its cabin, the fenders, the bumpers, the grille, the rocker panels, the spare and the lamps' housings and lenses. The wheels, springs, dampers, arms, exhaust, dust and tracks are drawn as without it. Its origin is at at in the chassis's frame, [0, 0, 0] if left out, and scale is metres to one of its units, 1 if left out. Its +x is the car's forward, +y up and +z right. The bodies are the same whichever drawing is used. Until the model has loaded, the car is drawn without a body. |
lock | Optional. Radians the steering wheel turns at full lock, the row's steer at ±1. Each frame the drawn steering wheel, and each of a model's steering wheels, is turned steer × lock about its column from the way it was made, so a steer to the left, positive, turns its top to the left. With none the wheel does not turn. |
points | Optional. { name: [x, y, z] | { at, part?, turn? } }: named places of the car in the chassis's frame, where a body sits, takes hold or puts its feet. Each is drawn as an empty three.js object of its name on the chassis. With part: "steer" it rides the steering wheel, the drawn one or a model's first, at at while the wheel is straight and turning with it. With turn, a quaternion [x, y, z, w] in the chassis's frame, the empty is turned so, as a hand bent onto it is. A point whose part names nothing the look draws fails, on the frame the car is made or, for a model, on the frame it comes with no steering wheel. |
With look.model, the model's own nodes place the lamps by the start of their names. Every node named beam… throws a beam of lights.beam, a spot light aimed along the node's +x, and its dip is the node's own turn. Every mesh named, or under a node named, tail…, reverse… or amber… takes the car's tail, reverse or amber lens material. A look with model and no lights has no lamps. Every node named steer… that is not under another is a steering wheel, which turns with the steering about its own x: its +x runs down the column into the dash, +y up its face and +z to the right.
look.lights
| Key | Meaning |
|---|---|
radius, depth, bezel | Two round headlights either side of the grille: a lens radius round, domed depth proud, in a chrome ring bezel thick. |
beam | { intensity, distance, decay, angle, penumbra, dip }: each headlight throws a spot light of intensity candela reaching distance metres and falling off by decay. Its cone is angle radians from its middle, soft over its outer penumbra, and aimed ahead dip radians down. |
tail | { glow, brake, light: { intensity, distance, decay } }. A tail light at each side of the back glows glow, and up to brake at a full brake. A point light behind the car goes to light.intensity as it brakes. |
reverse | { glow, light: { intensity, distance, decay } }. The reverse lights glow glow and light with light.intensity while the car drives backwards, and are dark otherwise. |
parking | Optional. { radius, depth, glow }: an amber parking light radius round in a housing depth deep under each front fender's nose, glowing glow. |
Every light is made with the car and kept, at no intensity while off, so switching one never changes how many lights a frame draws. None casts a shadow. The lights can be found in the render3d scene by name: box3dvehicle.beam for each headlight's spot light, box3dvehicle.brake and box3dvehicle.reverse for the two point lights, box3dvehicle.tail and box3dvehicle.backup for the drawn lenses of the tail and reverse lights,, box3dvehicle.model for a model's group on the chassis, and box3dvehicle.steer for the drawn steering wheel.
look.open
An open jeep, every panel rounded, built to the body's box round its cabin. All lengths are metres.
| Key | Meaning |
|---|---|
wall, floor, corner | The thickness of the tub's wall and of its rubber floor, and the radius of its rear corners. |
door | { from, to, drop, ease }: the tub's top dips drop into a door each side from from to to along x, easing in and out over ease. |
rib | { at, depth, height }: a rib round the tub at height at, depth proud and height tall. |
hood | { drop, round, dome? }: the hood from the cowl to the grille, its top falling drop toward the nose, its edges rounded round. A dome, { inset, height }, is pressed up in it, inset in from its edges. |
dash | { depth, height }: the dash across the cowl's back. |
seat | { width, depth, base, back, round, tilt, head }: two bucket seats at the cabin's back. base is the cushion's thickness, back the height of its back, which leans tilt radians, head the headrest's height (0 for none) and round the rounding of every edge. bench, optional and true, adds a bench across the tub behind them. |
tunnel | Optional. { width, height }: a hump down the floor. With stick, a gear stick that tall. |
steer | The radius of the steering wheel before the left seat, on a column into the dash. The wheel's origin is its hub and its frame is the chassis's pitched down the column: +x down the column into the dash, +y up the wheel's face, +z to the right. It turns with the steering by lock. |
windshield | { height, lean, frame, wiper }: a windshield height tall leaning back lean radians from the cowl, in a frame frame thick, with two wipers wiper long. |
mirror | Optional. { size, arm }: a mirror size across, out arm on a stalk each side. |
cage | { height, tube, bend, pad }: a roll bar height over the cabin's back, of tube tube round, bent bend round at the corners, with pad thick padding along its top. |
rocker | Optional. { height, depth }: a rubber panel along each side. |
Methods
Driving
Closed acts on the car's row. A seat reaches a car only through a player row that holds it, which passes them on. Each takes only a finite number and keeps it to its range.
pedal( v )
Sets the one pedal of an arcade car, −1 to 1, kept on the row as pedal. A car that picks its own forward gear brakes with it held back while it rolls forward. Once it goes slower than its vehicle's pedal.stop along its heading, it is put in reverse and the same pedal drives it backwards. Pushed forward, the pedal brakes the car while it rolls backwards, and below stop puts it back in drive. Any other car takes the pedal as its throttle.
throttle( v )
Sets the throttle itself, −1 to 1, and lets go of the pedal.
steer( v )
Sets the steering, −1 to 1. Positive turns left.
brake( v )
Sets the brake, 0 to 1.
shift( by )
Moves the gear by 1 or −1. A manual petrol car goes from reverse up to its top gear. An electric car, or an automatic, goes between reverse, neutral and drive. A direct-drive car has no gear.
The row
Fields of the box3dvehicle row.
| Field | Meaning |
|---|---|
vehicle | The name of the vehicle in .vehicles that the car is. |
throttle, brake, steer, pedal, gear | The controls, as the acts set them. |
rpm, torque | The engine's speed and torque, written every step on a petrol or electric car. |
chassis, wheels, joints | The ids of the car's parts. |
compression, load, grounded | One number for each wheel, written every step as it was at the start of the step: how far the spring is pushed in from full droop in metres, the newtons the suspension pushes the chassis up with there (and the wheel down), and whether the wheel touches anything. |
Rules
From #plugins/box3dvehicle/box3dvehicle.sim.ts.
vehicle( w, name, pos, rot ) : Row
Spawns a car of the fleet's vehicle name at pos turned rot, with its parts made and its joints driven, and returns its row. The row is spawned whole, as a row spawned in a step is sent before any hook of it runs.
scrap( w, car )
Ends a car and every part of it: its joints, its wheels, its chassis and its row.
design( world, car ) : Vehicle
The vehicle a car row is, the one of the scene's fleet that its vehicle names.
ride( vehicle, g ) : Ride[]
What each axle is on this car, standing still under gravity g in m/s². Each entry is { load, carried, hz, bump, rebound, clearance }: each wheel's load in newtons, the mass it carries in kg, how often the chassis bounces on the springs there in hertz, how near the dampers come to stopping that bounce without passing the rest point when pushed in and pulled out (1 stops it exactly), and the gap under the body in metres.
loads( vehicle, g ) : number[]
Each wheel's share of the chassis's weight in newtons, standing still on flat ground: the shares that hold the chassis up and level about its centre of mass.
standing( vehicle ) : number
How high the chassis origin stands over flat ground at rest, in metres: a wheel's radius plus the spring's length less its sag, less the mount's height, taking the highest of the axles.
pull( w ) : number | undefined
How hard the scene's gravity pulls in m/s²: the length of what its gravity mod hands back, or undefined when it names none.
automatic( vehicle ) : boolean
Whether a car picks its own forward gear, so its driver only chooses reverse, neutral or drive: an electric car, or a petrol car with automatic.
pedals( vehicle, car ) : { brake, reverse }
How hard a car's row brakes, 0 to 1, and whether it drives backwards. The brake is its brake, or its throttle below 0 where that is the brake pedal. It drives backwards in reverse gear, or with the throttle below 0 for a direct-drive car.
torqueAt( curve, rpm ) : number
A petrol engine's torque at full throttle at rpm, in N·m: the curve's points joined by straight lines, its ends held past them.
pointOf( vehicle, name ) : { at, part?, turn? } | undefined
The look's point name, a bare [x, y, z] given as { at }, or undefined for a name the look has not.
On the page
Through plugins.box3dvehicle.
point( id, name ) : THREE.Object3D | undefined
The empty of the look's point name on the car whose box3dvehicle row is id, as it is drawn this frame. Its world matrix is this frame's once the plugin's afterTick has placed the car. Undefined while the car is not drawn, for a name its look has not, and, for a point on a model's steering wheel, until the model has come.
Mods
Name them in world.box3dvehicle.mods.
- box3d
gravity:gravity(w)hands back the gravity the car's parts fall by, a vector. Its length is the g that every spring's preload and every figure of the ride is worked out in. A car's parts fall by box3d's gravity and nothing else, so a scene must name agravity: a car in a scene that names none fails on its first step. - terrain3d
land:land(plugins)is the page's ground, an object whoseheight(x, z)is the ground there. Dust and tracks need it, and with none no wheel is on the ground and none is thrown or laid. It must be listed before this plugin, and a scene with dust or tracks that lists it after, or not at all, fails. - hitscan3d
bodiesandstrike, for Hitting bodies.bodies(w)hands back the bodies a car can hit, each{ id, kind, pos, shapes }, its shapes capsules and upright cylinders: every body a shot can hit now.strike(w, row, struck)hurts one, calling its row'shitact, as a rule's, with what struck it.
Two more are named in the same place, and any plugin that hands them back may be named. grip(w, x, z) hands back how well the ground at [x, z] grips, a multiplier: each step every wheel's friction is set so that its contact grips as the wheel's friction times the grip under it. With none, every wheel grips at its wheel.friction everywhere. drag(w, x, z) hands back the ground's rolling resistance at [x, z], in newtons per newton of load: each step every wheel on the ground is pushed against the way it goes by that times what its corner's spring pushes it down with, never by more than takes its share of the car to a stop that step. With none, the ground holds no wheel back.
box3dvehicle gives three mods.
- box3d
kinds: the chassis, wheel and joint kinds, made from each car's vehicle. The chassis is the body's box and its cabin's hull, with the body's friction. Each wheel is a ball of its axle'swheel.radiuswith contact events on, so its row says what it touches, and with its mass and inertia set outright. Each joint is a wheel joint from the chassis to the wheel's inner face. - scatter3d
hollows: name it inworld.scatter3d.modsas{ hollows: ["box3dvehicle"] }.hollows(plugins)gives each car's body, from the bottom of its box to the top of its cabin, and each of its wheels as a box, so scatter3d draws no grass, bush or branch inside a car. - interact
pointandobject: name them inworld.interact.modsas{ point: "box3dvehicle", object: "box3dvehicle" }, so a body getting in, driving or getting out is placed at, and reaches for, the look'spoints.point(w, car, name)is{ at, yaw }, the point's world place this step:atis the chassis row'sposplus the point'satturned by the chassis row'srot, a point on the steering wheel taken with the wheel straight, andyawis the radians the chassis's +z faces about world up, facing(sin yaw, cos yaw). Before the car's first step, the chassis is where the row says it will be made. It is undefined for a name the look has not.object(plugins, car, name)is the page'spoint(car, name).