mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added rendering to character selection menu
Former-commit-id: 82992904639ec2f468c70f43f3f8fe721a98de51
This commit is contained in:
parent
fc0f2f0801
commit
d8f6025b68
@ -1,4 +1,5 @@
|
|||||||
mod ui;
|
mod ui;
|
||||||
|
mod scene;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
session::SessionState,
|
session::SessionState,
|
||||||
@ -9,6 +10,7 @@ use client::{self, Client};
|
|||||||
use common::{clock::Clock, msg::ClientMsg};
|
use common::{clock::Clock, msg::ClientMsg};
|
||||||
use std::{cell::RefCell, rc::Rc, time::Duration};
|
use std::{cell::RefCell, rc::Rc, time::Duration};
|
||||||
use ui::CharSelectionUi;
|
use ui::CharSelectionUi;
|
||||||
|
use scene::Scene;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
const FPS: u64 = 60;
|
const FPS: u64 = 60;
|
||||||
@ -16,6 +18,7 @@ const FPS: u64 = 60;
|
|||||||
pub struct CharSelectionState {
|
pub struct CharSelectionState {
|
||||||
char_selection_ui: CharSelectionUi,
|
char_selection_ui: CharSelectionUi,
|
||||||
client: Rc<RefCell<Client>>,
|
client: Rc<RefCell<Client>>,
|
||||||
|
scene: Scene,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CharSelectionState {
|
impl CharSelectionState {
|
||||||
@ -24,6 +27,7 @@ impl CharSelectionState {
|
|||||||
Self {
|
Self {
|
||||||
char_selection_ui: CharSelectionUi::new(window),
|
char_selection_ui: CharSelectionUi::new(window),
|
||||||
client,
|
client,
|
||||||
|
scene: Scene::new(window.renderer_mut()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,6 +86,12 @@ impl PlayState for CharSelectionState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Maintain the scene
|
||||||
|
self.scene.maintain(global_state.window.renderer_mut(), &self.client.borrow());
|
||||||
|
|
||||||
|
// Render the scene
|
||||||
|
self.scene.render(global_state.window.renderer_mut(), &self.client.borrow());
|
||||||
|
|
||||||
// Draw the UI to the screen
|
// Draw the UI to the screen
|
||||||
self.char_selection_ui
|
self.char_selection_ui
|
||||||
.render(global_state.window.renderer_mut());
|
.render(global_state.window.renderer_mut());
|
||||||
|
150
voxygen/src/menu/char_selection/scene.rs
Normal file
150
voxygen/src/menu/char_selection/scene.rs
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
use vek::*;
|
||||||
|
use client::Client;
|
||||||
|
use common::{
|
||||||
|
comp::Character,
|
||||||
|
figure::Segment,
|
||||||
|
};
|
||||||
|
use crate::{
|
||||||
|
render::{
|
||||||
|
Renderer,
|
||||||
|
Consts,
|
||||||
|
Globals,
|
||||||
|
Model,
|
||||||
|
SkyboxLocals,
|
||||||
|
SkyboxPipeline,
|
||||||
|
create_skybox_mesh,
|
||||||
|
PostProcessLocals,
|
||||||
|
PostProcessPipeline,
|
||||||
|
create_pp_mesh,
|
||||||
|
FigurePipeline,
|
||||||
|
},
|
||||||
|
scene::{
|
||||||
|
camera::Camera,
|
||||||
|
figure::{FigureModelCache, FigureState},
|
||||||
|
},
|
||||||
|
anim::{
|
||||||
|
Skeleton,
|
||||||
|
Animation,
|
||||||
|
character::{
|
||||||
|
CharacterSkeleton,
|
||||||
|
IdleAnimation,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Skybox {
|
||||||
|
model: Model<SkyboxPipeline>,
|
||||||
|
locals: Consts<SkyboxLocals>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PostProcess {
|
||||||
|
model: Model<PostProcessPipeline>,
|
||||||
|
locals: Consts<PostProcessLocals>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Scene {
|
||||||
|
globals: Consts<Globals>,
|
||||||
|
camera: Camera,
|
||||||
|
|
||||||
|
skybox: Skybox,
|
||||||
|
postprocess: PostProcess,
|
||||||
|
backdrop_model: Model<FigurePipeline>,
|
||||||
|
backdrop_state: FigureState<CharacterSkeleton>,
|
||||||
|
|
||||||
|
figure_model_cache: FigureModelCache,
|
||||||
|
figure_state: FigureState<CharacterSkeleton>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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(),
|
||||||
|
camera: Camera::new(resolution.x / resolution.y),
|
||||||
|
|
||||||
|
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.create_model(&FigureModelCache::load_mesh("knight.vox", Vec3::zero())).unwrap(),
|
||||||
|
backdrop_state: FigureState::new(renderer, CharacterSkeleton::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client) {
|
||||||
|
self.camera.set_focus_pos(Vec3::unit_z() * 1.75);
|
||||||
|
self.camera.update(client.state().get_time());
|
||||||
|
self.camera.set_distance(4.0);
|
||||||
|
self.camera.set_orientation(Vec3::new(
|
||||||
|
client.state().get_time() as f32 * 0.2,
|
||||||
|
0.3,
|
||||||
|
0.0,
|
||||||
|
));
|
||||||
|
|
||||||
|
let (view_mat, proj_mat, cam_pos) = self.camera.compute_dependents(client);
|
||||||
|
|
||||||
|
renderer.update_consts(
|
||||||
|
&mut self.globals,
|
||||||
|
&[Globals::new(
|
||||||
|
view_mat,
|
||||||
|
proj_mat,
|
||||||
|
cam_pos,
|
||||||
|
self.camera.get_focus_pos(),
|
||||||
|
100.0,
|
||||||
|
client.state().get_time_of_day(),
|
||||||
|
client.state().get_time(),
|
||||||
|
renderer.get_resolution(),
|
||||||
|
)],
|
||||||
|
);
|
||||||
|
|
||||||
|
self.figure_model_cache.clean(client.get_tick());
|
||||||
|
|
||||||
|
let tgt_skeleton = IdleAnimation::update_skeleton(
|
||||||
|
self.figure_state.skeleton_mut(),
|
||||||
|
client.state().get_time(),
|
||||||
|
client.state().get_time(),
|
||||||
|
);
|
||||||
|
self.figure_state.skeleton_mut().interpolate(&tgt_skeleton);
|
||||||
|
|
||||||
|
self.figure_state.update(renderer, Vec3::zero(), -Vec3::unit_y());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render(&mut self, renderer: &mut Renderer, client: &Client) {
|
||||||
|
renderer.render_skybox(&self.skybox.model, &self.globals, &self.skybox.locals);
|
||||||
|
|
||||||
|
let model = self.figure_model_cache.get_or_create_model(
|
||||||
|
renderer,
|
||||||
|
Character::random(),
|
||||||
|
client.get_tick(),
|
||||||
|
);
|
||||||
|
renderer.render_figure(
|
||||||
|
model,
|
||||||
|
&self.globals,
|
||||||
|
self.figure_state.locals(),
|
||||||
|
self.figure_state.bone_consts(),
|
||||||
|
);
|
||||||
|
|
||||||
|
renderer.render_figure(
|
||||||
|
&self.backdrop_model,
|
||||||
|
&self.globals,
|
||||||
|
self.backdrop_state.locals(),
|
||||||
|
self.backdrop_state.bone_consts(),
|
||||||
|
);
|
||||||
|
|
||||||
|
renderer.render_post_process(
|
||||||
|
&self.postprocess.model,
|
||||||
|
&self.globals,
|
||||||
|
&self.postprocess.locals,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -155,7 +155,6 @@ widget_ids! {
|
|||||||
warpaint_slider_indicator,
|
warpaint_slider_indicator,
|
||||||
warpaint_slider_range,
|
warpaint_slider_range,
|
||||||
warpaint_slider_text,
|
warpaint_slider_text,
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,13 +315,13 @@ impl CharSelectionUi {
|
|||||||
|
|
||||||
// Background Image
|
// Background Image
|
||||||
if !self.character_creation {
|
if !self.character_creation {
|
||||||
Image::new(self.imgs.bg_selection)
|
//Image::new(self.imgs.bg_selection)
|
||||||
.middle_of(ui_widgets.window)
|
// .middle_of(ui_widgets.window)
|
||||||
.set(self.ids.bg_selection, ui_widgets);
|
// .set(self.ids.bg_selection, ui_widgets);
|
||||||
|
|
||||||
// Logout_Button
|
// Logout_Button
|
||||||
if Button::image(self.imgs.button)
|
if Button::image(self.imgs.button)
|
||||||
.bottom_left_with_margins_on(self.ids.bg_selection, 10.0, 10.0)
|
.bottom_left_with_margins_on(ui_widgets.window, 10.0, 10.0)
|
||||||
.w_h(150.0, 40.0)
|
.w_h(150.0, 40.0)
|
||||||
.hover_image(self.imgs.button_hover)
|
.hover_image(self.imgs.button_hover)
|
||||||
.press_image(self.imgs.button_press)
|
.press_image(self.imgs.button_press)
|
||||||
@ -338,7 +337,7 @@ impl CharSelectionUi {
|
|||||||
|
|
||||||
// Create Character Button
|
// Create Character Button
|
||||||
if Button::image(self.imgs.button)
|
if Button::image(self.imgs.button)
|
||||||
.mid_bottom_with_margin_on(self.ids.bg_selection, 10.0)
|
.mid_bottom_with_margin_on(ui_widgets.window, 10.0)
|
||||||
.w_h(270.0, 50.0)
|
.w_h(270.0, 50.0)
|
||||||
.hover_image(self.imgs.button_hover)
|
.hover_image(self.imgs.button_hover)
|
||||||
.press_image(self.imgs.button_press)
|
.press_image(self.imgs.button_press)
|
||||||
@ -354,7 +353,7 @@ impl CharSelectionUi {
|
|||||||
}
|
}
|
||||||
// Test Characters
|
// Test Characters
|
||||||
if Button::image(self.imgs.test_char_l_button)
|
if Button::image(self.imgs.test_char_l_button)
|
||||||
.bottom_left_with_margins_on(self.ids.bg_selection, 395.0, 716.0)
|
.bottom_left_with_margins_on(ui_widgets.window, 395.0, 716.0)
|
||||||
.w_h(95.0, 130.0)
|
.w_h(95.0, 130.0)
|
||||||
.hover_image(self.imgs.test_char_l_button)
|
.hover_image(self.imgs.test_char_l_button)
|
||||||
.press_image(self.imgs.test_char_l_button)
|
.press_image(self.imgs.test_char_l_button)
|
||||||
@ -376,7 +375,7 @@ impl CharSelectionUi {
|
|||||||
.set(self.ids.version, ui_widgets);
|
.set(self.ids.version, ui_widgets);
|
||||||
// Click Character to Login <-- Temporary!
|
// Click Character to Login <-- Temporary!
|
||||||
Image::new(self.imgs.window_frame_2)
|
Image::new(self.imgs.window_frame_2)
|
||||||
.mid_top_with_margin_on(self.ids.bg_selection, 60.0)
|
.mid_top_with_margin_on(ui_widgets.window, 60.0)
|
||||||
.w_h(700.0, 70.0)
|
.w_h(700.0, 70.0)
|
||||||
.set(self.ids.help_text_bg, ui_widgets);
|
.set(self.ids.help_text_bg, ui_widgets);
|
||||||
Text::new("Click character to select it")
|
Text::new("Click character to select it")
|
||||||
@ -446,12 +445,13 @@ impl CharSelectionUi {
|
|||||||
// Character_Creation //////////////
|
// Character_Creation //////////////
|
||||||
else {
|
else {
|
||||||
// Background
|
// Background
|
||||||
Image::new(self.imgs.bg_creation)
|
//Image::new(self.imgs.bg_creation)
|
||||||
.middle_of(ui_widgets.window)
|
// .middle_of(ui_widgets.window)
|
||||||
.set(self.ids.bg_creation, ui_widgets);
|
// .set(self.ids.bg_creation, ui_widgets);
|
||||||
|
|
||||||
// Back Button
|
// Back Button
|
||||||
if Button::image(self.imgs.button)
|
if Button::image(self.imgs.button)
|
||||||
.bottom_left_with_margins_on(self.ids.bg_creation, 10.0, 10.0)
|
.bottom_left_with_margins_on(ui_widgets.window, 10.0, 10.0)
|
||||||
.w_h(150.0, 40.0)
|
.w_h(150.0, 40.0)
|
||||||
.hover_image(self.imgs.button_hover)
|
.hover_image(self.imgs.button_hover)
|
||||||
.press_image(self.imgs.button_press)
|
.press_image(self.imgs.button_press)
|
||||||
@ -466,7 +466,7 @@ impl CharSelectionUi {
|
|||||||
}
|
}
|
||||||
// Create Button
|
// Create Button
|
||||||
if Button::image(self.imgs.button)
|
if Button::image(self.imgs.button)
|
||||||
.bottom_right_with_margins_on(self.ids.bg_creation, 10.0, 10.0)
|
.bottom_right_with_margins_on(ui_widgets.window, 10.0, 10.0)
|
||||||
.w_h(150.0, 40.0)
|
.w_h(150.0, 40.0)
|
||||||
.hover_image(self.imgs.button_hover)
|
.hover_image(self.imgs.button_hover)
|
||||||
.press_image(self.imgs.button_press)
|
.press_image(self.imgs.button_press)
|
||||||
@ -482,7 +482,7 @@ impl CharSelectionUi {
|
|||||||
}
|
}
|
||||||
// Character Name Input
|
// Character Name Input
|
||||||
Rectangle::fill_with([320.0, 50.0], color::rgba(0.0, 0.0, 0.0, 0.99))
|
Rectangle::fill_with([320.0, 50.0], color::rgba(0.0, 0.0, 0.0, 0.99))
|
||||||
.mid_bottom_with_margin_on(self.ids.bg_creation, 20.0)
|
.mid_bottom_with_margin_on(ui_widgets.window, 20.0)
|
||||||
.set(self.ids.name_input_bg, ui_widgets);
|
.set(self.ids.name_input_bg, ui_widgets);
|
||||||
Button::image(self.imgs.name_input)
|
Button::image(self.imgs.name_input)
|
||||||
.w_h(337.0, 67.0)
|
.w_h(337.0, 67.0)
|
||||||
@ -514,7 +514,7 @@ impl CharSelectionUi {
|
|||||||
self.imgs.creation_window
|
self.imgs.creation_window
|
||||||
})
|
})
|
||||||
.w_h(628.0, 814.0)
|
.w_h(628.0, 814.0)
|
||||||
.top_left_with_margins_on(self.ids.bg_creation, 60.0, 30.0)
|
.top_left_with_margins_on(ui_widgets.window, 60.0, 30.0)
|
||||||
.set(self.ids.creation_window, ui_widgets);
|
.set(self.ids.creation_window, ui_widgets);
|
||||||
|
|
||||||
// Arrows
|
// Arrows
|
||||||
|
@ -95,12 +95,27 @@ impl Camera {
|
|||||||
self.ori.z = (self.ori.z + delta.z) % (2.0 * PI);
|
self.ori.z = (self.ori.z + delta.z) % (2.0 * PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the orientation of the camera about its focus
|
||||||
|
pub fn set_orientation(&mut self, orientation: Vec3<f32>) {
|
||||||
|
// Wrap camera yaw
|
||||||
|
self.ori.x = orientation.x % (2.0 * PI);
|
||||||
|
// Clamp camera pitch to the vertical limits
|
||||||
|
self.ori.y = orientation.y.min(PI / 2.0).max(-PI / 2.0);
|
||||||
|
// Wrap camera roll
|
||||||
|
self.ori.z = orientation.z % (2.0 * PI);
|
||||||
|
}
|
||||||
|
|
||||||
/// Zoom the camera by the given delta, limiting the input accordingly.
|
/// Zoom the camera by the given delta, limiting the input accordingly.
|
||||||
pub fn zoom_by(&mut self, delta: f32) {
|
pub fn zoom_by(&mut self, delta: f32) {
|
||||||
// Clamp camera dist to the 0 <= x <= infinity range
|
// Clamp camera dist to the 0 <= x <= infinity range
|
||||||
self.tgt_dist = (self.tgt_dist + delta).max(0.0);
|
self.tgt_dist = (self.tgt_dist + delta).max(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the distance of the camera from the target (i.e: zoom)
|
||||||
|
pub fn set_distance(&mut self, dist: f32) {
|
||||||
|
self.tgt_dist = dist;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, time: f64) {
|
pub fn update(&mut self, time: f64) {
|
||||||
// This is horribly frame time dependent, but so is most of the game
|
// This is horribly frame time dependent, but so is most of the game
|
||||||
let delta = self.last_time.replace(time).map_or(0.0, |t| time - t);
|
let delta = self.last_time.replace(time).map_or(0.0, |t| time - t);
|
||||||
|
@ -24,31 +24,29 @@ use specs::{Component, Entity as EcsEntity, Join, VecStorage};
|
|||||||
use std::{collections::HashMap, f32};
|
use std::{collections::HashMap, f32};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
pub struct FigureCache {
|
pub struct FigureModelCache {
|
||||||
models: HashMap<Character, (Model<FigurePipeline>, u64)>,
|
models: HashMap<Character, (Model<FigurePipeline>, u64)>,
|
||||||
states: HashMap<EcsEntity, FigureState<CharacterSkeleton>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FigureCache {
|
impl FigureModelCache {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
models: HashMap::new(),
|
models: HashMap::new(),
|
||||||
states: HashMap::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_or_create_model<'a>(
|
pub fn get_or_create_model(
|
||||||
models: &'a mut HashMap<Character, (Model<FigurePipeline>, u64)>,
|
&mut self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
tick: u64,
|
|
||||||
character: Character,
|
character: Character,
|
||||||
) -> &'a (Model<FigurePipeline>, u64) {
|
tick: u64,
|
||||||
match models.get_mut(&character) {
|
) -> &Model<FigurePipeline> {
|
||||||
|
match self.models.get_mut(&character) {
|
||||||
Some((model, last_used)) => {
|
Some((model, last_used)) => {
|
||||||
*last_used = tick;
|
*last_used = tick;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
models.insert(
|
self.models.insert(
|
||||||
character,
|
character,
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
@ -90,7 +88,7 @@ impl FigureCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&models[&character]
|
&self.models[&character].0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clean(&mut self, tick: u64) {
|
pub fn clean(&mut self, tick: u64) {
|
||||||
@ -99,7 +97,8 @@ impl FigureCache {
|
|||||||
.retain(|_, (_, last_used)| *last_used + 60 > tick);
|
.retain(|_, (_, last_used)| *last_used + 60 > tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_mesh(filename: &str, position: Vec3<f32>) -> Mesh<FigurePipeline> {
|
// TODO: Don't make this public
|
||||||
|
pub fn load_mesh(filename: &str, position: Vec3<f32>) -> Mesh<FigurePipeline> {
|
||||||
let fullpath: String = ["/voxygen/voxel/", filename].concat();
|
let fullpath: String = ["/voxygen/voxel/", filename].concat();
|
||||||
Segment::from(assets::load_expect::<DotVoxData>(fullpath.as_str()).as_ref())
|
Segment::from(assets::load_expect::<DotVoxData>(fullpath.as_str()).as_ref())
|
||||||
.generate_mesh(position)
|
.generate_mesh(position)
|
||||||
@ -187,10 +186,28 @@ impl FigureCache {
|
|||||||
Vec3::new(0.0, 0.0, -4.0),
|
Vec3::new(0.0, 0.0, -4.0),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn maintain(&mut self, renderer: &mut Renderer, client: &mut Client) {
|
pub struct FigureMgr {
|
||||||
|
model_cache: FigureModelCache,
|
||||||
|
states: HashMap<EcsEntity, FigureState<CharacterSkeleton>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FigureMgr {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
model_cache: FigureModelCache::new(),
|
||||||
|
states: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clean(&mut self, tick: u64) {
|
||||||
|
self.model_cache.clean(tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client) {
|
||||||
let time = client.state().get_time();
|
let time = client.state().get_time();
|
||||||
let ecs = client.state_mut().ecs_mut();
|
let ecs = client.state().ecs();
|
||||||
for (entity, pos, vel, dir, character, animation_history) in (
|
for (entity, pos, vel, dir, character, animation_history) in (
|
||||||
&ecs.entities(),
|
&ecs.entities(),
|
||||||
&ecs.read_storage::<comp::phys::Pos>(),
|
&ecs.read_storage::<comp::phys::Pos>(),
|
||||||
@ -208,17 +225,17 @@ impl FigureCache {
|
|||||||
|
|
||||||
let target_skeleton = match animation_history.current {
|
let target_skeleton = match animation_history.current {
|
||||||
comp::character::Animation::Idle => IdleAnimation::update_skeleton(
|
comp::character::Animation::Idle => IdleAnimation::update_skeleton(
|
||||||
&mut state.skeleton,
|
state.skeleton_mut(),
|
||||||
time,
|
time,
|
||||||
animation_history.time,
|
animation_history.time,
|
||||||
),
|
),
|
||||||
comp::character::Animation::Run => RunAnimation::update_skeleton(
|
comp::character::Animation::Run => RunAnimation::update_skeleton(
|
||||||
&mut state.skeleton,
|
state.skeleton_mut(),
|
||||||
(vel.0.magnitude(), time),
|
(vel.0.magnitude(), time),
|
||||||
animation_history.time,
|
animation_history.time,
|
||||||
),
|
),
|
||||||
comp::character::Animation::Jump => JumpAnimation::update_skeleton(
|
comp::character::Animation::Jump => JumpAnimation::update_skeleton(
|
||||||
&mut state.skeleton,
|
state.skeleton_mut(),
|
||||||
time,
|
time,
|
||||||
animation_history.time,
|
animation_history.time,
|
||||||
),
|
),
|
||||||
@ -229,8 +246,7 @@ impl FigureCache {
|
|||||||
state.update(renderer, pos.0, dir.0);
|
state.update(renderer, pos.0, dir.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.states
|
self.states.retain(|entity, _| ecs.entities().is_alive(*entity));
|
||||||
.retain(|entity, _| ecs.entities().is_alive(*entity));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(
|
pub fn render(
|
||||||
@ -241,13 +257,12 @@ impl FigureCache {
|
|||||||
) {
|
) {
|
||||||
let tick = client.get_tick();
|
let tick = client.get_tick();
|
||||||
let ecs = client.state().ecs();
|
let ecs = client.state().ecs();
|
||||||
let models = &mut self.models;
|
|
||||||
|
|
||||||
for (entity, &character) in (&ecs.entities(), &ecs.read_storage::<comp::Character>()).join()
|
for (entity, &character) in (&ecs.entities(), &ecs.read_storage::<comp::Character>()).join()
|
||||||
{
|
{
|
||||||
if let Some(state) = self.states.get(&entity) {
|
if let Some(state) = self.states.get(&entity) {
|
||||||
let model = Self::get_or_create_model(models, renderer, tick, character);
|
let model = self.model_cache.get_or_create_model(renderer, character, tick);
|
||||||
renderer.render_figure(&model.0, globals, &state.locals, &state.bone_consts);
|
renderer.render_figure(model, globals, &state.locals(), state.bone_consts());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,7 +285,7 @@ impl<S: Skeleton> FigureState<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, renderer: &mut Renderer, pos: Vec3<f32>, dir: Vec3<f32>) {
|
pub fn update(&mut self, renderer: &mut Renderer, pos: Vec3<f32>, dir: Vec3<f32>) {
|
||||||
let mat = Mat4::<f32>::identity()
|
let mat = Mat4::<f32>::identity()
|
||||||
* Mat4::translation_3d(pos)
|
* Mat4::translation_3d(pos)
|
||||||
* Mat4::rotation_z(-dir.x.atan2(dir.y)); // + f32::consts::PI / 2.0);
|
* Mat4::rotation_z(-dir.x.atan2(dir.y)); // + f32::consts::PI / 2.0);
|
||||||
@ -282,4 +297,16 @@ impl<S: Skeleton> FigureState<S> {
|
|||||||
.update_consts(&mut self.bone_consts, &self.skeleton.compute_matrices())
|
.update_consts(&mut self.bone_consts, &self.skeleton.compute_matrices())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn locals(&self) -> &Consts<FigureLocals> {
|
||||||
|
&self.locals
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bone_consts(&self) -> &Consts<FigureBoneData> {
|
||||||
|
&self.bone_consts
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn skeleton_mut(&mut self) -> &mut S {
|
||||||
|
&mut self.skeleton
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,10 @@ pub mod camera;
|
|||||||
pub mod figure;
|
pub mod figure;
|
||||||
pub mod terrain;
|
pub mod terrain;
|
||||||
|
|
||||||
use self::{camera::Camera, figure::FigureCache, terrain::Terrain};
|
use dot_vox;
|
||||||
|
use vek::*;
|
||||||
|
use common::{comp, figure::Segment};
|
||||||
|
use client::Client;
|
||||||
use crate::{
|
use crate::{
|
||||||
anim::{
|
anim::{
|
||||||
character::{CharacterSkeleton, RunAnimation},
|
character::{CharacterSkeleton, RunAnimation},
|
||||||
@ -15,10 +18,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
window::Event,
|
window::Event,
|
||||||
};
|
};
|
||||||
use client::Client;
|
use self::{camera::Camera, figure::FigureMgr, terrain::Terrain};
|
||||||
use common::{comp, figure::Segment};
|
|
||||||
use dot_vox;
|
|
||||||
use vek::*;
|
|
||||||
|
|
||||||
// TODO: Don't hard-code this
|
// TODO: Don't hard-code this
|
||||||
const CURSOR_PAN_SCALE: f32 = 0.005;
|
const CURSOR_PAN_SCALE: f32 = 0.005;
|
||||||
@ -41,7 +41,7 @@ pub struct Scene {
|
|||||||
postprocess: PostProcess,
|
postprocess: PostProcess,
|
||||||
terrain: Terrain,
|
terrain: Terrain,
|
||||||
|
|
||||||
figure_cache: FigureCache,
|
figure_mgr: FigureMgr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scene {
|
impl Scene {
|
||||||
@ -64,7 +64,7 @@ impl Scene {
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
},
|
},
|
||||||
terrain: Terrain::new(),
|
terrain: Terrain::new(),
|
||||||
figure_cache: FigureCache::new(),
|
figure_mgr: FigureMgr::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ impl Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Maintain data such as GPU constant buffers, models, etc. To be called once per tick.
|
/// Maintain data such as GPU constant buffers, models, etc. To be called once per tick.
|
||||||
pub fn maintain(&mut self, renderer: &mut Renderer, client: &mut Client) {
|
pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client) {
|
||||||
// Get player position
|
// Get player position
|
||||||
let player_pos = client
|
let player_pos = client
|
||||||
.state()
|
.state()
|
||||||
@ -144,10 +144,10 @@ impl Scene {
|
|||||||
self.terrain.maintain(renderer, client);
|
self.terrain.maintain(renderer, client);
|
||||||
|
|
||||||
// Maintain the figures
|
// Maintain the figures
|
||||||
self.figure_cache.maintain(renderer, client);
|
self.figure_mgr.maintain(renderer, client);
|
||||||
|
|
||||||
// Remove unused figures
|
// Remove unused figures
|
||||||
self.figure_cache.clean(client.get_tick());
|
self.figure_mgr.clean(client.get_tick());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render the scene using the provided `Renderer`
|
/// Render the scene using the provided `Renderer`
|
||||||
@ -157,7 +157,7 @@ impl Scene {
|
|||||||
|
|
||||||
// Render terrain and figures
|
// Render terrain and figures
|
||||||
self.terrain.render(renderer, &self.globals);
|
self.terrain.render(renderer, &self.globals);
|
||||||
self.figure_cache.render(renderer, client, &self.globals);
|
self.figure_mgr.render(renderer, client, &self.globals);
|
||||||
|
|
||||||
renderer.render_post_process(
|
renderer.render_post_process(
|
||||||
&self.postprocess.model,
|
&self.postprocess.model,
|
||||||
|
Loading…
Reference in New Issue
Block a user