custom perspective matrix based on k4a
This commit is contained in:
1 parent
991f1b8aaa
commit
67a10b0892
4 files changed
+109
-20
No files matched your search
@@ -19,7 +19,7 @@ pub fn run(capture_provider: Arc<CaptureProvider>, calibration_data: k4a_sys::k4
|
||||
let mut webcam_writer = WebcamWriter::open_file("/dev/video0", 1280, 720, 3)
|
||||
.expect("should be able to create webcamwriter");
|
||||
|
||||
let sdl_arcball = Arc::new(Mutex::new(SdlArcball::new(1280.0, 720.0)));
|
||||
let sdl_arcball = Arc::new(Mutex::new(SdlArcball::new(1280, 720)));
|
||||
|
||||
let sdl_context = sdl2::init().unwrap();
|
||||
let video = sdl_context.video().unwrap();
|
||||
|
||||
+62
-5
@@ -4,32 +4,46 @@ use cgmath::Vector3;
|
||||
use sdl2::event::Event;
|
||||
use sdl2::mouse::MouseButton;
|
||||
|
||||
const DEFAULT_ZOOM: f32 = 65.0;
|
||||
|
||||
// TODO: Enable camera resizing (or change of texture to differently sized texture)
|
||||
/// Wrap a camera arcball for use with SDL
|
||||
pub struct SdlArcball {
|
||||
// TODO: Enable camera resizing (or change of texture to differently sized texture)
|
||||
// Arcball camera state
|
||||
arcball: ArcballCamera<f32>,
|
||||
|
||||
// Dimensions of the window
|
||||
window_width: u32,
|
||||
window_height: u32,
|
||||
|
||||
// Last mouse state
|
||||
left_mouse_active: bool,
|
||||
right_mouse_active: bool,
|
||||
last_x: f32,
|
||||
last_y: f32,
|
||||
last_zoom: f32,
|
||||
}
|
||||
|
||||
impl SdlArcball {
|
||||
/// CTOR
|
||||
pub fn new(width: f32, height: f32) -> Self {
|
||||
pub fn new(window_width: u32, window_height: u32) -> Self {
|
||||
let center = Vector3::new(0.0, 0.0, 0.0);
|
||||
let zoom_speed = 1.0;
|
||||
let screen = [width, height];
|
||||
let screen = [window_width as f32, window_height as f32];
|
||||
let arcball = ArcballCamera::new(center, zoom_speed, screen);
|
||||
Self {
|
||||
arcball,
|
||||
window_width,
|
||||
window_height,
|
||||
left_mouse_active: false,
|
||||
right_mouse_active: false,
|
||||
last_x: 0.0,
|
||||
last_y: 0.0,
|
||||
last_zoom: DEFAULT_ZOOM,
|
||||
}
|
||||
}
|
||||
|
||||
/// Process an SDL event.
|
||||
pub fn process_event(&mut self, event: &Event) {
|
||||
match event {
|
||||
Event::MouseWheel { timestamp: _, window_id: _, which: _, x: _, y, direction: _ } => {
|
||||
@@ -52,12 +66,55 @@ impl SdlArcball {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mat4(&self) -> Matrix4<f32> {
|
||||
/// Get the view matrix
|
||||
pub fn get_view_matrix(&self) -> Matrix4<f32> {
|
||||
self.arcball.get_mat4()
|
||||
}
|
||||
|
||||
/// Get the perspective matrix
|
||||
pub fn get_perspective_matrix(&self) -> Matrix4<f32> {
|
||||
let zoom = self.last_zoom;
|
||||
let y_fov = zoom.to_radians();
|
||||
let aspect = self.window_width as f32 / self.window_height as f32;
|
||||
let n = 0.1f32;
|
||||
let f = 100.0f32;
|
||||
|
||||
// From linmath.h included in Microsoft's k4a open source code
|
||||
let a = 1.0f32 / (y_fov / 2.0).tan();
|
||||
|
||||
// NB: This is column-major, which is dumb.
|
||||
Matrix4::new(
|
||||
// Column 0
|
||||
a / aspect,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
|
||||
// Column 1
|
||||
0.0,
|
||||
a,
|
||||
0.0,
|
||||
0.0,
|
||||
|
||||
// Column 2
|
||||
0.0,
|
||||
0.0,
|
||||
-((f + n) / (f - n)),
|
||||
-((2.0 * f * n) / (f - n)),
|
||||
|
||||
// Column 3
|
||||
0.0,
|
||||
0.0,
|
||||
-1.0, // NB: This is not zero
|
||||
0.0,
|
||||
)
|
||||
}
|
||||
|
||||
fn mouse_wheel(&mut self, y: i32) {
|
||||
self.arcball.zoom(y as f32, 0.16);
|
||||
let y = y as f32;
|
||||
println!("Zoom: {}", y);
|
||||
self.arcball.zoom(y, 0.16);
|
||||
self.last_zoom = y;
|
||||
}
|
||||
|
||||
fn mouse_button_press(&mut self, mouse_button: &MouseButton, down: bool) {
|
||||
|
||||
@@ -8,11 +8,14 @@ use std::os::raw::{c_char, c_void};
|
||||
use std::ptr;
|
||||
use std::ptr::null;
|
||||
use std::str;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use arcball::ArcballCamera;
|
||||
use gl;
|
||||
use gl::types::*;
|
||||
|
||||
use k4a_sys_wrapper;
|
||||
use mouse::SdlArcball;
|
||||
use opengl_wrapper::{Buffer, gl_get_error, OpenGlError, VertexArray};
|
||||
use opengl_wrapper::Texture;
|
||||
use point_cloud::compile_shader::compile_shader;
|
||||
@@ -188,6 +191,8 @@ void main()
|
||||
";
|
||||
|
||||
pub struct PointCloudRenderer {
|
||||
arcball_camera: Arc<Mutex<SdlArcball>>,
|
||||
|
||||
/// The OpenGL program
|
||||
shader_program_id: GLuint,
|
||||
|
||||
@@ -200,7 +205,8 @@ pub struct PointCloudRenderer {
|
||||
// TODO: better matrix types
|
||||
view: [f32; 16],
|
||||
projection: [f32; 16],
|
||||
proj_view: [[f32; 4]; 4],
|
||||
view_matrix: [[f32; 4]; 4],
|
||||
projection_matrix: [[f32; 4]; 4],
|
||||
|
||||
/// Renderer setting: size of the rendered points
|
||||
point_size: u8,
|
||||
@@ -276,7 +282,7 @@ const fn initial_projection_matrix_4x4() -> [f32; 16] {
|
||||
|
||||
impl PointCloudRenderer {
|
||||
|
||||
pub fn new() -> Self {
|
||||
pub fn new(arcball: Arc<Mutex<SdlArcball>>) -> Self {
|
||||
let vertex_array_object = VertexArray::new_initialized();
|
||||
let vertex_color_buffer_object = Buffer::new_initialized();
|
||||
|
||||
@@ -335,10 +341,19 @@ impl PointCloudRenderer {
|
||||
[2.62268e-07, 1.0, -5.0, 1.0],
|
||||
];
|
||||
|
||||
let initial_projection = [
|
||||
[1.41272, 0.0, 0.0, 0.0],
|
||||
[0.0, 1.56969, 0.0, 0.0],
|
||||
[0.0, 0.0, -1.002, -1.0],
|
||||
[0.0, 0.0, -0.2002, 0.0],
|
||||
];
|
||||
|
||||
Self {
|
||||
arcball_camera: arcball,
|
||||
view: initial_view_matrix_4x4(),
|
||||
projection: initial_projection_matrix_4x4(),
|
||||
proj_view: initial_view,
|
||||
view_matrix: initial_view,
|
||||
projection_matrix: initial_projection,
|
||||
shader_program_id: program_id,
|
||||
vertex_shader_id,
|
||||
fragment_shader_id,
|
||||
@@ -355,11 +370,26 @@ impl PointCloudRenderer {
|
||||
}
|
||||
|
||||
///
|
||||
/// Update the view matrix
|
||||
/// Update the view matrices
|
||||
///
|
||||
pub fn update_view_projection(&mut self, proj_view: [[f32; 4]; 4]) {
|
||||
//println!("Matrix: {:?}", proj_view);
|
||||
self.proj_view = proj_view;
|
||||
pub fn update_view_projection(&mut self, view: [[f32; 4]; 4], projection: [[f32; 4]; 4]) {
|
||||
println!("\nView Matrix: {:?}", view);
|
||||
println!("Updated: {:?}", projection);
|
||||
self.view_matrix = view;
|
||||
//self.projection_matrix = projection;
|
||||
|
||||
let initial_projection = [
|
||||
[1.41272, 0.0, 0.0, 0.0],
|
||||
[0.0, 1.56969, 0.0, 0.0],
|
||||
[0.0, 0.0, -1.002, -1.0],
|
||||
[0.0, 0.0, -0.2002, 0.0],
|
||||
];
|
||||
|
||||
// Initial: [[1.41272, 0.0, 0.0, 0.0], [0.0, 1.56969, 0.0, 0.0], [0.0, 0.0, -1.002, -1.0], [0.0, 0.0, -0.2002, 0.0]]
|
||||
// Updated: [[0.88294804, 0.0, 0.0, 0.0], [0.0, 1.5696855, 0.0, 0.0], [0.0, 0.0, -1.002002, -0.2002002], [0.0, 0.0, -1.0, 0.0]]
|
||||
println!("Initial: {:?}", initial_projection);
|
||||
|
||||
self.projection_matrix = initial_projection;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -495,9 +525,11 @@ impl PointCloudRenderer {
|
||||
|
||||
// Update view/projection matrices in shader
|
||||
//gl::UniformMatrix4fv(self.view_index, 1, gl::FALSE, self.view.as_ptr());
|
||||
gl::UniformMatrix4fv(self.projection_index, 1, gl::FALSE, self.projection.as_ptr());
|
||||
//gl::UniformMatrix4fv(self.projection_index, 1, gl::FALSE, self.projection.as_ptr());
|
||||
let typed_projection = self.projection_matrix.as_ptr() as *const GLfloat;
|
||||
gl::UniformMatrix4fv(self.projection_index, 1, gl::FALSE, typed_projection);
|
||||
|
||||
let typed_view = self.proj_view.as_ptr() as *const GLfloat;
|
||||
let typed_view = self.view_matrix.as_ptr() as *const GLfloat;
|
||||
gl::UniformMatrix4fv(self.view_index, 1, gl::FALSE, typed_view);
|
||||
//gl::UniformMatrix4fv(self.projection_index, 1, gl::FALSE, typed_view);
|
||||
|
||||
|
||||
@@ -182,11 +182,11 @@ impl PointCloudVisualizer {
|
||||
.expect("Should be in correct depth sensor mode.");
|
||||
|
||||
let mut visualizer = Self {
|
||||
arcball_camera,
|
||||
arcball_camera: arcball_camera.clone(),
|
||||
m_dimensions_width: width,
|
||||
m_dimensions_height: height,
|
||||
enable_color_point_cloud,
|
||||
point_cloud_renderer: PointCloudRenderer::new(),
|
||||
point_cloud_renderer: PointCloudRenderer::new(arcball_camera.clone()),
|
||||
point_cloud_converter: GpuPointCloudConverter::new(),
|
||||
frame_buffer: Framebuffer::new_initialized(),
|
||||
depth_buffer,
|
||||
@@ -273,9 +273,9 @@ impl PointCloudVisualizer {
|
||||
|
||||
match self.arcball_camera.lock() {
|
||||
Ok(arcball) => {
|
||||
let proj_view: [[f32; 4]; 4] = (arcball.get_mat4()).into();
|
||||
// TODO: View matrix maths
|
||||
self.point_cloud_renderer.update_view_projection(proj_view);
|
||||
let view: [[f32; 4]; 4] = (arcball.get_view_matrix()).into();
|
||||
let perspective: [[f32; 4]; 4] = (arcball.get_perspective_matrix()).into();
|
||||
self.point_cloud_renderer.update_view_projection(view, perspective);
|
||||
},
|
||||
Err(_) => {},
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user