add3f(v, n) { v[0] += n[0], v[1] += n[1]; v[2] += n[2]; }
sub3f(v, n) { v[0] -= n[0], v[1] -= n[1]; v[2] -= n[2]; }
sub2f(v, n) { v[0] -= n[0], v[1] -= n[1]; }
neg3f(v) { v[0] = -v[0]; v[1] = -v[1]; v[2] = -v[2]; }
dot3f(v, o) (v[0]*o[0] + v[1]*o[1] + v[2]*o[2])
cross3f(a, b) { a[1]*b[2]-a[2]*b[1], a[2]*b[0]-a[0]*b[2], a[0]*b[1]-a[1]*b[0] }
norm3f(v, n) { float invlen = 1.0f/sqrtf(dot3f(n, n)); v[0] = n[0]*invlen; v[1] = n[1]*invlen; v[2] = n[2]*invlen; }
project3f(v, a, b) { float d = dot3f(a, b); v[0] = a[0] - b[0]*d; v[1] = a[1] - b[1]*d; v[2] = a[2] - b[2]*d; }