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 gizmo_physics_core::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 get_infos() -> Vec<gizmo_core::archetype::ComponentInfo> { vec![] }
45    unsafe fn write_to_archetype(self, _arch: &mut gizmo_core::archetype::Archetype, _row: usize, _tick: u32) {}
46    fn apply(self, world: &mut World, entity: Entity) {
47        world.add_component(
48            entity,
49            Transform::new(Vec3::ZERO).with_rotation(self.rotation),
50        );
51        world.add_component(entity, gizmo_physics_core::components::GlobalTransform::default());
52        world.add_component(
53            entity,
54            DirectionalLight::new(self.color, self.intensity, self.role),
55        );
56    }
57}
58
59// ============================================================
60//  PointLightBundle
61// ============================================================
62
63/// Nokta ışığı için hazır bundle.
64pub struct PointLightBundle {
65    pub position: Vec3,
66    pub color: Vec3,
67    pub intensity: f32,
68    pub radius: f32,
69}
70
71impl Default for PointLightBundle {
72    fn default() -> Self {
73        Self {
74            position: Vec3::ZERO,
75            color: Vec3::new(1.0, 1.0, 1.0),
76            intensity: 5.0,
77            radius: 20.0,
78        }
79    }
80}
81
82impl Bundle for PointLightBundle {
83    fn get_infos() -> Vec<gizmo_core::archetype::ComponentInfo> { vec![] }
84    unsafe fn write_to_archetype(self, _arch: &mut gizmo_core::archetype::Archetype, _row: usize, _tick: u32) {}
85    fn apply(self, world: &mut World, entity: Entity) {
86        world.add_component(entity, Transform::new(self.position));
87        world.add_component(entity, gizmo_physics_core::components::GlobalTransform::default());
88        world.add_component(
89            entity,
90            PointLight::new(self.color, self.intensity, self.radius),
91        );
92    }
93}
94
95// ============================================================
96//  SpotLightBundle
97// ============================================================
98
99/// Spot ışığı için hazır bundle.
100pub struct SpotLightBundle {
101    pub position: Vec3,
102    pub rotation: Quat,
103    pub color: Vec3,
104    pub intensity: f32,
105    pub radius: f32,
106    pub inner_angle: f32,
107    pub outer_angle: f32,
108}
109
110impl Default for SpotLightBundle {
111    fn default() -> Self {
112        Self {
113            position: Vec3::ZERO,
114            rotation: Quat::IDENTITY,
115            color: Vec3::new(1.0, 1.0, 1.0),
116            intensity: 10.0,
117            radius: 30.0,
118            inner_angle: 0.4,
119            outer_angle: 0.6,
120        }
121    }
122}
123
124impl Bundle for SpotLightBundle {
125    fn get_infos() -> Vec<gizmo_core::archetype::ComponentInfo> { vec![] }
126    unsafe fn write_to_archetype(self, _arch: &mut gizmo_core::archetype::Archetype, _row: usize, _tick: u32) {}
127    fn apply(self, world: &mut World, entity: Entity) {
128        world.add_component(
129            entity,
130            Transform::new(self.position).with_rotation(self.rotation),
131        );
132        world.add_component(entity, gizmo_physics_core::components::GlobalTransform::default());
133        world.add_component(
134            entity,
135            SpotLight::new(
136                self.color,
137                self.intensity,
138                self.radius,
139                self.inner_angle,
140                self.outer_angle,
141            ),
142        );
143    }
144}
145
146// ============================================================
147//  CameraBundle
148// ============================================================
149
150/// Kamera için hazır bundle.
151pub struct CameraBundle {
152    pub position: Vec3,
153    pub fov: f32,
154    pub near: f32,
155    pub far: f32,
156    pub yaw: f32,
157    pub pitch: f32,
158    pub exposure: f32,
159    pub primary: bool,
160}
161
162impl Default for CameraBundle {
163    fn default() -> Self {
164        Self {
165            position: Vec3::new(0.0, 5.0, 10.0),
166            fov: std::f32::consts::FRAC_PI_3,
167            near: 0.1,
168            far: 1500.0,
169            yaw: 0.0,
170            pitch: 0.0,
171            exposure: 1.0,
172            primary: true,
173        }
174    }
175}
176
177impl Bundle for CameraBundle {
178    fn get_infos() -> Vec<gizmo_core::archetype::ComponentInfo> { vec![] }
179    unsafe fn write_to_archetype(self, _arch: &mut gizmo_core::archetype::Archetype, _row: usize, _tick: u32) {}
180    fn apply(self, world: &mut World, entity: Entity) {
181        world.add_component(entity, Transform::new(self.position));
182        world.add_component(entity, gizmo_physics_core::components::GlobalTransform::default());
183        let mut cam = Camera::new(
184            self.fov,
185            self.near,
186            self.far,
187            self.yaw,
188            self.pitch,
189            self.primary,
190        );
191        cam.exposure = self.exposure;
192        world.add_component(entity, cam);
193    }
194}
195
196// ============================================================
197//  MeshBundle
198// ============================================================
199
200/// Mesh + Material + MeshRenderer için hazır bundle.
201///
202/// ```ignore
203/// world.spawn_bundle(
204///     MeshBundle::new(renderer.create_cube(), my_material)
205///         .with_name("Oyuncu")
206///         .at(Vec3::new(0.0, 5.0, 0.0))
207/// );
208/// ```
209pub struct MeshBundle {
210    pub position: Vec3,
211    pub rotation: Quat,
212    pub scale: Vec3,
213    pub mesh: crate::core::asset::Handle<Mesh>,
214    pub material: crate::core::asset::Handle<Material>,
215    pub name: Option<String>,
216}
217
218impl MeshBundle {
219    /// Yeni bir MeshBundle oluşturur (mesh ve material zorunlu).
220    pub fn new(
221        mesh: crate::core::asset::Handle<Mesh>,
222        material: crate::core::asset::Handle<Material>,
223    ) -> Self {
224        Self {
225            position: Vec3::ZERO,
226            rotation: Quat::IDENTITY,
227            scale: Vec3::ONE,
228            mesh,
229            material,
230            name: None,
231        }
232    }
233
234    /// Pozisyon ayarlar.
235    pub fn at(mut self, position: Vec3) -> Self {
236        self.position = position;
237        self
238    }
239
240    /// Rotasyon ayarlar.
241    pub fn with_rotation(mut self, rotation: Quat) -> Self {
242        self.rotation = rotation;
243        self
244    }
245
246    /// Ölçek ayarlar.
247    pub fn with_scale(mut self, scale: Vec3) -> Self {
248        self.scale = scale;
249        self
250    }
251
252    /// İsim verir.
253    pub fn with_name(mut self, name: &str) -> Self {
254        self.name = Some(name.to_string());
255        self
256    }
257}
258
259impl Bundle for MeshBundle {
260    fn get_infos() -> Vec<gizmo_core::archetype::ComponentInfo> { vec![] }
261    unsafe fn write_to_archetype(self, _arch: &mut gizmo_core::archetype::Archetype, _row: usize, _tick: u32) {}
262    fn apply(self, world: &mut World, entity: Entity) {
263        world.add_component(
264            entity,
265            Transform::new(self.position)
266                .with_rotation(self.rotation)
267                .with_scale(self.scale),
268        );
269        world.add_component(entity, gizmo_physics_core::components::GlobalTransform::default());
270        world.add_component(entity, self.mesh);
271        world.add_component(entity, self.material);
272        world.add_component(entity, MeshRenderer::new());
273        if let Some(name) = self.name {
274            world.add_component(entity, EntityName(name));
275        }
276    }
277}
278
279// ============================================================
280//  RigidBodyBundle
281// ============================================================
282
283use gizmo_physics_core::Collider;
284use gizmo_physics_rigid::components::{RigidBody, Velocity};
285
286/// Fizik nesnesi oluşturmak için sıfır-yük (zero-overhead) Bundle.
287/// Velocity veya Collider eklemeyi unutma hatalarını önler.
288pub struct RigidBodyBundle {
289    pub rigid_body: RigidBody,
290    pub velocity: Velocity,
291    pub collider: Collider,
292}
293
294impl Default for RigidBodyBundle {
295    fn default() -> Self {
296        Self {
297            rigid_body: RigidBody::default(),
298            velocity: Velocity::default(),
299            collider: Collider::default(),
300        }
301    }
302}
303
304impl RigidBodyBundle {
305    pub fn dynamic(mass: f32) -> Self {
306        Self {
307            rigid_body: RigidBody::new(mass, 0.5, 0.5, true),
308            ..Default::default()
309        }
310    }
311
312    pub fn static_body() -> Self {
313        Self {
314            rigid_body: RigidBody::new_static(),
315            ..Default::default()
316        }
317    }
318
319    pub fn with_collider(mut self, collider: Collider) -> Self {
320        self.collider = collider;
321        self
322    }
323}
324
325impl Bundle for RigidBodyBundle {
326    fn get_infos() -> Vec<gizmo_core::archetype::ComponentInfo> {
327        <(RigidBody, Velocity, Collider)>::get_infos()
328    }
329
330    unsafe fn write_to_archetype(self, arch: &mut gizmo_core::archetype::Archetype, row: usize, tick: u32) {
331        (self.rigid_body, self.velocity, self.collider).write_to_archetype(arch, row, tick)
332    }
333
334    fn apply(self, world: &mut World, entity: Entity) {
335        (self.rigid_body, self.velocity, self.collider).apply(world, entity)
336    }
337}