gloss_renderer/
actor.rs

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/// Contains a reference to an entity in the world so that any mesh processing
12/// will directly affect the relevant entity in the world.
13#[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        //check if there is an entity with the same name, if no then spawn one
21        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        // model_matrix: &na::SimilarityMatrix3<f32>,
33    ) {
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            //verts
43            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            //normals
50            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            //model matrix is now identity
57            command_buffer.insert_one(self.entity, ModelMatrix::default());
58        }
59
60        command_buffer.run_on(&mut scene.world);
61    }
62
63    //methods that are not static and act directly on the entity
64    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        //TODO modify data given the model matrix
74
75        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        //TODO modify data given the model matrix
96
97        Geom::save_ply(
98            &verts.0.to_dmatrix(),
99            faces.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
100            // faces.as_ref().map(|v| v.0.to_dmatrix().map(|x| x as u32)).as_ref(),
101            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// pub trait EntityGeom {
110//     fn save_obj(&self, scene: &Scene, path: &str);
111// }
112
113// impl EntityGeom for Entity {
114//     fn save_obj(&self, scene: &Scene, path: &str) {
115//         let Some(verts) = scene.get_comp::<&Verts>(&self).ok() else {
116//             error!("No vertices present on entity, cannot save as obj");
117//             return;
118//         };
119//         let Some(faces) = scene.get_comp::<&Faces>(&self).ok() else {
120//             error!("No faces present on entity, cannot save as obj");
121//             return;
122//         };
123//         let normals = scene.get_comp::<&Normals>(&self).ok();
124//         let uvs = scene.get_comp::<&UVs>(&self).ok();
125//         Geom::save_obj(
126//             &verts.0,
127//             &faces.0,
128//             uvs.as_ref().map(|v| &v.0),
129//             normals.as_ref().map(|v| &v.0),
130//             path,
131//         );
132//     }
133// }