blue_engine_core/objects/
mod.rs

1//! # Objects
2//!
3//! Objects make it easier to work with Blue Engine, it automates most of work needed for
4//! creating 3D objects and showing them on screen. A range of default objects are available
5//! as well as ability to customize each of them and even create your own! You can also
6//! customize almost everything there is about them!
7
8use crate::utils::default_resources::{DEFAULT_SHADER, DEFAULT_TEXTURE};
9use crate::{
10    Matrix4, Pipeline, PipelineData, Quaternion, Renderer, ShaderSettings, TextureData,
11    UnsignedIntType, Vector3, Vector4, Vertex,
12};
13use std::sync::Arc;
14mod transformation;
15pub use transformation::{RotateAmount, RotateAxis};
16mod instance;
17pub use instance::{Instance, InstanceRaw};
18mod shader_builder;
19pub use shader_builder::{ShaderBuilder, ShaderConfigs};
20mod resource_sharing;
21mod updating;
22
23/// Objects make it easier to work with Blue Engine, it automates most of work needed for
24/// creating 3D objects and showing them on screen. A range of default objects are available
25/// as well as ability to customize each of them and even create your own! You can also
26/// customize almost everything there is about them!
27pub struct Object {
28    /// Give your object a name, which can help later on for debugging.
29    pub name: std::sync::Arc<str>,
30    /// A list of Vertex
31    pub vertices: Vec<Vertex>,
32    /// A list of indices that dictates the order that vertices appear
33    pub indices: Vec<UnsignedIntType>,
34    /// Describes how to uniform buffer is structures
35    pub uniform_layout: wgpu::BindGroupLayout,
36    /// Pipeline holds all the data that is sent to GPU, including shaders and textures
37    pub pipeline: Pipeline,
38    /// List of instances of this object
39    pub instances: Vec<Instance>,
40    /// instance buffer
41    pub instance_buffer: wgpu::Buffer,
42    /// Dictates the size of your object in relation to the world
43    pub size: Vector3,
44    /// Dictates the position of your object in pixels
45    pub position: Vector3,
46    /// Dictates the rotation of your object
47    pub rotation: Vector3,
48    // flags the object to be updated until next frame
49    pub(crate) changed: bool,
50    /// Transformation matrices helps to apply changes to your object, including position, orientation, ...
51    /// Best choice is to let the Object system handle it
52    pub translation_matrix: Matrix4,
53    /// Transformation matrices helps to apply changes to your object, including position, orientation, ...
54    /// Best choice is to let the Object system handle it
55    pub scale_matrix: Matrix4,
56    /// Transformation matrices helps to apply changes to your object, including position, orientation, ...
57    /// Best choice is to let the Object system handle it
58    pub rotation_quaternion: Quaternion,
59    /// Transformation matrix, but inversed
60    pub inverse_transformation_matrix: Matrix4,
61    /// The main color of your object
62    pub color: Vector4,
63    /// A struct making it easier to manipulate specific parts of shader
64    pub shader_builder: crate::objects::ShaderBuilder,
65    /// Shader settings
66    pub shader_settings: ShaderSettings,
67    /// Camera have any effect on the object?
68    pub camera_effect: Option<std::sync::Arc<str>>,
69    /// Uniform Buffers to be sent to GPU. These are raw and not compiled for GPU yet
70    pub uniform_buffers: Vec<wgpu::Buffer>,
71    /// Should be rendered or not
72    pub is_visible: bool,
73    /// Objects with higher number get rendered later and appear "on top" when occupying the same space
74    pub render_order: usize,
75}
76unsafe impl Send for Object {}
77unsafe impl Sync for Object {}
78
79/// Extra settings to customize objects on time of creation
80#[derive(Debug, Clone)]
81pub struct ObjectSettings {
82    /// Should it be affected by camera?
83    pub camera_effect: Option<std::sync::Arc<str>>,
84    /// Shader Settings
85    pub shader_settings: ShaderSettings,
86}
87impl Default for ObjectSettings {
88    fn default() -> Self {
89        Self {
90            camera_effect: Some("main".into()),
91            shader_settings: ShaderSettings::default(),
92        }
93    }
94}
95unsafe impl Send for ObjectSettings {}
96unsafe impl Sync for ObjectSettings {}
97
98/// A unified way to handle objects
99///
100/// This is a container for objects that is used to apply different operations on the objects at the same time.
101/// It can deref to the object hashmap itself when needed.
102pub struct ObjectStorage(std::collections::HashMap<Arc<str>, Object>);
103impl ObjectStorage {
104    /// Creates a new object storage
105    pub fn new() -> Self {
106        ObjectStorage(std::collections::HashMap::new())
107    }
108}
109impl Default for ObjectStorage {
110    fn default() -> Self {
111        Self::new()
112    }
113}
114unsafe impl Send for ObjectStorage {}
115unsafe impl Sync for ObjectStorage {}
116crate::macros::impl_deref!(ObjectStorage, std::collections::HashMap<Arc<str>, Object>);
117
118impl Object {
119    /// Creates a new object
120    ///
121    /// Is used to define a new object and add it to the storage. This offers full customizability
122    /// and a framework for in-engine shapes to be developed.
123    pub fn new(
124        name: impl AsRef<str>,
125        vertices: Vec<Vertex>,
126        indices: Vec<UnsignedIntType>,
127        settings: ObjectSettings,
128        renderer: &mut Renderer,
129    ) -> Result<Object, crate::error::Error> {
130        let vertex_buffer = renderer.build_vertex_buffer(&vertices, &indices);
131
132        let uniform = renderer.build_uniform_buffer(&vec![
133            renderer.build_uniform_buffer_part("Transformation Matrix", Matrix4::IDENTITY),
134            renderer
135                .build_uniform_buffer_part("Color", crate::utils::default_resources::DEFAULT_COLOR),
136        ]);
137
138        let shader_source =
139            ShaderBuilder::new(DEFAULT_SHADER.to_string(), settings.camera_effect.clone());
140        let shader = renderer.build_shader(
141            name.as_ref(),
142            shader_source.shader.clone(),
143            Some(&uniform.1),
144            settings.shader_settings,
145        );
146
147        let texture = renderer.build_texture(
148            "Default Texture",
149            TextureData::Bytes(DEFAULT_TEXTURE.to_vec()),
150            crate::prelude::TextureMode::Clamp,
151            //crate::prelude::TextureFormat::PNG
152        )?;
153
154        let instance = Instance::default();
155        let instance_buffer = renderer.build_instance(vec![instance.build()]);
156
157        Ok(Object {
158            name: name.as_ref().into(),
159            vertices,
160            indices,
161            pipeline: Pipeline {
162                vertex_buffer: PipelineData::Data(vertex_buffer),
163                shader: PipelineData::Data(shader),
164                texture: PipelineData::Data(texture),
165                uniform: PipelineData::Data(Some(uniform.0)),
166            },
167            instances: vec![instance],
168            instance_buffer,
169            uniform_layout: uniform.1,
170            size: Vector3::ONE,
171            position: Vector3::ZERO,
172            rotation: Vector3::ZERO,
173            changed: false,
174            translation_matrix: Matrix4::IDENTITY,
175            scale_matrix: Matrix4::IDENTITY,
176            rotation_quaternion: Quaternion::IDENTITY,
177            inverse_transformation_matrix: Matrix4::transpose(&Matrix4::inverse(
178                &Matrix4::IDENTITY,
179            )),
180            color: crate::utils::default_resources::DEFAULT_COLOR,
181            shader_builder: shader_source,
182            shader_settings: settings.shader_settings,
183            camera_effect: settings.camera_effect,
184            uniform_buffers: vec![
185                renderer.build_uniform_buffer_part("Transformation Matrix", Matrix4::IDENTITY),
186                renderer.build_uniform_buffer_part(
187                    "Color",
188                    crate::utils::default_resources::DEFAULT_COLOR,
189                ),
190            ],
191            is_visible: true,
192            render_order: 0,
193        })
194    }
195}