pub struct MdlMesh {Show 40 fields
pub fn_ptr_gen_vertices: u32,
pub fn_ptr_remove_temp_array: u32,
pub bounding_min: [f32; 3],
pub bounding_max: [f32; 3],
pub bsphere_radius: f32,
pub bsphere_center: [f32; 3],
pub diffuse_color: [f32; 3],
pub ambient_color: [f32; 3],
pub transparency_hint: i32,
pub texture_0: String,
pub texture_1: String,
pub animate_uv: i32,
pub uv_direction_x: f32,
pub uv_direction_y: f32,
pub uv_jitter: f32,
pub uv_jitter_speed: f32,
pub texture_channel_count: u16,
pub light_mapped: bool,
pub rotate_texture: bool,
pub is_background_geometry: bool,
pub beaming: bool,
pub total_surface_area: f32,
pub positions: Vec<[f32; 3]>,
pub normals: Vec<[f32; 3]>,
pub vertex_colors: Vec<[u8; 4]>,
pub uv1: Vec<[f32; 2]>,
pub uv2: Vec<[f32; 2]>,
pub uv3: Vec<[f32; 2]>,
pub uv4: Vec<[f32; 2]>,
pub tangent_space: Vec<[[f32; 3]; 3]>,
pub faces: Vec<MdlFace>,
pub inverted_counter: u32,
pub has_embedded_positions: bool,
pub shared_index_offset: i32,
pub shared_index_pool: i32,
pub shared_index_size: i32,
pub indices_per_face: u32,
pub vertex_count: u16,
pub render: bool,
pub shadow: bool,
}Expand description
A triangle mesh contained within a node.
Vertex attribute data comes from the companion MDX file. Each attribute
is stored in a separate array, matching the interleaved MDX vertex layout
controlled by the mdx_vertex_flags bitfield and per-attribute byte offsets
in the TriMesh header (+0x100..+0x120).
See docs/notes/mdl_mdx.md §MDX Vertex Layout for the full specification.
Fields§
§fn_ptr_gen_vertices: u32gen_vertices function pointer stub (u32). Extra +0x00.
fn_ptr_remove_temp_array: u32remove_temporary_array function pointer stub (u32). Extra +0x04.
bounding_min: [f32; 3]Bounding box minimum corner (3×f32). Extra +0x14.
bounding_max: [f32; 3]Bounding box maximum corner (3×f32). Extra +0x20.
bsphere_radius: f32Bounding sphere radius (f32). Extra +0x2C.
bsphere_center: [f32; 3]Bounding sphere center (3×f32). Extra +0x30.
diffuse_color: [f32; 3]RGB diffuse color (3×f32). Extra +0x3C.
ambient_color: [f32; 3]RGB ambient color (3×f32). Extra +0x48.
transparency_hint: i32Transparency hint (0=opaque, 1=transparent). Extra +0x54.
texture_0: StringPrimary texture name (up to 32 chars). Extra +0x58.
texture_1: StringSecondary/lightmap texture name (up to 32 chars). Extra +0x78.
animate_uv: i32UV animation enable flag. Extra +0xE8.
uv_direction_x: f32UV animation direction X. Extra +0xEC.
uv_direction_y: f32UV animation direction Y. Extra +0xF0.
uv_jitter: f32UV jitter amount. Extra +0xF4.
uv_jitter_speed: f32UV jitter speed. Extra +0xF8.
texture_channel_count: u16Number of UV texture channels. Extra +0x132.
light_mapped: boolLightmapped flag. Extra +0x134.
rotate_texture: boolRotate texture flag. Extra +0x135.
is_background_geometry: boolBackground geometry flag. Extra +0x136.
beaming: boolBeaming flag. Extra +0x138.
total_surface_area: f32Total surface area (computed by toolset). Extra +0x13C.
positions: Vec<[f32; 3]>Vertex positions (3×f32: x, y, z). MDX flag 0x01.
normals: Vec<[f32; 3]>Vertex normals (3×f32: x, y, z). MDX flag 0x20.
vertex_colors: Vec<[u8; 4]>Vertex colors (4×u8: R, G, B, A). No flag bit - offset != -1 indicates presence.
uv1: Vec<[f32; 2]>Primary UV coordinates (2×f32: u, v). MDX flag 0x02.
uv2: Vec<[f32; 2]>Secondary UV coordinates (2×f32: u, v). MDX flag 0x04.
uv3: Vec<[f32; 2]>Tertiary UV coordinates (2×f32: u, v). MDX flag 0x08.
uv4: Vec<[f32; 2]>Quaternary UV coordinates (2×f32: u, v). MDX flag 0x10.
tangent_space: Vec<[[f32; 3]; 3]>Tangent space basis (3×3×f32: tangent, bitangent, cross). MDX flag 0x80.
Each entry is 36 bytes: three vec3s forming the tangent-space basis used for bump/normal mapping.
faces: Vec<MdlFace>Face data parsed from the MaxFace array (32 bytes per face on disk).
inverted_counter: u32Mesh sequence “inverted counter” value from index_buffer_pools (+0xC8).
Preserved from binary on roundtrip. For newly constructed models, compute
via the inverted counter formula (see mesh_derived_fields.md §1.5).
The engine overwrites this at load time with a GL pool handle.
has_embedded_positions: boolWhether the source binary used the “embedded position” variant for the
vertex_indices_count payload (+0xB0).
When true, the writer emits a 4-byte tag + vertex_count * 12 bytes
of position data instead of a single u32 face_count * 3.
TriMesh shared index offset scalar (+0xD4).
TriMesh shared index pool scalar (+0xD8).
TriMesh shared index size scalar (+0xDC).
indices_per_face: u32TriMesh indices-per-face scalar (+0xE0). Vanilla value is typically 3.
vertex_count: u16Number of vertices declared in the mesh header.
render: boolIs this mesh renderable? (MdlNodeTriMesh +0x189).
shadow: boolDoes this mesh cast shadows? (MdlNodeTriMesh +0x187).
Implementations§
Source§impl MdlMesh
impl MdlMesh
Sourcepub fn compute_bounding_box(&self) -> Option<([f32; 3], [f32; 3])>
pub fn compute_bounding_box(&self) -> Option<([f32; 3], [f32; 3])>
Compute the axis-aligned bounding box from vertex positions.
Returns (bounding_min, bounding_max), or None if positions are empty.
Sourcepub fn compute_bounding_sphere(&self) -> Option<([f32; 3], f32)>
pub fn compute_bounding_sphere(&self) -> Option<([f32; 3], f32)>
Compute the centroid-based bounding sphere from vertex positions.
Uses the engine’s algorithm from PartTriMesh::GetMinimumSphere
(0x00443330): center = centroid, radius = max distance to any vertex.
This is NOT the true minimum bounding sphere (Welzl), but matches
vanilla file values.
Returns (center, radius), or None if positions are empty.
Sourcepub fn compute_total_surface_area(&self) -> f32
pub fn compute_total_surface_area(&self) -> f32
Compute the total surface area of all triangles in the mesh.
Returns 0.0 if positions or faces are empty.
Sourcepub fn recompute_face_planes(&mut self)
pub fn recompute_face_planes(&mut self)
Recompute plane_normal and plane_distance for all faces from vertex positions.
Uses the standard cross-product formula:
normal = normalize(cross(v1 - v0, v2 - v0))
distance = -dot(normal, v0)Degenerate triangles (zero-area) get a zero normal and zero distance.
Sourcepub fn compute_face_adjacency(&mut self)
pub fn compute_face_adjacency(&mut self)
Compute face adjacency from vertex positions using position-based edge matching.
For each edge of each face, finds the adjacent face sharing that edge.
Uses 0xFFFF as the no-neighbor sentinel. Position matching uses {:.4e}
formatting for floating-point key comparison (handles duplicate vertices
at the same position with different normals/UVs).
For non-manifold edges (more than 2 faces sharing an edge), the smallest face index is used (deterministic, matches PyKotor behavior).
Sourcepub fn recompute_derived_fields(&mut self)
pub fn recompute_derived_fields(&mut self)
Recompute all derivable geometric fields at once.
Updates: bounding box, bounding sphere, total surface area, face plane normals/distances, and face adjacency.