Restructured animation code

This commit is contained in:
Joshua Barretto 2019-01-14 14:40:22 +00:00
parent 86e70751e0
commit 0a122431db
5 changed files with 193 additions and 143 deletions

View File

@ -0,0 +1,66 @@
pub mod run;
// Reexports
pub use self::run::RunAnimation;
// Crate
use crate::render::FigureBoneData;
// Local
use super::{
Skeleton,
Bone,
};
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 {
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(),
}
}
}
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(),
]
}
}

View File

@ -0,0 +1,44 @@
// Library
use vek::*;
// Local
use super::{
CharacterSkeleton,
super::Animation,
};
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.5, -wave * 4.0, -(wave_fast.abs() - 0.5) * 3.0);
skeleton.r_foot.offset = Vec3::new(3.5, 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);
}
}

View File

@ -1,3 +1,5 @@
pub mod character;
// Library // Library
use vek::*; use vek::*;
@ -35,59 +37,6 @@ pub trait Skeleton {
fn compute_matrices(&self) -> [FigureBoneData; 16]; fn compute_matrices(&self) -> [FigureBoneData; 16];
} }
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 {
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(),
}
}
}
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 { pub trait Animation {
type Skeleton; type Skeleton;
type Dependency; type Dependency;
@ -97,39 +46,3 @@ pub trait Animation {
dependency: Self::Dependency, 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);
}
}

View File

@ -55,9 +55,11 @@ impl Meshable for Segment {
{ {
let col = col.map(|e| e as f32 / 255.0); let col = col.map(|e| e as f32 / 255.0);
// TODO: Face occlusion
// -x // -x
if self.get(pos - Vec3::unit_x())
.map(|v| v.is_empty())
.unwrap_or(true)
{
mesh.push_quad(create_quad( mesh.push_quad(create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_y(), offs + pos.map(|e| e as f32) + Vec3::unit_y(),
-Vec3::unit_y(), -Vec3::unit_y(),
@ -66,7 +68,12 @@ impl Meshable for Segment {
col, col,
0, 0,
)); ));
}
// +x // +x
if self.get(pos + Vec3::unit_x())
.map(|v| v.is_empty())
.unwrap_or(true)
{
mesh.push_quad(create_quad( mesh.push_quad(create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_x(), offs + pos.map(|e| e as f32) + Vec3::unit_x(),
Vec3::unit_y(), Vec3::unit_y(),
@ -75,7 +82,12 @@ impl Meshable for Segment {
col, col,
0, 0,
)); ));
}
// -y // -y
if self.get(pos - Vec3::unit_y())
.map(|v| v.is_empty())
.unwrap_or(true)
{
mesh.push_quad(create_quad( mesh.push_quad(create_quad(
offs + pos.map(|e| e as f32), offs + pos.map(|e| e as f32),
Vec3::unit_x(), Vec3::unit_x(),
@ -84,7 +96,12 @@ impl Meshable for Segment {
col, col,
0, 0,
)); ));
}
// +y // +y
if self.get(pos + Vec3::unit_y())
.map(|v| v.is_empty())
.unwrap_or(true)
{
mesh.push_quad(create_quad( mesh.push_quad(create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_y(), offs + pos.map(|e| e as f32) + Vec3::unit_y(),
Vec3::unit_z(), Vec3::unit_z(),
@ -93,7 +110,12 @@ impl Meshable for Segment {
col, col,
0, 0,
)); ));
}
// -z // -z
if self.get(pos - Vec3::unit_z())
.map(|v| v.is_empty())
.unwrap_or(true)
{
mesh.push_quad(create_quad( mesh.push_quad(create_quad(
offs + pos.map(|e| e as f32), offs + pos.map(|e| e as f32),
Vec3::unit_y(), Vec3::unit_y(),
@ -102,7 +124,12 @@ impl Meshable for Segment {
col, col,
0, 0,
)); ));
}
// +z // +z
if self.get(pos + Vec3::unit_z())
.map(|v| v.is_empty())
.unwrap_or(true)
{
mesh.push_quad(create_quad( mesh.push_quad(create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_z(), offs + pos.map(|e| e as f32) + Vec3::unit_z(),
Vec3::unit_x(), Vec3::unit_x(),
@ -113,6 +140,7 @@ impl Meshable for Segment {
)); ));
} }
} }
}
mesh mesh
} }

View File

@ -32,8 +32,7 @@ use crate::{
mesh::Meshable, mesh::Meshable,
anim::{ anim::{
Animation, Animation,
CharacterSkeleton, character::{CharacterSkeleton, RunAnimation},
RunAnimation,
}, },
}; };
@ -152,8 +151,8 @@ impl Scene {
&mut self.test_figure.skeleton, &mut self.test_figure.skeleton,
self.client.state().get_tick(), self.client.state().get_tick(),
); );
self.test_figure.update_locals(renderer, FigureLocals::default()); self.test_figure.update_locals(renderer, FigureLocals::default()).unwrap();
self.test_figure.update_skeleton(renderer); self.test_figure.update_skeleton(renderer).unwrap();
} }
/// Render the scene using the provided `Renderer` /// Render the scene using the provided `Renderer`