use trackpad to move camera/world
This commit is contained in:
@@ -26,7 +26,7 @@ pub fn main() {
|
|||||||
'main:
|
'main:
|
||||||
//while let Some(_) = window.next() {
|
//while let Some(_) = window.next() {
|
||||||
loop {
|
loop {
|
||||||
scene.update(&mut window.encoder);
|
scene.update(&mut vr, &mut window.encoder);
|
||||||
view.draw(&mut window, &mut vr, &scene);
|
view.draw(&mut window, &mut vr, &scene);
|
||||||
|
|
||||||
// handle window events
|
// handle window events
|
||||||
@@ -38,6 +38,11 @@ pub fn main() {
|
|||||||
|
|
||||||
scene.event(Event::Piston(ev));
|
scene.event(Event::Piston(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle VR events
|
||||||
|
while let Some(ev) = vr.poll_next_event() {
|
||||||
|
scene.event(Event::Vr(ev));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("shutting down");
|
debug!("shutting down");
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ pub trait Scene<D: gfx::Device,
|
|||||||
F: gfx::Factory<D::Resources>> {
|
F: gfx::Factory<D::Resources>> {
|
||||||
fn event(&mut self, event: Event);
|
fn event(&mut self, event: Event);
|
||||||
fn update(&mut self,
|
fn update(&mut self,
|
||||||
|
vr: &mut vr::VR,
|
||||||
encoder: &mut gfx::Encoder<D::Resources, D::CommandBuffer>);
|
encoder: &mut gfx::Encoder<D::Resources, D::CommandBuffer>);
|
||||||
fn render(&self,
|
fn render(&self,
|
||||||
factory: &mut F,
|
factory: &mut F,
|
||||||
|
|||||||
@@ -1,17 +1,23 @@
|
|||||||
use scene;
|
use scene;
|
||||||
use tile;
|
use tile;
|
||||||
use view;
|
use view;
|
||||||
|
use vr;
|
||||||
use world as model;
|
use world as model;
|
||||||
use world::HasMap;
|
use world::HasMap;
|
||||||
|
|
||||||
extern crate gfx;
|
extern crate gfx;
|
||||||
|
extern crate nalgebra as na;
|
||||||
|
extern crate num_traits;
|
||||||
|
extern crate openvr_sys;
|
||||||
extern crate piston_window;
|
extern crate piston_window;
|
||||||
|
|
||||||
|
use std::collections::BTreeMap;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use gfx::tex;
|
use gfx::tex;
|
||||||
use gfx::traits::FactoryExt;
|
use gfx::traits::FactoryExt;
|
||||||
|
use self::num_traits::identities::One;
|
||||||
|
|
||||||
gfx_defines! {
|
gfx_defines! {
|
||||||
vertex Vertex {
|
vertex Vertex {
|
||||||
@@ -21,8 +27,11 @@ gfx_defines! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant Locals {
|
constant Locals {
|
||||||
|
camera: [[f32; 4]; 4] = "camera",
|
||||||
millis: u32 = "millis",
|
millis: u32 = "millis",
|
||||||
anim: u32 = "anim",
|
anim: u32 = "anim",
|
||||||
|
treadmill_x: f32 = "treadmill_x",
|
||||||
|
treadmill_y: f32 = "treadmill_y",
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline pipe {
|
pipeline pipe {
|
||||||
@@ -44,8 +53,8 @@ fn get_model(world: &model::World) -> (Vec<Vertex>, Vec<u32>) {
|
|||||||
for (r, row) in world.map().rows().enumerate() {
|
for (r, row) in world.map().rows().enumerate() {
|
||||||
for (c, tile) in row.into_iter().enumerate() {
|
for (c, tile) in row.into_iter().enumerate() {
|
||||||
let tileidx = tile.val as u32;
|
let tileidx = tile.val as u32;
|
||||||
let rf = (((r + 26) % 256) as i16 - 128) as f32;
|
let rf = (((r + 90) % 256) as i16 - 128) as f32;
|
||||||
let cf = (((c + 48) % 256) as i16 - 128) as f32;
|
let cf = (((c + 144) % 256) as i16 - 128) as f32;
|
||||||
verticies.extend_from_slice(
|
verticies.extend_from_slice(
|
||||||
&[Vertex { pos: [ cf + 0., 0., -rf - 1. ], uv: [0., 0.], tileidx: tileidx },
|
&[Vertex { pos: [ cf + 0., 0., -rf - 1. ], uv: [0., 0.], tileidx: tileidx },
|
||||||
Vertex { pos: [ cf + 1., 0., -rf - 1. ], uv: [1., 0.], tileidx: tileidx },
|
Vertex { pos: [ cf + 1., 0., -rf - 1. ], uv: [1., 0.], tileidx: tileidx },
|
||||||
@@ -60,9 +69,16 @@ fn get_model(world: &model::World) -> (Vec<Vertex>, Vec<u32>) {
|
|||||||
(verticies, indicies)
|
(verticies, indicies)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
enum TrackMode {
|
||||||
|
TOUCH,
|
||||||
|
PRESS
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WorldScene<D: gfx::Device,
|
pub struct WorldScene<D: gfx::Device,
|
||||||
F: gfx::Factory<D::Resources>> {
|
F: gfx::Factory<D::Resources>> {
|
||||||
pso: gfx::PipelineState<D::Resources, pipe::Meta>,
|
pso: gfx::PipelineState<D::Resources, pipe::Meta>,
|
||||||
|
camera: na::Matrix4<f32>,
|
||||||
locals: gfx::handle::Buffer<D::Resources, Locals>,
|
locals: gfx::handle::Buffer<D::Resources, Locals>,
|
||||||
atlas: gfx::handle::ShaderResourceView<D::Resources,
|
atlas: gfx::handle::ShaderResourceView<D::Resources,
|
||||||
<view::ColorFormat as gfx::format::Formatted>::View>,
|
<view::ColorFormat as gfx::format::Formatted>::View>,
|
||||||
@@ -73,6 +89,8 @@ pub struct WorldScene<D: gfx::Device,
|
|||||||
slice: gfx::Slice<D::Resources>,
|
slice: gfx::Slice<D::Resources>,
|
||||||
|
|
||||||
start_time: SystemTime,
|
start_time: SystemTime,
|
||||||
|
treadmills: (f32, f32),
|
||||||
|
pads: BTreeMap<u32, (TrackMode, Option<openvr_sys::VRControllerState_t>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: gfx::Device, F: gfx::Factory<D::Resources>> WorldScene<D, F> {
|
impl<D: gfx::Device, F: gfx::Factory<D::Resources>> WorldScene<D, F> {
|
||||||
@@ -86,6 +104,7 @@ impl<D: gfx::Device, F: gfx::Factory<D::Resources>> WorldScene<D, F> {
|
|||||||
FRAGMENT_SHADER_SRC,
|
FRAGMENT_SHADER_SRC,
|
||||||
pipe::new())
|
pipe::new())
|
||||||
.expect("create pipeline"),
|
.expect("create pipeline"),
|
||||||
|
camera: na::Matrix4::one(),
|
||||||
locals: factory.create_constant_buffer(1),
|
locals: factory.create_constant_buffer(1),
|
||||||
atlas: tile::get_tiles::<_, _, view::ColorFormat>(factory),
|
atlas: tile::get_tiles::<_, _, view::ColorFormat>(factory),
|
||||||
sampler: factory.create_sampler(tex::SamplerInfo::new(tex::FilterMethod::Scale,
|
sampler: factory.create_sampler(tex::SamplerInfo::new(tex::FilterMethod::Scale,
|
||||||
@@ -95,6 +114,8 @@ impl<D: gfx::Device, F: gfx::Factory<D::Resources>> WorldScene<D, F> {
|
|||||||
vbuf: vertex_buffer,
|
vbuf: vertex_buffer,
|
||||||
slice: slice,
|
slice: slice,
|
||||||
start_time: SystemTime::now(),
|
start_time: SystemTime::now(),
|
||||||
|
treadmills: (0.0, 0.0),
|
||||||
|
pads: BTreeMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,15 +130,78 @@ impl<D: gfx::Device,
|
|||||||
F: gfx::Factory<D::Resources>> scene::Scene<D, F> for WorldScene<D, F> {
|
F: gfx::Factory<D::Resources>> scene::Scene<D, F> for WorldScene<D, F> {
|
||||||
|
|
||||||
fn event(&mut self, event: scene::Event) {
|
fn event(&mut self, event: scene::Event) {
|
||||||
|
use scene::Event::*;
|
||||||
|
use vr::Event::*;
|
||||||
|
match event {
|
||||||
|
Vr(Touch { dev_idx, controller }) => {
|
||||||
|
self.pads.insert(dev_idx, (TrackMode::TOUCH, None));
|
||||||
|
},
|
||||||
|
Vr(Press { dev_idx, controller }) => {
|
||||||
|
self.pads.insert(dev_idx, (TrackMode::PRESS, None));
|
||||||
|
},
|
||||||
|
Vr(Unpress { dev_idx, controller }) => {
|
||||||
|
self.pads.insert(dev_idx, (TrackMode::TOUCH, None));
|
||||||
|
},
|
||||||
|
Vr(Untouch { dev_idx, controller }) => {
|
||||||
|
self.pads.remove(&dev_idx);
|
||||||
|
},
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self,
|
fn update(&mut self,
|
||||||
|
vr: &mut vr::VR,
|
||||||
encoder: &mut gfx::Encoder<D::Resources, D::CommandBuffer>) {
|
encoder: &mut gfx::Encoder<D::Resources, D::CommandBuffer>) {
|
||||||
const NANOS_PER_MILLI: u32 = 1_000_000;
|
const NANOS_PER_MILLI: u32 = 1_000_000;
|
||||||
const MILLIS_PER_SEC: u64 = 1_000;
|
const MILLIS_PER_SEC: u64 = 1_000;
|
||||||
let elapsed = self.start_time.elapsed().expect("scene timer");
|
let elapsed = self.start_time.elapsed().expect("scene timer");
|
||||||
let millis = elapsed.subsec_nanos() / NANOS_PER_MILLI + (elapsed.as_secs() * MILLIS_PER_SEC) as u32;
|
let millis = elapsed.subsec_nanos() / NANOS_PER_MILLI + (elapsed.as_secs() * MILLIS_PER_SEC) as u32;
|
||||||
encoder.update_constant_buffer(&self.locals, &Locals { millis: millis, anim: ANIMDATA[0] });
|
|
||||||
|
for (pad, track) in self.pads.iter_mut() {
|
||||||
|
let mode = track.0;
|
||||||
|
if let Some(state) = vr.get_controller_state(*pad) {
|
||||||
|
if let Some(old_state) = track.1 {
|
||||||
|
match mode {
|
||||||
|
TrackMode::TOUCH => {
|
||||||
|
const THRESHOLD: f32 = 0.005;
|
||||||
|
const SCALE: f32 = 32.0;
|
||||||
|
let xdiff = state.rAxis[0].x - old_state.rAxis[0].x;
|
||||||
|
let ydiff = state.rAxis[0].y - old_state.rAxis[0].y;
|
||||||
|
if xdiff.abs() > THRESHOLD { self.treadmills.0 += SCALE * xdiff; }
|
||||||
|
if ydiff.abs() > THRESHOLD { self.treadmills.1 += SCALE * ydiff; }
|
||||||
|
},
|
||||||
|
TrackMode::PRESS => {
|
||||||
|
use self::na::ToHomogeneous;
|
||||||
|
let rot = na::Vector3::new(0.0, 0.0, 0.0);
|
||||||
|
if state.rAxis[0].x > 0.5 {
|
||||||
|
self.camera = na::Similarity3::new(na::Vector3::new(-0.5, 0.0, 0.0),
|
||||||
|
rot, 1.0).to_homogeneous() * self.camera;
|
||||||
|
} if state.rAxis[0].x < -0.5 {
|
||||||
|
self.camera = na::Similarity3::new(na::Vector3::new( 0.5, 0.0, 0.0),
|
||||||
|
rot, 1.0).to_homogeneous() * self.camera;
|
||||||
|
} if state.rAxis[0].y > 0.5 {
|
||||||
|
self.camera = na::Similarity3::new(na::Vector3::new( 0.0, -0.5, 0.0),
|
||||||
|
rot, 1.0).to_homogeneous() * self.camera;
|
||||||
|
} if state.rAxis[0].y < -0.5 {
|
||||||
|
self.camera = na::Similarity3::new(na::Vector3::new( 0.0, 0.5, 0.0),
|
||||||
|
rot, 1.0).to_homogeneous() * self.camera;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if state.unPacketNum == old_state.unPacketNum {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*track = (mode, Some(state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
encoder.update_constant_buffer(&self.locals, &Locals { camera: *(self.camera).as_ref(),
|
||||||
|
millis: millis,
|
||||||
|
anim: ANIMDATA[0],
|
||||||
|
treadmill_x: self.treadmills.0,
|
||||||
|
treadmill_y: self.treadmills.1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self,
|
fn render(&self,
|
||||||
@@ -158,6 +242,7 @@ fn get_data_model() -> model::World {
|
|||||||
|
|
||||||
const VERTEX_SHADER_SRC: &'static [u8] = br#"
|
const VERTEX_SHADER_SRC: &'static [u8] = br#"
|
||||||
#version 150
|
#version 150
|
||||||
|
#define PI 3.1415926538
|
||||||
|
|
||||||
in vec3 a_pos;
|
in vec3 a_pos;
|
||||||
in vec2 a_uv;
|
in vec2 a_uv;
|
||||||
@@ -168,20 +253,25 @@ const VERTEX_SHADER_SRC: &'static [u8] = br#"
|
|||||||
mat4 u_matrix;
|
mat4 u_matrix;
|
||||||
};
|
};
|
||||||
uniform b_locals {
|
uniform b_locals {
|
||||||
|
mat4 camera;
|
||||||
uint millis;
|
uint millis;
|
||||||
uint animdata;
|
uint animdata;
|
||||||
|
float treadmill_x;
|
||||||
|
float treadmill_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
v_uv = a_uv;
|
v_uv = a_uv;
|
||||||
v_tileidx = a_tileidx;
|
v_tileidx = a_tileidx;
|
||||||
float TWO_PI_CIRC = 44.0 / 7.0 / 256.0;
|
float TWO_PI_CIRC = 2 * PI / 256.0;
|
||||||
float R = 128.0;
|
float R = 128.0;
|
||||||
float R2 = 16.0;
|
float R2 = 16.0;
|
||||||
gl_Position = u_matrix * vec4(R * -1.0 * sin(TWO_PI_CIRC * a_pos.x), // "z"
|
|
||||||
(R + R2 * cos(TWO_PI_CIRC * a_pos.x)) * cos(TWO_PI_CIRC * a_pos.z), // "x"
|
gl_Position = u_matrix * camera * vec4(R * -1.0 * sin(TWO_PI_CIRC * (a_pos.x + treadmill_x)),
|
||||||
(R + R2 * cos(TWO_PI_CIRC * a_pos.x)) * sin(TWO_PI_CIRC * a_pos.z), // "y"
|
(R + R2 * cos(TWO_PI_CIRC * (a_pos.x + treadmill_x))) * cos(TWO_PI_CIRC * (a_pos.z + treadmill_y)),
|
||||||
|
(R + R2 * cos(TWO_PI_CIRC * (a_pos.x + treadmill_x))) * sin(TWO_PI_CIRC * (a_pos.z + treadmill_y)),
|
||||||
1.0);
|
1.0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
float which = (1.0 + sin(float(millis) / 5000.)) / 2.0;
|
float which = (1.0 + sin(float(millis) / 5000.)) / 2.0;
|
||||||
gl_Position = u_matrix * vec4(a_pos.x,
|
gl_Position = u_matrix * vec4(a_pos.x,
|
||||||
@@ -201,9 +291,12 @@ const FRAGMENT_SHADER_SRC: &'static [u8] = br#"
|
|||||||
out vec4 pixcolor;
|
out vec4 pixcolor;
|
||||||
uniform sampler2D t_atlas;
|
uniform sampler2D t_atlas;
|
||||||
uniform b_locals {
|
uniform b_locals {
|
||||||
|
mat4 camera;
|
||||||
uint millis;
|
uint millis;
|
||||||
//uvec4 animdata;
|
//uvec4 animdata;
|
||||||
uint animdata;
|
uint animdata;
|
||||||
|
float treadmill_x;
|
||||||
|
float treadmill_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ pub type ColorFormat = gfx::format::Srgba8;
|
|||||||
pub type DepthFormat = gfx::format::DepthStencil;
|
pub type DepthFormat = gfx::format::DepthStencil;
|
||||||
|
|
||||||
const NEAR: f32 = 0.01;
|
const NEAR: f32 = 0.01;
|
||||||
const FAR: f32 = 1000000.0;
|
const FAR: f32 = 1000.0;
|
||||||
|
|
||||||
gfx_constant_struct! {
|
gfx_constant_struct! {
|
||||||
Trans {
|
Trans {
|
||||||
@@ -79,7 +79,11 @@ impl ViewRoot<gfx_device_gl::Device, ColorFormat, DepthFormat> {
|
|||||||
let proj_mat = vr.projection_matrix(eye, NEAR, FAR);
|
let proj_mat = vr.projection_matrix(eye, NEAR, FAR);
|
||||||
let eye_mat = vr.head_to_eye_transform(eye);
|
let eye_mat = vr.head_to_eye_transform(eye);
|
||||||
|
|
||||||
let trans = Trans { matrix: *(proj_mat * eye_mat * hmd_mat).as_ref() };
|
use self::na::ToHomogeneous;
|
||||||
|
let view_mat = na::Similarity3::new(na::Vector3::new(0.0, 128.0 - 16.0, 0.0),
|
||||||
|
na::Vector3::new(0.0, 0.0, 0.0), 1.0).to_homogeneous();
|
||||||
|
|
||||||
|
let trans = Trans { matrix: *(proj_mat * eye_mat * hmd_mat * view_mat).as_ref() };
|
||||||
window.encoder.update_constant_buffer(&self.trans, &trans);
|
window.encoder.update_constant_buffer(&self.trans, &trans);
|
||||||
|
|
||||||
scene.render(&mut window.factory,
|
scene.render(&mut window.factory,
|
||||||
|
|||||||
Reference in New Issue
Block a user