treballant en les naus de title

This commit is contained in:
2025-12-16 22:14:55 +01:00
parent 75a4a1b3b9
commit bc5982b286
12 changed files with 946 additions and 19 deletions

View File

@@ -10,17 +10,55 @@
namespace Rendering {
// Helper: aplicar rotació 3D a un punt 2D (assumeix Z=0)
static Punt apply_3d_rotation(float x, float y, const Rotation3D& rot) {
float z = 0.0f; // Tots els punts 2D comencen a Z=0
// Pitch (rotació 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ó eix Y): guiñada esquerra/dreta
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ó 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)
// Naus volen cap al punt de fuga (320, 240) a "infinit" (Z → +∞)
// Z més gran = més lluny = més petit a pantalla
constexpr float perspective_factor = 500.0f;
float scale_factor = perspective_factor / (perspective_factor + z2);
return {x3 * scale_factor, y3 * scale_factor};
}
// 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) {
static Punt transform_point(const Punt& point, const Punt& shape_centre, const Punt& posicio, float angle, float escala, const Rotation3D* rotation_3d) {
// 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
// 2. Aplicar rotació 3D (si es proporciona)
if (rotation_3d && rotation_3d->has_rotation()) {
Punt rotated_3d = apply_3d_rotation(centered_x, centered_y, *rotation_3d);
centered_x = rotated_3d.x;
centered_y = rotated_3d.y;
}
// 3. Aplicar escala al punt (després de rotació 3D)
float scaled_x = centered_x * escala;
float scaled_y = centered_y * escala;
// 3. Aplicar rotació
// 4. Aplicar rotació 2D (Z-axis, tradicional)
// 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
@@ -30,7 +68,7 @@ static Punt transform_point(const Punt& point, const Punt& shape_centre, const P
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
// 5. Aplicar trasllació a posició mundial
return {rotated_x + posicio.x, rotated_y + posicio.y};
}
@@ -41,7 +79,8 @@ void render_shape(SDL_Renderer* renderer,
float escala,
bool dibuixar,
float progress,
float brightness) {
float brightness,
const Rotation3D* rotation_3d) {
// Verificar que la forma és vàlida
if (!shape || !shape->es_valida()) {
return;
@@ -60,16 +99,16 @@ void render_shape(SDL_Renderer* renderer,
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);
Punt p1 = transform_point(primitive.points[i], shape_centre, posicio, angle, escala, rotation_3d);
Punt p2 = transform_point(primitive.points[i + 1], shape_centre, posicio, angle, escala, rotation_3d);
linea(renderer, static_cast<int>(p1.x), static_cast<int>(p1.y), static_cast<int>(p2.x), static_cast<int>(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);
Punt p1 = transform_point(primitive.points[0], shape_centre, posicio, angle, escala, rotation_3d);
Punt p2 = transform_point(primitive.points[1], shape_centre, posicio, angle, escala, rotation_3d);
linea(renderer, static_cast<int>(p1.x), static_cast<int>(p1.y), static_cast<int>(p2.x), static_cast<int>(p2.y), dibuixar, brightness);
}

View File

@@ -12,6 +12,20 @@
namespace Rendering {
// Estructura per rotacions 3D (pitch, yaw, roll)
struct Rotation3D {
float pitch; // Rotació eix X (cabeceo arriba/baix)
float yaw; // Rotació eix Y (guiñada esquerra/dreta)
float roll; // Rotació eix Z (alabeo lateral)
Rotation3D() : pitch(0.0f), yaw(0.0f), roll(0.0f) {}
Rotation3D(float p, float y, float r) : pitch(p), yaw(y), roll(r) {}
bool has_rotation() const {
return pitch != 0.0f || yaw != 0.0f || roll != 0.0f;
}
};
// Renderitzar forma amb transformacions
// - renderer: SDL renderer
// - shape: forma vectorial a dibuixar
@@ -28,6 +42,7 @@ void render_shape(SDL_Renderer* renderer,
float escala = 1.0f,
bool dibuixar = true,
float progress = 1.0f,
float brightness = 1.0f);
float brightness = 1.0f,
const Rotation3D* rotation_3d = nullptr);
} // namespace Rendering