mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Moved to Skeleton and Animation traits
This commit is contained in:
parent
8184bc6fc0
commit
86e70751e0
@ -1,6 +1,7 @@
|
||||
#version 330 core
|
||||
|
||||
in vec3 f_pos;
|
||||
in vec3 f_norm;
|
||||
in vec3 f_col;
|
||||
|
||||
layout (std140)
|
||||
@ -22,5 +23,13 @@ uniform u_globals {
|
||||
out vec4 tgt_color;
|
||||
|
||||
void main() {
|
||||
tgt_color = vec4(f_col, 1.0);
|
||||
vec3 world_norm = (model_mat * vec4(f_norm, 0.0)).xyz;
|
||||
|
||||
float ambient = 0.5;
|
||||
|
||||
vec3 sun_dir = normalize(vec3(1.3, 1.7, 1.1));
|
||||
|
||||
float sun_diffuse = dot(sun_dir, world_norm) * 0.5;
|
||||
|
||||
tgt_color = vec4(f_col * (ambient + sun_diffuse), 1.0);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#version 330 core
|
||||
|
||||
in vec3 v_pos;
|
||||
in vec3 v_norm;
|
||||
in vec3 v_col;
|
||||
in uint v_bone_idx;
|
||||
|
||||
@ -30,10 +31,12 @@ uniform u_bones {
|
||||
};
|
||||
|
||||
out vec3 f_pos;
|
||||
out vec3 f_norm;
|
||||
out vec3 f_col;
|
||||
|
||||
void main() {
|
||||
f_pos = v_pos;
|
||||
f_norm = v_norm;
|
||||
f_col = v_col;
|
||||
|
||||
gl_Position =
|
||||
|
@ -6,7 +6,7 @@ use crate::render::FigureBoneData;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Bone {
|
||||
parent: Option<u8>, // MUST be less than the current bone index
|
||||
parent_idx: Option<u8>, // MUST be less than the current bone index
|
||||
pub offset: Vec3<f32>,
|
||||
pub ori: Quaternion<f32>,
|
||||
}
|
||||
@ -14,50 +14,122 @@ pub struct Bone {
|
||||
impl Bone {
|
||||
pub fn default() -> Self {
|
||||
Self {
|
||||
parent: None,
|
||||
parent_idx: None,
|
||||
offset: Vec3::zero(),
|
||||
ori: Quaternion::identity(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_parent_idx(&self) -> Option<u8> { self.parent_idx }
|
||||
|
||||
pub fn set_parent_idx(&mut self, parent_idx: u8) {
|
||||
self.parent_idx = Some(parent_idx);
|
||||
}
|
||||
|
||||
pub fn compute_base_matrix(&self) -> Mat4<f32> {
|
||||
Mat4::<f32>::translation_3d(self.offset) * Mat4::from(self.ori)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Skeleton {
|
||||
bones: [Bone; 16],
|
||||
pub trait Skeleton {
|
||||
fn compute_matrices(&self) -> [FigureBoneData; 16];
|
||||
}
|
||||
|
||||
impl Skeleton {
|
||||
pub fn default() -> Self {
|
||||
pub struct CharacterSkeleton {
|
||||
head: Bone,
|
||||
chest: Bone,
|
||||
belt: Bone,
|
||||
leggings: Bone,
|
||||
l_hand: Bone,
|
||||
r_hand: Bone,
|
||||
l_foot: Bone,
|
||||
r_foot: Bone,
|
||||
back: Bone,
|
||||
}
|
||||
|
||||
impl CharacterSkeleton {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
bones: [Bone::default(); 16],
|
||||
head: Bone::default(),
|
||||
chest: Bone::default(),
|
||||
belt: Bone::default(),
|
||||
leggings: Bone::default(),
|
||||
l_hand: Bone::default(),
|
||||
r_hand: Bone::default(),
|
||||
l_foot: Bone::default(),
|
||||
r_foot: Bone::default(),
|
||||
back: Bone::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_bone(mut self, bone_idx: u8, bone: Bone) -> Self {
|
||||
self.bones[bone_idx as usize] = bone;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn bone(&self, bone_idx: u8) -> &Bone { &self.bones[bone_idx as usize] }
|
||||
pub fn bone_mut(&mut self, bone_idx: u8) -> &mut Bone { &mut self.bones[bone_idx as usize] }
|
||||
|
||||
pub fn compute_matrices(&self) -> [FigureBoneData; 16] {
|
||||
let mut bone_data = [FigureBoneData::default(); 16];
|
||||
for i in 0..16 {
|
||||
bone_data[i] = FigureBoneData::new(
|
||||
self.bones[i].compute_base_matrix()
|
||||
// *
|
||||
//if let Some(parent_idx) = self.bones[i].parent {
|
||||
// bone_data[parent_idx as usize]
|
||||
//} else {
|
||||
// Mat4::identity()
|
||||
//}
|
||||
);
|
||||
}
|
||||
bone_data
|
||||
}
|
||||
}
|
||||
|
||||
impl Skeleton for CharacterSkeleton {
|
||||
fn compute_matrices(&self) -> [FigureBoneData; 16] {
|
||||
let chest_mat = self.chest.compute_base_matrix();
|
||||
|
||||
[
|
||||
FigureBoneData::new(self.head.compute_base_matrix()),
|
||||
FigureBoneData::new(chest_mat),
|
||||
FigureBoneData::new(self.belt.compute_base_matrix()),
|
||||
FigureBoneData::new(self.leggings.compute_base_matrix()),
|
||||
FigureBoneData::new(self.l_hand.compute_base_matrix()),
|
||||
FigureBoneData::new(self.r_hand.compute_base_matrix()),
|
||||
FigureBoneData::new(self.l_foot.compute_base_matrix()),
|
||||
FigureBoneData::new(self.r_foot.compute_base_matrix()),
|
||||
FigureBoneData::new(chest_mat * self.back.compute_base_matrix()),
|
||||
FigureBoneData::default(),
|
||||
FigureBoneData::default(),
|
||||
FigureBoneData::default(),
|
||||
FigureBoneData::default(),
|
||||
FigureBoneData::default(),
|
||||
FigureBoneData::default(),
|
||||
FigureBoneData::default(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Animation {
|
||||
type Skeleton;
|
||||
type Dependency;
|
||||
|
||||
fn update_skeleton(
|
||||
skeleton: &mut Self::Skeleton,
|
||||
dependency: Self::Dependency,
|
||||
);
|
||||
}
|
||||
|
||||
pub struct RunAnimation;
|
||||
|
||||
impl Animation for RunAnimation {
|
||||
type Skeleton = CharacterSkeleton;
|
||||
type Dependency = f64;
|
||||
|
||||
fn update_skeleton(
|
||||
skeleton: &mut Self::Skeleton,
|
||||
time: f64,
|
||||
) {
|
||||
let wave = (time as f32 * 10.0).sin();
|
||||
let wave_fast = (time as f32 * 5.0).sin();
|
||||
|
||||
skeleton.head.offset = Vec3::unit_z() * 13.0;
|
||||
skeleton.head.ori = Quaternion::rotation_z(wave * 0.3);
|
||||
|
||||
skeleton.chest.offset = Vec3::unit_z() * 9.0;
|
||||
skeleton.chest.ori = Quaternion::rotation_z(wave * 0.3);
|
||||
|
||||
skeleton.belt.offset = Vec3::unit_z() * 7.0;
|
||||
skeleton.belt.ori = Quaternion::rotation_z(wave * 0.3);
|
||||
|
||||
skeleton.leggings.offset = Vec3::unit_z() * 4.0;
|
||||
skeleton.leggings.ori = Quaternion::rotation_z(wave * 0.3);
|
||||
|
||||
skeleton.l_hand.offset = Vec3::new(-8.0, wave * 4.0, 9.0);
|
||||
skeleton.r_hand.offset = Vec3::new(8.0, -wave * 4.0, 9.0);
|
||||
|
||||
skeleton.l_foot.offset = Vec3::new(-3.0, -wave * 4.0, -(wave_fast.abs() - 0.5) * 3.0);
|
||||
skeleton.r_foot.offset = Vec3::new(3.0, wave * 4.0, (wave_fast.abs() - 0.5) * 3.0);
|
||||
|
||||
skeleton.back.offset = Vec3::new(-8.0, 5.0, 16.0);
|
||||
skeleton.back.ori = Quaternion::rotation_y(2.5);
|
||||
}
|
||||
}
|
||||
|
@ -29,14 +29,15 @@ fn create_quad(
|
||||
origin: Vec3<f32>,
|
||||
unit_x: Vec3<f32>,
|
||||
unit_y: Vec3<f32>,
|
||||
norm: Vec3<f32>,
|
||||
col: Rgb<f32>,
|
||||
bone: u8,
|
||||
) -> Quad<FigurePipeline> {
|
||||
Quad::new(
|
||||
FigureVertex::new(origin, col, bone),
|
||||
FigureVertex::new(origin + unit_x, col, bone),
|
||||
FigureVertex::new(origin + unit_x + unit_y, col, bone),
|
||||
FigureVertex::new(origin + unit_y, col, bone),
|
||||
FigureVertex::new(origin, norm, col, bone),
|
||||
FigureVertex::new(origin + unit_x, norm, col, bone),
|
||||
FigureVertex::new(origin + unit_x + unit_y, norm, col, bone),
|
||||
FigureVertex::new(origin + unit_y, norm, col, bone),
|
||||
)
|
||||
}
|
||||
|
||||
@ -61,6 +62,7 @@ impl Meshable for Segment {
|
||||
offs + pos.map(|e| e as f32) + Vec3::unit_y(),
|
||||
-Vec3::unit_y(),
|
||||
Vec3::unit_z(),
|
||||
-Vec3::unit_x(),
|
||||
col,
|
||||
0,
|
||||
));
|
||||
@ -69,6 +71,7 @@ impl Meshable for Segment {
|
||||
offs + pos.map(|e| e as f32) + Vec3::unit_x(),
|
||||
Vec3::unit_y(),
|
||||
Vec3::unit_z(),
|
||||
Vec3::unit_x(),
|
||||
col,
|
||||
0,
|
||||
));
|
||||
@ -77,6 +80,7 @@ impl Meshable for Segment {
|
||||
offs + pos.map(|e| e as f32),
|
||||
Vec3::unit_x(),
|
||||
Vec3::unit_z(),
|
||||
-Vec3::unit_y(),
|
||||
col,
|
||||
0,
|
||||
));
|
||||
@ -85,6 +89,7 @@ impl Meshable for Segment {
|
||||
offs + pos.map(|e| e as f32) + Vec3::unit_y(),
|
||||
Vec3::unit_z(),
|
||||
Vec3::unit_x(),
|
||||
Vec3::unit_y(),
|
||||
col,
|
||||
0,
|
||||
));
|
||||
@ -93,6 +98,7 @@ impl Meshable for Segment {
|
||||
offs + pos.map(|e| e as f32),
|
||||
Vec3::unit_y(),
|
||||
Vec3::unit_x(),
|
||||
-Vec3::unit_z(),
|
||||
col,
|
||||
0,
|
||||
));
|
||||
@ -101,6 +107,7 @@ impl Meshable for Segment {
|
||||
offs + pos.map(|e| e as f32) + Vec3::unit_z(),
|
||||
Vec3::unit_x(),
|
||||
Vec3::unit_y(),
|
||||
Vec3::unit_z(),
|
||||
col,
|
||||
0,
|
||||
));
|
||||
|
@ -25,6 +25,7 @@ use super::{
|
||||
gfx_defines! {
|
||||
vertex Vertex {
|
||||
pos: [f32; 3] = "v_pos",
|
||||
norm: [f32; 3] = "v_norm",
|
||||
col: [f32; 3] = "v_col",
|
||||
bone_idx: u8 = "v_bone_idx",
|
||||
}
|
||||
@ -50,10 +51,11 @@ gfx_defines! {
|
||||
}
|
||||
|
||||
impl Vertex {
|
||||
pub fn new(pos: Vec3<f32>, col: Rgb<f32>, bone_idx: u8) -> Self {
|
||||
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>, col: Rgb<f32>, bone_idx: u8) -> Self {
|
||||
Self {
|
||||
pos: pos.into_array(),
|
||||
col: col.into_array(),
|
||||
norm: norm.into_array(),
|
||||
bone_idx,
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ use crate::{
|
||||
anim::Skeleton,
|
||||
};
|
||||
|
||||
pub struct Figure {
|
||||
pub struct Figure<S: Skeleton> {
|
||||
// GPU data
|
||||
model: Model<FigurePipeline>,
|
||||
bone_consts: Consts<FigureBoneData>,
|
||||
@ -22,15 +22,15 @@ pub struct Figure {
|
||||
|
||||
// CPU data
|
||||
bone_meshes: [Option<Mesh<FigurePipeline>>; 16],
|
||||
pub skeleton: Skeleton,
|
||||
pub skeleton: S,
|
||||
}
|
||||
|
||||
impl Figure {
|
||||
impl<S: Skeleton> Figure<S> {
|
||||
pub fn new(
|
||||
renderer: &mut Renderer,
|
||||
bone_meshes: [Option<Mesh<FigurePipeline>>; 16]
|
||||
bone_meshes: [Option<Mesh<FigurePipeline>>; 16],
|
||||
skeleton: S,
|
||||
) -> Result<Self, Error> {
|
||||
let skeleton = Skeleton::default();
|
||||
let mut this = Self {
|
||||
model: renderer.create_model(&Mesh::new())?,
|
||||
bone_consts: renderer.create_consts(&skeleton.compute_matrices())?,
|
||||
|
@ -30,6 +30,11 @@ use crate::{
|
||||
},
|
||||
window::Event,
|
||||
mesh::Meshable,
|
||||
anim::{
|
||||
Animation,
|
||||
CharacterSkeleton,
|
||||
RunAnimation,
|
||||
},
|
||||
};
|
||||
|
||||
// Local
|
||||
@ -51,7 +56,7 @@ pub struct Scene {
|
||||
globals: Consts<Globals>,
|
||||
skybox: Skybox,
|
||||
|
||||
test_figure: Figure,
|
||||
test_figure: Figure<CharacterSkeleton>,
|
||||
|
||||
client: Client,
|
||||
}
|
||||
@ -85,10 +90,10 @@ impl Scene {
|
||||
Some(load_segment("chest.vox").generate_mesh_with_offset(Vec3::new(-6.0, -3.0, 0.0))),
|
||||
Some(load_segment("belt.vox").generate_mesh_with_offset(Vec3::new(-5.0, -3.0, 0.0))),
|
||||
Some(load_segment("pants.vox").generate_mesh_with_offset(Vec3::new(-5.0, -3.0, 0.0))),
|
||||
Some(load_segment("foot.vox").generate_mesh_with_offset(Vec3::new(-2.5, -3.0, 0.0))),
|
||||
Some(load_segment("foot.vox").generate_mesh_with_offset(Vec3::new(-2.5, -3.0, 0.0))),
|
||||
Some(load_segment("hand.vox").generate_mesh_with_offset(Vec3::new(-2.0, -2.0, -1.0))),
|
||||
Some(load_segment("hand.vox").generate_mesh_with_offset(Vec3::new(-2.0, -2.0, -1.0))),
|
||||
Some(load_segment("foot.vox").generate_mesh_with_offset(Vec3::new(-2.5, -3.0, 0.0))),
|
||||
Some(load_segment("foot.vox").generate_mesh_with_offset(Vec3::new(-2.5, -3.0, 0.0))),
|
||||
Some(load_segment("sword.vox").generate_mesh_with_offset(Vec3::new(-6.5, -1.0, 0.0))),
|
||||
None,
|
||||
None,
|
||||
@ -98,6 +103,7 @@ impl Scene {
|
||||
None,
|
||||
None,
|
||||
],
|
||||
CharacterSkeleton::new(),
|
||||
)
|
||||
.unwrap(),
|
||||
|
||||
@ -142,26 +148,10 @@ impl Scene {
|
||||
.expect("Failed to update global constants");
|
||||
|
||||
// TODO: Don't do this here
|
||||
let offs = (self.client.state().get_tick() as f32 * 10.0).sin();
|
||||
self.test_figure.skeleton.bone_mut(0).offset = Vec3::new(0.0, 0.0, 13.0);
|
||||
self.test_figure.skeleton.bone_mut(0).ori = Quaternion::rotation_z(offs * 0.3);
|
||||
// Chest
|
||||
self.test_figure.skeleton.bone_mut(1).offset = Vec3::new(0.0, 0.0, 9.0);
|
||||
self.test_figure.skeleton.bone_mut(2).offset = Vec3::new(0.0, 0.0, 7.0);
|
||||
self.test_figure.skeleton.bone_mut(3).offset = Vec3::new(0.0, 0.0, 4.0);
|
||||
self.test_figure.skeleton.bone_mut(1).ori = Quaternion::rotation_z(offs * 0.15);
|
||||
self.test_figure.skeleton.bone_mut(2).ori = Quaternion::rotation_z(offs * 0.15);
|
||||
self.test_figure.skeleton.bone_mut(3).ori = Quaternion::rotation_z(offs * 0.15);
|
||||
//Feet
|
||||
self.test_figure.skeleton.bone_mut(4).offset = Vec3::new(-3.0, -offs * 4.0, 0.0);
|
||||
self.test_figure.skeleton.bone_mut(5).offset = Vec3::new(3.0, offs * 4.0, 0.0);
|
||||
// Hands
|
||||
self.test_figure.skeleton.bone_mut(6).offset = Vec3::new(-8.0, offs * 4.0, 9.0);
|
||||
self.test_figure.skeleton.bone_mut(7).offset = Vec3::new(8.0, -offs * 4.0, 9.0);
|
||||
// Sword
|
||||
self.test_figure.skeleton.bone_mut(8).offset = Vec3::new(-8.0, 5.0, 24.0);
|
||||
self.test_figure.skeleton.bone_mut(8).ori = Quaternion::rotation_y(2.5);
|
||||
|
||||
RunAnimation::update_skeleton(
|
||||
&mut self.test_figure.skeleton,
|
||||
self.client.state().get_tick(),
|
||||
);
|
||||
self.test_figure.update_locals(renderer, FigureLocals::default());
|
||||
self.test_figure.update_skeleton(renderer);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user