draco_decoder 0.0.26

a draco decoder on rust (wip)
Documentation
#[cxx::bridge]
mod cpp {
    struct MeshAttribute {
        dim: u32,
        data_type: u32,
        offset: u32,
        length: u32,
        unique_id: u32,
    }

    struct MeshConfig {
        vertex_count: u32,
        index_count: u32,
        index_length: u32,
        buffer_size: usize,
        attributes: Vec<MeshAttribute>,
    }

    unsafe extern "C++" {
        include!("decoder_api.h");

        type DracoMesh;

        pub fn decode_point_cloud(data: &[u8]) -> Vec<u8>;

        pub fn create_mesh(data: &[u8]) -> UniquePtr<DracoMesh>;

        pub fn compute_mesh_config(mesh: &DracoMesh, config: &mut MeshConfig) -> bool;

        pub unsafe fn decode_mesh_to_buffer(
            mesh: &DracoMesh,
            out_ptr: *mut u8,
            out_len: usize,
        ) -> usize;
    }
}

#[allow(dead_code)]
pub fn decode_point_cloud_native(data: &[u8]) -> Vec<u8> {
    cpp::decode_point_cloud(data)
}

fn convert_config(cpp_config: cpp::MeshConfig) -> crate::DracoDecodeConfig {
    let mut config = crate::DracoDecodeConfig::new(
        cpp_config.vertex_count,
        cpp_config.index_count,
        cpp_config.buffer_size,
    );

    for attr in cpp_config.attributes {
        let data_type = crate::AttributeDataType::from_draco_data_type(attr.data_type as i32);
        config.add_attribute(attr.dim, data_type, attr.offset, attr.length);
    }

    config
}

pub fn decode_mesh_with_config(data: &[u8]) -> Option<crate::MeshDecodeResult> {
    let mesh = cpp::create_mesh(data);
    if mesh.is_null() {
        panic!("Failed to create mesh from data");
    }

    let mut cpp_config = cpp::MeshConfig {
        vertex_count: 0,
        index_count: 0,
        index_length: 0,
        buffer_size: 0,
        attributes: Vec::new(),
    };

    if !cpp::compute_mesh_config(&mesh, &mut cpp_config) {
        panic!("Failed to compute mesh config");
    }

    let buffer_size = cpp_config.buffer_size;
    let config = convert_config(cpp_config);
    let mut buffer = vec![0u8; buffer_size];

    let written = unsafe { cpp::decode_mesh_to_buffer(&mesh, buffer.as_mut_ptr(), buffer.len()) };

    if written == 0 {
        panic!("Failed to decode mesh to buffer");
    }

    buffer.truncate(written);

    Some(crate::MeshDecodeResult {
        data: buffer,
        config,
    })
}