1use gloss_hecs::{CommandBuffer, Entity};
2use log::{error, warn};
3
4use crate::{
5 components::{Colors, Faces, ModelMatrix, Normals, UVs, Verts},
6 geom::Geom,
7 scene::Scene,
8};
9use gloss_utils::tensor::{DynamicMatrixOps, DynamicTensorFloat2D};
10
11#[derive(Clone, Copy)]
14pub struct Actor {
15 pub entity: Entity,
16}
17
18impl Actor {
19 pub fn new(name: &str, scene: &mut Scene) -> Self {
20 let entity = scene.get_or_create_hidden_entity(name).entity();
22 Self { entity }
23 }
24
25 pub fn from_entity(entity: Entity) -> Self {
26 Self { entity }
27 }
28
29 pub fn apply_model_matrix(
30 &mut self,
31 scene: &mut Scene,
32 ) {
34 let mut command_buffer = CommandBuffer::new();
35
36 {
37 let Some(model_matrix) = scene.get_comp::<&ModelMatrix>(&self.entity).ok() else {
38 warn!("No model matrix to apply");
39 return;
40 };
41
42 if let Ok(verts) = scene.get_comp::<&Verts>(&self.entity) {
44 let new_verts = Geom::transform_verts(&verts.0.to_dmatrix(), &model_matrix.0);
45 let new_verts_tensor = DynamicTensorFloat2D::from_dmatrix(&new_verts);
46 command_buffer.insert_one(self.entity, Verts(new_verts_tensor));
47 }
48
49 if let Ok(normals) = scene.get_comp::<&Normals>(&self.entity) {
51 let new_normals = Geom::transform_vectors(&normals.0.to_dmatrix(), &model_matrix.0);
52 let new_normals_tensor = DynamicTensorFloat2D::from_dmatrix(&new_normals);
53 command_buffer.insert_one(self.entity, Normals(new_normals_tensor));
54 }
55
56 command_buffer.insert_one(self.entity, ModelMatrix::default());
58 }
59
60 command_buffer.run_on(&mut scene.world);
61 }
62
63 pub fn save_obj(&self, scene: &Scene, path: &str) {
65 let Some(verts) = scene.get_comp::<&Verts>(&self.entity).ok() else {
66 error!("No vertices present on entity, cannot save as obj");
67 return;
68 };
69 let faces = scene.get_comp::<&Faces>(&self.entity).ok();
70 let normals = scene.get_comp::<&Normals>(&self.entity).ok();
71 let uvs = scene.get_comp::<&UVs>(&self.entity).ok();
72
73 Geom::save_obj(
76 &verts.0.to_dmatrix(),
77 faces.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
78 uvs.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
79 normals.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
80 path,
81 );
82 }
83
84 pub fn save_ply(&self, scene: &Scene, path: &str) {
85 let Some(verts) = scene.get_comp::<&Verts>(&self.entity).ok() else {
86 error!("No vertices present on entity, cannot save as obj");
87 return;
88 };
89
90 let faces = scene.get_comp::<&Faces>(&self.entity).ok();
91 let normals = scene.get_comp::<&Normals>(&self.entity).ok();
92 let uvs = scene.get_comp::<&UVs>(&self.entity).ok();
93 let colors = scene.get_comp::<&Colors>(&self.entity).ok();
94
95 Geom::save_ply(
98 &verts.0.to_dmatrix(),
99 faces.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
100 uvs.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
102 normals.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
103 colors.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
104 path,
105 );
106 }
107}
108
109