From d579781accd225080f52d9e046ac4cf512c94801 Mon Sep 17 00:00:00 2001
From: Joshua Barretto <joshua.s.barretto@gmail.com>
Date: Mon, 14 Jan 2019 14:40:22 +0000
Subject: [PATCH] Restructured animation code

---
 voxygen/src/anim/character/mod.rs |  66 +++++++++++++++
 voxygen/src/anim/character/run.rs |  44 ++++++++++
 voxygen/src/anim/mod.rs           |  91 +--------------------
 voxygen/src/mesh/segment.rs       | 128 ++++++++++++++++++------------
 voxygen/src/scene/mod.rs          |   7 +-
 5 files changed, 193 insertions(+), 143 deletions(-)
 create mode 100644 voxygen/src/anim/character/mod.rs
 create mode 100644 voxygen/src/anim/character/run.rs

diff --git a/voxygen/src/anim/character/mod.rs b/voxygen/src/anim/character/mod.rs
new file mode 100644
index 0000000000..0e63aecf31
--- /dev/null
+++ b/voxygen/src/anim/character/mod.rs
@@ -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(),
+        ]
+    }
+}
diff --git a/voxygen/src/anim/character/run.rs b/voxygen/src/anim/character/run.rs
new file mode 100644
index 0000000000..8e055a8fd1
--- /dev/null
+++ b/voxygen/src/anim/character/run.rs
@@ -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);
+    }
+}
diff --git a/voxygen/src/anim/mod.rs b/voxygen/src/anim/mod.rs
index 5d4ba84268..6351ed94df 100644
--- a/voxygen/src/anim/mod.rs
+++ b/voxygen/src/anim/mod.rs
@@ -1,3 +1,5 @@
+pub mod character;
+
 // Library
 use vek::*;
 
@@ -35,59 +37,6 @@ pub trait Skeleton {
     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 {
     type Skeleton;
     type Dependency;
@@ -97,39 +46,3 @@ pub trait Animation {
         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);
-    }
-}
diff --git a/voxygen/src/mesh/segment.rs b/voxygen/src/mesh/segment.rs
index 3cd86b8b5b..4bb540afb5 100644
--- a/voxygen/src/mesh/segment.rs
+++ b/voxygen/src/mesh/segment.rs
@@ -55,62 +55,90 @@ impl Meshable for Segment {
             {
                 let col = col.map(|e| e as f32 / 255.0);
 
-                // TODO: Face occlusion
-
                 // -x
-                mesh.push_quad(create_quad(
-                    offs + pos.map(|e| e as f32) + Vec3::unit_y(),
-                    -Vec3::unit_y(),
-                    Vec3::unit_z(),
-                    -Vec3::unit_x(),
-                    col,
-                    0,
-                ));
+                if self.get(pos - Vec3::unit_x())
+                    .map(|v| v.is_empty())
+                    .unwrap_or(true)
+                {
+                    mesh.push_quad(create_quad(
+                        offs + pos.map(|e| e as f32) + Vec3::unit_y(),
+                        -Vec3::unit_y(),
+                        Vec3::unit_z(),
+                        -Vec3::unit_x(),
+                        col,
+                        0,
+                    ));
+                }
                 // +x
-                mesh.push_quad(create_quad(
-                    offs + pos.map(|e| e as f32) + Vec3::unit_x(),
-                    Vec3::unit_y(),
-                    Vec3::unit_z(),
-                    Vec3::unit_x(),
-                    col,
-                    0,
-                ));
+                if self.get(pos + Vec3::unit_x())
+                    .map(|v| v.is_empty())
+                    .unwrap_or(true)
+                {
+                    mesh.push_quad(create_quad(
+                        offs + pos.map(|e| e as f32) + Vec3::unit_x(),
+                        Vec3::unit_y(),
+                        Vec3::unit_z(),
+                        Vec3::unit_x(),
+                        col,
+                        0,
+                    ));
+                }
                 // -y
-                mesh.push_quad(create_quad(
-                    offs + pos.map(|e| e as f32),
-                    Vec3::unit_x(),
-                    Vec3::unit_z(),
-                    -Vec3::unit_y(),
-                    col,
-                    0,
-                ));
+                if self.get(pos - Vec3::unit_y())
+                    .map(|v| v.is_empty())
+                    .unwrap_or(true)
+                {
+                    mesh.push_quad(create_quad(
+                        offs + pos.map(|e| e as f32),
+                        Vec3::unit_x(),
+                        Vec3::unit_z(),
+                        -Vec3::unit_y(),
+                        col,
+                        0,
+                    ));
+                }
                 // +y
-                mesh.push_quad(create_quad(
-                    offs + pos.map(|e| e as f32) + Vec3::unit_y(),
-                    Vec3::unit_z(),
-                    Vec3::unit_x(),
-                    Vec3::unit_y(),
-                    col,
-                    0,
-                ));
+                if self.get(pos + Vec3::unit_y())
+                    .map(|v| v.is_empty())
+                    .unwrap_or(true)
+                {
+                    mesh.push_quad(create_quad(
+                        offs + pos.map(|e| e as f32) + Vec3::unit_y(),
+                        Vec3::unit_z(),
+                        Vec3::unit_x(),
+                        Vec3::unit_y(),
+                        col,
+                        0,
+                    ));
+                }
                 // -z
-                mesh.push_quad(create_quad(
-                    offs + pos.map(|e| e as f32),
-                    Vec3::unit_y(),
-                    Vec3::unit_x(),
-                    -Vec3::unit_z(),
-                    col,
-                    0,
-                ));
+                if self.get(pos - Vec3::unit_z())
+                    .map(|v| v.is_empty())
+                    .unwrap_or(true)
+                {
+                    mesh.push_quad(create_quad(
+                        offs + pos.map(|e| e as f32),
+                        Vec3::unit_y(),
+                        Vec3::unit_x(),
+                        -Vec3::unit_z(),
+                        col,
+                        0,
+                    ));
+                }
                 // +z
-                mesh.push_quad(create_quad(
-                    offs + pos.map(|e| e as f32) + Vec3::unit_z(),
-                    Vec3::unit_x(),
-                    Vec3::unit_y(),
-                    Vec3::unit_z(),
-                    col,
-                    0,
-                ));
+                if self.get(pos + Vec3::unit_z())
+                    .map(|v| v.is_empty())
+                    .unwrap_or(true)
+                {
+                    mesh.push_quad(create_quad(
+                        offs + pos.map(|e| e as f32) + Vec3::unit_z(),
+                        Vec3::unit_x(),
+                        Vec3::unit_y(),
+                        Vec3::unit_z(),
+                        col,
+                        0,
+                    ));
+                }
             }
         }
 
diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs
index d529fe9473..2fb16e1ad3 100644
--- a/voxygen/src/scene/mod.rs
+++ b/voxygen/src/scene/mod.rs
@@ -32,8 +32,7 @@ use crate::{
     mesh::Meshable,
     anim::{
         Animation,
-        CharacterSkeleton,
-        RunAnimation,
+        character::{CharacterSkeleton, RunAnimation},
     },
 };
 
@@ -152,8 +151,8 @@ impl Scene {
             &mut self.test_figure.skeleton,
             self.client.state().get_tick(),
         );
-        self.test_figure.update_locals(renderer, FigureLocals::default());
-        self.test_figure.update_skeleton(renderer);
+        self.test_figure.update_locals(renderer, FigureLocals::default()).unwrap();
+        self.test_figure.update_skeleton(renderer).unwrap();
     }
 
     /// Render the scene using the provided `Renderer`