MdlMesh

Struct MdlMesh 

Source
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: u32

gen_vertices function pointer stub (u32). Extra +0x00.

§fn_ptr_remove_temp_array: u32

remove_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: f32

Bounding 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: i32

Transparency hint (0=opaque, 1=transparent). Extra +0x54.

§texture_0: String

Primary texture name (up to 32 chars). Extra +0x58.

§texture_1: String

Secondary/lightmap texture name (up to 32 chars). Extra +0x78.

§animate_uv: i32

UV animation enable flag. Extra +0xE8.

§uv_direction_x: f32

UV animation direction X. Extra +0xEC.

§uv_direction_y: f32

UV animation direction Y. Extra +0xF0.

§uv_jitter: f32

UV jitter amount. Extra +0xF4.

§uv_jitter_speed: f32

UV jitter speed. Extra +0xF8.

§texture_channel_count: u16

Number of UV texture channels. Extra +0x132.

§light_mapped: bool

Lightmapped flag. Extra +0x134.

§rotate_texture: bool

Rotate texture flag. Extra +0x135.

§is_background_geometry: bool

Background geometry flag. Extra +0x136.

§beaming: bool

Beaming flag. Extra +0x138.

§total_surface_area: f32

Total 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: u32

Mesh 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: bool

Whether 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.

§shared_index_offset: i32

TriMesh shared index offset scalar (+0xD4).

§shared_index_pool: i32

TriMesh shared index pool scalar (+0xD8).

§shared_index_size: i32

TriMesh shared index size scalar (+0xDC).

§indices_per_face: u32

TriMesh indices-per-face scalar (+0xE0). Vanilla value is typically 3.

§vertex_count: u16

Number of vertices declared in the mesh header.

§render: bool

Is this mesh renderable? (MdlNodeTriMesh +0x189).

§shadow: bool

Does this mesh cast shadows? (MdlNodeTriMesh +0x187).

Implementations§

Source§

impl MdlMesh

Source

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.

Source

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.

Source

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.

Source

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.

Source

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).

Source

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.

Trait Implementations§

Source§

impl Clone for MdlMesh

Source§

fn clone(&self) -> MdlMesh

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for MdlMesh

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for MdlMesh

Source§

fn default() -> MdlMesh

Returns the “default value” for a type. Read more
Source§

impl PartialEq for MdlMesh

Source§

fn eq(&self, other: &MdlMesh) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for MdlMesh

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Az for T

Source§

fn az<Dst>(self) -> Dst
where T: Cast<Dst>,

Casts the value.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<Src, Dst> CastFrom<Src> for Dst
where Src: Cast<Dst>,

Source§

fn cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> CheckedAs for T

Source§

fn checked_as<Dst>(self) -> Option<Dst>
where T: CheckedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> CheckedCastFrom<Src> for Dst
where Src: CheckedCast<Dst>,

Source§

fn checked_cast_from(src: Src) -> Option<Dst>

Casts the value.
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<T> OverflowingAs for T

Source§

fn overflowing_as<Dst>(self) -> (Dst, bool)
where T: OverflowingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> OverflowingCastFrom<Src> for Dst
where Src: OverflowingCast<Dst>,

Source§

fn overflowing_cast_from(src: Src) -> (Dst, bool)

Casts the value.
Source§

impl<T> SaturatingAs for T

Source§

fn saturating_as<Dst>(self) -> Dst
where T: SaturatingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> SaturatingCastFrom<Src> for Dst
where Src: SaturatingCast<Dst>,

Source§

fn saturating_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> StrictAs for T

Source§

fn strict_as<Dst>(self) -> Dst
where T: StrictCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> StrictCastFrom<Src> for Dst
where Src: StrictCast<Dst>,

Source§

fn strict_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> UnwrappedAs for T

Source§

fn unwrapped_as<Dst>(self) -> Dst
where T: UnwrappedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> UnwrappedCastFrom<Src> for Dst
where Src: UnwrappedCast<Dst>,

Source§

fn unwrapped_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> WrappingAs for T

Source§

fn wrapping_as<Dst>(self) -> Dst
where T: WrappingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> WrappingCastFrom<Src> for Dst
where Src: WrappingCast<Dst>,

Source§

fn wrapping_cast_from(src: Src) -> Dst

Casts the value.