1use gloss_geometry::geom;
2use gloss_hecs::{CommandBuffer, Entity};
3use log::{error, warn};
4
5use crate::{
6 components::{Colors, Faces, ModelMatrix, Normals, UVs, Verts},
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(&mut self, scene: &mut Scene) {
30 let mut command_buffer = CommandBuffer::new();
31
32 {
33 let Some(model_matrix) = scene.get_comp::<&ModelMatrix>(&self.entity).ok() else {
34 warn!("No model matrix to apply");
35 return;
36 };
37
38 if let Ok(verts) = scene.get_comp::<&Verts>(&self.entity) {
40 let new_verts = geom::transform_verts(&verts.0.to_dmatrix(), &model_matrix.0);
41 let new_verts_tensor = DynamicTensorFloat2D::from_dmatrix(&new_verts);
42 command_buffer.insert_one(self.entity, Verts(new_verts_tensor));
43 }
44
45 if let Ok(normals) = scene.get_comp::<&Normals>(&self.entity) {
47 let new_normals = geom::transform_vectors(&normals.0.to_dmatrix(), &model_matrix.0);
48 let new_normals_tensor = DynamicTensorFloat2D::from_dmatrix(&new_normals);
49 command_buffer.insert_one(self.entity, Normals(new_normals_tensor));
50 }
51
52 command_buffer.insert_one(self.entity, ModelMatrix::default());
54 }
55
56 command_buffer.run_on(&mut scene.world);
57 }
58
59 pub fn save_obj(&self, scene: &Scene, path: &str) {
61 let Some(verts) = scene.get_comp::<&Verts>(&self.entity).ok() else {
62 error!("No vertices present on entity, cannot save as obj");
63 return;
64 };
65 let faces = scene.get_comp::<&Faces>(&self.entity).ok();
66 let normals = scene.get_comp::<&Normals>(&self.entity).ok();
67 let uvs = scene.get_comp::<&UVs>(&self.entity).ok();
68
69 geom::save_obj(
71 &verts.0.to_dmatrix(),
72 faces.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
73 uvs.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
74 normals.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
75 path,
76 );
77 }
78
79 pub fn save_ply(&self, scene: &Scene, path: &str) {
80 let Some(verts) = scene.get_comp::<&Verts>(&self.entity).ok() else {
81 error!("No vertices present on entity, cannot save as obj");
82 return;
83 };
84
85 let faces = scene.get_comp::<&Faces>(&self.entity).ok();
86 let normals = scene.get_comp::<&Normals>(&self.entity).ok();
87 let uvs = scene.get_comp::<&UVs>(&self.entity).ok();
88 let colors = scene.get_comp::<&Colors>(&self.entity).ok();
89
90 geom::save_ply(
93 &verts.0.to_dmatrix(),
94 faces.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
95 uvs.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
96 normals.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
97 colors.as_ref().map(|v| v.0.to_dmatrix()).as_ref(),
98 path,
99 );
100 }
101}