Resources Numerical accuracy
Calculations
Every calculation under our calculation policies: what it works out, its formula and the precision it runs at. Open one to see its code as it is in the released app.
Calculations
-
Rotation matrix to quaternion
The unit quaternion of a rotation given by its three axes.
Rigid body simulation anim/physics.js64-bit- ModelCraft
-
Placement matrix from a body state
The placement's world matrix for a simulated position and turn.
axes = q applied to X, Y, Z, times the placement's scale; origin = body center − rotated, scaled center offset
Rigid body simulation anim/physics.js64-bit- ModelCraft
-
Mass and inertia
The inverse mass and inverse moments of inertia of a box or a sphere.
sphere: I = 0.4 m r²; box: I_x = m (b² + c²) ÷ 12, and likewise for y and z
Rigid body simulation anim/physics.js64-bit- ModelCraft
-
Depth of a point inside a box
How far a point is inside a box and the outward normal of the nearest face.
local = q⁻¹ (p − center); depth = min over axes of (half + margin − |local|) − margin
Rigid body simulation anim/physics.js64-bit- ModelCraft
-
Positional correction
Pushes two bodies apart along a normal by a given distance, sharing it by their mass and inertia.
w = Σ (1 ÷ m + (r × n) · I⁻¹ (r × n)); λ = c ÷ w; x += n λ ÷ m; q += ½ (Δω, 0) q, made unit
Rigid body simulation anim/physics.js64-bit- ModelCraft
-
Step size and frame count
How many frames are recorded and how long one substep is.
frames = max(1, round((to − from) × fps) + 1); h = 1 ÷ fps ÷ substeps
Rigid body simulation anim/physics.js64-bit- ModelCraft
-
Integration of one substep
Advances each moving body's speed, position and turn by one substep under gravity.
v += g h; x += v h; q += ½ h (ω, 0) q, made unit
Rigid body simulation anim/physics.js64-bit- ModelCraft
-
Contacts and static friction
Pushes each touching point out of the surface and holds it still where friction can.
μ = √(μ_a μ_b); held when slide < μ |λ| × 1.5 + 1e-9
Rigid body simulation anim/physics.js64-bit- ModelCraft
-
Velocities from positions
Works each body's speed and spin back from how far it moved in the substep.
v = (x − x_prev) ÷ h; ω = 2 ÷ h × vector part of (q × q_prev⁻¹)
Rigid body simulation anim/physics.js64-bit- ModelCraft
-
Dynamic friction and bounce
Slows sliding at each contact and sets the speed a body leaves a surface with.
friction impulse = min(μ |λ| ÷ h, sliding speed ÷ inverse mass); leaving speed = −e × min(incoming normal speed, 0); e = 0 when |incoming| < 2 |g · n| h
Rigid body simulation anim/physics.js64-bit- ModelCraft
-
Settled test
Says whether every body has come to rest at the end of the run.
settled when every |v| < 0.02 and every |ω| < 0.05
Rigid body simulation anim/physics.js64-bit- ModelCraft
-
4×4 matrix product
The product of two column-major 4×4 matrices.
Bone frames and pose matrices anim/rig.js64-bit- ModelCraft
-
4×4 matrix inverse
The inverse of a 4×4 matrix by cofactors.
M⁻¹ = adjugate(M) ÷ det(M)
Bone frames and pose matrices anim/rig.js64-bit- ModelCraft
-
A bone's rest frame
The matrix from a bone's own frame to the mesh: Y from head to tail, Z as near the mesh's +Z as it can be, turned by the roll.
y = (tail − head) made unit; z = (up − y (up · y)) made unit; x = y × z; roll turns x and z about y
Bone frames and pose matrices anim/rig.js64-bit- ModelCraft
-
Posed bone and skin matrices
Each bone's posed frame and the matrix that moves rest points to the pose.
W = W_parent × R_parent⁻¹ × R × local; skin = W × R⁻¹
Bone frames and pose matrices anim/rig.js64-bit- ModelCraft
-
Skin matrices as dual quaternions
Each bone's turn and move as a unit dual quaternion, for dual-quaternion skinning.
dual part = ½ × (t, 0) × q
Bone frames and pose matrices anim/rig.js64-bit- ModelCraft
-
A bone's pose from a drag
The location or rotation a bone gets when it is dragged in the view.
turn: angle swept round the bone's head on screen, about the view axis carried into the bone's frame; move: pixels × pixel size, along the camera's right and up, carried into the bone's frame
Bone frames and pose matrices anim/rig-view.js64-bit- ModelCraft
-
The four strongest bones per vertex
Keeps each vertex's four largest weights and scales them to add up to 1.
w_q = w_q ÷ Σ of the kept weights
Skin weights and skinning anim/rig.js32-bit in part- ModelCraft
-
Linear blend skinning
Moves each vertex to the weighted sum of its positions under its bones' matrices.
p′ = Σ wᵢ × (Mᵢ × p)
Skin weights and skinning anim/rig.js32-bit in part- ModelCraft
-
Dual quaternion skinning
Blends the bones' dual quaternions by weight, makes the result unit and moves the vertex with it.
(r, d) = Σ ±wᵢ (rᵢ, dᵢ); both divided by |r|; p′ = r p r⁻¹ + 2 d r⁻¹
Skin weights and skinning anim/rig.js32-bit in part- ModelCraft
-
Distance from a point to a bone
The distance from a vertex to the segment from a bone's head to its tail.
k = clamp(((p − a) · (b − a)) ÷ |b − a|², 0, 1); d = |a + (b − a) k − p|
Skin weights and skinning anim/weights.js64-bit- ModelCraft
-
Edge weights of the mesh
For each vertex, its neighbors and a weight for each edge, used to spread heat and to smooth.
edge weight = 1 ÷ max(1e-12, length²)
Skin weights and skinning anim/weights.js64-bit- ModelCraft
-
Automatic weights
Each bone's weight on each vertex, by bone heat or by distance, with faint weights dropped and each vertex's weights adding up to 1.
heat: solve (L + H) w = H p per bone, H = 1 ÷ nearest distance²; envelope: w = 1 ÷ d⁴ for bones within twice the nearest distance; drop w < 0.01; divide by the sum
Skin weights and skinning anim/weights.js32-bit in part- ModelCraft
-
One dab of the weight brush
Raises, lowers, sets or smooths a bone's weight on the vertices under the brush, and scales the other bones' weights to share what is left.
falloff f = (1 − d² ÷ r²)² × strength; add: w + f (1 − w); subtract: w − f w; others scaled by max(0, 1 − w) ÷ their sum
Skin weights and skinning anim/weights.js32-bit in part- ModelCraft
-
Weights from packed joint layers
Turns the four joint numbers and weights per vertex read from a file into one weight layer per bone.
weight of bone b on vertex v = Σ of the packed weights that name b
Skin weights and skinning anim/weights.js32-bit in part- ModelCraft
-
Skin weights read from an FBX file
Keeps each control point's four strongest clusters and scales their weights to add up to 1.
w = w ÷ Σ of the four kept weights
Skin weights and skinning io/fbx-import.js32-bit in part- ModelCraft
-
One sample of a property
Reads one stored sample of a scalar or array property into a typed array.
Alembic import io/abc.js64-bit- ModelCraft
-
16-bit float to a number
Decodes a half-precision float.
subnormal: ± m × 2⁻²⁴; normal: ± (1 + m ÷ 1024) × 2^(e − 15)
Alembic import io/abc.js64-bit- ModelCraft
-
Which time sample is read
The index of the stored sample nearest a given time.
time of sample i = times[i mod n] + floor(i ÷ n) × time per cycle; nearest by |time − t|
Alembic import io/abc.js64-bit- ModelCraft
-
An object's transform
Builds an object's matrix from its list of scale, translate, rotate and matrix operations.
M = op₁ × op₂ × … (the first operation outermost)
Alembic import io/abc.js64-bit- ModelCraft
-
Rotation about an axis
The matrix of a turn by an angle in degrees about an axis.
a = deg × π ÷ 180; Rodrigues' formula with the axis made unit
Alembic import io/abc.js64-bit- ModelCraft
-
Mesh points into Z up
Copies the file's points into the model's coordinates.
(x, y, z) → (x, −z, y)
Alembic import io/abc.js64-bit- ModelCraft
-
Node matrix into Z up
Changes a node's matrix from Y up to Z up.
M′ = C × M × C⁻¹
Alembic import io/abc.js64-bit- ModelCraft
-
Which way the faces turn
Decides whether the file's faces must be turned round, by comparing each face's own normal with the file's normals.
Newell normal n = Σ (yₐ − y_b)(zₐ + z_b), …; agree when n · Σ file normals > 0
Alembic import io/abc.js64-bit- ModelCraft
-
Axes and unit
The matrix that takes the file's coordinates to Z up and meters.
k = UnitScaleFactor × 0.01; columns = ± k along the model axis each file axis maps to
FBX import: axes, units and transforms io/fbx-import.js64-bit- ModelCraft
-
Node matrices into the model's axes
Carries a node's matrix from the file's axes and unit into the model's.
M′ = A × M × A⁻¹
FBX import: axes, units and transforms io/fbx-import.js64-bit- ModelCraft
-
Euler angles to a matrix
The rotation matrix of three angles in degrees in the file's rotation order.
XYZ order: R = Rz × Ry × Rx, angles × π ÷ 180
FBX import: axes, units and transforms io/fbx-import.js64-bit- ModelCraft
-
An object's own matrix
Builds a model's local matrix from its translation, offsets, pivots, pre-, own and post-rotation, and scaling.
M = T × Roff × Rp × Rpre × R × Rpost⁻¹ × Rp⁻¹ × Soff × Sp × S × Sp⁻¹
FBX import: axes, units and transforms io/fbx-import.js64-bit- ModelCraft
-
Mesh points into the model
Carries each control point through the axis and unit matrix.
p′ = A × p
FBX import: axes, units and transforms io/fbx-import.js64-bit- ModelCraft
-
Lamps
A lamp's position, direction and brightness from an FBX light.
lumens = Intensity × 8; direction = the node's −Y, made unit
FBX import: axes, units and transforms io/fbx-import.js64-bit- ModelCraft
-
Cameras
A saved view's eye, target and field of view from an FBX camera.
target = eye + 10 × forward; parallel view height = OrthoZoom × 10
FBX import: axes, units and transforms io/fbx-import.js64-bit- ModelCraft
-
Reading an accessor
Reads one accessor's numbers, with its sparse part, into a typed array.
normalized: v ÷ 127, 255, 32767 or 65535 (signed values not below −1)
glTF import: reading numbers io/gltf-read.js64-bit- ModelCraft
-
Positions
Takes a primitive's positions as 32-bit floats and checks each is a sane number.
glTF import: reading numbers io/gltf-read.js64-bit- ModelCraft
-
Matrix from translation, rotation and scale
A node's 4×4 matrix from its translation, quaternion and scale.
quaternion made unit; rotation entries 1 − 2(y² + z²), 2(xy + zw), …, each column times its scale
glTF import: reading numbers io/gltf-read.js64-bit- ModelCraft
-
A node's local matrix
Uses the node's 16-number matrix as given, or builds it from translation, rotation and scale.
glTF import: reading numbers io/gltf-read.js64-bit- ModelCraft
-
Morph weights and the skin
A primitive's positions and normals as the scene shows them: morph targets added by their weights, then moved by the skin's joints.
morph: p += w × target; skin: p′ = Σ wᵢ (Jᵢ × IBMᵢ × p) ÷ Σ wᵢ
glTF import: meshes, skins and placements io/gltf-import.js32-bit in part- ModelCraft
-
Welding vertices
Makes one mesh vertex for every distinct point of a primitive and swaps the axes to Z up.
same vertex when x, y and z (and joints and weights) are equal as text; stored as (x, −z, y)
glTF import: meshes, skins and placements io/gltf-import.js64-bit- ModelCraft
-
Triangles with no area
Drops triangles that repeat a vertex or whose corners lie on one line.
kept when |(b − a) × (c − a)| > 1e-18
glTF import: meshes, skins and placements io/gltf-import.js64-bit- ModelCraft
-
Sharp edges
Marks an edge sharp where the file's normals break across it, or where the two faces bend.
with normals: sharp unless n₁ · n₂ > 0.9995 at both ends; without: sharp when the face normals' dot product < 0.99996
glTF import: meshes, skins and placements io/gltf-import.js64-bit- ModelCraft
-
Node matrix into Z up
Changes a node's matrix from Y up to Z up.
M′ = C × M × C⁻¹
glTF import: meshes, skins and placements io/gltf-import.js64-bit- ModelCraft
A calculation is added only after its source was read. Each statement can be checked in the code shown on its policy's page; the app repositories are public. When a release changes a calculation, its page says so until it has been read again.