M2Model

Struct M2Model 

Source
pub struct M2Model {
Show 45 fields pub header: M2Header, pub name: Option<String>, pub global_sequences: Vec<u32>, pub animations: Vec<M2Animation>, pub animation_lookup: Vec<u16>, pub bones: Vec<M2Bone>, pub key_bone_lookup: Vec<u16>, pub vertices: Vec<M2Vertex>, pub textures: Vec<M2Texture>, pub materials: Vec<M2Material>, pub particle_emitters: Vec<M2ParticleEmitter>, pub ribbon_emitters: Vec<M2RibbonEmitter>, pub texture_animations: Vec<M2TextureAnimation>, pub color_animations: Vec<M2ColorAnimation>, pub transparency_animations: Vec<M2TransparencyAnimation>, pub events: Vec<M2Event>, pub attachments: Vec<M2Attachment>, pub cameras: Vec<M2Camera>, pub lights: Vec<M2Light>, pub raw_data: M2RawData, pub skin_file_ids: Option<SkinFileIds>, pub animation_file_ids: Option<AnimationFileIds>, pub texture_file_ids: Option<TextureFileIds>, pub physics_file_id: Option<PhysicsFileId>, pub skeleton_file_id: Option<SkeletonFileId>, pub bone_file_ids: Option<BoneFileIds>, pub lod_data: Option<LodData>, pub extended_particle_data: Option<ExtendedParticleData>, pub parent_animation_blacklist: Option<ParentAnimationBlacklist>, pub parent_animation_data: Option<ParentAnimationData>, pub waterfall_effect: Option<WaterfallEffect>, pub edge_fade_data: Option<EdgeFadeData>, pub model_alpha_data: Option<ModelAlphaData>, pub lighting_details: Option<LightingDetails>, pub recursive_particle_ids: Option<RecursiveParticleIds>, pub geometry_particle_ids: Option<GeometryParticleIds>, pub texture_animation_chunk: Option<TextureAnimationChunk>, pub particle_geoset_data: Option<ParticleGeosetData>, pub dboc_chunk: Option<DbocChunk>, pub afra_chunk: Option<AfraChunk>, pub dpiv_chunk: Option<DpivChunk>, pub parent_sequence_bounds: Option<ParentSequenceBounds>, pub parent_event_data: Option<ParentEventData>, pub collision_mesh_data: Option<CollisionMeshData>, pub physics_file_data: Option<PhysicsFileDataChunk>,
}
Expand description

Main M2 model structure

Fields§

§header: M2Header

M2 header

§name: Option<String>

Model name

§global_sequences: Vec<u32>

Global sequences

§animations: Vec<M2Animation>

Animations

§animation_lookup: Vec<u16>

Animation lookups

§bones: Vec<M2Bone>

Bones

§key_bone_lookup: Vec<u16>

Key bone lookups

§vertices: Vec<M2Vertex>

Vertices

§textures: Vec<M2Texture>

Textures

§materials: Vec<M2Material>

Materials (render flags)

§particle_emitters: Vec<M2ParticleEmitter>

Particle emitters

§ribbon_emitters: Vec<M2RibbonEmitter>

Ribbon emitters

§texture_animations: Vec<M2TextureAnimation>

Texture animations

§color_animations: Vec<M2ColorAnimation>

Color animations

§transparency_animations: Vec<M2TransparencyAnimation>

Transparency animations

§events: Vec<M2Event>

Events

§attachments: Vec<M2Attachment>

Attachments

§cameras: Vec<M2Camera>

Cameras

§lights: Vec<M2Light>

Lights

§raw_data: M2RawData

Raw data for other sections This is used to preserve data that we don’t fully parse yet

§skin_file_ids: Option<SkinFileIds>

Chunked format data (Legion+ only) Contains FileDataID references for external files

§animation_file_ids: Option<AnimationFileIds>

Animation file IDs (Legion+ only)

§texture_file_ids: Option<TextureFileIds>

Texture file IDs (Legion+ only)

§physics_file_id: Option<PhysicsFileId>

Physics file ID (Legion+ only)

§skeleton_file_id: Option<SkeletonFileId>

Skeleton file ID (Legion+ only)

§bone_file_ids: Option<BoneFileIds>

Bone file IDs (Legion+ only)

§lod_data: Option<LodData>

Level of detail data (Legion+ only)

§extended_particle_data: Option<ExtendedParticleData>

Advanced rendering features (Legion+ only) Extended particle data (EXPT/EXP2 chunks)

§parent_animation_blacklist: Option<ParentAnimationBlacklist>

Parent animation blacklist (PABC chunk)

§parent_animation_data: Option<ParentAnimationData>

Parent animation data (PADC chunk)

§waterfall_effect: Option<WaterfallEffect>

Waterfall effects (WFV1/WFV2/WFV3 chunks)

§edge_fade_data: Option<EdgeFadeData>

Edge fade rendering (EDGF chunk)

§model_alpha_data: Option<ModelAlphaData>

Model alpha calculations (NERF chunk)

§lighting_details: Option<LightingDetails>

Lighting details (DETL chunk)

§recursive_particle_ids: Option<RecursiveParticleIds>

Recursive particle model IDs (RPID chunk)

§geometry_particle_ids: Option<GeometryParticleIds>

Geometry particle model IDs (GPID chunk)

§texture_animation_chunk: Option<TextureAnimationChunk>

Phase 7 specialized chunks TXAC texture animation chunk

§particle_geoset_data: Option<ParticleGeosetData>

PGD1 particle geoset data

§dboc_chunk: Option<DbocChunk>

DBOC chunk (purpose unknown)

§afra_chunk: Option<AfraChunk>

AFRA chunk (purpose unknown)

§dpiv_chunk: Option<DpivChunk>

DPIV chunk (collision mesh for player housing)

§parent_sequence_bounds: Option<ParentSequenceBounds>

PSBC chunk (parent sequence bounds)

§parent_event_data: Option<ParentEventData>

PEDC chunk (parent event data)

§collision_mesh_data: Option<CollisionMeshData>

PCOL chunk (collision mesh data)

§physics_file_data: Option<PhysicsFileDataChunk>

PFDC chunk (physics file data)

Implementations§

Source§

impl M2Model

Source

pub fn parse_embedded_skin( &self, original_m2_data: &[u8], skin_index: usize, ) -> Result<SkinFile>

Parse embedded skin profiles from pre-WotLK M2 models

For models with version <= 260, skin data is embedded in the M2 file itself. The views array contains ModelView structures with direct offsets to skin data.

Note: Many character models only have the first skin profile (index 0) properly embedded. Additional skin profiles may contain invalid data.

§Arguments
  • original_m2_data - The complete original M2 file data
  • skin_index - Index of the skin profile to extract (0-based)
§Returns

Returns the parsed SkinFile for the requested skin profile index

§Errors

Returns an error if the skin index is out of range or contains invalid data

§Example
// Load a pre-WotLK model
let m2_data = fs::read("HumanMale.m2")?;
let m2_format = parse_m2(&mut Cursor::new(&m2_data))?;
let model = m2_format.model();

if model.header.version <= 260 {
    // Parse the first embedded skin profile
    let skin = model.parse_embedded_skin(&m2_data, 0)?;
    println!("Embedded skin has {} submeshes", skin.submeshes().len());
}
Source

pub fn embedded_skin_count(&self) -> Option<u32>

Get the number of embedded skin profiles in a pre-WotLK model

Returns None if the model uses external skin files (version > 260)

Source

pub fn has_embedded_skins(&self) -> bool

Check if this model uses embedded skins (pre-WotLK) or external skin files

Source

pub fn parse_all_embedded_skins( &self, original_m2_data: &[u8], ) -> Result<Vec<SkinFile>>

Parse all embedded skin profiles from a pre-WotLK model

This is a convenience method that extracts all skin profiles at once.

§Arguments
  • original_m2_data - The complete original M2 file data
§Returns

A vector of all parsed skin profiles

Source§

impl M2Model

Source

pub fn parse_legacy<R: Read + Seek>(reader: &mut R) -> Result<Self>

Parse a legacy M2 model from a reader (MD20 format)

Source

pub fn parse_chunked<R: Read + Seek>(reader: &mut R) -> Result<Self>

Parse a chunked M2 model from a reader (MD21 format)

Source

pub fn parse<R: Read + Seek>(reader: &mut R) -> Result<Self>

Parse an M2 model from a reader

Source

pub fn load<P: AsRef<Path>>(path: P) -> Result<M2Format>

Load an M2 model from a file with format detection

Source

pub fn load_legacy<P: AsRef<Path>>(path: P) -> Result<Self>

Load a legacy M2 model from a file

Source

pub fn save<P: AsRef<Path>>(&self, path: P) -> Result<()>

Save an M2 model to a file

Source

pub fn write<W: Write + Seek>(&self, writer: &mut W) -> Result<()>

Write an M2 model to a writer

Source

pub fn convert(&self, target_version: M2Version) -> Result<Self>

Convert this model to a different version

Source

pub fn validate(&self) -> Result<()>

Validate the model structure

Source

pub fn has_external_files(&self) -> bool

Check if this model has external file references (Legion+ chunked format)

Source

pub fn skin_file_count(&self) -> usize

Get the number of skin files referenced

Source

pub fn animation_file_count(&self) -> usize

Get the number of animation files referenced

Source

pub fn texture_file_count(&self) -> usize

Get the number of texture files referenced

Source

pub fn resolve_skin_path( &self, index: usize, resolver: &dyn FileResolver, ) -> Result<String>

Resolve a skin file path by index using a FileResolver

Source

pub fn load_skin_file( &self, index: usize, resolver: &dyn FileResolver, ) -> Result<Vec<u8>>

Load a skin file by index using a FileResolver

Source

pub fn resolve_animation_path( &self, index: usize, resolver: &dyn FileResolver, ) -> Result<String>

Resolve an animation file path by index using a FileResolver

Source

pub fn load_animation_file( &self, index: usize, resolver: &dyn FileResolver, ) -> Result<Vec<u8>>

Load an animation file by index using a FileResolver

Source

pub fn resolve_texture_path( &self, index: usize, resolver: &dyn FileResolver, ) -> Result<String>

Resolve a texture file path by index using a FileResolver Falls back to embedded texture names for pre-Legion models

Source

pub fn load_texture_file( &self, index: usize, resolver: &dyn FileResolver, ) -> Result<Vec<u8>>

Load a texture file by index using a FileResolver Falls back to embedded texture names for pre-Legion models

Source

pub fn get_skin_file_ids(&self) -> Option<&[u32]>

Get all skin file IDs

Source

pub fn get_animation_file_ids(&self) -> Option<&[u32]>

Get all animation file IDs

Source

pub fn get_texture_file_ids(&self) -> Option<&[u32]>

Get all texture file IDs

Source

pub fn get_physics_file_id(&self) -> Option<u32>

Get the physics file ID

Source

pub fn get_skeleton_file_id(&self) -> Option<u32>

Get the skeleton file ID

Source

pub fn get_bone_file_ids(&self) -> Option<&[u32]>

Get all bone file IDs

Source

pub fn get_lod_data(&self) -> Option<&LodData>

Get the LOD data

Source

pub fn load_physics( &self, resolver: &dyn FileResolver, ) -> Result<Option<PhysicsData>>

Load physics data using a FileResolver

Source

pub fn load_skeleton( &self, resolver: &dyn FileResolver, ) -> Result<Option<SkeletonData>>

Load skeleton data using a FileResolver

Source

pub fn load_bone_data( &self, index: usize, resolver: &dyn FileResolver, ) -> Result<Option<BoneData>>

Load bone data by index using a FileResolver

Source

pub fn bone_file_count(&self) -> usize

Get the number of bone files referenced

Source

pub fn select_lod(&self, distance: f32) -> Option<&LodLevel>

Select the appropriate LOD level for a given distance

Source

pub fn has_lod_data(&self) -> bool

Check if the model has LOD data

Source

pub fn is_animation_blacklisted(&self, sequence_id: u16) -> bool

Check if an animation sequence is blacklisted

Source

pub fn get_extended_particle_data(&self) -> Option<&ExtendedParticleData>

Get extended particle data

Source

pub fn get_parent_animation_blacklist( &self, ) -> Option<&ParentAnimationBlacklist>

Get parent animation blacklist

Source

pub fn get_parent_animation_data(&self) -> Option<&ParentAnimationData>

Get parent animation data

Source

pub fn get_waterfall_effect(&self) -> Option<&WaterfallEffect>

Get waterfall effect data

Source

pub fn get_edge_fade_data(&self) -> Option<&EdgeFadeData>

Get edge fade data

Source

pub fn get_model_alpha_data(&self) -> Option<&ModelAlphaData>

Get model alpha data

Source

pub fn get_lighting_details(&self) -> Option<&LightingDetails>

Get lighting details

Source

pub fn get_recursive_particle_ids(&self) -> Option<&[u32]>

Get recursive particle model IDs

Source

pub fn get_geometry_particle_ids(&self) -> Option<&[u32]>

Get geometry particle model IDs

Source

pub fn load_particle_models( &self, file_resolver: &dyn FileResolver, ) -> Result<Vec<M2Model>>

Load particle models using a FileResolver This method implements recursion protection to avoid infinite loops

Source

pub fn get_parent_sequence_bounds(&self) -> Option<&ParentSequenceBounds>

Check if the model has any advanced rendering features Get parent sequence bounds data (PSBC chunk)

Source

pub fn get_parent_event_data(&self) -> Option<&ParentEventData>

Get parent event data (PEDC chunk)

Source

pub fn get_collision_mesh_data(&self) -> Option<&CollisionMeshData>

Get collision mesh data (PCOL chunk)

Source

pub fn get_physics_file_data(&self) -> Option<&PhysicsFileDataChunk>

Get physics file data (PFDC chunk)

Source

pub fn has_advanced_features(&self) -> bool

Check if model has advanced features (Legion+)

Source§

impl M2Model

Source

pub fn parse_all_data(&self, original_data: &[u8]) -> Result<EnhancedModelData>

Parse all available data from the M2 model

This method extracts all vertices, bones, animations, textures, and materials from the model, and for vanilla models (version 256), also extracts embedded skin data.

§Arguments
  • original_data - The complete original M2 file data (required for embedded skins)
§Returns

Returns EnhancedModelData containing all extracted model information

§Example
let m2_data = fs::read("HumanMale.m2")?;
let m2_format = parse_m2(&mut Cursor::new(&m2_data))?;
let model = m2_format.model();

// Extract all model data
let enhanced_data = model.parse_all_data(&m2_data)?;

println!("Model has {} vertices, {} bones, {} animations",
    enhanced_data.vertices.len(),
    enhanced_data.bones.len(),
    enhanced_data.animations.len());
Source

pub fn display_info(&self, enhanced_data: &EnhancedModelData)

Display comprehensive model information

This method prints detailed information about the model including all its components.

§Arguments
  • enhanced_data - The enhanced model data to display
§Example
let m2_data = fs::read("HumanMale.m2")?;
let m2_format = parse_m2(&mut Cursor::new(&m2_data))?;
let model = m2_format.model();

let enhanced_data = model.parse_all_data(&m2_data)?;
model.display_info(&enhanced_data);

Trait Implementations§

Source§

impl Clone for M2Model

Source§

fn clone(&self) -> M2Model

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 M2Model

Source§

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

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

impl Default for M2Model

Source§

fn default() -> Self

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

impl M2ModelAnimationExt for M2Model

Source§

fn resolve_bone_animations( &self, data: &[u8], ) -> Result<Vec<ResolvedBoneAnimation>>

Resolve all bone animation data from the model
Source§

fn get_bind_pose(&self, data: &[u8]) -> Result<Vec<ResolvedBoneAnimation>>

Get bind pose for all bones (no animation, just rest position)

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> 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<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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<R, P> ReadPrimitive<R> for P
where R: Read + ReadEndian<P>, P: Default,

Source§

fn read_from_little_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_little_endian().
Source§

fn read_from_big_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_big_endian().
Source§

fn read_from_native_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_native_endian().
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.