moltrun 1.7.2

High-performance game engine library with AI capabilities, built on wgpu for modern 3D graphics and physics simulation
Documentation
use crate::core::Entity;
use crate::components::{Transform, Sprite};
use crate::runtime::Camera;
use super::super::resources::Vertex;
use super::transform::{CoordinateTransform, Transform2D};

/// 개별 스프라이트 렌더링 데이터
/// 정점, 인덱스, 텍스처 경로를 함께 관리
pub struct SpriteRenderData {
    pub vertices: [Vertex; 4],
    pub indices: [u16; 6],
    pub texture_path: String,
}

/// 스프라이트 배치 수집기 - ECS에서 렌더링할 데이터 추출
pub struct SpriteBatch {
    sprites: Vec<SpriteRenderData>,
    coord_transform: CoordinateTransform,
}

impl SpriteBatch {
    pub fn new(screen_width: f32, screen_height: f32) -> Self {
        Self {
            sprites: Vec::new(),
            coord_transform: CoordinateTransform::new(screen_width, screen_height),
        }
    }
    
    /// 프레임 시작 - 배치 초기화
    pub fn begin_frame(&mut self) {
        self.sprites.clear();
    }
    
    /// ECS 엔티티들에서 스프라이트 데이터 수집 (카메라 적용)
    pub fn collect_sprites(&mut self, entities: &[Entity], camera: &Camera) {
        for entity in entities {
            if let (Some(transform), Some(sprite)) = (
                entity.get_component::<Transform>(),
                entity.get_component::<Sprite>()
            ) {
                if sprite.is_visible() {
                    // 카메라 offset 적용: world space → view space
                    let view_position = camera.world_to_view(transform.position);
                    
                    // view_position을 사용하는 임시 Transform 생성
                    let mut view_transform = transform.clone();
                    view_transform.position = view_position;
                    
                    // 스프라이트 정점 생성 (view space 사용)
                    let vertices = Transform2D::calculate_sprite_corners(
                        &view_transform, 
                        sprite, 
                        &self.coord_transform
                    );
                    
                    // 인덱스 생성 (사각형 = 2개 삼각형)
                    let base_index = (self.sprites.len() * 4) as u16;
                    let indices = [
                        base_index, base_index + 1, base_index + 2,
                        base_index + 2, base_index + 3, base_index
                    ];
                    
                    // 텍스처 경로 복사
                    let texture_path = sprite.texture_path.clone();
                    
                    // 스프라이트 데이터 추가
                    self.sprites.push(SpriteRenderData {
                        vertices,
                        indices,
                        texture_path,
                    });
                }
            }
        }
    }
    
    /// 수집된 스프라이트 데이터 반환
    pub fn sprites(&self) -> &[SpriteRenderData] {
        &self.sprites
    }
    
    /// 렌더링할 것이 있는지 확인
    pub fn is_empty(&self) -> bool {
        self.sprites.is_empty()
    }
    
    /// 스프라이트 개수 반환
    pub fn sprite_count(&self) -> usize {
        self.sprites.len()
    }
    
    /// 하위 호환성을 위한 vertices() - 모든 정점을 평탄화
    pub fn vertices(&self) -> Vec<Vertex> {
        self.sprites
            .iter()
            .flat_map(|s| s.vertices.iter().copied())
            .collect()
    }
    
    /// 하위 호환성을 위한 indices() - 모든 인덱스를 평탄화
    pub fn indices(&self) -> Vec<u16> {
        self.sprites
            .iter()
            .flat_map(|s| s.indices.iter().copied())
            .collect()
    }
}