#pragma once #include #include #include namespace vcs { // GE affine matrices use the same layout as ge_renderer::transform_4x3: // // view = A * world + t // A = [m0 m3 m6; m1 m4 m7; m2 m5 m8], t = [m9 m10 m11]. // // view_to_world is A^-1 in row-major order. The three named axes are its // columns, so A^-1 * view_direction is exactly // right*x + up*y + forward*z. They are intentionally not normalized: retaining // scale/shear makes the result a true inverse for every nonsingular GE view. struct GeCloudCameraFrame { std::array view_to_world{}; std::array position{}; std::array right{}; std::array up{}; std::array forward{}; }; namespace ge_cloud_camera_detail { constexpr double absolute(double value) noexcept { return value < 0.0 ? -value : value; } constexpr bool finite(double value) noexcept { return value == value && value <= std::numeric_limits::max() && value >= -std::numeric_limits::max(); } constexpr bool finite_float_result(double value) noexcept { return finite(value) && absolute(value) <= static_cast(std::numeric_limits::max()); } } // namespace ge_cloud_camera_detail // Computes a full inverse of the GE view's 3x3 linear part. Returns false for // non-finite or (numerically) singular input and leaves `out` unchanged. [[nodiscard]] inline constexpr bool ge_cloud_invert_view_linear( const std::array &view, std::array &out) noexcept { using ge_cloud_camera_detail::absolute; using ge_cloud_camera_detail::finite; using ge_cloud_camera_detail::finite_float_result; for (float value : view) { if (!finite(static_cast(value))) return false; } const double a = view[0], b = view[3], c = view[6]; const double d = view[1], e = view[4], f = view[7]; const double g = view[2], h = view[5], i = view[8]; double scale = 0.0; for (std::size_t index = 0; index < 9; ++index) { const double value = absolute(static_cast(view[index])); if (value > scale) scale = value; } if (scale == 0.0) return false; const double determinant = a * (e * i - f * h) - b * (d * i - f * g) + c * (d * h - e * g); const double singular_threshold = 8.0 * static_cast(std::numeric_limits::epsilon()) * scale * scale * scale; if (!finite(determinant) || absolute(determinant) <= singular_threshold) return false; const double inverse_determinant = 1.0 / determinant; const std::array inverse{ (e * i - f * h) * inverse_determinant, (c * h - b * i) * inverse_determinant, (b * f - c * e) * inverse_determinant, (f * g - d * i) * inverse_determinant, (a * i - c * g) * inverse_determinant, (c * d - a * f) * inverse_determinant, (d * h - e * g) * inverse_determinant, (b * g - a * h) * inverse_determinant, (a * e - b * d) * inverse_determinant, }; std::array result{}; for (std::size_t index = 0; index < inverse.size(); ++index) { if (!finite_float_result(inverse[index])) return false; result[index] = static_cast(inverse[index]); } out = result; return true; } // Builds the world-space camera origin and the exact view-to-world basis from // a GE world-to-view matrix. Returns false and leaves `out` unchanged if the // matrix cannot be inverted or any derived value is non-finite. [[nodiscard]] inline constexpr bool ge_cloud_camera_frame_from_view( const std::array &view, GeCloudCameraFrame &out) noexcept { std::array inverse{}; if (!ge_cloud_invert_view_linear(view, inverse)) return false; const double tx = view[9], ty = view[10], tz = view[11]; const std::array position{ -(static_cast(inverse[0]) * tx + static_cast(inverse[1]) * ty + static_cast(inverse[2]) * tz), -(static_cast(inverse[3]) * tx + static_cast(inverse[4]) * ty + static_cast(inverse[5]) * tz), -(static_cast(inverse[6]) * tx + static_cast(inverse[7]) * ty + static_cast(inverse[8]) * tz), }; for (double value : position) { if (!ge_cloud_camera_detail::finite_float_result(value)) return false; } GeCloudCameraFrame result{}; result.view_to_world = inverse; result.position = {static_cast(position[0]), static_cast(position[1]), static_cast(position[2])}; result.right = {inverse[0], inverse[3], inverse[6]}; result.up = {inverse[1], inverse[4], inverse[7]}; result.forward = {inverse[2], inverse[5], inverse[8]}; out = result; return true; } namespace ge_cloud_camera_detail { // Compile-time contract check using an exact 90-degree rotation and // translation. This also catches accidental row/column transposition. static_assert([] { constexpr std::array view{ 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 3.0f, -2.0f, -4.0f, }; GeCloudCameraFrame frame{}; return ge_cloud_camera_frame_from_view(view, frame) && frame.position == std::array{2.0f, 3.0f, 4.0f} && frame.right == std::array{0.0f, -1.0f, 0.0f} && frame.up == std::array{1.0f, 0.0f, 0.0f} && frame.forward == std::array{0.0f, 0.0f, 1.0f}; }()); static_assert([] { constexpr std::array singular{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, }; GeCloudCameraFrame frame{}; return !ge_cloud_camera_frame_from_view(singular, frame); }()); } // namespace ge_cloud_camera_detail } // namespace vcs