use crate::{
msrd::Streaming,
parse_count32_offset32, parse_offset32_count32, parse_opt_ptr32, parse_ptr32,
parse_string_opt_ptr32, parse_string_ptr32,
spch::Spch,
vertex::{DataType, VertexData},
xc3_write_binwrite_impl,
};
use bilge::prelude::*;
use binrw::{args, binread, BinRead, BinWrite};
use xc3_write::{Xc3Write, Xc3WriteOffsets};
#[derive(Debug, BinRead, Xc3Write)]
#[br(magic(b"DMXM"))]
#[xc3(magic(b"DMXM"))]
pub struct Mxmd {
#[br(assert(version == 10111 || version == 10112))]
pub version: u32,
#[br(parse_with = parse_ptr32, args { inner: version })]
#[xc3(offset(u32), align(16))]
pub models: Models,
#[br(parse_with = parse_ptr32)]
#[xc3(offset(u32), align(16))]
pub materials: Materials,
#[br(parse_with = parse_opt_ptr32)]
#[xc3(offset(u32), align(16))]
pub unk1: Option<Unk1>,
#[br(parse_with = parse_opt_ptr32)]
#[xc3(offset(u32))]
pub vertex_data: Option<VertexData>,
#[br(parse_with = parse_opt_ptr32)]
#[xc3(offset(u32))]
pub spch: Option<Spch>,
#[br(parse_with = parse_opt_ptr32)]
#[xc3(offset(u32))]
pub packed_textures: Option<PackedTextures>,
pub unk5: u32,
#[br(parse_with = parse_opt_ptr32)]
#[xc3(offset(u32))]
pub streaming: Option<Streaming>,
pub unk: [u32; 9],
}
#[binread]
#[derive(Debug, Xc3Write)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct Materials {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_offset32_count32, args { offset: base_offset, inner: base_offset })]
#[xc3(offset_count(u32, u32), align(4))]
pub materials: Vec<Material>,
pub unk1: u32,
pub unk2: u32,
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32), align(4))]
pub floats: Vec<f32>, #[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub ints: Vec<(u16, u16)>, #[br(parse_with = parse_opt_ptr32)]
#[br(args { offset: base_offset, inner: base_offset })]
#[xc3(offset(u32))]
pub material_unk1: Option<MaterialUnk1>, pub unk4: u32,
#[br(parse_with = parse_offset32_count32, args { offset: base_offset, inner: base_offset })]
#[xc3(offset_count(u32, u32))]
pub shader_programs: Vec<ShaderProgramInfo>,
pub unks1: [u32; 2],
#[br(parse_with = parse_count32_offset32, offset = base_offset)]
#[xc3(count_offset(u32, u32))]
pub alpha_test_textures: Vec<AlphaTestTexture>,
pub unks3: [u32; 3],
#[br(parse_with = parse_opt_ptr32)]
#[br(args { offset: base_offset, inner: base_offset })]
#[xc3(offset(u32))]
pub material_unk2: Option<MaterialUnk2>,
#[br(parse_with = parse_opt_ptr32)]
#[br(args { offset: base_offset, inner: base_offset })]
#[xc3(offset(u32))]
pub material_unk3: Option<MaterialUnk3>,
pub unks3_1: [u32; 2],
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub samplers: Option<Samplers>,
pub unks4: [u32; 3],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct AlphaTestTexture {
pub texture_index: u16,
pub unk1: u16,
pub unk2: u32,
}
#[derive(Debug, BinRead, Xc3Write)]
#[br(import_raw(base_offset: u64))]
pub struct ShaderProgramInfo {
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub attributes: Vec<VertexAttribute>,
pub unk3: u32, pub unk4: u32, #[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub parameters: Vec<MaterialParameter>, #[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub textures: Vec<u16>, #[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub uniform_blocks: Vec<(u16, u16)>, pub unk11: u32, pub unk12: u16, pub unk13: u16, pub padding: [u32; 5],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct VertexAttribute {
pub data_type: DataType,
pub relative_offset: u16,
pub buffer_index: u16,
pub unk4: u16, }
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct MaterialParameter {
pub param_type: ParamType,
pub floats_index_offset: u16, pub unk: u16,
pub count: u16, }
#[derive(Debug, BinRead, BinWrite, Clone, Copy, PartialEq, Eq, Hash)]
#[brw(repr(u16))]
pub enum ParamType {
Unk0 = 0,
TexMatrix = 1,
WorkFloat4 = 2,
WorkColor = 3,
Unk4 = 4,
Unk5 = 5,
Unk6 = 6,
Unk7 = 7,
Unk10 = 10,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct MaterialUnk1 {
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub unk1: Vec<(u16, u16)>,
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub unk2: Vec<u16>,
pub unk: [u32; 8],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct MaterialUnk2 {
#[br(parse_with = parse_count32_offset32, offset = base_offset)]
#[xc3(count_offset(u32, u32))]
pub unk1: Vec<[u32; 3]>,
pub unk: [u32; 4],
}
#[derive(Debug, BinRead, Xc3Write)]
#[br(import_raw(base_offset: u64))]
pub struct MaterialUnk3 {
#[br(parse_with = parse_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub unk1: [u32; 8],
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub unk2: Vec<[f32; 5]>,
pub unk: [u32; 4],
}
#[binread]
#[derive(Debug, Xc3Write, Xc3WriteOffsets)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct Samplers {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_count32_offset32, offset = base_offset)]
#[xc3(count_offset(u32, u32))]
pub samplers: Vec<Sampler>,
pub unk: [u32; 2],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct Sampler {
pub flags: SamplerFlags,
pub unk2: f32,
}
#[bitsize(32)]
#[derive(DebugBits, FromBits, BinRead, BinWrite, Clone, Copy)]
#[br(map = u32::into)]
#[bw(map = |&x| u32::from(x))]
pub struct SamplerFlags {
pub repeat_u: bool,
pub repeat_v: bool,
pub mirror_u: bool,
pub mirror_v: bool,
pub nearest: bool,
pub force_clamp: bool,
pub disable_mipmap_filter: bool,
pub unk1: bool,
pub unk3: bool,
pub unk: u23,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct Material {
#[br(parse_with = parse_string_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub name: String,
pub flags: MaterialFlags,
pub render_flags: u32,
pub color: [f32; 4],
pub alpha_test_ref: [u8; 4],
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub textures: Vec<Texture>,
pub state_flags: StateFlags,
pub m_unks1_1: u32,
pub m_unks1_2: u32,
pub m_unks1_3: u32,
pub m_unks1_4: u32,
pub floats_start_index: u32, pub ints_start_index: u32,
pub ints_count: u32,
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub shader_programs: Vec<ShaderProgram>,
pub unk5: u32,
pub unk_start_index: u16, pub unk_count: u16,
pub m_unks2: [u16; 3],
pub alpha_test_texture_index: u16,
pub m_unks3: [u16; 8],
}
#[bitsize(32)]
#[derive(DebugBits, FromBits, BinRead, BinWrite, Clone, Copy)]
#[br(map = u32::into)]
#[bw(map = |&x| u32::from(x))]
pub struct MaterialFlags {
pub unk1: bool,
pub unk2: bool,
pub alpha_mask: bool,
pub separate_mask: bool,
pub unk: u28,
}
#[derive(Debug, BinRead, BinWrite, Clone, Copy, PartialEq, Eq, Hash)]
pub struct StateFlags {
pub flag0: u8, pub blend_state: BlendState,
pub cull_mode: CullMode,
pub flag3: u8, pub stencil_state1: StencilState1,
pub stencil_state2: StencilState2,
pub depth_func: DepthFunc,
pub flag7: u8, }
#[derive(Debug, BinRead, BinWrite, Clone, Copy, PartialEq, Eq, Hash)]
#[brw(repr(u8))]
pub enum BlendState {
Disabled = 0,
AlphaBlend = 1,
Additive = 2,
Multiplicative = 3,
Unk6 = 6, }
#[derive(Debug, BinRead, BinWrite, Clone, Copy, PartialEq, Eq, Hash)]
#[brw(repr(u8))]
pub enum StencilState1 {
Always = 0,
Unk1 = 1,
Always2 = 4,
Unk5 = 5,
Unk8 = 8,
Unk9 = 9,
UnkHair = 16,
Unk20 = 20,
}
#[derive(Debug, BinRead, BinWrite, Clone, Copy, PartialEq, Eq, Hash)]
#[brw(repr(u8))]
pub enum StencilState2 {
Disabled = 0,
Enabled = 1,
Unk2 = 2,
Unk6 = 6,
Unk7 = 7,
Unk8 = 8,
}
#[derive(Debug, BinRead, BinWrite, Clone, Copy, PartialEq, Eq, Hash)]
#[brw(repr(u8))]
pub enum DepthFunc {
Disabled = 0,
LessEqual = 1,
Equal = 3,
}
#[derive(Debug, BinRead, BinWrite, Clone, Copy, PartialEq, Eq, Hash)]
#[brw(repr(u8))]
pub enum CullMode {
Back = 0,
Front = 1,
Disabled = 2,
Unk3 = 3, }
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct ShaderProgram {
pub program_index: u32,
pub unk_type: ShaderUnkType,
pub material_buffer_index: u16,
pub flags: u32, }
#[derive(Debug, BinRead, BinWrite, PartialEq, Eq, Clone, Copy, Hash)]
#[brw(repr(u16))]
pub enum ShaderUnkType {
Unk0 = 0, Unk1 = 1, Unk6 = 6, Unk7 = 7, Unk9 = 9, }
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct Texture {
pub texture_index: u16,
pub sampler_index: u16,
pub unk2: u16,
pub unk3: u16,
}
#[binread]
#[derive(Debug, Xc3Write)]
#[br(stream = r)]
#[br(import_raw(version: u32))]
#[xc3(base_offset)]
pub struct Models {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(if(version != 10111))]
pub models_flags: Option<ModelsFlags>,
pub max_xyz: [f32; 3],
pub min_xyz: [f32; 3],
#[br(restore_position)]
#[xc3(skip)]
pub models_offset: u32,
#[br(parse_with = parse_offset32_count32, args { offset: base_offset, inner: base_offset })]
#[xc3(offset_count(u32, u32))]
pub models: Vec<Model>,
pub unk2: u32,
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub skinning: Option<Skinning>,
pub unks3_1: [u32; 14],
#[br(parse_with = parse_offset32_count32, args { offset: base_offset, inner: base_offset })]
#[xc3(offset_count(u32, u32), align(16))]
pub model_unks: Vec<ModelUnk>,
pub unks3_2: [u32; 2],
#[br(parse_with = parse_opt_ptr32)]
#[br(args { offset: base_offset, inner: base_offset })]
#[xc3(offset(u32))]
pub model_unk8: Option<ModelUnk8>,
pub unk3_3: u32,
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub model_unk7: Option<ModelUnk7>,
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32), align(16))]
pub morph_controllers: Option<MorphControllers>,
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32), align(16))]
pub model_unk1: Option<ModelUnk1>,
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub model_unk3: Option<ModelUnk3>,
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32), align(16))]
pub lod_data: Option<LodData>,
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32), align(16))]
pub model_unk4: Option<ModelUnk4>,
pub unk_field2: u32,
pub model_unk9: [u32; 2],
#[br(args { size: models_offset, base_offset})]
#[br(if(version > 10111))]
pub extra: Option<ModelsExtraData>,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import { size: u32, base_offset: u64 })]
pub enum ModelsExtraData {
#[br(pre_assert(size == 160))]
Unk1,
#[br(pre_assert(size == 164))]
Unk2(#[br(args_raw(base_offset))] ModelsExtraDataUnk2),
#[br(pre_assert(size == 168))]
Unk3(#[br(args_raw(base_offset))] ModelsExtraDataUnk3),
#[br(pre_assert(size == 200))]
Unk4(#[br(args_raw(base_offset))] ModelsExtraDataUnk4),
#[br(pre_assert(size == 204))]
Unk5(#[br(args_raw(base_offset))] ModelsExtraDataUnk5),
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct ModelsExtraDataUnk2 {
#[br(parse_with = parse_opt_ptr32)]
#[br(args { offset: base_offset, inner: base_offset })]
#[xc3(offset(u32))]
pub model_unk10: Option<ModelUnk10>,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct ModelsExtraDataUnk3 {
#[br(parse_with = parse_opt_ptr32)]
#[br(args { offset: base_offset, inner: base_offset })]
#[xc3(offset(u32))]
pub model_unk10: Option<ModelUnk10>,
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub model_unk5: Option<ModelUnk5>,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct ModelsExtraDataUnk4 {
#[br(parse_with = parse_opt_ptr32)]
#[br(args { offset: base_offset, inner: base_offset })]
#[xc3(offset(u32))]
pub model_unk10: Option<ModelUnk10>,
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub model_unk5: Option<ModelUnk5>,
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub model_unk6: Option<ModelUnk6>,
pub unk: Option<[u32; 7]>,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct ModelsExtraDataUnk5 {
#[br(parse_with = parse_opt_ptr32)]
#[br(args { offset: base_offset, inner: base_offset })]
#[xc3(offset(u32))]
pub model_unk10: Option<ModelUnk10>,
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub model_unk5: Option<ModelUnk5>,
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub model_unk6: Option<ModelUnk6>,
pub unk: Option<[u32; 8]>,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct Model {
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub meshes: Vec<Mesh>,
pub unk1: u32,
pub max_xyz: [f32; 3],
pub min_xyz: [f32; 3],
pub bounding_radius: f32,
pub unks: [u32; 7],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct Mesh {
pub render_flags: u32,
pub skin_flags: u32, pub vertex_buffer_index: u16,
pub index_buffer_index: u16,
pub unk_index: u16,
pub material_index: u16,
pub unk2: u32,
pub unk3: u32,
pub unk4: u32,
pub unk5: u16,
pub lod: u16, pub unks6: [i32; 4],
}
#[bitsize(32)]
#[derive(DebugBits, FromBits, BinRead, BinWrite, Clone, Copy)]
#[br(map = u32::into)]
#[bw(map = |&x| u32::from(x))]
pub struct ModelsFlags {
pub unk1: bool,
pub has_model_unk8: bool,
pub unk3: bool,
pub unk4: bool,
pub unk5: bool,
pub unk6: bool,
pub has_model_unk7: bool,
pub unk8: bool,
pub unk9: bool,
pub unk10: bool,
pub has_morph_controllers: bool,
pub has_model_unk1: bool,
pub has_model_unk3: bool,
pub unk14: bool,
pub unk15: bool,
pub has_skinning: bool,
pub unk17: bool,
pub has_lod_data: bool,
pub has_model_unk4: bool,
pub unk20: bool,
pub unk21: bool,
pub unk22: bool,
pub unk23: bool,
pub unk24: bool,
pub unk25: bool,
pub unk26: bool,
pub unk27: bool,
pub unk28: bool,
pub unk29: bool,
pub unk30: bool,
pub unk31: bool,
pub unk32: bool,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct ModelUnk {
#[br(parse_with = parse_string_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
name1: String,
#[br(parse_with = parse_string_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
name2: String,
unk1: u16,
unk2: u16,
unk3: u32,
}
#[binread]
#[derive(Debug, Xc3Write, Xc3WriteOffsets)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct MorphControllers {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_offset32_count32, args { offset: base_offset, inner: base_offset })]
#[xc3(offset_count(u32, u32))]
controllers: Vec<MorphController>,
unk1: u32,
unk: [u32; 3],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct MorphController {
#[br(parse_with = parse_string_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
name1: String,
#[br(parse_with = parse_string_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
name2: Option<String>,
unk1: u16,
unk2: u16, unk3: u16, unk4: u16,
unk: [u32; 3],
}
#[binread]
#[derive(Debug, Xc3Write, Xc3WriteOffsets)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct ModelUnk3 {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_count32_offset32, args { offset: base_offset, inner: base_offset })]
#[xc3(count_offset(u32, u32))]
pub items: Vec<ModelUnk3Item>,
pub unk: [u32; 4],
}
#[derive(Debug, BinRead, Xc3Write)]
#[br(import_raw(base_offset: u64))]
pub struct ModelUnk3Item {
#[br(parse_with = parse_string_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub name: String,
pub unk1: u32, pub unk2: u32,
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub unk3: Vec<u16>,
}
#[binread]
#[derive(Debug, Xc3Write, Xc3WriteOffsets)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct ModelUnk4 {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub items: Vec<(u16, u16)>,
pub unks: [u32; 4],
}
#[binread]
#[derive(Debug, Xc3Write, Xc3WriteOffsets)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct ModelUnk5 {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_count32_offset32)]
#[br(args { offset: base_offset, inner: base_offset })]
#[xc3(count_offset(u32, u32))]
pub items: Vec<StringOffset>,
pub unks: [u32; 4],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct StringOffset {
#[br(parse_with = parse_string_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub name: String,
}
#[binread]
#[derive(Debug, Xc3Write, Xc3WriteOffsets)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct ModelUnk6 {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_count32_offset32, offset = base_offset)]
#[xc3(count_offset(u32, u32))]
pub items: Vec<[u32; 2]>,
pub unks: [u32; 4],
}
#[binread]
#[derive(Debug, Xc3Write, Xc3WriteOffsets)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct ModelUnk7 {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_count32_offset32, offset = base_offset)]
#[xc3(count_offset(u32, u32))]
pub items: Vec<[f32; 9]>,
pub unks: [u32; 4],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct ModelUnk8 {
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub unk1: Vec<[u32; 5]>,
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub unk2: Vec<[f32; 4]>,
pub unks: [u32; 2],
}
#[binread]
#[derive(Debug, Xc3Write, Xc3WriteOffsets)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct ModelUnk9 {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_count32_offset32, args { offset: base_offset, inner: base_offset })]
#[xc3(count_offset(u32, u32))]
pub items: Vec<ModelUnk9Item>,
pub unk: [u32; 4],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct ModelUnk10 {
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub unk1: Vec<u32>,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct ModelUnk9Item {
#[br(parse_with = parse_string_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub name: String,
pub unk1: u32,
pub unk2: u32,
pub unk3: u32,
pub unk4: u32,
}
#[binread]
#[derive(Debug, Xc3Write)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct ModelUnk1 {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_offset32_count32)]
#[br(args { offset: base_offset, inner: base_offset })]
#[xc3(offset_count(u32, u32))]
pub items1: Vec<ModelUnk1Item1>,
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub items2: Vec<ModelUnk1Item2>,
#[br(parse_with = parse_ptr32)]
#[br(args { offset: base_offset, inner: args! { count: items1.len() }})]
#[xc3(offset(u32))]
pub items3: Vec<f32>,
pub unk1: u32, #[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub items4: Vec<[u32; 5]>,
pub unk4: u32,
pub unk5: u32,
#[br(if(unk4 != 0 || unk5 != 0))]
#[br(args_raw(base_offset))]
pub extra: Option<ModelUnk1Extra>,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct ModelUnk1Extra {
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub unk_inner: Option<ModelUnk1Inner>,
pub unk: [u32; 4],
}
#[binread]
#[derive(Debug, Xc3Write, Xc3WriteOffsets)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct ModelUnk1Inner {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub items1: Vec<(u16, u16)>,
#[br(parse_with = parse_ptr32)]
#[br(args {
offset: base_offset,
inner: args! {
count: items1.iter().map(|(a,_)| *a).max().unwrap_or_default() as usize
}
})]
#[xc3(offset(u32))]
pub unk_offset: Vec<u16>,
pub unks: [u32; 5],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct ModelUnk1Item1 {
#[br(parse_with = parse_string_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub name: String,
pub unk: [u32; 3],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct ModelUnk1Item2 {
pub unk1: u32,
pub unk2: u32,
pub unk3: u32,
pub unk4: u32,
pub unk5: u32,
}
#[binread]
#[derive(Debug, Xc3Write)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct LodData {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
pub unk1: u32, #[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32), align(8))]
pub items1: Vec<LodItem1>,
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub groups: Vec<LodGroup>,
pub unks: [u32; 4],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct LodItem1 {
pub unk1: [u32; 4],
pub unk2: f32,
pub unk3: [u8; 4],
pub unk4: [u32; 2],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct LodGroup {
pub base_lod_index: u16,
pub lod_count: u16,
pub unk1: u32,
pub unk2: u32,
}
#[binread]
#[derive(Debug, Xc3Write)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct PackedTextures {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_count32_offset32, args { offset: base_offset, inner: base_offset })]
#[xc3(count_offset(u32, u32))]
pub textures: Vec<PackedTexture>,
pub unk2: u32,
#[xc3(shared_offset)]
pub strings_offset: u32,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct PackedTexture {
pub usage: TextureUsage,
#[br(parse_with = parse_count32_offset32, offset = base_offset)]
#[xc3(count_offset(u32, u32), align(4096))]
pub mibl_data: Vec<u8>,
#[br(parse_with = parse_string_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub name: String,
}
#[binread]
#[derive(Debug, Xc3Write, Clone, PartialEq)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct PackedExternalTextures {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_count32_offset32, args { offset: base_offset, inner: base_offset })]
#[xc3(count_offset(u32, u32), align(2))]
pub textures: Vec<PackedExternalTexture>,
pub unk2: u32, #[xc3(shared_offset)]
pub strings_offset: u32,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets, Clone, PartialEq)]
#[br(import_raw(base_offset: u64))]
pub struct PackedExternalTexture {
pub usage: TextureUsage,
pub mibl_length: u32,
pub mibl_offset: u32,
#[br(parse_with = parse_string_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub name: String,
}
#[derive(Debug, BinRead, BinWrite, Clone, Copy, PartialEq, Eq, Hash)]
#[brw(repr(u32))]
pub enum TextureUsage {
Unk0 = 0,
Temp = 1048576,
Unk6 = 1074790400,
Nrm = 1179648,
Unk13 = 131072,
WavePlus = 136314882,
Col = 2097152,
Unk8 = 2162689,
Alp = 2228224,
Unk = 268435456,
Alp2 = 269484032,
Col2 = 270532608,
Unk11 = 270663680,
Unk9 = 272629760,
Alp3 = 273678336,
Nrm2 = 273809408,
Col3 = 274726912,
Unk3 = 274857984,
Unk2 = 275775488,
Unk20 = 287309824,
Unk17 = 3276800,
F01 = 403701762, Unk4 = 4194304,
Unk7 = 536870912,
Unk15 = 537001984,
Temp2 = 537919488,
Unk14 = 538050560,
Col4 = 538968064,
Alp4 = 539099136,
Unk12 = 540147712,
Unk18 = 65537,
Unk19 = 805306368,
Unk5 = 807403520,
Unk10 = 807534592,
VolTex = 811597824,
Unk16 = 811728896,
}
#[binread]
#[derive(Debug, Xc3Write)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct Skinning {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
pub count1: u32,
pub count2: u32,
#[br(temp, restore_position)]
bones_offset: u32,
#[br(parse_with = parse_ptr32)]
#[br(args {
offset: base_offset,
inner: args! { count: count1 as usize, inner: base_offset }
})]
#[xc3(offset(u32))]
pub bones: Vec<Bone>,
#[br(parse_with = parse_ptr32)]
#[br(args { offset: base_offset, inner: args! { count: count1 as usize } })]
#[xc3(offset(u32), align(16))]
pub inverse_bind_transforms: Vec<[[f32; 4]; 4]>,
#[br(temp, restore_position)]
offsets: [u32; 2],
#[br(parse_with = parse_opt_ptr32)]
#[br(args {
offset: base_offset,
inner: args! {
count: if offsets[1] > 0 { (offsets[1] - offsets[0]) as usize / 16 } else { 0 }
}
})]
#[xc3(offset(u32))]
pub transforms2: Option<Vec<[f32; 4]>>,
#[br(parse_with = parse_opt_ptr32)]
#[br(args {
offset: base_offset,
inner: args! { count: bones.iter().map(|b| b.unk_index as usize + 1).max().unwrap_or_default() }
})]
#[xc3(offset(u32))]
pub transforms3: Option<Vec<[[f32; 4]; 2]>>,
#[br(parse_with = parse_count32_offset32, offset = base_offset)]
#[xc3(count_offset(u32, u32))]
pub bone_indices: Vec<u16>,
#[br(if(transforms2.is_some()))]
#[br(args_raw(base_offset))]
pub unk_offset4: Option<SkinningUnkBones>,
#[br(if(transforms3.is_some()))]
#[br(args_raw(base_offset))]
pub unk_offset5: Option<SkinningUnk5>,
#[br(if(!bone_indices.is_empty()))]
#[br(args_raw(base_offset))]
pub as_bone_data: Option<SkinningAsBoneData>,
#[br(if(bones_offset == 60))]
pub unk: Option<[u32; 4]>,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct SkinningUnkBones {
#[br(parse_with = parse_opt_ptr32)]
#[br(args { offset: base_offset, inner: base_offset })]
#[xc3(offset(u32))]
pub unk_offset4: Option<UnkBones>,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct SkinningUnk5 {
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub unk_offset5: Option<SkeletonUnk5>,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct SkinningAsBoneData {
#[br(parse_with = parse_opt_ptr32, args { offset: base_offset, inner: base_offset })]
#[xc3(offset(u32))]
pub as_bone_data: Option<AsBoneData>,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct Bone {
#[br(parse_with = parse_string_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub name: String,
pub unk1: f32,
pub unk_type: (u16, u16),
pub unk_index: u32,
pub unk: [u32; 2],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct UnkBones {
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub bones: Vec<UnkBone>,
#[br(parse_with = parse_ptr32)]
#[br(args { offset: base_offset, inner: args! { count: bones.len() }})]
#[xc3(offset(u32))]
pub unk_offset: Vec<[[f32; 4]; 4]>,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct UnkBone {
pub unk1: u32,
pub bone_index: u16,
pub parent_index: u16,
pub unks: [u32; 7],
}
#[binread]
#[derive(Debug, Xc3Write, Xc3WriteOffsets)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct SkeletonUnk5 {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_count32_offset32, offset = base_offset)]
#[xc3(count_offset(u32, u32))]
pub unk1: Vec<[u16; 105]>,
#[br(parse_with = parse_opt_ptr32, offset = base_offset)]
#[xc3(offset(u32))]
pub unk_offset: Option<[f32; 12]>,
pub unk: [u32; 5],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
#[br(import_raw(base_offset: u64))]
pub struct AsBoneData {
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub bones: Vec<AsBone>,
#[br(parse_with = parse_offset32_count32, offset = base_offset)]
#[xc3(offset_count(u32, u32))]
pub unk1: Vec<AsBoneValue>,
#[br(parse_with = parse_ptr32)]
#[br(args { offset: base_offset, inner: args! { count: bones.len() * 3 }})]
#[xc3(offset(u32))]
pub unk2: Vec<[[f32; 4]; 4]>,
pub unk3: u32,
pub unk: [u32; 2],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct AsBone {
pub bone_index: u16,
pub parent_index: u16,
pub unk: [u32; 19],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct AsBoneValue {
unk1: [f32; 4],
unk2: [f32; 4],
unk3: [f32; 4],
unk4: [f32; 2],
}
#[binread]
#[derive(Debug, Xc3Write)]
#[br(stream = r)]
#[xc3(base_offset)]
pub struct Unk1 {
#[br(temp, try_calc = r.stream_position())]
base_offset: u64,
#[br(parse_with = parse_count32_offset32, offset = base_offset)]
#[xc3(count_offset(u32, u32))]
pub unk1: Vec<Unk1Unk1>,
#[br(parse_with = parse_count32_offset32, offset = base_offset)]
#[xc3(count_offset(u32, u32))]
pub unk2: Vec<Unk1Unk2>,
#[br(parse_with = parse_count32_offset32, offset = base_offset)]
#[xc3(count_offset(u32, u32))]
pub unk3: Vec<Unk1Unk3>,
#[br(parse_with = parse_count32_offset32, offset = base_offset)]
#[xc3(count_offset(u32, u32))]
pub unk4: Vec<Unk1Unk4>,
pub unk: [u32; 4],
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct Unk1Unk1 {
pub index: u16,
pub unk2: u16, }
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct Unk1Unk2 {
pub unk1: u16, pub index: u16,
pub unk3: u16,
pub unk4: u16,
pub unk5: u32, }
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct Unk1Unk3 {
pub unk1: u16,
pub unk2: u16,
pub unk3: u32,
pub unk4: u16,
pub unk5: u16,
pub unk6: u16,
pub unk7: u16,
}
#[derive(Debug, BinRead, Xc3Write, Xc3WriteOffsets)]
pub struct Unk1Unk4 {
pub unk1: f32,
pub unk2: f32,
pub unk3: f32,
pub unk4: u32,
}
xc3_write_binwrite_impl!(
ParamType,
ShaderUnkType,
StateFlags,
ModelsFlags,
SamplerFlags,
TextureUsage
);
impl Xc3Write for MaterialFlags {
type Offsets<'a> = ();
fn xc3_write<W: std::io::Write + std::io::Seek>(
&self,
writer: &mut W,
data_ptr: &mut u64,
) -> xc3_write::Xc3Result<Self::Offsets<'_>> {
u32::from(*self).write_le(writer)?;
*data_ptr = (*data_ptr).max(writer.stream_position()?);
Ok(())
}
}
impl<'a> Xc3WriteOffsets for SkinningOffsets<'a> {
fn write_offsets<W: std::io::Write + std::io::Seek>(
&self,
writer: &mut W,
_base_offset: u64,
data_ptr: &mut u64,
) -> xc3_write::Xc3Result<()> {
let base_offset = self.base_offset;
let bones = self.bones.write_offset(writer, base_offset, data_ptr)?;
if !self.bone_indices.data.is_empty() {
self.bone_indices
.write_full(writer, base_offset, data_ptr)?;
}
self.inverse_bind_transforms
.write_full(writer, base_offset, data_ptr)?;
self.transforms2.write_full(writer, base_offset, data_ptr)?;
self.transforms3.write_full(writer, base_offset, data_ptr)?;
self.unk_offset4
.write_offsets(writer, base_offset, data_ptr)?;
self.as_bone_data
.write_offsets(writer, base_offset, data_ptr)?;
self.unk_offset5
.write_offsets(writer, base_offset, data_ptr)?;
for bone in bones.0 {
bone.name.write_full(writer, base_offset, data_ptr)?;
}
Ok(())
}
}
impl<'a> Xc3WriteOffsets for ModelUnk1Offsets<'a> {
fn write_offsets<W: std::io::Write + std::io::Seek>(
&self,
writer: &mut W,
_base_offset: u64,
data_ptr: &mut u64,
) -> xc3_write::Xc3Result<()> {
let base_offset = self.base_offset;
let items1 = self.items1.write_offset(writer, base_offset, data_ptr)?;
self.items3.write_full(writer, base_offset, data_ptr)?;
if !self.items2.data.is_empty() {
self.items2.write_full(writer, base_offset, data_ptr)?;
}
if !self.items4.data.is_empty() {
self.items4.write_full(writer, base_offset, data_ptr)?;
}
for item in items1.0 {
item.name.write_full(writer, base_offset, data_ptr)?;
}
self.extra.write_offsets(writer, base_offset, data_ptr)?;
Ok(())
}
}
impl<'a> Xc3WriteOffsets for LodDataOffsets<'a> {
fn write_offsets<W: std::io::Write + std::io::Seek>(
&self,
writer: &mut W,
_base_offset: u64,
data_ptr: &mut u64,
) -> xc3_write::Xc3Result<()> {
let base_offset = self.base_offset;
self.groups.write_full(writer, base_offset, data_ptr)?;
self.items1.write_full(writer, base_offset, data_ptr)?;
Ok(())
}
}
impl<'a> Xc3WriteOffsets for ModelsOffsets<'a> {
fn write_offsets<W: std::io::Write + std::io::Seek>(
&self,
writer: &mut W,
_base_offset: u64,
data_ptr: &mut u64,
) -> xc3_write::Xc3Result<()> {
let base_offset = self.base_offset;
self.models.write_full(writer, base_offset, data_ptr)?;
self.skinning.write_full(writer, base_offset, data_ptr)?;
if !self.model_unks.data.is_empty() {
self.model_unks.write_full(writer, base_offset, data_ptr)?;
}
self.model_unk8.write_full(writer, base_offset, data_ptr)?;
self.morph_controllers
.write_full(writer, base_offset, data_ptr)?;
self.lod_data.write_full(writer, base_offset, data_ptr)?;
self.model_unk7.write_full(writer, base_offset, data_ptr)?;
self.model_unk1.write_full(writer, base_offset, data_ptr)?;
self.model_unk4.write_full(writer, base_offset, data_ptr)?;
self.model_unk3.write_full(writer, base_offset, data_ptr)?;
self.extra.write_offsets(writer, base_offset, data_ptr)?;
Ok(())
}
}
impl<'a> Xc3WriteOffsets for ShaderProgramInfoOffsets<'a> {
fn write_offsets<W: std::io::Write + std::io::Seek>(
&self,
writer: &mut W,
base_offset: u64,
data_ptr: &mut u64,
) -> xc3_write::Xc3Result<()> {
self.attributes.write_full(writer, base_offset, data_ptr)?;
if !self.textures.data.is_empty() {
self.textures.write_full(writer, base_offset, data_ptr)?;
}
self.uniform_blocks
.write_full(writer, base_offset, data_ptr)?;
self.parameters.write_full(writer, base_offset, data_ptr)?;
*data_ptr += self.parameters.data.len() as u64 * 16;
Ok(())
}
}
impl<'a> Xc3WriteOffsets for MaterialsOffsets<'a> {
fn write_offsets<W: std::io::Write + std::io::Seek>(
&self,
writer: &mut W,
_base_offset: u64,
data_ptr: &mut u64,
) -> xc3_write::Xc3Result<()> {
let base_offset = self.base_offset;
let materials = self.materials.write_offset(writer, base_offset, data_ptr)?;
self.floats.write_full(writer, base_offset, data_ptr)?;
self.ints.write_full(writer, base_offset, data_ptr)?;
for material in &materials.0 {
material
.shader_programs
.write_full(writer, base_offset, data_ptr)?;
}
for material in &materials.0 {
material
.textures
.write_full(writer, base_offset, data_ptr)?;
}
if !self.alpha_test_textures.data.is_empty() {
self.alpha_test_textures
.write_full(writer, base_offset, data_ptr)?;
}
self.material_unk1
.write_full(writer, base_offset, data_ptr)?;
self.material_unk2
.write_full(writer, base_offset, data_ptr)?;
self.material_unk3
.write_full(writer, base_offset, data_ptr)?;
self.samplers.write_full(writer, base_offset, data_ptr)?;
self.shader_programs
.write_full(writer, base_offset, data_ptr)?;
for material in &materials.0 {
material.name.write_full(writer, base_offset, data_ptr)?;
}
Ok(())
}
}
impl<'a> Xc3WriteOffsets for MxmdOffsets<'a> {
fn write_offsets<W: std::io::Write + std::io::Seek>(
&self,
writer: &mut W,
base_offset: u64,
data_ptr: &mut u64,
) -> xc3_write::Xc3Result<()> {
self.models.write_full(writer, base_offset, data_ptr)?;
self.materials.write_full(writer, base_offset, data_ptr)?;
self.streaming.write_full(writer, base_offset, data_ptr)?;
*data_ptr += 1;
self.unk1.write_full(writer, base_offset, data_ptr)?;
self.vertex_data.write_full(writer, base_offset, data_ptr)?;
self.spch.write_full(writer, base_offset, data_ptr)?;
self.packed_textures
.write_full(writer, base_offset, data_ptr)?;
Ok(())
}
}
impl<'a> Xc3WriteOffsets for Unk1Offsets<'a> {
fn write_offsets<W: std::io::Write + std::io::Seek>(
&self,
writer: &mut W,
_base_offset: u64,
data_ptr: &mut u64,
) -> xc3_write::Xc3Result<()> {
let base_offset = self.base_offset;
self.unk1.write_full(writer, base_offset, data_ptr)?;
self.unk2.write_full(writer, base_offset, data_ptr)?;
self.unk3.write_full(writer, base_offset, data_ptr)?;
if !self.unk4.data.is_empty() {
self.unk4.write_full(writer, base_offset, data_ptr)?;
}
Ok(())
}
}
impl<'a> Xc3WriteOffsets for ModelUnk3ItemOffsets<'a> {
fn write_offsets<W: std::io::prelude::Write + std::io::prelude::Seek>(
&self,
writer: &mut W,
base_offset: u64,
data_ptr: &mut u64,
) -> xc3_write::Xc3Result<()> {
self.unk3.write_full(writer, base_offset, data_ptr)?;
self.name.write_full(writer, base_offset, data_ptr)?;
Ok(())
}
}
impl<'a> Xc3WriteOffsets for MaterialUnk3Offsets<'a> {
fn write_offsets<W: std::io::prelude::Write + std::io::prelude::Seek>(
&self,
writer: &mut W,
base_offset: u64,
data_ptr: &mut u64,
) -> xc3_write::Xc3Result<()> {
self.unk2.write_full(writer, base_offset, data_ptr)?;
self.unk1.write_full(writer, base_offset, data_ptr)?;
Ok(())
}
}
impl<'a> Xc3WriteOffsets for PackedTexturesOffsets<'a> {
fn write_offsets<W: std::io::prelude::Write + std::io::prelude::Seek>(
&self,
writer: &mut W,
_base_offset: u64,
data_ptr: &mut u64,
) -> xc3_write::Xc3Result<()> {
let base_offset = self.base_offset;
let textures = self.textures.write_offset(writer, base_offset, data_ptr)?;
self.strings_offset
.write_full(writer, base_offset, data_ptr)?;
for texture in &textures.0 {
texture.name.write_full(writer, base_offset, data_ptr)?;
}
for texture in &textures.0 {
texture
.mibl_data
.write_full(writer, base_offset, data_ptr)?;
}
Ok(())
}
}
impl<'a> Xc3WriteOffsets for PackedExternalTexturesOffsets<'a> {
fn write_offsets<W: std::io::prelude::Write + std::io::prelude::Seek>(
&self,
writer: &mut W,
_base_offset: u64,
data_ptr: &mut u64,
) -> xc3_write::Xc3Result<()> {
let base_offset = self.base_offset;
let textures = self.textures.write_offset(writer, base_offset, data_ptr)?;
self.strings_offset
.write_full(writer, base_offset, data_ptr)?;
for texture in &textures.0 {
texture.name.write_full(writer, base_offset, data_ptr)?;
}
Ok(())
}
}