Replace Qt math wrappers with Eigen across ViewportWindow, OverlayRenderer,
Federation, and the bonsai-side viewport modules. Eigen was already the
canonical type for the actually-important matrix work (InstanceCompose,
ModelGpuData, federation matrices); QVector3D/QVector4D/QMatrix4x4 were
leftover from when Qt was the path of least resistance. They offered
nothing over Eigen for our use case beyond a few graphics helpers
(lookAt / perspective / ortho) which were 30 lines to write.
Substitutions:
QMatrix4x4 → Eigen::Matrix4f
QVector2D → Eigen::Vector2f
QVector3D → Eigen::Vector3f
QVector4D → Eigen::Vector4f
API rewrites:
.lengthSquared() → .squaredNorm()
.length() → .norm()
.isNull() → .isZero()
.setToIdentity() → .setIdentity()
.constData() → .data()
.toVector3D() → .head<3>()
.inverted(&ok) → tryInvert4f(M, out)
Q::dotProduct(a,b) → a.dot(b)
Q::crossProduct(a,b) → a.cross(b)
QMat4x4(... row-major) → Eigen::Map<const Matrix4f>(col-major buf)
QMat4x4().lookAt(...) → lookAtRH(eye, target, up)
QMat4x4().perspective(.) → perspectiveYFovGL(fovy, aspect, n, f)
QMat4x4().ortho(...) → orthoGL(l, r, b, t, n, f)
Default-init divergence handled explicitly (QMatrix4x4() = identity,
QVector3D() = zero; Eigen leaves both uninitialized). Public API
(CameraState, HomeView, ViewportWindow::computeObjectAabb, the
addSectionPlaneAtSurface / pickSurfaceAt / raycast signatures) follows
through to Eigen too; bonsai-side View.cpp and Commands.cpp updated to
match.
Camera helpers (lookAtRH, perspectiveYFovGL, orthoGL, tryInvert4f)
extracted to a new CameraMath.h so OverlayRenderer's gizmo MVP and
ViewportWindow's buildViewProj share the same definitions. Federation
drops its <QVector3D> include in favour of <Eigen/Dense> (already had
the latter for the georef matrices).
Builds: desktop IfcViewerMinimal ✓, BonsaiViewer ✓, web IfcViewerWeb ✓.
Tests: 100/100 pass. Closes#78 + #79; opens the door for #80-#83.