Skip to content

Commit

Permalink
feat: support orthographic camera move
Browse files Browse the repository at this point in the history
  • Loading branch information
mizy committed Jan 2, 2025
1 parent 52f03ea commit c9f3411
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 57 deletions.
2 changes: 1 addition & 1 deletion examples/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ async fn run() {
window,
)
.await;
test_xyz::add_xyz_line(&mut mini_gpu);
test_xyz::add_xyz_line(&mut mini_gpu, None);
let mut camera_controller = MapController::default();
mini_gpu
.renderer
Expand Down
4 changes: 2 additions & 2 deletions examples/objloader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ async fn run() {
.await;
make_test_mesh(&mut mini_gpu).await;
let mut camera_controller = MapController::default();
camera_controller.config.width = size.width as f32;
camera_controller.config.height = size.height as f32;
camera_controller.config.width = mini_gpu.renderer.viewport.width;
camera_controller.config.height = mini_gpu.renderer.viewport.height;

mini_gpu
.renderer
Expand Down
57 changes: 27 additions & 30 deletions examples/orthographic_camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use ::mini_gpu::{
controller::map::MapController,
material::MaterialTrait,
materials::image::{Image, ImageConfig},
orthographic_camera::OrthographicCamera,
},
entity::Entity,
mini_gpu::{self, MiniGPU},
Expand Down Expand Up @@ -33,11 +34,12 @@ async fn run() {
window,
)
.await;
make_test_mesh(&mut mini_gpu);
utils::camera::default_orthographic_camera(&mut mini_gpu);
test_xyz::add_xyz_line(&mut mini_gpu);
make_test_mesh(&mut mini_gpu).await;
test_xyz::add_xyz_line(&mut mini_gpu, Some(10.));
let mut camera_controller = MapController::default();
camera_controller.config.pan_speed = 0.01;
camera_controller.config.width = mini_gpu.renderer.viewport.width;
camera_controller.config.height = mini_gpu.renderer.viewport.height;

mini_gpu
.renderer
Expand Down Expand Up @@ -68,6 +70,8 @@ async fn run() {
physical_size.width as f32 / physical_size.height as f32,
&mini_gpu.renderer,
);
camera_controller.config.width = mini_gpu.renderer.viewport.width;
camera_controller.config.height = mini_gpu.renderer.viewport.height;
mini_gpu.renderer.window.request_redraw();
}
WindowEvent::CloseRequested => target.exit(),
Expand All @@ -84,32 +88,25 @@ async fn run() {
.unwrap();
}

fn make_test_mesh(mini_gpu: &mut MiniGPU) {
let bytes = include_bytes!("./case.jpg");
let image = image::load_from_memory(bytes).unwrap();
let texture = Texture::from_image(
&mini_gpu.renderer.device,
&mini_gpu.renderer.queue,
&image,
Some("texture"),
)
.unwrap();

let material = Image::new(
ImageConfig {
texture: Some(texture),
..Default::default()
},
&mini_gpu.renderer,
);
println!("width: {}", image.width());
println!("height: {}", image.height());
let scale = image.width() as f32 / image.height() as f32;
let mesh = material.make_image_mesh(scale * 1., 1., vec![1.0, 0.0, 0.0], &mini_gpu.renderer);
async fn make_test_mesh(mini_gpu: &mut MiniGPU) {
let path = std::path::Path::new("examples/models/cube/cube.obj");
let obj = utils::obj::load_obj(path, mini_gpu).await;
match obj {
Ok(size) => {
println!("Loaded obj with {} vertices", size);
}
Err(e) => {
println!("Failed to load obj ({:?})", e,);
}
}

let entity_id = mini_gpu.scene.add_entity(Entity::new());
mini_gpu.scene.set_entity_component(entity_id, mesh, "mesh");
mini_gpu
.scene
.set_entity_component::<Box<dyn MaterialTrait>>(entity_id, Box::new(material), "material");
let camera = mini_gpu.scene.get_default_camera().unwrap();
let orthographic_camera = camera
.as_any()
.downcast_mut::<OrthographicCamera>()
.unwrap();
orthographic_camera.config.width = 10.0;
orthographic_camera.config.aspect = mini_gpu.renderer.viewport.aspect;
orthographic_camera.config.position.z = 10.0;
camera.update_bind_group(&mini_gpu.renderer);
}
19 changes: 14 additions & 5 deletions src/components/controller/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ pub struct MapController {
pub struct MapControllerConfig {
pub rotate_speed: f32,
pub pan_speed: f32,
pub width: f32,
pub height: f32,
pub width: f32, // window width
pub height: f32, //// window height
}

impl Default for MapControllerConfig {
Expand Down Expand Up @@ -121,11 +121,20 @@ impl MapController {
let dis = self.mouse_now_pos - self.before_pos;
let camera_look_at = (camera.config.target - camera.config.position).normalize();
let camera_right = camera_look_at.cross(-camera.config.up).normalize();
let camera_forward = camera_look_at.cross(camera_right).normalize();
let camera_move = camera_right * dis.x * self.config.pan_speed
+ camera_forward * dis.y * self.config.pan_speed;
let camera_up = camera.config.up.normalize();
// 计算每个像素对应的世界坐标系中的距离
let view_width = camera.config.width;
let view_height = camera.config.width / camera.config.aspect;
let pan_speed_x = view_width / self.config.width;
let pan_speed_y = view_height / self.config.height;

let camera_move = (camera_right * dis.x * pan_speed_x
+ camera_up * dis.y * pan_speed_y)
* self.config.pan_speed;

camera.config.position += camera_move;
camera.config.target += camera_move;

self.before_pos = self.mouse_now_pos;
} else if self.mouse_left_pressed {
let dis = self.mouse_now_pos - self.before_pos;
Expand Down
4 changes: 2 additions & 2 deletions src/components/orthographic_camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ pub struct OrthographicCameraConfig {
impl Default for OrthographicCameraConfig {
fn default() -> Self {
Self {
width: 10.0,
width: 10.0, // ndc width
aspect: 1.0,
near: 0.1,
far: 100.0,
far: 1000.0,
position: Vec3::new(0.0, 0.0, 10.0),
target: Vec3::new(0.0, 0.0, 0.0),
up: Vec3::new(0.0, 1.0, 0.0),
Expand Down
16 changes: 7 additions & 9 deletions src/components/viewport.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
use glam::Vec2;

pub struct Viewport {
pub width: f32,
pub height: f32,
pub aspect: f32,
// per pixel representation of the screen
pub pixel_size: Vec2,
}

impl Viewport {
pub fn new(width: f32, height: f32) -> Viewport {
// todo: pass camera props to calculate pixel size
pub fn new(width: u32, height: u32) -> Viewport {
let width_f32 = width as f32;
let height_f32 = height as f32;
Viewport {
width,
height,
aspect: width / height,
pixel_size: Vec2::new(1.0 / width, 1.0 / height),
width: width_f32,
height: height_f32,
aspect: width_f32 / height_f32,
}
}
}
10 changes: 8 additions & 2 deletions src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use std::{collections::HashMap, sync::Arc};

use winit::window::Window;

use crate::{scene::Scene, system::system::System, utils::depth_texture};
use crate::{
components::viewport::Viewport, scene::Scene, system::system::System, utils::depth_texture,
};

pub struct Renderer {
pub config: RendererConfig,
Expand All @@ -15,6 +17,7 @@ pub struct Renderer {
pub window: Arc<Window>,
pub systems_map: HashMap<String, Box<dyn System>>,
pub depth_texture: depth_texture::DepthTexture,
pub viewport: Viewport,
}

pub struct RendererConfig {
Expand All @@ -25,7 +28,7 @@ pub struct RendererConfig {
impl Renderer {
pub async fn new(config: RendererConfig, window: Arc<Window>) -> Renderer {
let instance = wgpu::Instance::default();
let surface = instance.create_surface(window.clone()).unwrap() ;
let surface = instance.create_surface(window.clone()).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::default(),
Expand Down Expand Up @@ -66,6 +69,7 @@ impl Renderer {
depth_texture::DepthTexture::new(&device, &surface_config, "depth_texture");
Renderer {
window,
viewport: Viewport::new(config.width, config.height),
config,
surface_config,
swapchain_format,
Expand All @@ -79,6 +83,8 @@ impl Renderer {
}

pub fn resize(&mut self, width: u32, height: u32) {
self.viewport.width = width as f32;
self.viewport.height = height as f32;
self.surface_config.width = width;
self.surface_config.height = height;
self.surface.configure(&self.device, &self.surface_config);
Expand Down
2 changes: 2 additions & 0 deletions src/utils/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use crate::{
pub fn default_orthographic_camera(mini_gpu: &mut MiniGPU) {
let mut camera = OrthographicCamera::new(
OrthographicCameraConfig {
width: mini_gpu.config.width as f32,
aspect: mini_gpu.config.width as f32 / mini_gpu.config.height as f32,
..Default::default()
},
&mini_gpu.renderer,
Expand Down
18 changes: 12 additions & 6 deletions src/utils/test_xyz.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::{
components::{
material::{Material, MaterialConfig, MaterialTrait}, materials::shader::ShaderParser, mesh::Mesh
material::{Material, MaterialConfig, MaterialTrait},
materials::shader::ShaderParser,
mesh::Mesh,
},
entity,
mini_gpu::MiniGPU,
Expand Down Expand Up @@ -28,19 +30,23 @@ fn fs_main(out:VertexOutput) -> @location(0) vec4f {
}
"#;

pub fn add_xyz_line(mini_gpu: &mut MiniGPU) {
pub fn add_xyz_line(mini_gpu: &mut MiniGPU, user_size: Option<f32>) {
let size = user_size.unwrap_or(0.5);
let mesh = Mesh::new(
vec![0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5],
vec![
0.0, 0.0, 0.0, size, 0.0, 0.0, 0.0, size, 0.0, 0.0, 0.0, size,
],
vec![0, 1, 0, 2, 0, 3],
&mini_gpu.renderer,
);
let mut shader_parser = ShaderParser::new();

let material_line = Material::new(
MaterialConfig {
shader: shader_parser
.parse_shader(TEST_XYZLINE_SHADER)
.to_string().to_string(),
.parse_shader(TEST_XYZLINE_SHADER)
.to_string()
.to_string(),
topology: wgpu::PrimitiveTopology::LineList,
uniforms: vec![0.],
},
Expand Down

0 comments on commit c9f3411

Please sign in to comment.