1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use cgmath::Point3;
use cgmath::prelude::*;
use mesh::Mesh;
use util::*;
use subdivide::Subdivide;
use wrap::GiftWrapper;
#[derive(Clone)]
struct Bone {
from: Point3<f32>,
to: Point3<f32>,
}
pub struct SkeletonMesh {
bones: Vec<Bone>,
mesh: Mesh,
end_radius: f32,
max_radius: f32,
}
impl SkeletonMesh {
pub fn new() -> Self {
SkeletonMesh {
bones: Vec::new(),
mesh: Mesh::new(),
end_radius: 0.005,
max_radius: 0.025
}
}
pub fn set_end_radius(&mut self, radius: f32) {
self.end_radius = radius;
}
pub fn add_bone(&mut self, from: Point3<f32>, to: Point3<f32>) {
let bone = Bone {from: from, to: to};
self.bones.push(bone);
}
fn add_sphere(&mut self, position: Point3<f32>, radius: f32) {
let mut mesh = Mesh::new();
let face_id = mesh.add_plane(radius, radius);
let normal = mesh.face_norm(face_id);
mesh.extrude_face(face_id, normal, radius).translate(position.x,
position.y,
position.z - radius * 0.5);
self.mesh += mesh.subdivide();
}
pub fn generate_mesh(&mut self) -> &mut Mesh {
let end_radius = self.end_radius;
for bone in self.bones.clone() {
self.add_sphere(bone.from, end_radius);
self.add_sphere(bone.to, end_radius);
let bone_vector = bone.to - bone.from;
let norm = bone_vector.normalize();
let mut big_radius = bone_vector.magnitude() * 0.15;
if big_radius > self.max_radius {
big_radius = self.max_radius;
}
let big_end_quad = make_quad(bone.from, norm, end_radius, norm);
let small_end_quad = make_quad(bone.to, -norm, end_radius, -norm);
let middle_for_big_quad = make_quad((bone.from + bone_vector * 0.2) - (-norm) * big_radius, -norm, big_radius, -norm);
let middle_for_small_quad = make_quad((bone.from + bone_vector * 0.2) - norm * big_radius, norm, big_radius, norm);
let big_end_face = self.mesh.add_positions(big_end_quad);
let small_end_face = self.mesh.add_positions(small_end_quad);
let middle_for_big_face = self.mesh.add_positions(middle_for_big_quad);
let middle_for_small_face = self.mesh.add_positions(middle_for_small_quad);
{
let mut wrapper = GiftWrapper::new();
wrapper.stitch_two_faces(&mut self.mesh, big_end_face, middle_for_big_face);
}
{
let mut wrapper = GiftWrapper::new();
wrapper.stitch_two_faces(&mut self.mesh, small_end_face, middle_for_small_face);
}
}
&mut self.mesh
}
}