planar method
Texture coordinates of a point (x, y, z) on a flat face facing
(nx, ny, nz): projected onto the face, in metres (of the world
for ShapeUv.metres), right and down as seen from outside it.
Implementation
(double, double) planar(
double x,
double y,
double z,
double nx,
double ny,
double nz,
) {
final px = x * uv.sx, py = y * uv.sy, pz = z * uv.sz;
var mx = nx / uv.sx, my = ny / uv.sy, mz = nz / uv.sz;
final len = math.sqrt(mx * mx + my * my + mz * mz);
if (len > 0) {
mx /= len;
my /= len;
mz /= len;
}
if (my.abs() >= 0.9) {
// A floor or a ceiling: north is up the texture.
return my < 0 ? (px, -pz) : (-px, -pz);
}
// A wall: right is (−n) × up, down is right × n.
final rl = math.sqrt(mz * mz + mx * mx);
final rx = -mz / rl, rz = mx / rl;
final dx = -rz * my, dy = rz * mx - rx * mz, dz = rx * my;
return (px * rx + pz * rz, px * dx + py * dy + pz * dz);
}