Build the world-space reflection matrix for plane (n, plane_y). Reflects a world-space point `p` across the plane `n · p = d` where `d = n · (0, plane_y, 0) = n.y * plane_y`. The returned 4×4 matrix R has `R · p = p - 2 (n·p - d) n`, with R applied post-multiply on column vectors (Bloom convention). Plug this into the view chain via `mirror_view = view * R` — post-multiplying R into the view mat
(plane_y: f32, normal: [f32; 3])
| 129 | /// post-multiplying R into the view matrix means: world → mirror |
| 130 | /// (R) → camera (view). |
| 131 | pub fn reflection_matrix(plane_y: f32, normal: [f32; 3]) -> [[f32; 4]; 4] { |
| 132 | let n = normalise(normal); |
| 133 | let d = n[1] * plane_y; |
| 134 | // Standard Householder-style reflection across the plane. |
| 135 | // Column-major; multiplies p as `R * p` (post-mul). |
| 136 | let nx = n[0]; let ny = n[1]; let nz = n[2]; |
| 137 | [ |
| 138 | [1.0 - 2.0 * nx * nx, -2.0 * nx * ny, -2.0 * nx * nz, 0.0], |
| 139 | [-2.0 * ny * nx, 1.0 - 2.0 * ny * ny, -2.0 * ny * nz, 0.0], |
| 140 | [-2.0 * nz * nx, -2.0 * nz * ny, 1.0 - 2.0 * nz * nz, 0.0], |
| 141 | [2.0 * nx * d, 2.0 * ny * d, 2.0 * nz * d, 1.0], |
| 142 | ] |
| 143 | } |
| 144 | |
| 145 | /// Compose a mirrored view matrix from the camera's current view |
| 146 | /// matrix and the reflection plane. |