Coder Social home page Coder Social logo

ssbh_lib's Introduction

ssbh_lib GitHub release (latest by date including pre-releases)

Libraries and tools for working with the SSBH binary formats in Rust.

SSBH Formats

Click the links below to see the corresponding Rust source file with the file format's struct definitions. All SSBH formats start with the file magic HBSS and use the same representation for types like arrays and offsets.

Format Supported Versions (major.minor)
Hlpb (.nuhlpb) 1.1
Matl (.numatb) 1.5, 1.6
Modl (.numdlb,.nusrcmdlb) 1.7
Mesh (.numshb) 1.8, 1.9, 1.10
Skel (.nusktb) 1.0
Anim (.nuanmb) 1.2, 2.0, 2.1
Nlst (.nulstb) 1.0
Nrpd (.nurpdb) 1.6
Nufx (.nufxlb) 1.0, 1.1
Shdr (.nushdb) 1.2

The ssbh_lib library also supports the non SSBH formats MeshEx (.numshexb) and Adj (.adjb).

If you find an SSBH format used in a game that isn't supported here, feel free to open a pull request to add it. The ssbh_lib types can also be used in your own project with the BinRead and SsbhWrite derives to support new SSBH formats without needing to modify ssbh_lib.

Projects

Project Description Crate Documentation
ssbh_lib A library to read and write SSBH formats Latest Version docs.rs
ssbh_data A high level API for reading and writing SSBH data Latest Version docs.rs

For making quick edits to SSBH files in a text editor, use ssbh_lib_json. ssbh_data_json supports fewer formats than ssbh_lib_json but adds the ability to decode and edit the buffer data in Mesh or Anim files. Python bindings for ssbh_data are available with ssbh_data_py.

Tools

Building

With a recent version of Rust installed, run cargo build --release.

Credits

  • SSBHLib - the original C# implementation for reading and writing SSBH files
  • geometry_tools - vertex data and geometry bounding calculations
  • binrw - binary parsing library and inspiration for porting the C# implementation to Rust
  • glam - efficient vector and matrix math using SIMD
  • see the Cargo.toml files for the remaining projects used

ssbh_lib's People

Contributors

jam1garner avatar scanmountgoat avatar thatnintendonerd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ssbh_lib's Issues

derive SsbhWrite for c style enums

#[derive(SsbhWrite)]
#[SsbhWrite(repr(u8))]
pub enum CompressionType {
    Direct = 1,
    ConstTransform = 2,
    Compressed = 4,
    Constant = 5,
}
#[SsbhCEnum(u8)]
pub enum CompressionType {
    Direct = 1,
    ConstTransform = 2,
    Compressed = 4,
    Constant = 5,
}

Don't assume data type for reading attributes for mesh data

This fails for non Smash Ultimate models such as Pokemon Snap. The vertex normals can't be assumed to have 4 components, for example. A reasonable solution may be to convert sizes 1,2,3,4 to size 4 for reading tangents, for example, and set the remaining values to defaults.

  • Support arbitrary component lengths based on data type

improve command line argument handling for json to ssbh

If no output path is provided, the extension can be inferred from the SSBH type in the JSON data.
ssbh_lib_json.exe input.numdlb -> input.numdlb.json
ssbh_lib_json.exe input.nufxb -> input.numdlb.json
ssbh_lib_json.exe skel.json ->skel.nusktb
ssbh_lib_json.exe matl_data.json ->matl_data.numatb

Generate bounding info from points

This is required for creating new mesh files from existing data. The process can be automated using glam for a more efficient and correct implementation than requiring people to compute their own bounding information. The functionality can probably be it's own crate and be combined with normals, tangents, and other functions ported from SFGraphics.utils.

  • bounding sphere
  • axis-aligned bounding box
  • oriented bounding box

add mesh decoding to ssbh_data

The mesh buffers can be used as is for rendering in Vulkan, OpenGL, etc if the vertex attribute offsets and strides are configured correctly. The decoder crate will add more convenient wrappers for accessing the values of the buffer and not the raw binary data itself. It's probably doable to expose an iterator and avoid copying the entire data into a separate buffer.

The code could be used as follows.

let mesh_data = ssbh_mesh_decoder::decode(mesh);
for object in mesh_data.objects {
   // Copy the data into a Vec
   println!("{:?}", object.read_attribute_data(MeshAttribute::Position0));

    // Enumerate the buffer without actually copying/modifying it?
    for value in object.vertices.iter() {
        println!("{:?}", object.read_attribute_data(MeshAttribute::Position0));
    }
}
  • Rigging buffer (vertex index and vertex weight)
  • Get vertex indices
  • Get vertex positions
  • Get vertex normals
  • handle varying data types and attribute lengths (vector4, byte, etc)
  • Get specific attribute data (always convert to float)
    - [ ] Get pointers to raw buffers and associated offset, stride etc (get_attribute_buffer_info(mesh, mesh_object, attribute))

fix mesh rebuilding for version 1.8 and 1.9

  • There is a third vertex buffer than contains stride2 * vertex_count many bytes where stride2 = 32
  • vertex_buffer1_offset is not correct for MeshObject
  • unk6 is not correct for MeshObject

add modl support

The types can match the ssbh_lib definition but use standard rust types.

add tests for read_data

This should test that offset, stride, count, etc work correctly given a small byte buffer.

simplify struct definitions for Mesh

The bounding sphere fields are shared between Mesh and MeshObject and could be simplified. This will also make the JSON output more readable.

example:

struct BoundingSphere { 
    center: Vector3,
    radius: f32
}

add functions to read Ssbh types from a reader or from a file

This should be implemented for each SSBH type (mesh, matl, etc) and for Ssbh itself.

impl MyStruct {
    fn open<P: AsRef<Path>>(path: P) -> Result<Self> {
        // Buffer the read.
        let mut reader = BufReader::new(File::open(path.as_ref())?);
        MyStruct::read(&mut reader)
    }

    fn read<R: Read + Seek>(reader: &mut R) -> Result<Self> { ... }
}

matl export not 1:1

This may be a padding issue. The JSON output is the same for an unmodified and exported numatb.

Improve error types for mesh_data

The current implementation relies heavily on panics and error strings and doesn't provide much useful information.

  • define custom error types

decode data for mesh bone buffer

The MeshBoneBuffer byte array can be parsed as an array of structs.

struct VertexInfluence {
    vertex_index: u16,
    weight: f32
}

don't duplicate export code for 8 byte aligned strings

The internal string representation is an implementation detail and can just be exposed as a getter function fn text(&self) -> &str or fn text(&self) -> &str. Having separate types for 4 and 8 byte alignment should reduce the amount of repeated code for implementing SsbhWrite.

fix test cases for ssbh byte buffer

The data pointer and data being written doesn't match the expected behavior for arrays despite producing 1:1 export for actual SSBH files.

improve code documentation (cargo doc)

Base types such as Mesh, Skel, etc should be annotated with their supported versions. Comments should link to related types, functions, etc. Public functions should contain short example code when possible, which also allows for additional tests.

automatically generate exporting code for ssbh types

It should be possible to create a trait and a derive macro to simplify writing SSBH types. BinWrite currently doesn't support the necessary features to pass the data pointer as an argument. Each type should implement write_ssbh(writer, data_ptr) as well as alignment_in_bytes() and size_in_bytes().

handle null relative offsets

Example:
root\assist\bombermanbombmanager\model\body\c00\model.numdlb has a "null" animation file name pointer.

Tangent0 uses map1 as the name

This doesn't seem to have any impact on the data being used correctly by Smash Ultimate but is inconsistent with the in game mesh files.

Improve json formatting for byte buffers (MESH/ANIM)

Serializing individual bytes is difficult to read. It may be better to base64 code the entire buffer. Converting mesh and anim buffers to actual vertex/animation data would be easier to read, but should probably be a separate option because it isn't part of the specification itself.

Nrpd export not 1:1

The JSON output before and after export is identical, but the binary files are not identical. Different RenderPassContainer objects may point to the same string data, which doesn't seem to be part of any of the other SSBH formats.

add anim decoding to ssbh_data

The AnimTrack fields data_offset and data_size can be parsed using an enum and some custom parsing logic. Some of the logic from the anim track decoder can be present in the parsing. It might be tricky to come up with an API that supports both version 1.x and version 2.x anim files. Version 1.2 seems to just use uncompressed data and identical types to version 2.x.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.