Skip to main content

gizmo_engine/
bundles.rs

1//! Bevy tarzı önceden tanımlanmış Bundle yapıları.
2//!
3//! Bir entity'ye birden fazla bileşeni tek seferde eklemek için kullanılır.
4//!
5//! ```ignore
6//! world.spawn_bundle(CameraBundle {
7//!     position: Vec3::new(0.0, 3.0, 10.0),
8//!     fov: 60.0_f32.to_radians(),
9//!     ..default()
10//! });
11//! ```
12
13use crate::core::{Bundle, Entity, EntityName, World};
14use crate::math::{Quat, Vec3};
15use crate::physics::Transform;
16use crate::renderer::components::{
17    Camera, DirectionalLight, LightRole, Material, Mesh, MeshRenderer, PointLight, SpotLight,
18};
19
20// ============================================================
21//  DirectionalLightBundle
22// ============================================================
23
24/// Yönlü ışık (güneş) için hazır bundle.
25pub struct DirectionalLightBundle {
26    pub rotation: Quat,
27    pub color: Vec3,
28    pub intensity: f32,
29    pub role: LightRole,
30}
31
32impl Default for DirectionalLightBundle {
33    fn default() -> Self {
34        Self {
35            rotation: Quat::from_rotation_x(-std::f32::consts::PI / 4.0),
36            color: Vec3::new(1.0, 1.0, 1.0),
37            intensity: 3.0,
38            role: LightRole::Sun,
39        }
40    }
41}
42
43impl Bundle for DirectionalLightBundle {
44    fn apply(self, world: &mut World, entity: Entity) {
45        world.add_component(
46            entity,
47            Transform::new(Vec3::ZERO).with_rotation(self.rotation),
48        );
49        world.add_component(entity, crate::physics::GlobalTransform::default());
50        world.add_component(
51            entity,
52            DirectionalLight::new(self.color, self.intensity, self.role),
53        );
54    }
55}
56
57// ============================================================
58//  PointLightBundle
59// ============================================================
60
61/// Nokta ışığı için hazır bundle.
62pub struct PointLightBundle {
63    pub position: Vec3,
64    pub color: Vec3,
65    pub intensity: f32,
66    pub radius: f32,
67}
68
69impl Default for PointLightBundle {
70    fn default() -> Self {
71        Self {
72            position: Vec3::ZERO,
73            color: Vec3::new(1.0, 1.0, 1.0),
74            intensity: 5.0,
75            radius: 20.0,
76        }
77    }
78}
79
80impl Bundle for PointLightBundle {
81    fn apply(self, world: &mut World, entity: Entity) {
82        world.add_component(entity, Transform::new(self.position));
83        world.add_component(entity, crate::physics::GlobalTransform::default());
84        world.add_component(
85            entity,
86            PointLight::new(self.color, self.intensity, self.radius),
87        );
88    }
89}
90
91// ============================================================
92//  SpotLightBundle
93// ============================================================
94
95/// Spot ışığı için hazır bundle.
96pub struct SpotLightBundle {
97    pub position: Vec3,
98    pub rotation: Quat,
99    pub color: Vec3,
100    pub intensity: f32,
101    pub radius: f32,
102    pub inner_angle: f32,
103    pub outer_angle: f32,
104}
105
106impl Default for SpotLightBundle {
107    fn default() -> Self {
108        Self {
109            position: Vec3::ZERO,
110            rotation: Quat::IDENTITY,
111            color: Vec3::new(1.0, 1.0, 1.0),
112            intensity: 10.0,
113            radius: 30.0,
114            inner_angle: 0.4,
115            outer_angle: 0.6,
116        }
117    }
118}
119
120impl Bundle for SpotLightBundle {
121    fn apply(self, world: &mut World, entity: Entity) {
122        world.add_component(
123            entity,
124            Transform::new(self.position).with_rotation(self.rotation),
125        );
126        world.add_component(entity, crate::physics::GlobalTransform::default());
127        world.add_component(
128            entity,
129            SpotLight::new(
130                self.color,
131                self.intensity,
132                self.radius,
133                self.inner_angle,
134                self.outer_angle,
135            ),
136        );
137    }
138}
139
140// ============================================================
141//  CameraBundle
142// ============================================================
143
144/// Kamera için hazır bundle.
145pub struct CameraBundle {
146    pub position: Vec3,
147    pub fov: f32,
148    pub near: f32,
149    pub far: f32,
150    pub yaw: f32,
151    pub pitch: f32,
152    pub primary: bool,
153}
154
155impl Default for CameraBundle {
156    fn default() -> Self {
157        Self {
158            position: Vec3::new(0.0, 5.0, 10.0),
159            fov: std::f32::consts::FRAC_PI_3,
160            near: 0.1,
161            far: 1500.0,
162            yaw: 0.0,
163            pitch: 0.0,
164            primary: true,
165        }
166    }
167}
168
169impl Bundle for CameraBundle {
170    fn apply(self, world: &mut World, entity: Entity) {
171        world.add_component(entity, Transform::new(self.position));
172        world.add_component(entity, crate::physics::GlobalTransform::default());
173        world.add_component(
174            entity,
175            Camera::new(
176                self.fov,
177                self.near,
178                self.far,
179                self.yaw,
180                self.pitch,
181                self.primary,
182            ),
183        );
184    }
185}
186
187// ============================================================
188//  MeshBundle
189// ============================================================
190
191/// Mesh + Material + MeshRenderer için hazır bundle.
192///
193/// ```ignore
194/// world.spawn_bundle(
195///     MeshBundle::new(renderer.create_cube(), my_material)
196///         .with_name("Oyuncu")
197///         .at(Vec3::new(0.0, 5.0, 0.0))
198/// );
199/// ```
200pub struct MeshBundle {
201    pub position: Vec3,
202    pub rotation: Quat,
203    pub scale: Vec3,
204    pub mesh: crate::core::asset::Handle<Mesh>,
205    pub material: crate::core::asset::Handle<Material>,
206    pub name: Option<String>,
207}
208
209impl MeshBundle {
210    /// Yeni bir MeshBundle oluşturur (mesh ve material zorunlu).
211    pub fn new(
212        mesh: crate::core::asset::Handle<Mesh>,
213        material: crate::core::asset::Handle<Material>,
214    ) -> Self {
215        Self {
216            position: Vec3::ZERO,
217            rotation: Quat::IDENTITY,
218            scale: Vec3::ONE,
219            mesh,
220            material,
221            name: None,
222        }
223    }
224
225    /// Pozisyon ayarlar.
226    pub fn at(mut self, position: Vec3) -> Self {
227        self.position = position;
228        self
229    }
230
231    /// Rotasyon ayarlar.
232    pub fn with_rotation(mut self, rotation: Quat) -> Self {
233        self.rotation = rotation;
234        self
235    }
236
237    /// Ölçek ayarlar.
238    pub fn with_scale(mut self, scale: Vec3) -> Self {
239        self.scale = scale;
240        self
241    }
242
243    /// İsim verir.
244    pub fn with_name(mut self, name: &str) -> Self {
245        self.name = Some(name.to_string());
246        self
247    }
248}
249
250impl Bundle for MeshBundle {
251    fn apply(self, world: &mut World, entity: Entity) {
252        world.add_component(
253            entity,
254            Transform::new(self.position)
255                .with_rotation(self.rotation)
256                .with_scale(self.scale),
257        );
258        world.add_component(entity, crate::physics::GlobalTransform::default());
259        world.add_component(entity, self.mesh);
260        world.add_component(entity, self.material);
261        world.add_component(entity, MeshRenderer::new());
262        if let Some(name) = self.name {
263            world.add_component(entity, EntityName(name));
264        }
265    }
266}