Starting to work
This commit is contained in:
parent
b9bdac0dae
commit
376a38c4dc
|
@ -66,6 +66,11 @@ macro_rules! make_vector {
|
||||||
pub fn $x(&self) -> T {
|
pub fn $x(&self) -> T {
|
||||||
self.data[$y]
|
self.data[$y]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a mut ref to the coordinate of the vector.
|
||||||
|
pub fn $x_mut(&mut self) -> &mut T {
|
||||||
|
&mut self.data[$y]
|
||||||
|
}
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,14 +12,17 @@ use glium::glutin::Event;
|
||||||
use glium::glutin::WindowEvent;
|
use glium::glutin::WindowEvent;
|
||||||
use glium::glutin::VirtualKeyCode;
|
use glium::glutin::VirtualKeyCode;
|
||||||
|
|
||||||
|
|
||||||
|
use model_converter::math::vector::Vector3;
|
||||||
use model_converter::parser::{parse, parse_into_model};
|
use model_converter::parser::{parse, parse_into_model};
|
||||||
use model_converter::renderer::Renderer;
|
use model_converter::renderer::Renderer;
|
||||||
use model_converter::renderer::camera::RotatingCamera;
|
use model_converter::renderer::controls::OrbitControls;
|
||||||
|
use model_converter::renderer::camera::Camera;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
let mut model = parse("./assets/models/toonlink/link.mtl").unwrap();
|
let mut model = parse("./assets/models/cube/cube.mtl").unwrap();
|
||||||
parse_into_model("./assets/models/toonlink/link.obj", &mut model).unwrap();
|
parse_into_model("./assets/models/cube/cube.obj", &mut model).unwrap();
|
||||||
|
|
||||||
let mut events_loop = EventsLoop::new();
|
let mut events_loop = EventsLoop::new();
|
||||||
let window = WindowBuilder::new();
|
let window = WindowBuilder::new();
|
||||||
|
@ -31,18 +34,21 @@ fn main() {
|
||||||
let mut renderer = Renderer::new(display);
|
let mut renderer = Renderer::new(display);
|
||||||
renderer.add_model(&model);
|
renderer.add_model(&model);
|
||||||
|
|
||||||
let mut camera = RotatingCamera::new(50.0);
|
let mut camera = Camera::new(
|
||||||
|
Vector3::new( 0.0, 0.0, 0.0),
|
||||||
|
Vector3::new( 0.0, 0.0, 0.0),
|
||||||
|
Vector3::new( 0.0, 1.0, 0.0),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut controls = OrbitControls::new(&mut camera);
|
||||||
|
|
||||||
while !closed {
|
while !closed {
|
||||||
|
|
||||||
camera.increase_theta(0.025);
|
|
||||||
|
|
||||||
let mut target = renderer.draw();
|
|
||||||
renderer.render(&camera, &mut target);
|
|
||||||
|
|
||||||
target.finish().unwrap();
|
|
||||||
|
|
||||||
events_loop.poll_events(|ev| {
|
events_loop.poll_events(|ev| {
|
||||||
|
|
||||||
|
use model_converter::renderer::controls::Controls;
|
||||||
|
controls.manage_event(&ev, &mut camera);
|
||||||
|
|
||||||
match ev {
|
match ev {
|
||||||
// Close window
|
// Close window
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
|
@ -61,5 +67,11 @@ fn main() {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let mut target = renderer.draw();
|
||||||
|
renderer.render(&camera, &mut target);
|
||||||
|
target.finish().unwrap();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use math::vector::Vector3;
|
use math::vector::Vector3;
|
||||||
|
|
||||||
pub trait Camera {
|
pub trait RenderCamera {
|
||||||
fn get_view_matrix(&self) -> [[f32; 4]; 4];
|
fn get_view_matrix(&self) -> [[f32; 4]; 4];
|
||||||
fn get_perspective_matrix(&self, dimensions: (u32, u32)) -> [[f32; 4]; 4] {
|
fn get_perspective_matrix(&self, dimensions: (u32, u32)) -> [[f32; 4]; 4] {
|
||||||
let (width, height) = dimensions;
|
let (width, height) = dimensions;
|
||||||
|
@ -61,15 +61,15 @@ pub fn look_at_matrix(position: [f32; 3], target: [f32; 3], up: [f32; 3]) -> [[f
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FixedCamera {
|
pub struct Camera {
|
||||||
position: Vector3<f32>,
|
pub position: Vector3<f32>,
|
||||||
target: Vector3<f32>,
|
pub target: Vector3<f32>,
|
||||||
up: Vector3<f32>,
|
pub up: Vector3<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FixedCamera {
|
impl Camera {
|
||||||
pub fn new(position: Vector3<f32>, target: Vector3<f32>, up: Vector3<f32>) -> FixedCamera {
|
pub fn new(position: Vector3<f32>, target: Vector3<f32>, up: Vector3<f32>) -> Camera {
|
||||||
FixedCamera {
|
Camera {
|
||||||
position: position,
|
position: position,
|
||||||
target: target,
|
target: target,
|
||||||
up: up,
|
up: up,
|
||||||
|
@ -77,7 +77,7 @@ impl FixedCamera {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Camera for FixedCamera {
|
impl RenderCamera for Camera {
|
||||||
fn get_view_matrix(&self) -> [[f32; 4]; 4] {
|
fn get_view_matrix(&self) -> [[f32; 4]; 4] {
|
||||||
look_at_matrix(self.position.into(), self.target.into(), self.up.into())
|
look_at_matrix(self.position.into(), self.target.into(), self.up.into())
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ impl RotatingCamera {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Camera for RotatingCamera {
|
impl RenderCamera for RotatingCamera {
|
||||||
fn get_view_matrix(&self) -> [[f32; 4]; 4] {
|
fn get_view_matrix(&self) -> [[f32; 4]; 4] {
|
||||||
let position = Vector3::new(
|
let position = Vector3::new(
|
||||||
self.distance * self.theta.cos(),
|
self.distance * self.theta.cos(),
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
const EPSILON: f32 = 0.001;
|
||||||
|
|
||||||
|
use glium::glutin::{
|
||||||
|
Event,
|
||||||
|
WindowEvent,
|
||||||
|
ElementState,
|
||||||
|
MouseButton,
|
||||||
|
MouseScrollDelta,
|
||||||
|
};
|
||||||
|
|
||||||
|
use math::vector::Vector2;
|
||||||
|
use renderer::camera::Camera;
|
||||||
|
|
||||||
|
/// The trait that all controls should implement.
|
||||||
|
pub trait Controls {
|
||||||
|
|
||||||
|
/// Modifies the camera depending on the event.
|
||||||
|
fn manage_event(&mut self, event: &Event, camera: &mut Camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An orbit controls allowing to orbit around an object.
|
||||||
|
///
|
||||||
|
/// Only object centered are supported.
|
||||||
|
pub struct OrbitControls {
|
||||||
|
/// The last position of the mouse.
|
||||||
|
mouse_position: Vector2<f32>,
|
||||||
|
|
||||||
|
/// Wether the left click of the mouse is pressed or not.
|
||||||
|
pressed: bool,
|
||||||
|
|
||||||
|
/// The theta angle of the position of the camera in spheric coordinates.
|
||||||
|
theta: f32,
|
||||||
|
|
||||||
|
/// The phi angle of the position of the camera in spheric coordinates.
|
||||||
|
phi: f32,
|
||||||
|
|
||||||
|
/// The distance between the camera and the origin.
|
||||||
|
distance: f32,
|
||||||
|
|
||||||
|
/// The sensitiviy of the rotation of the mouse.
|
||||||
|
sensitivity: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OrbitControls {
|
||||||
|
|
||||||
|
/// Creates a new orbit controls, and initializes the camera.
|
||||||
|
pub fn new(camera: &mut Camera) -> OrbitControls {
|
||||||
|
let controls = OrbitControls {
|
||||||
|
mouse_position: Vector2::new(0.0, 0.0),
|
||||||
|
pressed: false,
|
||||||
|
theta: 0.0,
|
||||||
|
phi: 0.0,
|
||||||
|
distance: 5.0,
|
||||||
|
sensitivity: 200.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
*camera.position.x_mut() = controls.distance * controls.theta.cos();
|
||||||
|
*camera.position.y_mut() = 0.0;
|
||||||
|
*camera.position.z_mut() = controls.distance * controls.phi.sin();
|
||||||
|
controls
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Controls for OrbitControls {
|
||||||
|
fn manage_event(&mut self, event: &Event, camera: &mut Camera) {
|
||||||
|
match *event {
|
||||||
|
|
||||||
|
Event::WindowEvent {
|
||||||
|
event: WindowEvent::MouseInput {
|
||||||
|
button: MouseButton::Left,
|
||||||
|
state, ..
|
||||||
|
}, ..
|
||||||
|
} => {
|
||||||
|
self.pressed = state == ElementState::Pressed;
|
||||||
|
},
|
||||||
|
|
||||||
|
Event::WindowEvent {
|
||||||
|
event: WindowEvent::MouseWheel {
|
||||||
|
delta: MouseScrollDelta::LineDelta(_, y), ..
|
||||||
|
}, ..
|
||||||
|
} => {
|
||||||
|
self.distance -= y;
|
||||||
|
|
||||||
|
*camera.position.x_mut() = self.distance * self.phi.cos() * self.theta.cos();
|
||||||
|
*camera.position.y_mut() = self.distance * self.phi.sin();
|
||||||
|
*camera.position.z_mut() = self.distance * self.phi.cos() * self.theta.sin();
|
||||||
|
},
|
||||||
|
|
||||||
|
Event::WindowEvent{
|
||||||
|
event: WindowEvent::CursorMoved {
|
||||||
|
position: (x, y), ..
|
||||||
|
}, ..
|
||||||
|
} => {
|
||||||
|
let current_position = Vector2::new(x as f32, y as f32);
|
||||||
|
|
||||||
|
if self.pressed {
|
||||||
|
let difference = (current_position - self.mouse_position) / self.sensitivity;
|
||||||
|
|
||||||
|
self.theta += difference.x();
|
||||||
|
self.phi += difference.y();
|
||||||
|
|
||||||
|
use std::f32::consts::PI;
|
||||||
|
self.phi = self.phi.max(- PI/2.0 + EPSILON);
|
||||||
|
self.phi = self.phi.min( PI/2.0 - EPSILON);
|
||||||
|
|
||||||
|
*camera.position.x_mut() = self.distance * self.phi.cos() * self.theta.cos();
|
||||||
|
*camera.position.y_mut() = self.distance * self.phi.sin();
|
||||||
|
*camera.position.z_mut() = self.distance * self.phi.cos() * self.theta.sin();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record new position
|
||||||
|
self.mouse_position = current_position;
|
||||||
|
},
|
||||||
|
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod camera;
|
pub mod camera;
|
||||||
|
pub mod controls;
|
||||||
|
|
||||||
use glium::draw_parameters::DepthTest;
|
use glium::draw_parameters::DepthTest;
|
||||||
use glium::texture::{
|
use glium::texture::{
|
||||||
|
@ -20,7 +21,7 @@ use glium::{
|
||||||
use image;
|
use image;
|
||||||
|
|
||||||
use model::{Model, Vertex};
|
use model::{Model, Vertex};
|
||||||
use renderer::camera::Camera;
|
use renderer::camera::RenderCamera;
|
||||||
|
|
||||||
pub struct RenderMaterial {
|
pub struct RenderMaterial {
|
||||||
texture: Option<SrgbTexture2d>,
|
texture: Option<SrgbTexture2d>,
|
||||||
|
@ -105,7 +106,7 @@ impl<'a> Renderer<'a> {
|
||||||
self.display.draw()
|
self.display.draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render<C: Camera>(&self, camera: &C, target: &mut Frame) {
|
pub fn render<C: RenderCamera>(&self, camera: &C, target: &mut Frame) {
|
||||||
use glium::Surface;
|
use glium::Surface;
|
||||||
target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
|
target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
|
||||||
|
|
||||||
|
@ -119,6 +120,7 @@ impl<'a> Renderer<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
for &(_, ref buffers) in &self.models {
|
for &(_, ref buffers) in &self.models {
|
||||||
|
|
||||||
for &(ref material, ref buffer) in buffers {
|
for &(ref material, ref buffer) in buffers {
|
||||||
|
|
||||||
let perspective = camera.get_perspective_matrix(target.get_dimensions());
|
let perspective = camera.get_perspective_matrix(target.get_dimensions());
|
||||||
|
|
Loading…
Reference in New Issue