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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Note: this is mostly copied and adapted from https://github.com/PistonDevelopers/wavefront_obj,
// could potentially be moved to a shared dependency

/// A set of objects from the Collada document
#[derive(Clone, Debug)]
pub struct ObjSet {
  /// Which material library to use.
  pub material_library: Option<String>,
  /// The set of objects.
  pub objects: Vec<Object>,
}


/// A mesh object.
#[derive(Clone, Debug)]
pub struct Object {
  pub id: String,
  /// A human-readable name for this object. This can be set in blender.
  pub name: String,
  /// The set of vertices this object is composed of. These are referenced
  /// by index in `faces`.
  pub vertices: Vec<Vertex>,
  /// The set of attached joints for each vertex. Should match
  /// length of 'vertices' if present
  pub joint_weights: Vec<JointWeights>,
  /// The set of texture vertices referenced by this object. The actual
  /// vertices are indexed by the second element in a `VTNIndex`.
  pub tex_vertices: Vec<TVertex>,
  /// The set of normals referenced by this object. This are are referenced
  /// by the third element in a `VTNIndex`.
  pub normals: Vec<Normal>,
  /// A set of shapes (with materials applied to them) of which this object is
  /// composed.
  pub geometry: Vec<Geometry>,
}


/// A set of shapes, all using the given material.
#[derive(Clone, Debug)]
pub struct Geometry {
  /// Should we use smooth shading when rendering this?
  pub smooth_shading_group: usize,
  /// The shapes of which this geometry is composed.
  pub mesh: Vec<PrimitiveElement>,
}


#[derive(Clone, Debug)]
pub struct Triangles {
  /// The vertices of the triangles.
  pub vertices: Vec<(VTNIndex, VTNIndex, VTNIndex)>,
  /// The material of the polylist. Optional.
  pub material: Option<String>,
}


/// The various shapes supported by this library that can be found in a Polylist.
///
/// Convex polygons more complicated than a triangle are automatically
/// converted into triangles.
#[derive(Clone, Copy, Debug, Hash)]
pub enum Shape {
  /// A point specified by its position.
  Point(VTNIndex),
  /// A line specified by its endpoints.
  Line(VTNIndex, VTNIndex),
  /// A triangle specified by its three vertices.
  Triangle(VTNIndex, VTNIndex, VTNIndex),
}


/// Provides the information needed for a mesh to bind vertex attributes
/// together and then organize those vertices into individual polygons.
#[derive(Clone, Debug)]
pub struct Polylist {
  /// The shapes in this polylist.
  pub shapes: Vec<Shape>,
  /// The material of the polylist. Optional.
  pub material: Option<String>,
}


/// Geometric primitives, which assemble values from the inputs into vertex
/// attribute data.
#[derive(Clone, Debug)]
pub enum PrimitiveElement {
  // Lines,
  // LineStrips,
  // Polygons,
  Polylist(Polylist),
  Triangles(Triangles),
  // Trifans,
  // Tristrips,
}


/// A single 3-dimensional point on the corner of an object.
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug)]
pub struct Vertex {
  pub x: f64,
  pub y: f64,
  pub z: f64,
}


/// Represents the weights of any joints that should
/// control the vertex with skinned animation
#[derive(Clone, Copy, Debug)]
pub struct JointWeights {
  /// Indices of joints attached to this vertex.
  /// Maximum of 4 joints
  pub joints: [usize; 4],
  /// Weights for each joint attached to this vertex.
  /// Maximum of 4 joints
  pub weights: [f32; 4],
}
/// A single 3-dimensional normal
pub type Normal = Vertex;

/// A single 2-dimensional point on a texture. "Texure Vertex".
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug)]
pub struct TVertex {
  pub x: f64,
  pub y: f64,
}

/// An index into the `vertices` array of an object, representing a vertex in
/// the mesh. After parsing, this is guaranteed to be a valid index into the
/// array, so unchecked indexing may be used.
pub type VertexIndex = usize;

/// An index into the `texture vertex` array of an object.
///
/// Unchecked indexing may be used, because the values are guaranteed to be in
/// range by the parser.
pub type TextureIndex = usize;

/// An index into the `normals` array of an object.
///
/// Unchecked indexing may be used, because the values are guaranteed to be in
/// range by the parser.
pub type NormalIndex = usize;

/// An index into the vertex array, with an optional index into the texture
/// array. This is used to define the corners of shapes which may or may not
/// be textured.
pub type VTNIndex = (VertexIndex, Option<TextureIndex>, Option<NormalIndex>);