veloren/voxygen/src/menu/char_selection/scene.rs

230 lines
6.9 KiB
Rust
Raw Normal View History

use crate::{
anim::{
2020-01-26 00:22:48 +00:00
character::{CharacterSkeleton, IdleAnimation, SkeletonAttr},
fixture::FixtureSkeleton,
2020-01-26 00:22:48 +00:00
Animation, Skeleton,
},
render::{
2019-07-21 15:04:36 +00:00
create_pp_mesh, create_skybox_mesh, Consts, FigurePipeline, Globals, Light, Model,
2019-09-25 12:00:00 +00:00
PostProcessLocals, PostProcessPipeline, Renderer, Shadow, SkyboxLocals, SkyboxPipeline,
},
scene::{
2019-07-22 19:11:00 +00:00
camera::{Camera, CameraMode},
2019-08-19 02:57:41 +00:00
figure::{load_mesh, FigureModelCache, FigureState},
},
2019-09-18 16:46:12 +00:00
window::{Event, PressState},
};
use client::Client;
use common::{
comp::{humanoid, Body, Equipment},
state::DeltaTime,
2019-08-16 14:58:14 +00:00
terrain::BlockKind,
};
use log::error;
2019-11-30 06:41:20 +00:00
use specs::WorldExt;
use vek::*;
struct Skybox {
model: Model<SkyboxPipeline>,
locals: Consts<SkyboxLocals>,
}
struct PostProcess {
model: Model<PostProcessPipeline>,
locals: Consts<PostProcessLocals>,
}
pub struct Scene {
globals: Consts<Globals>,
2019-07-21 15:04:36 +00:00
lights: Consts<Light>,
2019-09-25 12:00:00 +00:00
shadows: Consts<Shadow>,
camera: Camera,
skybox: Skybox,
postprocess: PostProcess,
backdrop_model: Model<FigurePipeline>,
backdrop_state: FigureState<FixtureSkeleton>,
figure_model_cache: FigureModelCache,
figure_state: FigureState<CharacterSkeleton>,
2019-09-18 16:46:12 +00:00
turning: bool,
char_ori: f32,
}
impl Scene {
pub fn new(renderer: &mut Renderer) -> Self {
let resolution = renderer.get_resolution().map(|e| e as f32);
Self {
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
2019-07-21 15:04:36 +00:00
lights: renderer.create_consts(&[Light::default(); 32]).unwrap(),
2019-09-25 12:00:00 +00:00
shadows: renderer.create_consts(&[Shadow::default(); 32]).unwrap(),
2019-07-22 19:11:00 +00:00
camera: Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson),
skybox: Skybox {
model: renderer.create_model(&create_skybox_mesh()).unwrap(),
locals: renderer.create_consts(&[SkyboxLocals::default()]).unwrap(),
},
postprocess: PostProcess {
model: renderer.create_model(&create_pp_mesh()).unwrap(),
locals: renderer
.create_consts(&[PostProcessLocals::default()])
.unwrap(),
},
figure_model_cache: FigureModelCache::new(),
figure_state: FigureState::new(renderer, CharacterSkeleton::new()),
backdrop_model: renderer
2019-08-19 02:57:41 +00:00
.create_model(&load_mesh(
2019-08-06 06:31:48 +00:00
"fixture.selection_bg",
2019-06-22 14:30:53 +00:00
Vec3::new(-55.0, -49.5, -2.0),
))
.unwrap(),
backdrop_state: FigureState::new(renderer, FixtureSkeleton::new()),
2019-09-18 16:46:12 +00:00
turning: false,
char_ori: 0.0,
}
}
pub fn globals(&self) -> &Consts<Globals> { &self.globals }
/// Handle an incoming user input event (e.g.: cursor moved, key pressed,
/// window closed).
///
/// If the event is handled, return true.
pub fn handle_input_event(&mut self, event: Event) -> bool {
match event {
// When the window is resized, change the camera's aspect ratio
Event::Resize(dims) => {
self.camera.set_aspect_ratio(dims.x as f32 / dims.y as f32);
true
},
2019-09-18 16:46:12 +00:00
Event::MouseButton(_, state) => {
self.turning = state == PressState::Pressed;
true
},
2019-09-18 16:46:12 +00:00
Event::CursorMove(delta) if self.turning => {
self.char_ori += delta.x * 0.01;
true
},
// All other events are unhandled
_ => false,
}
}
pub fn maintain(
&mut self,
renderer: &mut Renderer,
client: &Client,
body: Option<humanoid::Body>,
2020-02-13 12:28:03 +00:00
gamma: f32,
) {
2019-09-18 16:46:12 +00:00
self.camera.set_focus_pos(Vec3::unit_z() * 1.5);
self.camera.update(client.state().get_time());
2019-09-18 16:46:12 +00:00
self.camera.set_distance(3.0); // 4.2
self.camera
.set_orientation(Vec3::new(client.state().get_time() as f32 * 0.0, 0.0, 0.0));
let (view_mat, proj_mat, cam_pos) = self.camera.compute_dependents(client);
2019-09-25 09:09:45 +00:00
const VD: f32 = 115.0; //View Distance
const TIME: f64 = 43200.0; // hours*3600 seconds
if let Err(err) = renderer.update_consts(&mut self.globals, &[Globals::new(
view_mat,
proj_mat,
cam_pos,
self.camera.get_focus_pos(),
VD,
TIME,
client.state().get_time(),
renderer.get_resolution(),
0,
0,
BlockKind::Air,
None,
2020-02-13 12:28:03 +00:00
gamma,
)]) {
error!("Renderer failed to update: {:?}", err);
}
self.figure_model_cache.clean(client.get_tick());
if let Some(body) = body {
let tgt_skeleton = IdleAnimation::update_skeleton(
self.figure_state.skeleton_mut(),
client.state().get_time(),
client.state().get_time(),
&mut 0.0,
&SkeletonAttr::from(&body),
);
self.figure_state.skeleton_mut().interpolate(
&tgt_skeleton,
client.state().ecs().read_resource::<DeltaTime>().0,
);
}
self.figure_state.update(
renderer,
Vec3::zero(),
2019-10-14 10:22:48 +00:00
Vec3::zero(),
2019-09-18 16:46:12 +00:00
Vec3::new(self.char_ori.sin(), -self.char_ori.cos(), 0.0),
1.0,
Rgba::broadcast(1.0),
1.0 / 60.0, // TODO: Use actual deltatime here?
1.0,
1.0,
0,
true,
);
}
pub fn render(
&mut self,
renderer: &mut Renderer,
client: &Client,
body: Option<humanoid::Body>,
equipment: &Equipment,
) {
renderer.render_skybox(&self.skybox.model, &self.globals, &self.skybox.locals);
if let Some(body) = body {
let model = &self
.figure_model_cache
.get_or_create_model(
renderer,
Body::Humanoid(body),
Some(equipment),
client.get_tick(),
CameraMode::default(),
None,
)
.0;
renderer.render_figure(
model,
&self.globals,
self.figure_state.locals(),
self.figure_state.bone_consts(),
&self.lights,
&self.shadows,
);
}
renderer.render_figure(
&self.backdrop_model,
&self.globals,
self.backdrop_state.locals(),
self.backdrop_state.bone_consts(),
2019-07-21 15:04:36 +00:00
&self.lights,
2019-09-25 12:00:00 +00:00
&self.shadows,
);
renderer.render_post_process(
&self.postprocess.model,
&self.globals,
&self.postprocess.locals,
);
}
}