digama0 / dae-parser

Rust crate for parsing Collada DAE files
Apache License 2.0
9 stars 0 forks source link

License: MIT Apache License 2.0 docs.rs crates.io Download numbers Github CI Minimum rustc version

Collada parser

This is a parser for the Collada (.dae) format, used for interchange between 3D renderers and games. Compared to the collada crate, this crate attempts to more directly represent the Collada data model, and it is also significantly more complete. It supports both reading and writing.

Usage

The main entry point is the [Document] type, which has a [FromStr] implementation to convert literal strings / slices, or [Document::from_file] to read from a .dae file on disk.

Collada documents are parsed eagerly, validating everything according to the COLLADA schema. Once parsed, the data structures (structs and enums) can be navigated directly, as all the data structures are public, and reflect the XML schema closely.

This library implements only version 1.4.1 of the Collada spec, although it may be expanded in the future. (Please open an issue or PR if you find anything missing from the spec, or if you have a use case for a later version.)

use std::str::FromStr;
use dae_parser::*;

let dae_file = r##"<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
  <asset>
    <created>1970-01-01T00:00:00Z</created>
    <modified>1970-01-01T00:00:00Z</modified>
  </asset>
  <library_geometries>
    <geometry id="Cube-mesh" name="Cube">
      <mesh>
        <source id="Cube-mesh-positions">
          <float_array id="Cube-mesh-positions-array" count="18">
            1 1 1 1 -1 1 1 -1 -1 -1 1 1 -1 -1 1 -1 -1 -1
          </float_array>
          <technique_common>
            <accessor source="#Cube-mesh-positions-array" count="6" stride="3">
              <param name="X" type="float"/>
              <param name="Y" type="float"/>
              <param name="Z" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <vertices id="Cube-mesh-vertices">
          <input semantic="POSITION" source="#Cube-mesh-positions"/>
        </vertices>
        <triangles material="Material-material" count="4">
          <input semantic="VERTEX" source="#Cube-mesh-vertices" offset="0"/>
          <p>3 1 0 1 5 2 3 4 1 1 4 5</p>
        </triangles>
      </mesh>
    </geometry>
  </library_geometries>
</COLLADA>"##;

let document = Document::from_str(dae_file).unwrap();
let cube = document.local_map::<Geometry>().unwrap().get_str("Cube-mesh").unwrap();
let sources_map = document.local_map::<Source>().unwrap();
let vertices_map = document.local_map::<Vertices>().unwrap();
// sources.get("Cube-mesh-positions").unwrap();
assert_eq!(cube.id.as_ref().unwrap(), "Cube-mesh");
let mesh = cube.element.as_mesh().unwrap();
let tris = mesh.elements[0].as_triangles().unwrap();
assert_eq!(
    tris.data.as_deref().unwrap(),
    &[3, 1, 0, 1, 5, 2, 3, 4, 1, 1, 4, 5]
);
assert_eq!(tris.inputs[0].semantic, Semantic::Vertex);
let vertices = vertices_map.get_raw(&tris.inputs[0].source).unwrap();
assert_eq!(vertices.id, "Cube-mesh-vertices");
let source = sources_map
    .get_raw(&vertices.position_input().source)
    .unwrap();
assert_eq!(source.id.as_deref(), Some("Cube-mesh-positions"));

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.