mraphics_core/geometry/
instance.rs1use crate::{
2 GadgetData, GeometryView, Material, MaterialView,
3 constants::{MODEL_MAT_INDEX, MODEL_MAT_LABEL},
4};
5use nalgebra::{Isometry3, Matrix4, Translation3, UnitQuaternion, UnitVector3, Vector3};
6
7pub struct RenderInstance {
8 pub identifier: String,
9 pub geometry: GeometryView,
10 pub material: MaterialView,
11
12 scale: Vector3<f32>,
13 isometry: Isometry3<f32>,
14 matrix: Matrix4<f32>,
15}
16
17impl RenderInstance {
18 pub fn new<M: Material>(identifier: String, material: &M) -> Self {
19 Self {
20 identifier,
21 geometry: GeometryView::new(),
22 material: MaterialView::new(material.identifier())
23 .with_code(material.shader_code().to_string()),
24 scale: Vector3::new(1.0, 1.0, 1.0),
25 isometry: Isometry3::new(Vector3::zeros(), Vector3::zeros()),
26 matrix: Matrix4::identity(),
27 }
28 }
29
30 pub fn matrix(&self) -> &Matrix4<f32> {
31 &self.matrix
32 }
33
34 pub fn rotation(&self) -> &UnitQuaternion<f32> {
35 &self.isometry.rotation
36 }
37
38 pub fn set_rotation(&mut self, rotation: &UnitQuaternion<f32>) {
39 self.isometry.rotation.clone_from(rotation);
40 self.update_matrix();
41 }
42
43 pub fn rotate_x(&mut self, angle_rad: f32) {
44 self.isometry.rotation =
45 UnitQuaternion::from_axis_angle(&UnitVector3::new_normalize(Vector3::x()), angle_rad)
46 * self.isometry.rotation;
47 self.update_matrix();
48 }
49
50 pub fn rotate_y(&mut self, angle_rad: f32) {
51 self.isometry.rotation =
52 UnitQuaternion::from_axis_angle(&UnitVector3::new_normalize(Vector3::y()), angle_rad)
53 * self.isometry.rotation;
54 self.update_matrix();
55 }
56
57 pub fn rotate_z(&mut self, angle_rad: f32) {
58 self.isometry.rotation =
59 UnitQuaternion::from_axis_angle(&UnitVector3::new_normalize(Vector3::z()), angle_rad)
60 * self.isometry.rotation;
61 self.update_matrix();
62 }
63
64 pub fn translation(&self) -> &Translation3<f32> {
65 &self.isometry.translation
66 }
67
68 pub fn move_to(&mut self, position: &Vector3<f32>) {
69 self.isometry.translation.vector = *position;
70 self.update_matrix();
71 }
72
73 pub fn move_by(&mut self, offset: &Vector3<f32>) {
74 self.isometry.translation.vector += offset;
75 self.update_matrix();
76 }
77
78 pub fn scale(&self) -> &Vector3<f32> {
79 &self.scale
80 }
81
82 pub fn scale_by(&mut self, factor: &Vector3<f32>) {
83 self.scale.component_mul_assign(factor);
84 self.update_matrix();
85 }
86
87 pub fn scale_to(&mut self, scale: &Vector3<f32>) {
88 self.scale.copy_from(scale);
89 self.update_matrix();
90 }
91
92 fn update_matrix(&mut self) {
93 self.matrix = self.isometry.to_homogeneous() * Matrix4::new_nonuniform_scaling(&self.scale);
94
95 self.geometry.reset_uniforms();
96 self.geometry.uniforms.push(GadgetData {
97 label: MODEL_MAT_LABEL.to_string(),
98 index: MODEL_MAT_INDEX,
99 data: bytemuck::cast_slice(self.matrix.as_slice()).to_vec(),
100 needs_update_value: true,
101 needs_update_buffer: true,
102 })
103 }
104}
105
106pub trait Renderable {
107 fn identifier(&self) -> usize;
108 fn build_instance(&self) -> RenderInstance;
109}