use super::gltf::GltfBuilder;
use super::gr2_reader::Gr2Reader;
use super::texture_loading::load_textures_for_gr2;
use crate::error::{Error, Result};
use std::path::Path;
#[derive(Debug)]
pub struct TexturedGlbResult {
pub glb_data: Vec<u8>,
pub warnings: Vec<String>,
}
pub fn convert_gr2_bytes_to_glb_with_textures(
gr2_data: &[u8],
gr2_filename: &str,
textures_pak_path: &Path,
) -> Result<TexturedGlbResult> {
let mut warnings = Vec::new();
let reader = Gr2Reader::new(gr2_data)?;
let skeleton = reader.parse_skeleton(gr2_data)?;
let meshes = reader.parse_meshes(gr2_data)?;
if meshes.is_empty() {
let info = reader.get_content_info(gr2_data)?;
return Err(Error::ConversionError(format!(
"No meshes found in GR2 file (contains: {})",
info.describe()
)));
}
let mut builder = GltfBuilder::new();
let (skin_idx, root_bone_idx, bone_remap) = if let Some(ref skel) = skeleton {
let models = reader.parse_models(gr2_data).unwrap_or_default();
let skel_profile = super::convert::to_bg3_skeleton_profile_from(skel, &models);
let result = builder.add_skeleton_with_profile(skel, skel_profile);
let root_idx = Some(builder.bone_node_offset);
(Some(result.skin_idx), root_idx, Some(result.bone_remap))
} else {
(None, None, None)
};
let material_idx =
load_textures_for_gr2(gr2_filename, textures_pak_path, &mut builder, &mut warnings);
for mesh in &meshes {
let mut mesh = mesh.clone();
if let (Some(remap), Some(skel)) = (&bone_remap, &skeleton) {
super::convert::remap_mesh_bone_indices(&mut mesh, skel, remap);
}
builder.add_mesh_with_material(&mesh, skin_idx, material_idx);
}
let glb_data = builder.build_glb(root_bone_idx)?;
Ok(TexturedGlbResult { glb_data, warnings })
}