Skip to main content

rusting_engine/scene/
object.rs

1use crate::geometry::Mesh;
2use crate::rendering::compute_registry::ComputeShaderType;
3use crate::rendering::shader_registry::ShaderType;
4use crate::scene::animation::AnimationType;
5use nalgebra::{Matrix4, Rotation3, Vector3};
6use std::sync::Arc;
7use vulkano::image::{view::ImageView, ImageAccess};
8
9#[repr(C)]
10#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
11pub struct InstanceData {
12    pub model: [[f32; 4]; 4], // 64 bytes
13    pub color: [f32; 4],      // 16 bytes, color + emission
14    pub mat_props: [f32; 4],  // 16 bytes
15    pub velocity: [f32; 4],   // 16 bytes
16    pub physic: [f32; 4],     // 16 bytes
17    pub rotation: [f32; 4],   // 16 bytes
18                              // Total 144 bytes
19}
20
21#[repr(C)]
22#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
23pub struct PhysicsPushConstants {
24    pub dt: f32,
25    pub total_objects: u32,
26    pub offset: u32,
27    pub count: u32,
28}
29
30#[derive(Clone)]
31pub struct Instance {
32    pub color: [f32; 3],
33    pub emissive: f32,
34    pub roughness: f32,
35    pub metalness: f32,
36    pub base_color_texture: Option<usize>,
37    pub metallic_roughness_texture: Option<usize>,
38    pub animation: AnimationType,
39    pub model_matrix: [[f32; 4]; 4],
40    pub velocity: [f32; 4],
41    pub mass: f32,
42    pub collision: f32,
43    pub gravity: f32,
44    pub rotation: [f32; 4],
45    pub shader: ShaderType,
46    pub compute_shader: ComputeShaderType,
47}
48
49impl Default for Instance {
50    fn default() -> Self {
51        Self {
52            animation: AnimationType::Static,
53            velocity: [0.0, 0.0, 0.0, 1.0],
54            model_matrix: [
55                [1.0, 0.0, 0.0, 0.0],
56                [0.0, 1.0, 0.0, 0.0],
57                [0.0, 0.0, 1.0, 0.0],
58                [0.0, 0.0, 0.0, 1.0],
59            ],
60            color: [1.0, 1.0, 1.0],
61            emissive: 0.0,
62            base_color_texture: None,
63            metallic_roughness_texture: None,
64            roughness: 0.5,
65            metalness: 0.5,
66            mass: 1.0,
67            collision: 0.0,
68            gravity: 1.0,
69            rotation: [0.0, 0.0, 0.0, 0.0],
70            shader: ShaderType::Pbr,
71            compute_shader: ComputeShaderType::FullPhysics,
72        }
73    }
74}
75
76pub struct Texture {
77    pub pixels: Vec<u8>,
78    pub width: u32,
79    pub height: u32,
80}
81
82// ! TRANSFORM - Position, rotation, and scale of an object
83#[derive(Copy, Clone, Debug)]
84pub struct Transform {
85    pub position: [f32; 3], // Translation in world space
86    pub rotation: [f32; 3], // Euler angles, but I like Quaternions, but its complex as hell to implement it everywhere, but I sure that I will do this soon(maybe later then soon)
87    pub scale: [f32; 3],    // Scale factors
88}
89
90// * It can be used to create a new objects or set default settings, like in blender 'reset transform' or something like that
91impl Default for Transform {
92    fn default() -> Self {
93        Self {
94            position: [0.0, 0.0, 0.0],
95            rotation: [0.0, 0.0, 0.0],
96            scale: [1.0, 1.0, 1.0],
97        }
98    }
99}
100
101impl Transform {
102    pub fn to_matrix(&self) -> [[f32; 4]; 4] {
103        let translation = Matrix4::new_translation(&Vector3::from(self.position));
104
105        let rotation =
106            Rotation3::from_euler_angles(self.rotation[0], self.rotation[1], self.rotation[2])
107                .to_homogeneous();
108
109        let scale = Matrix4::new_nonuniform_scaling(&Vector3::from(self.scale));
110
111        let model_matrix = translation * rotation * scale;
112
113        model_matrix.into()
114    }
115    pub fn from_matrix(m: Matrix4<f32>) -> Self {
116        let position = [m[(0, 3)], m[(1, 3)], m[(2, 3)]];
117
118        let scale = [
119            Vector3::new(m[(0, 0)], m[(1, 0)], m[(2, 0)]).norm(),
120            Vector3::new(m[(0, 1)], m[(1, 1)], m[(2, 1)]).norm(),
121            Vector3::new(m[(0, 2)], m[(1, 2)], m[(2, 2)]).norm(),
122        ];
123
124        let rotation_matrix = nalgebra::Matrix3::new(
125            m[(0, 0)] / scale[0],
126            m[(0, 1)] / scale[1],
127            m[(0, 2)] / scale[2],
128            m[(1, 0)] / scale[0],
129            m[(1, 1)] / scale[1],
130            m[(1, 2)] / scale[2],
131            m[(2, 0)] / scale[0],
132            m[(2, 1)] / scale[1],
133            m[(2, 2)] / scale[2],
134        );
135
136        let rotation = Rotation3::from_matrix_unchecked(rotation_matrix).euler_angles();
137
138        Self {
139            position,
140            rotation: [rotation.0, rotation.1, rotation.2],
141            scale,
142        }
143    }
144    // * Helper methods for common transformations, but I use dirrect change, bc I did like that all time in THREE.js, but this functions can be pretty useful for someone
145    // translate
146    pub fn translate(mut self, x: f32, y: f32, z: f32) -> Self {
147        self.position = [x, y, z];
148        self
149    }
150
151    // rotate
152    pub fn rotate(mut self, x: f32, y: f32, z: f32) -> Self {
153        self.rotation = [x, y, z];
154        self
155    }
156
157    // scale
158    pub fn scale(mut self, x: f32, y: f32, z: f32) -> Self {
159        self.scale = [x, y, z];
160        self
161    }
162
163    // uniform_scale
164    pub fn uniform_scale(mut self, s: f32) -> Self {
165        self.scale = [s, s, s];
166        self
167    }
168
169    // I am going crazy
170}
171
172pub struct RenderBatch {
173    pub mesh: Mesh,
174    pub instances: Vec<Instance>,
175    pub shader: ShaderType,
176    pub compute_shader: ComputeShaderType,
177}