Skip to content

Commit 81c452e

Browse files
Merge pull request #99 from AryanpurTech/v0.7-Camera-Fix
v0.7 Camera Fix
2 parents 142abd6 + 66af0ab commit 81c452e

8 files changed

Lines changed: 90 additions & 100 deletions

File tree

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [0.7.1] - 2025-04-01
6+
7+
### Bug Fixes
8+
9+
- The camera target being inaccurately set ([5062995](https://github.com/AryanpurTech/BlueEngine/commit/5062995f72e7479a7055131826ab4427647936fc))
10+
- Camera aspect ratio fix ([09302c7](https://github.com/AryanpurTech/BlueEngine/commit/09302c7a58be3ccb3ea7d9784a62af51fcecfd69))
11+
12+
### Miscellaneous Tasks
13+
14+
- Updated version numbers ([d49b531](https://github.com/AryanpurTech/BlueEngine/commit/d49b5312c6fa21eadef4d3acef8bbbc1e5753525))
15+
516
## [0.7.0] - 2025-03-31
617

718
### Bug Fixes

Cargo.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "blue_engine"
3-
version = "0.7.0"
3+
version = "0.7.1"
44
authors = ["Elham Aryanpur <elhamaryanpur5@gmail.com>"]
55
edition = "2024"
66
description = "General-Purpose, Easy-to-use, Fast, and Portable graphics engine"
@@ -33,12 +33,12 @@ android_game_activity = [
3333
u32 = ["blue_engine_core?/u32", "blue_engine_dynamic?/u32"]
3434

3535
[dependencies]
36-
blue_engine_core = { version = "0.7.0", optional = true }
36+
blue_engine_core = { version = "0.7.1", optional = true }
3737
# blue_engine_core = { path = "crates/blue_engine_core", optional = true }
3838

3939
# Wasm does not support dynamic linking.
4040
[target.'cfg(not(target_family = "wasm"))'.dependencies]
41-
blue_engine_dynamic = { version = "0.7.0", optional = true }
41+
blue_engine_dynamic = { version = "0.7.1", optional = true }
4242
# blue_engine_dynamic = { path = "crates/blue_engine_dynamic", optional = true }
4343

4444
# ========== EXAMPLES ========== #

crates/blue_engine_core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "blue_engine_core"
3-
version = "0.7.0"
3+
version = "0.7.1"
44
authors = ["Elham Aryanpur <elhamaryanpur5@gmail.com>"]
55
edition = "2024"
66
description = "USE blue_engine THIS IS FOR INTERNAL USE"

crates/blue_engine_core/src/utils/camera.rs

Lines changed: 60 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
use super::default_resources::OPENGL_TO_WGPU_MATRIX;
88
use crate::{
9-
Matrix4, UniformBuffers,
9+
Matrix4, UniformBuffers, Vector2,
1010
prelude::{Renderer, Vector3},
1111
};
1212
use winit::dpi::PhysicalSize;
@@ -41,7 +41,7 @@ pub struct Camera {
4141
/// The up vector of the camera. This defines the elevation of the camera
4242
pub up: Vector3,
4343
/// The resolution of the camera view
44-
pub resolution: (f32, f32), //maybe this should be a Vector2i
44+
pub resolution: Vector2,
4545
/// The projection of the camera
4646
pub projection: Projection,
4747
/// The closest view of camera
@@ -54,8 +54,6 @@ pub struct Camera {
5454
pub(crate) changed: bool,
5555
/// The uniform data of the camera to be sent to the gpu
5656
pub uniform_data: UniformBuffers,
57-
/// The position and target of the camera
58-
pub(crate) add_position_and_target: bool,
5957
}
6058
unsafe impl Send for Camera {}
6159
unsafe impl Sync for Camera {}
@@ -84,9 +82,9 @@ impl Camera {
8482

8583
let mut camera = Self {
8684
position: Vector3::new(0.0, 0.0, 3.0),
87-
target: Vector3::new(0.0, 0.0, -1.0),
85+
target: Vector3::new(0.0, 0.0, 0.0),
8886
up: Vector3::new(0.0, 1.0, 0.0),
89-
resolution: (window_size.width as f32, window_size.height as f32),
87+
resolution: Vector2::new(window_size.width as f32, window_size.height as f32),
9088
projection: crate::Projection::Perspective {
9189
fov: 70f32 * (std::f32::consts::PI / 180f32),
9290
},
@@ -95,13 +93,39 @@ impl Camera {
9593
view_data: Matrix4::IDENTITY,
9694
changed: true,
9795
uniform_data: camera_uniform.0,
98-
add_position_and_target: false,
9996
};
10097
camera.build_view_projection_matrix();
10198

10299
camera
103100
}
104101

102+
/// Builds a view matrix for camera projection
103+
pub fn build_view_matrix(&self) -> Matrix4 {
104+
Matrix4::look_at_rh(self.position, self.target, self.up)
105+
}
106+
107+
/// Builds a projection matrix for camera
108+
pub fn build_projection_matrix(&self) -> Matrix4 {
109+
let aspect = self.resolution.x / self.resolution.y;
110+
111+
match self.projection {
112+
crate::Projection::Perspective { fov } => {
113+
Matrix4::perspective_rh(fov, aspect, self.near, self.far)
114+
}
115+
crate::Projection::Orthographic { zoom } => {
116+
let width = zoom;
117+
let height = width / aspect;
118+
119+
let left = width * -0.5;
120+
let right = width * 0.5;
121+
let bottom = height * -0.5;
122+
let top = height * 0.5;
123+
124+
Matrix4::orthographic_rh(left, right, bottom, top, self.near, self.far)
125+
}
126+
}
127+
}
128+
105129
/// Updates the view uniform matrix that decides how camera works
106130
pub fn build_view_projection_matrix(&mut self) {
107131
let view = self.build_view_matrix();
@@ -115,16 +139,42 @@ impl Camera {
115139
let view = self.build_view_matrix();
116140
let ortho = Matrix4::orthographic_rh(
117141
0f32,
118-
self.resolution.0,
142+
self.resolution.x,
119143
0f32,
120-
self.resolution.1,
144+
self.resolution.y,
121145
self.near,
122146
self.far,
123147
);
124148
self.view_data = ortho * view;
125149
self.changed = true;
126150
}
127151

152+
/// This builds a uniform buffer data from camera view data that is sent to the GPU in next frame
153+
pub fn update_view_projection(&mut self, renderer: &mut Renderer) {
154+
if self.changed {
155+
let updated_buffer = renderer
156+
.build_uniform_buffer(&[renderer
157+
.build_uniform_buffer_part("Camera Uniform", self.camera_uniform_buffer())])
158+
.0;
159+
self.uniform_data = updated_buffer;
160+
self.changed = false;
161+
}
162+
}
163+
164+
/// This builds a uniform buffer data from camera view data that is sent to the GPU in next frame, and returns the bindgroup
165+
pub fn update_view_projection_and_return(
166+
&mut self,
167+
renderer: &mut Renderer,
168+
) -> crate::UniformBuffers {
169+
let updated_buffer = renderer
170+
.build_uniform_buffer(&[
171+
renderer.build_uniform_buffer_part("Camera Uniform", self.camera_uniform_buffer())
172+
])
173+
.0;
174+
175+
updated_buffer
176+
}
177+
128178
/// Returns a matrix uniform buffer from camera data that can be sent to GPU
129179
pub fn camera_uniform_buffer(&self) -> Matrix4 {
130180
self.view_data
@@ -162,7 +212,7 @@ impl Camera {
162212

163213
/// Sets the aspect ratio of the camera
164214
pub fn set_resolution(&mut self, window_size: PhysicalSize<u32>) {
165-
self.resolution = (window_size.width as f32, window_size.height as f32);
215+
self.resolution = Vector2::new(window_size.width as f32, window_size.height as f32);
166216
self.build_view_projection_matrix();
167217
}
168218

@@ -171,72 +221,6 @@ impl Camera {
171221
self.projection = projection;
172222
self.build_view_projection_matrix();
173223
}
174-
175-
/// Enables adding position and target for the view target
176-
pub fn add_position_and_target(&mut self, enable: bool) {
177-
self.add_position_and_target = enable;
178-
}
179-
180-
/// This builds a uniform buffer data from camera view data that is sent to the GPU in next frame
181-
pub fn update_view_projection(&mut self, renderer: &mut Renderer) {
182-
if self.changed {
183-
let updated_buffer = renderer
184-
.build_uniform_buffer(&[renderer
185-
.build_uniform_buffer_part("Camera Uniform", self.camera_uniform_buffer())])
186-
.0;
187-
self.uniform_data = updated_buffer;
188-
self.changed = false;
189-
}
190-
}
191-
192-
/// This builds a uniform buffer data from camera view data that is sent to the GPU in next frame, and returns the bindgroup
193-
pub fn update_view_projection_and_return(
194-
&mut self,
195-
renderer: &mut Renderer,
196-
) -> crate::UniformBuffers {
197-
let updated_buffer = renderer
198-
.build_uniform_buffer(&[
199-
renderer.build_uniform_buffer_part("Camera Uniform", self.camera_uniform_buffer())
200-
])
201-
.0;
202-
203-
updated_buffer
204-
}
205-
206-
/// Builds a view matrix for camera projection
207-
pub fn build_view_matrix(&self) -> Matrix4 {
208-
Matrix4::look_at_rh(
209-
self.position.into(),
210-
if self.add_position_and_target {
211-
(self.position + self.target).into()
212-
} else {
213-
self.target.into()
214-
},
215-
self.up.into(),
216-
)
217-
}
218-
219-
/// Builds a projection matrix for camera
220-
pub fn build_projection_matrix(&self) -> Matrix4 {
221-
let aspect = self.resolution.0 / self.resolution.1;
222-
223-
match self.projection {
224-
crate::Projection::Perspective { fov } => {
225-
Matrix4::perspective_rh(aspect, fov, self.near, self.far)
226-
}
227-
crate::Projection::Orthographic { zoom } => {
228-
let width = zoom;
229-
let height = width / aspect;
230-
231-
let left = width * -0.5;
232-
let right = width * 0.5;
233-
let bottom = height * -0.5;
234-
let top = height * 0.5;
235-
236-
Matrix4::orthographic_rh(left, right, bottom, top, self.near, self.far)
237-
}
238-
}
239-
}
240224
}
241225

242226
impl CameraContainer {
@@ -311,12 +295,6 @@ impl CameraContainer {
311295
main_camera.set_projection(projection);
312296
}
313297
}
314-
/// Enables adding position and target for the view target
315-
pub fn add_position_and_target(&mut self, enable: bool) {
316-
if let Some(main_camera) = self.cameras.get_mut("main") {
317-
main_camera.add_position_and_target(enable);
318-
}
319-
}
320298
/// This builds a uniform buffer data from camera view data that is sent to the GPU in next frame
321299
pub fn update_view_projection(&mut self, renderer: &mut Renderer) {
322300
if let Some(main_camera) = self.cameras.get_mut("main") {

crates/blue_engine_dynamic/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "blue_engine_dynamic"
3-
version = "0.7.0"
3+
version = "0.7.1"
44
authors = ["Elham Aryanpur <elhamaryanpur5@gmail.com>"]
55
edition = "2024"
66
description = "USE blue_engine THIS IS FOR INTERNAL USE"
@@ -20,5 +20,5 @@ android_game_activity = ["blue_engine_core/android_game_activity"]
2020
u32 = ["blue_engine_core/u32"]
2121

2222
[dependencies]
23-
blue_engine_core = { version = "0.7.0" }
23+
blue_engine_core = { version = "0.7.1" }
2424
# blue_engine_core = { path = "../blue_engine_core" }

crates/blue_engine_utilities/src/definitions/flycamera.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ use blue_engine::{CameraContainer, InputHelper, ObjectStorage, Vector3, winit};
33

44
impl FlyCamera {
55
pub fn new(camera: &mut CameraContainer) -> Self {
6-
camera.add_position_and_target(true);
7-
86
Self {
97
camera_right: Self::update_vertices(camera),
108
yaw: -90f32,
@@ -117,6 +115,7 @@ impl blue_engine::Signal for FlyCamera {
117115
+ (camera.get("main").unwrap().target * camera_speed);
118116

119117
camera.set_position([result.x, result.y, result.z]);
118+
camera.set_target([result.x, result.y, result.z]);
120119
}
121120

122121
// S
@@ -125,6 +124,7 @@ impl blue_engine::Signal for FlyCamera {
125124
- (camera.get("main").unwrap().target * camera_speed);
126125

127126
camera.set_position([result.x, result.y, result.z]);
127+
camera.set_target([result.x, result.y, result.z]);
128128
}
129129
// A
130130
if input.key_held(blue_engine::KeyCode::KeyA) {
@@ -133,6 +133,7 @@ impl blue_engine::Signal for FlyCamera {
133133
let result = camera_pos - (self.camera_right * camera_speed);
134134

135135
camera.set_position([result.x, result.y, result.z]);
136+
camera.set_target([result.x, result.y, result.z]);
136137
}
137138
// D
138139
if input.key_held(blue_engine::KeyCode::KeyD) {
@@ -141,6 +142,7 @@ impl blue_engine::Signal for FlyCamera {
141142
let result = camera_pos + (self.camera_right * camera_speed);
142143

143144
camera.set_position([result.x, result.y, result.z]);
145+
camera.set_target([result.x, result.y, result.z]);
144146
}
145147
}
146148
}

examples/camera/rotate_around.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
*/
66

77
use blue_engine::{
8-
Vector3,
98
prelude::{Engine, ObjectSettings, ShaderSettings},
109
primitive_shapes::square,
1110
};
@@ -33,13 +32,13 @@ fn main() {
3332
);
3433

3534
let radius = 2f32;
36-
let start = std::time::SystemTime::now();
35+
let start = std::time::Instant::now();
3736

3837
engine
3938
.update_loop(move |_, _, _, _, camera, _| {
40-
let camx = start.elapsed().unwrap().as_secs_f32().sin() * radius;
41-
let camz = start.elapsed().unwrap().as_secs_f32().cos() * radius;
42-
camera.set_position(Vector3::new(camx, 0.0, camz));
39+
let camx = start.elapsed().as_secs_f32().sin() * radius;
40+
let camz = start.elapsed().as_secs_f32().cos() * radius;
41+
camera.set_position([camx, 0.0, camz]);
4342
})
4443
.expect("Error during update loop");
4544
}

0 commit comments

Comments
 (0)