sevenx_engine 0.2.11

Engine de jogos 2D/3D completa com suporte Android, física, áudio, partículas, tilemap, UI, eventos e sistema 3D avançado com PBR.
Documentation
// Câmera 3D Experimental
use crate::mesh3d::Vec3;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Camera3D {
    pub position: Vec3,
    pub target: Vec3,
    pub up: Vec3,
    pub fov: f32,
    pub near: f32,
    pub far: f32,
    pub aspect_ratio: f32,
}

impl Camera3D {
    pub fn new(width: u32, height: u32) -> Self {
        Self {
            position: Vec3::new(0.0, 0.0, 5.0),
            target: Vec3::zero(),
            up: Vec3::new(0.0, 1.0, 0.0),
            fov: 60.0,
            near: 0.1,
            far: 100.0,
            aspect_ratio: width as f32 / height as f32,
        }
    }

    pub fn look_at(&mut self, target: Vec3) {
        self.target = target;
    }

    pub fn move_forward(&mut self, distance: f32) {
        let forward = Vec3::new(
            self.target.x - self.position.x,
            self.target.y - self.position.y,
            self.target.z - self.position.z,
        )
        .normalize();

        self.position.x += forward.x * distance;
        self.position.y += forward.y * distance;
        self.position.z += forward.z * distance;
    }

    pub fn rotate_around_target(&mut self, angle_x: f32, angle_y: f32) {
        let dx = self.position.x - self.target.x;
        let dy = self.position.y - self.target.y;
        let dz = self.position.z - self.target.z;

        // Rotação Y
        let cos_y = angle_y.cos();
        let sin_y = angle_y.sin();
        let new_x = dx * cos_y - dz * sin_y;
        let new_z = dx * sin_y + dz * cos_y;

        // Rotação X
        let cos_x = angle_x.cos();
        let sin_x = angle_x.sin();
        let new_y = dy * cos_x - new_z * sin_x;
        let final_z = dy * sin_x + new_z * cos_x;

        self.position.x = self.target.x + new_x;
        self.position.y = self.target.y + new_y;
        self.position.z = self.target.z + final_z;
    }

    // Projeção simples de ponto 3D para 2D
    pub fn project(&self, point: &Vec3, screen_width: u32, screen_height: u32) -> Option<(i32, i32, f32)> {
        let dx = point.x - self.position.x;
        let dy = point.y - self.position.y;
        let dz = point.z - self.position.z;

        if dz <= 0.0 {
            return None;
        }

        let fov_rad = self.fov.to_radians();
        let scale = (fov_rad / 2.0).tan();

        let x = dx / (dz * scale * self.aspect_ratio);
        let y = dy / (dz * scale);

        let screen_x = ((x + 1.0) * 0.5 * screen_width as f32) as i32;
        let screen_y = ((1.0 - y) * 0.5 * screen_height as f32) as i32;

        Some((screen_x, screen_y, dz))
    }

    // Retorna vetor forward da câmera
    pub fn get_forward(&self) -> Vec3 {
        (self.target - self.position).normalize()
    }

    // Retorna vetor right da câmera
    pub fn get_right(&self) -> Vec3 {
        self.get_forward().cross(&self.up).normalize()
    }

    // Retorna vetor up da câmera
    pub fn get_up(&self) -> Vec3 {
        self.get_right().cross(&self.get_forward()).normalize()
    }

    // Define posição da câmera
    pub fn set_position(&mut self, position: Vec3) {
        self.position = position;
    }
}