c80212adb9
Tanda de identifier-naming de variables y constantes locales a funciones
o archivos. Ninguno cross-file (los símbolos públicos quedan para una
pasada manual con VS Code).
- audio_adapter.cpp: path → PATH (const local en 3 funciones).
- vector_text.cpp: symbols → SYMBOLS, char_width_scaled → CHAR_WIDTH_SCALED,
char_height_scaled → CHAR_HEIGHT_SCALED, spacing_scaled → SPACING_SCALED
(const locales en render/renderCentered/get_text_width).
- physics_world.cpp: acceleration → ACCELERATION (const local en update).
- constants.hpp::dins_zona_joc: point → POINT.
- game_scene.cpp:
- stepGameOver: game_over_text → GAME_OVER_TEXT.
- dibuixar_marcador: scale/spacing → SCALE/SPACING (const), y la ref
local 'scoreboard' (const SDL_FRect&) → 'scoreboard_zone' para no
colisionar con Defaults::Zones::SCOREBOARD (las refs no son
"constant" según el .clang-tidy y deben ser lower_case).
- dibuixar_missatge_stage: max_width → MAX_WIDTH (const local).
- dibuixar_continue: continue_text/counter_str/continues_text →
UPPER_CASE.
- title_scene.cpp::draw (sección MAIN): spacing → SPACING, main_text →
MAIN_TEXT, escala_main → MAIN_SCALE.
- shape_renderer.cpp: const Vec2& SHAPE_CENTRE → shape_centre (es ref,
no constant).
- collision_system.cpp: const Vec2& POS_ENEMIC → enemy_pos (ref + traducción).
- init_hud_animator.cpp: refs ZONA → zone (en 2 funciones), SCOREBOARD →
scoreboard_zone (sin colisionar con Defaults::Zones::SCOREBOARD).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
112 lines
4.4 KiB
C++
112 lines
4.4 KiB
C++
// shape_renderer.cpp - Implementació del renderizado de formes
|
|
// © 2026 JailDesigner
|
|
|
|
#include "core/rendering/shape_renderer.hpp"
|
|
|
|
#include <cmath>
|
|
|
|
#include "core/defaults.hpp"
|
|
#include "core/rendering/line_renderer.hpp"
|
|
|
|
namespace Rendering {
|
|
|
|
// Helper: aplicar rotación 3D a un point 2D (assumeix Z=0)
|
|
static auto apply3dRotation(float x, float y, const Rotation3D& rot) -> Vec2 {
|
|
float z = 0.0F; // Todos los points 2D comencen a Z=0
|
|
|
|
// Pitch (rotación eix X): cabeceo arriba/baix
|
|
float cos_pitch = std::cos(rot.pitch);
|
|
float sin_pitch = std::sin(rot.pitch);
|
|
float y1 = (y * cos_pitch) - (z * sin_pitch);
|
|
float z1 = (y * sin_pitch) + (z * cos_pitch);
|
|
|
|
// Yaw (rotación eix Y): guiñada izquierda/derecha
|
|
float cos_yaw = std::cos(rot.yaw);
|
|
float sin_yaw = std::sin(rot.yaw);
|
|
float x2 = (x * cos_yaw) + (z1 * sin_yaw);
|
|
float z2 = (-x * sin_yaw) + (z1 * cos_yaw);
|
|
|
|
// Roll (rotación eix Z): alabeo lateral
|
|
float cos_roll = std::cos(rot.roll);
|
|
float sin_roll = std::sin(rot.roll);
|
|
float x3 = (x2 * cos_roll) - (y1 * sin_roll);
|
|
float y3 = (x2 * sin_roll) + (y1 * cos_roll);
|
|
|
|
// Proyecció perspectiva (Z-divide simple)
|
|
// Naves quieren hacia el point de fuga (320, 240) a "infinit" (Z → +∞)
|
|
// Z més grande = més lluny = més pequeño a pantalla
|
|
constexpr float PERSPECTIVE_FACTOR = 500.0F;
|
|
float scale_factor = PERSPECTIVE_FACTOR / (PERSPECTIVE_FACTOR + z2);
|
|
|
|
return {.x = x3 * scale_factor, .y = y3 * scale_factor};
|
|
}
|
|
|
|
// Helper: transformar un point con rotación, scale i traslación
|
|
static auto transformPoint(const Vec2& point, const Vec2& shape_centre, const Vec2& position, float angle, float scale, const Rotation3D* rotation_3d) -> Vec2 {
|
|
// 1. Centrar el point respecte al centro de la shape
|
|
float centered_x = point.x - shape_centre.x;
|
|
float centered_y = point.y - shape_centre.y;
|
|
|
|
// 2. Aplicar rotación 3D (si es proporciona)
|
|
if ((rotation_3d != nullptr) && rotation_3d->has_rotation()) {
|
|
Vec2 rotated_3d = apply3dRotation(centered_x, centered_y, *rotation_3d);
|
|
centered_x = rotated_3d.x;
|
|
centered_y = rotated_3d.y;
|
|
}
|
|
|
|
// 3. Aplicar scale al point (después de rotación 3D)
|
|
float scaled_x = centered_x * scale;
|
|
float scaled_y = centered_y * scale;
|
|
|
|
// 4. Aplicar rotación 2D (Z-axis, tradicional)
|
|
// IMPORTANT: En el sistema original, angle=0 apunta AMUNT (no derecha)
|
|
// Per això usem (angle - PI/2) per compensar
|
|
// Pero aquí angle ya ve en el sistema correcte del juego
|
|
float cos_a = std::cos(angle);
|
|
float sin_a = std::sin(angle);
|
|
|
|
float rotated_x = (scaled_x * cos_a) - (scaled_y * sin_a);
|
|
float rotated_y = (scaled_x * sin_a) + (scaled_y * cos_a);
|
|
|
|
// 5. Aplicar traslación a posición mundial
|
|
return {.x = rotated_x + position.x, .y = rotated_y + position.y};
|
|
}
|
|
|
|
void render_shape(Rendering::Renderer* renderer,
|
|
const std::shared_ptr<Graphics::Shape>& shape,
|
|
const Vec2& position,
|
|
float angle,
|
|
float scale,
|
|
float progress,
|
|
float brightness,
|
|
const Rotation3D* rotation_3d,
|
|
SDL_Color color) {
|
|
if (!shape || !shape->isValid()) {
|
|
return;
|
|
}
|
|
if (progress < 1.0F) {
|
|
return;
|
|
}
|
|
|
|
const Vec2& shape_centre = shape->getCenter();
|
|
|
|
for (const auto& primitive : shape->get_primitives()) {
|
|
if (primitive.type == Graphics::PrimitiveType::POLYLINE) {
|
|
// POLYLINE: conectar puntos consecutivos.
|
|
for (size_t i = 0; i < primitive.points.size() - 1; i++) {
|
|
const Vec2 P1 = transformPoint(primitive.points[i], shape_centre, position, angle, scale, rotation_3d);
|
|
const Vec2 P2 = transformPoint(primitive.points[i + 1], shape_centre, position, angle, scale, rotation_3d);
|
|
linea(renderer, static_cast<int>(P1.x), static_cast<int>(P1.y),
|
|
static_cast<int>(P2.x), static_cast<int>(P2.y), brightness, 0.0F, color);
|
|
}
|
|
} else if (primitive.points.size() >= 2) { // LINE
|
|
const Vec2 P1 = transformPoint(primitive.points[0], shape_centre, position, angle, scale, rotation_3d);
|
|
const Vec2 P2 = transformPoint(primitive.points[1], shape_centre, position, angle, scale, rotation_3d);
|
|
linea(renderer, static_cast<int>(P1.x), static_cast<int>(P1.y),
|
|
static_cast<int>(P2.x), static_cast<int>(P2.y), brightness, 0.0F, color);
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace Rendering
|