custom perspective matrix based on k4a

This commit is contained in:
Brandon Thomas committed 2020-05-01 06:07:32 -04:00
1 parent 991f1b8aaa
commit 67a10b0892
4 files changed
+109 -20

No files matched your search

+1 -1
View File
@@ -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
View File
@@ -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) {
+41 -9
View File
@@ -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);
+5 -5
View File
@@ -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(_) => {},
}