#3d-model #file-format #wii #graphics #gamedev #archive-format #reading-file

brres

brres 是一个为读取和写入用于任天堂Wii游戏的 .brres 3D模型存档而设计的Rust包。该库提供了C绑定,使其在基于Rust和C/C++的项目中都有用。

8个版本

0.1.7 2024年8月3日
0.1.6 2024年6月15日

13数据格式 中排名

Download history 54/week @ 2024-06-07 436/week @ 2024-06-14 7/week @ 2024-06-21 5/week @ 2024-06-28 20/week @ 2024-07-05 2/week @ 2024-07-19 9/week @ 2024-07-26 128/week @ 2024-08-02 3/week @ 2024-08-09

每月下载量 142

MITGPL-2.0-or-later

1MB
18K SLoC

C++ 13K SLoC // 0.1% comments Rust 4K SLoC // 0.0% comments Bitbake 715 SLoC

crates.io docs.rs

brres

读取BRRES文件的WIP Rust/C++包

BRRES (.brres) 是任天堂为Nintendo Wii开发的专用3D模型格式。在《马里奥赛车Wii》、《风之纹章:暗影帝王》和《超级 Smash Bros: Brawl》等游戏中使用,.brres是一种灵活且高效的文件格式。几乎所有的数据都以原始GPU显示列表的形式存储,这些列表可以直接由Wii的“flipper” GPU读取。

文件格式:.brres

在最底层,“.brres”是一种用于以下子文件的存档格式。除了SHP0之外,所有格式都受到支持。

文件类型 描述 Rust结构
BRRES v0 3D资源 存档
MDL0 v11 3D模型 模型
TEX0 v1/v3 纹理 纹理
SRT0 v5 纹理缩放/旋转/平移动画 JSONSrtData
VIS0 v4 骨骼可见性动画 JSONVisData
CLR0 v4 着色器均匀动画 JSONClrAnim,编辑限制
CHR0 v4 骨骼/角色动画 ChrData,编辑限制
PAT0 v4 纹理图像动画 JSONPatAnim,编辑限制
SHP0 顶点形变动画 不支持

文件格式:.mdl0

文件类型 描述 Rust结构
MDL0.ByteCode 绘制调用 + 骨骼 合并到 JSONBoneDataJSONDrawMatrix
MDL0.Bone 骨骼 JSONBoneData
MDL0.PositionBuf 包含顶点位置 VertexPositionBuffer
MDL0.NormalBuf 包含顶点法线 VertexNormalBuffer
MDL0.ColorBuf 包含顶点颜色 VertexColorBuffer
MDL0.UVBuf 包含UV贴图 VertexTextureCoordinateBuffer
MDL0.FurVecBuf 与毛发相关 不支持
MDL0.FurPosBuf 与毛发相关 不支持
MDL0.Material 材质数据 JSONMaterial
MDL0.TEV 着色器数据 合并到 JSONMaterial
MDL0.Mesh 3D网格数据 网格
MDL0.TextureLink 内部 重新计算
MDL0.PaletteLink 内部 重新计算
MDL0.UserData 元数据 不支持

因此,Rust 对 MDL0 文件的视图如下

struct Model {
    pub name: String,
    pub info: JSONModelInfo,

    pub bones: Vec<JSONBoneData>,
    pub materials: Vec<JSONMaterial>,
    pub meshes: Vec<Mesh>,

    // Vertex buffers
    pub positions: Vec<VertexPositionBuffer>,
    pub normals: Vec<VertexNormalBuffer>,
    pub texcoords: Vec<VertexTextureCoordinateBuffer>,
    pub colors: Vec<VertexColorBuffer>,

    /// For skinning
    pub matrices: Vec<JSONDrawMatrix>,
}

读取文件

从文件系统上的路径读取 .brres 文件。

let archive = brres::Archive::from_path("kuribo.brres").unwrap();
assert!(archive.models[1].name == "kuribo");

println!("{:#?}", archive.get_model("kuribo").unwrap().meshes[0]);

从字节数组原始切片读取 .brres 文件。

let raw_bytes = std::fs::read("kuribo.brres").expect("Expected kuribo :)");

let archive = brres::Archive::from_memory(&raw_bytes).unwrap();
assert!(archive.models[1].name == "kuribo");

println!("{:#?}", archive.get_model("kuribo").unwrap().meshes[0]);

写入文件

(写入文件)

let buf = kuribo.write_path("kuribo_modified.brres").unwrap();

(写入内存)

let buf = kuribo.write_memory().unwrap();
std::fs::write("kuribo_modified.brres", buf).unwrap();

示例

fn test_read_raw_brres() {
    // Read the sea.brres file into a byte array
    let brres_data = fs::read("sea.brres").expect("Failed to read sea.brres file");

    // Call the read_raw_brres function
    match brres::Archive::from_memory(&brres_data) {
        Ok(archive) => {
            println!("{:#?}", archive.get_model("sea").unwrap().meshes[0]);
        }
        Err(e) => {
            panic!("Error reading brres file: {:#?}", e);
        }
    }
}

进度

librii::g3d 的 JSON 导出导入层之上实现 Rust 层。重要的是,像纹理数据和顶点数据这样的大型缓冲区实际上并不是编码在 JSON 中,而是直接作为二进制数据块传递。这允许 JSON 文件保持轻量,并导致最小化的编码延迟(待测试)。

格式 支持
MDL0
TEX0
SRT0
PAT0 是*
CLR0 是*
CHR0 是*
VIS0
SHP0
  • 编辑时轨道排序的限制

当前限制

  • PAT0、CLR0 和 CHR0 的支持略低于理想状态。特别是,现有代码强调位完美重建,但缺乏用于编辑的有用灵活性。未来的版本应解决此问题。
  • 库的内部部分是用 C++ 编写的。此外,Windows 上需要 clang 编译器。不能使用 Microsoft Visual C++ 编译器。
  • 还需要大量的文档。
  • SHP0 不支持,尽管几乎从未使用。
  • 仅支持 V11 MDL0。对于较老的标题,我们应该支持较老(和较新)的版本(v7:Wii Sports?v9:Brawl,v12:Kirby 等。)
  • JSON* 结构可能不应该直接公开。
  • 枚举值的名称并不总是遵循 Rust 规范。

测试

使用单元测试来验证正确性。使用 cargo test 运行套件

brres-sys

底层文档可在此处找到 here

依赖关系

~1.4–4.5MB
~87K SLoC