lovr
lovr copied to clipboard
Add Mat4:reflect
Useful for mirrors. See cpml.
From what I understand,
Reflection matrix is Translate(p) * Reflect(n) * Translate(-p)
Reflect(n) is
col1 = (1,0,0) - 2 * dot(n, (1,0,0)) * n
col2 = (0,1,0) - 2 * dot(n, (0,1,0)) * n
col3 = (0,0,1) - 2 * dot(n, (0,0,1)) * n
MAF mat4 mat4_reflect(mat4 m, vec3 position, vec3 normal) {
float tmp[16];
float nx = normal[0], ny = normal[1], nz = normal[2];
float d = vec3_dot(position, normal);
tmp[0] = -2 * nx * nx + 1;
tmp[1] = -2 * nx * ny; // cpml is missing -
tmp[2] = -2 * nx * nz;
tmp[3] = 0;
tmp[4] = -2 * ny * nx;
tmp[5] = -2 * ny * ny + 1;
tmp[6] = -2 * ny * nz;
tmp[7] = 0;
tmp[8] = -2 * nz * nx;
tmp[9] = -2 * nz * ny;
tmp[10] = -2 * nz * nz + 1;
tmp[11] = 0;
tmp[12] = 2 * d * nx;
tmp[13] = 2 * d * ny;
tmp[14] = 2 * d * nz;
tmp[15] = 1;
mat4_mul(tmp, m);
mat4_set(m, tmp);
return m;
}
In this implementation of mirror (line 55) I arrived at a different method:
Transform(mirrorPose) * FlipZ(n) * Transform(mirrorPose:invert())
where FlipZ is a simple :scale(1, 1, -1)
operation. This method worked for any orientation of mirror and viewer. I found this to be simper than the proposed reflect function which also needs translations.
Is there ambiguity here on which axis/axes get reflected?
Implemented in cad98d8b2ba8800c62c0d028484b8cde4c4970cf