pub struct BlenderMesh {
Show 13 fields pub vertex_positions: Vec<f32>, pub vertex_position_indices: Vec<u16>, pub num_vertices_in_each_face: Vec<u8>, pub vertex_normals: Vec<f32>, pub vertex_normal_indices: Option<Vec<u16>>, pub vertex_uvs: Option<Vec<f32>>, pub vertex_uv_indices: Option<Vec<u16>>, pub texture_name: Option<String>, pub armature_name: Option<String>, pub vertex_group_indices: Option<Vec<u8>>, pub vertex_group_weights: Option<Vec<f32>>, pub num_groups_for_each_vertex: Option<Vec<u8>>, pub bounding_box: BoundingBox,
}
Expand description

All of the data about a Blender mesh

Fields

vertex_positions: Vec<f32>

All of the mesh’s vertices. Three items in the vector make one vertex. So indices 0, 1 and 2 are a vertex, 3, 4 and 5 are a vertex.. etc. [v1x, v1y, v1z, v2x, v2y, v2z, …]

vertex_position_indices: Vec<u16>

The indices within vertex positions that make up each triangle in our mesh. Three vertex position indices correspond to one triangle [0, 1, 2, 0, 2, 3, …]

num_vertices_in_each_face: Vec<u8>

TODO: enum..? if they’re all equal we replace the MyEnum::PerVertex(Vec) with MyEnum::Equal(4)

vertex_normals: Vec<f32>vertex_normal_indices: Option<Vec<u16>>vertex_uvs: Option<Vec<f32>>

If your mesh is textured these will be all of the mesh’s vertices’ uv coordinates. Every vertex has two UV coordinates. [v1s, v1t, v2s, v2t, v3s, v3t] TODO: Combine vertex_uvs, vertex_uv_indices, texture_name into texture_info

vertex_uv_indices: Option<Vec<u16>>texture_name: Option<String>armature_name: Option<String>vertex_group_indices: Option<Vec<u8>>

TODO: When we move to single index triangulate and add new vertices give those vertices the same group indices / weights TODO: A function that trims this down to n weights and indices per vertex. Similar to our triangulate function TODO: Make sure that when we combine vertex indices we expand our group weights

vertex_group_weights: Option<Vec<f32>>num_groups_for_each_vertex: Option<Vec<u8>>

TODO: enum..? if they’re all equal we replace the MyEnum::PerVertex(Vec) with MyEnum::Equal(4)

bounding_box: BoundingBox

Implementations

We export our models with indices for positions, normals and uvs because

  1. Easier because we we can unit test that here vs. a blender python script that’s much trickier to test.
  2. Reduces amount of data required to represent the model on disk.

OpenGL only supports one index buffer, we convert our vertex data from having three indices to having one. This usually requires some duplication of vertex data. We duplicate the minimum amount of vertex data necessary.

FIXME: Wrote a test and threw code at the wall until it passed. Need to refactor this extensively! Any work on this before refactoring will not be worth the time Split this up into smaller functions that it calls, and clean up those functions.

Blender meshes get exported with a Z up coordinate system. Here we flip our coordinate system to be y up

@see https://gamedev.stackexchange.com/a/7932

TODO: When we have bone data we’ll need to change them to port change-mat4-coordinate-system into here. https://github.com/chinedufn/change-mat4-coordinate-system/blob/master/change-mat4-coordinate-system.js

When exporting a mesh from Blender, faces will usually have 4 vertices (quad) but some faces might have 3 (triangle).

We read self.num_vertices_in_each_face to check how many vertices each face has.

If a face has 4 vertices we convert it into two triangles, each with 3 vertices.

Panics

Panics if a face has more than 4 vertices. In the future we might support 5+ vertices, but I haven’t run into that yet. Not even sure if Blender can have faces with 5 vertices..

Different vertices might have different numbers of bones that influence them. A vertex near the shoulder might be influenced by the neck and upper arm and sternum, while a vertex in a toe might only be influenced by a toe bone.

When passing data to the GPU, each vertex needs the same number of bone attributes, so we must add/remove bones from each vertex to get them equal.

Say we’re setting 3 groups per vertex:

  • If a vertex has one vertex group (bone) we will create two fake bones with 0.0 weight.
  • If a vertex has 5 bones we’ll remove the one with the smallest weighting (influence).

Trait Implementations

Formats the value using the given formatter. Read more
Deserialize this value from the given Serde deserializer. Read more
This method tests for self and other values to be equal, and is used by ==. Read more
This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more
Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Should always be Self
The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Checks if self is actually part of its subset T (and can be converted to it).
Use with care! Same as self.to_subset but without any property checks. Always succeeds.
The inclusion map: converts self to the equivalent element of its superset.
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.