ik3dplugin
Arms and legs bent to reach points on a held prop or a machine.
Putting it in a scene
ik3d has no row and no prefab, and draws nothing of its own. Each frame it bends the limbs of the bodies another plugin draws, from rows every seat already has. It is listed after the plugins its mods name and before render3d, and the scene must list render3d; any other order throws.
"plugins": ["loader", "scenemanager", "player", "anim", "interact", "ik3d", "render3d"],
"world": {
"ik3d": {
"mods": { "body": "anim", "limbs": "interact" },
"kinds": {
"xbot": {
"anchor": { "prop": "rifle", "bone": "RightShoulder", "at": [0.133, 0.167, 0.087], "turn": [-87.2, -36.2, 29.5], "point": "stock" },
"limbs": [
{ "bones": ["RightArm", "RightForeArm", "RightHand"], "prop": "rifle", "target": "grip", "pole": [-1, -1, 0] },
{ "bones": ["LeftArm", "LeftForeArm", "LeftHand"], "prop": "rifle", "target": "support", "pole": [1, -1, 0] }
]
}
}
}
}
Properties
Read from world.ik3d.
.mods : { body, limbs? }
The plugins that hand ik3d its bodies and any limbs beside a kind's own (see Mods). body is required.
.kinds : { [kind]: { anchor?, limbs? } }
Kind name, as the body mod names it, to how its body holds its props. A row whose kind is not listed is bent only for the limbs the limbs mod hands it. The table is checked whenever its content changes, and an entry out of shape throws naming it. A bone suffix no bone ends with, a prop the body does not hold and a target the prop does not have throw naming them once the body and its props are there. A prop whose model is still loading is waited for, and until it is there the body stands as its clip draws it.
| Key | Meaning |
|---|---|
anchor | Optional: { prop, bone, at, turn, point }. The prop hung as prop, a loader model, is set so that its empty whose name ends with point, such as a rifle's stock, stands at the frame of the first bone whose name ends with bone, with that frame's scale taken off, moved by at in metres and turned by turn in degrees, an XYZ Euler, in that frame. turn turns the prop about the point, so a stock stays in the shoulder while the muzzle swings. A prop with no such empty is set by its root. With no anchor, every prop stays where its body hung it. |
limbs | Optional: [{ bones, prop, target, pole }], each a limb that reaches a point on a held prop. bones is three bone suffixes: an arm, its forearm and its hand, or a thigh, its shin and its foot. target ends the name of an empty inside the prop hung as prop. pole is a direction in the body root's frame, not zero, that the elbow or knee points toward. |
How a limb reaches
The end bone is put at the target's world position and turned to its world rotation. The distance from the upper bone to the target is cut to what the two bones can span, a millimetre short of straight and no closer than the difference of their lengths, and the middle joint is placed on the side of that line toward pole. The upper and lower bones are each turned by the shortest arc, so the twist each had is kept. The lengths are the bones' own as they stand, so a limb is never stretched. A target out of reach leaves the end bone short of it, by the distance short reports.
Each frame the anchor is set first, then each limb in order: the kind's own, then the handed ones. This is done in ik3d's tick, so an actor's tick reads the reached pose, such as a muzzle where the hands hold it, and again after the body's plugin hangs its props for the frame. Every solve starts from the pose the clip draws, so solving twice in a frame lands the same. A limp body is not bent. A body that goes limp, ends, or whose kind is taken out of kinds stands as its clip draws it again. Where a Mixamo model's meshes each bind a copy of the skeleton, the copy whose bone names carry no _N is solved and every other copy takes its bones' turns.
Methods
On the page, through plugins.ik3d.
short( id ) : number[] | undefined
For each limb of the row on the last solve, in metres, how far its end bone ended from its target: 0 when the target was in reach. The kind's limbs come first, then the handed ones. Undefined for a row that is not being bent.
The solve
From #plugins/ik3d/ik3d.solve.ts. T is the three.js module, handed in. Each writes the objects it turns and brings their world matrices up to date, so the caller reads the result at once.
anchor( T, prop, bone, at, turn, point? )
Sets prop so the empty inside it whose name ends with point lands at bone's world frame, scale taken off, moved by at metres and turned by turn degrees (XYZ) in that frame. With no point, or no such empty, the prop's root lands there. The root's position, rotation and scale are all written.
reach( T, [upper, lower, end], target, pole, up ) : number
Bends a three-bone limb so end stands at target's world position, turned to its world rotation, the middle joint toward pole, a direction in up's frame. Returns how far end ended from the target, in metres.
check( numbers )
From #plugins/ik3d/ik3d.plugin.ts. Checks a world.ik3d table and throws a sentence naming the kind and the field that is out of shape.
Mods
Name them in world.ik3d.mods. Each plugin named is listed before ik3d in the scene's plugins.
- anim
body, required:(plugins, row) → { kind, root, props, limp }, the body anim draws for the row.kindis the kind it is drawn by, itsasor its own,rootits model,propsevery prop its kind hangs as{ model, root }in the kind's order,rootundefined while that model loads, andlimpthe row's field its kind'sreadsnames. Undefined for a row anim does not draw, or whose model is not built yet. - interact
limbs, optional:(plugins, row) → [{ bones, pole, target }], the hands and feet the step of an interaction bends, each reaching a point of the machine.targetis the three.js object it reaches. Undefined or empty for none. With nolimbsmod, a row is bent for its kind's limbs alone.