// shape_renderer.cpp - Implementació del renderitzat de formes // © 2025 Port a C++20 amb SDL3 #include "core/rendering/shape_renderer.hpp" #include #include "core/defaults.hpp" #include "core/rendering/line_renderer.hpp" namespace Rendering { // Helper: transformar un punt amb rotació, escala i trasllació static Punt transform_point(const Punt& point, const Punt& shape_centre, const Punt& posicio, float angle, float escala) { // 1. Centrar el punt respecte al centre de la forma float centered_x = point.x - shape_centre.x; float centered_y = point.y - shape_centre.y; // 2. Aplicar escala al punt centrat float scaled_x = centered_x * escala; float scaled_y = centered_y * escala; // 3. Aplicar rotació // IMPORTANT: En el sistema original, angle=0 apunta AMUNT (no dreta) // Per això usem (angle - PI/2) per compensar // Però aquí angle ja ve en el sistema correcte del joc 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; // 4. Aplicar trasllació a posició mundial return {rotated_x + posicio.x, rotated_y + posicio.y}; } void render_shape(SDL_Renderer* renderer, const std::shared_ptr& shape, const Punt& posicio, float angle, float escala, bool dibuixar, float progress, float brightness) { // Verificar que la forma és vàlida if (!shape || !shape->es_valida()) { return; } // Si progress < 1.0, no dibuixar (tot o res) if (progress < 1.0f) { return; } // Obtenir el centre de la forma per a transformacions const Punt& shape_centre = shape->get_centre(); // Iterar sobre totes les primitives for (const auto& primitive : shape->get_primitives()) { if (primitive.type == Graphics::PrimitiveType::POLYLINE) { // POLYLINE: connectar punts consecutius for (size_t i = 0; i < primitive.points.size() - 1; i++) { Punt p1 = transform_point(primitive.points[i], shape_centre, posicio, angle, escala); Punt p2 = transform_point(primitive.points[i + 1], shape_centre, posicio, angle, escala); linea(renderer, static_cast(p1.x), static_cast(p1.y), static_cast(p2.x), static_cast(p2.y), dibuixar, brightness); } } else { // PrimitiveType::LINE // LINE: exactament 2 punts if (primitive.points.size() >= 2) { Punt p1 = transform_point(primitive.points[0], shape_centre, posicio, angle, escala); Punt p2 = transform_point(primitive.points[1], shape_centre, posicio, angle, escala); linea(renderer, static_cast(p1.x), static_cast(p1.y), static_cast(p2.x), static_cast(p2.y), dibuixar, brightness); } } } } } // namespace Rendering