From d3076fbdec36768015ebdf12666fe90d8ce7656d Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Fri, 22 May 2026 10:20:39 +0200 Subject: [PATCH] =?UTF-8?q?tweak(ship-3d):=20descans=20prop=20de=20P-PRESS?= =?UTF-8?q?=20/=20Y-PLAY,=20m=C3=A9s=20mida,=20pitch=20+14=C2=B0=20lift?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/game/title/ship_animator3d.cpp | 41 +++++++++++++++------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/source/game/title/ship_animator3d.cpp b/source/game/title/ship_animator3d.cpp index 6792c4d..f25c554 100644 --- a/source/game/title/ship_animator3d.cpp +++ b/source/game/title/ship_animator3d.cpp @@ -23,31 +23,36 @@ namespace Title { constexpr Vec3 VANISHING_POINT{.x = 0.0F, .y = 0.0F, .z = SHIP_EXIT_Z}; // Directors VP → origen de cada nau, normalitzats. P1 ve des de "les 7" - // del rellotge (baix-esquerra), P2 des de "les 5" (baix-dreta). El rellotge - // envolta el VP en l'espai 3D; el seu centre coincideix amb el VP a pantalla. - // Tots tres punts d'animació (initial, target, EXIT) cauen sobre aquesta - // línia recta, així el forward_dir és constant i no hi ha "POP" en - // canviar d'estat. - constexpr Vec3 PATH_DIR_P1{.x = -0.286F, .y = -0.143F, .z = -0.949F}; - constexpr Vec3 PATH_DIR_P2{.x = +0.286F, .y = -0.143F, .z = -0.949F}; + // del rellotge (baix-esquerra), P2 des de "les 5" (baix-dreta). Els + // components estan calibrats perquè a TARGET_DIST el pixel projectat + // caigui aprox sota la "P de PRESS" / "Y de PLAY" del text del títol. + constexpr Vec3 PATH_DIR_P1{.x = -0.0887F, .y = -0.0683F, .z = -0.9938F}; + constexpr Vec3 PATH_DIR_P2{.x = +0.0887F, .y = -0.0683F, .z = -0.9938F}; // Distàncies des del VP al llarg del path (unitats mundials). - constexpr float TARGET_DIST = 540.0F; // Posició de descans (intermèdia) - constexpr float ENTRY_DIST = 740.0F; // Posició inicial (més a prop de càmera) + constexpr float TARGET_DIST = 563.5F; // Descans a Z≈240 → pixel ≈ (510, 460) + constexpr float ENTRY_DIST = 750.0F; // Inicial a Z≈54 → fora pantalla baix-esq. + + // Pitch addicional sobre el look-at pur per fer que el dors de la nau + // s'incline cap a la càmera (~-14° afegits). Amb forward quasi paral·lel + // a +Z, el pitch look-at és ~-94°; afegint això queda al voltant de -108°, + // que és l'angle visualment validat com a "bo" per l'usuari. + constexpr float PITCH_LIFT_RAD = -0.25F; // Look-at: calcula pitch+yaw que duen (0,-1,0) local a forward_dir mundial. // Requereix l'ordre de rotació X→Y→Z al applyTransform de wireframe3d. // Si forward és quasi vertical (sin(pitch) ≈ 0), retorna yaw=0 (qualsevol). auto computePitchYawForLookAt(const Vec3& forward_dir) -> Vec2 { const float DY = std::clamp(forward_dir.y, -1.0F, 1.0F); - const float PITCH = -std::acos(-DY); // ∈ [-π, 0] - const float SIN_PITCH = std::sin(PITCH); - if (std::abs(SIN_PITCH) < 1.0E-5F) { - return Vec2{.x = PITCH, .y = 0.0F}; + const float PITCH_LOOKAT = -std::acos(-DY); // ∈ [-π, 0] + const float SIN_PITCH = std::sin(PITCH_LOOKAT); + float yaw = 0.0F; + if (std::abs(SIN_PITCH) >= 1.0E-5F) { + const float SY = -forward_dir.x / SIN_PITCH; + const float CY = -forward_dir.z / SIN_PITCH; + yaw = std::atan2(SY, CY); } - const float SY = -forward_dir.x / SIN_PITCH; - const float CY = -forward_dir.z / SIN_PITCH; - return Vec2{.x = PITCH, .y = std::atan2(SY, CY)}; + return Vec2{.x = PITCH_LOOKAT + PITCH_LIFT_RAD, .y = yaw}; } auto safeNormalize(const Vec3& v, const Vec3& fallback) -> Vec3 { @@ -70,8 +75,8 @@ namespace Title { } // Mida visual i animació. - constexpr float SHIP_FLOAT_SCALE = 1.0F; - constexpr float SHIP_ENTRY_SCALE = 1.0F; // Mida mundial idèntica; la perspectiva fa la resta + constexpr float SHIP_FLOAT_SCALE = 1.1F; + constexpr float SHIP_ENTRY_SCALE = 1.1F; // Mida mundial idèntica; la perspectiva fa la resta constexpr float ENTRY_DURATION = 2.0F; constexpr float EXIT_DURATION = 1.0F;