gltf_v1_json/
skin.rs

1use gltf_v1_derive::Validate;
2use serde_derive::{Deserialize, Serialize};
3
4use super::{accessor::Accessor, common::StringIndex, node::Node};
5
6#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
7pub struct Skin {
8    #[serde(
9        rename = "bindShapeMatrix",
10        skip_serializing_if = "matrix_is_default",
11        default = "default_matrix"
12    )]
13    pub bind_shape_matrix: [f32; 16],
14    #[serde(rename = "inverseBindMatrices")]
15    pub inverse_bind_matrices: StringIndex<Accessor>,
16    #[serde(default)]
17    #[serde(rename = "jointNames")]
18    pub joint_names: Vec<StringIndex<Node>>,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub name: Option<String>,
21}
22
23fn matrix_is_default(value: &[f32; 16]) -> bool {
24    value[0] == 1.0
25        && value[1] == 0.0
26        && value[2] == 0.0
27        && value[3] == 0.0
28        && value[4] == 0.0
29        && value[5] == 1.0
30        && value[6] == 0.0
31        && value[7] == 0.0
32        && value[8] == 0.0
33        && value[9] == 0.0
34        && value[10] == 1.0
35        && value[11] == 0.0
36        && value[12] == 0.0
37        && value[13] == 0.0
38        && value[14] == 0.0
39        && value[15] == 1.0
40}
41
42fn default_matrix() -> [f32; 16] {
43    [
44        1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
45    ]
46}
47
48#[test]
49fn test_skin_deserialize() {
50    let data = r#"{
51            "bindShapeMatrix": [
52                1,
53                0,
54                0,
55                0,
56                0,
57                1,
58                0,
59                0,
60                0,
61                0,
62                1,
63                0,
64                0,
65                0,
66                0,
67                1
68            ],
69            "inverseBindMatrices": "accessor_id",
70            "jointNames": [
71                "joint_name",
72                "another_joint_name"
73            ],
74            "name": "user-defined skin name",
75            "extensions" : {
76               "extension_name" : {
77                  "extension specific" : "value"
78               }
79            },
80            "extras" : {
81                "Application specific" : "The extra object can contain any properties."
82            }     
83        }"#;
84    let skin: Result<Skin, _> = serde_json::from_str(data);
85    let skin_unwrap = skin.unwrap();
86    println!("{}", serde_json::to_string(&skin_unwrap).unwrap());
87    assert_eq!(Some("user-defined skin name".to_string()), skin_unwrap.name);
88}