11use crate :: resource_pack:: identifier:: { Identifier , ModelId } ;
2- use serde:: { Deserialize , Serialize } ;
32use crate :: utils:: clean_json_numbers;
3+ use serde:: { Deserialize , Serialize } ;
44
55#[ derive( Clone , Debug , Serialize , Deserialize ) ]
66pub struct Item {
@@ -26,14 +26,22 @@ pub enum Model {
2626 model : ModelId ,
2727 #[ serde( default , skip_serializing_if = "Vec::is_empty" ) ]
2828 tints : Vec < TintSource > ,
29+ #[ serde( skip_serializing_if = "Option::is_none" , flatten) ]
30+ transformation : Option < Transformation > ,
2931 } ,
3032 #[ serde( rename = "composite" , alias = "minecraft:composite" ) ]
31- Composite { models : Vec < Model > } ,
33+ Composite {
34+ models : Vec < Model > ,
35+ #[ serde( skip_serializing_if = "Option::is_none" , flatten) ]
36+ transformation : Option < Transformation > ,
37+ } ,
3238 #[ serde( rename = "condition" , alias = "minecraft:condition" ) ]
3339 Condition {
3440 property : String ,
3541 on_true : Box < Model > ,
3642 on_false : Box < Model > ,
43+ #[ serde( skip_serializing_if = "Option::is_none" , flatten) ]
44+ transformation : Option < Transformation > ,
3745 #[ serde( flatten) ]
3846 extra : serde_json:: Value ,
3947 } ,
@@ -43,6 +51,8 @@ pub enum Model {
4351 cases : Vec < SelectCase > ,
4452 #[ serde( skip_serializing_if = "Option::is_none" ) ]
4553 fallback : Option < Box < Model > > ,
54+ #[ serde( skip_serializing_if = "Option::is_none" , flatten) ]
55+ transformation : Option < Transformation > ,
4656 #[ serde( flatten) ]
4757 extra : serde_json:: Value ,
4858 } ,
@@ -54,20 +64,57 @@ pub enum Model {
5464 entries : Vec < RangeEntry > ,
5565 #[ serde( skip_serializing_if = "Option::is_none" ) ]
5666 fallback : Option < Box < Model > > ,
67+ #[ serde( skip_serializing_if = "Option::is_none" , flatten) ]
68+ transformation : Option < Transformation > ,
5769 #[ serde( flatten) ]
5870 extra : serde_json:: Value ,
5971 } ,
6072 #[ serde( rename = "special" , alias = "minecraft:special" ) ]
6173 Special {
6274 base : ModelId ,
6375 model : SpecialModelData ,
76+ #[ serde( skip_serializing_if = "Option::is_none" , flatten) ]
77+ transformation : Option < Transformation > ,
6478 } ,
6579 #[ serde( rename = "empty" , alias = "minecraft:empty" ) ]
6680 Empty { } ,
67- #[ serde( rename = "bundle/selected_item" , alias = "minecraft:bundle/selected_item" ) ]
81+ #[ serde(
82+ rename = "bundle/selected_item" ,
83+ alias = "minecraft:bundle/selected_item"
84+ ) ]
6885 BundleSelectedItem { } ,
6986}
7087
88+ // TODO: Convert Object to list
89+ #[ derive( Clone , Debug , Serialize , Deserialize ) ]
90+ pub enum Transformation {
91+ List { transformation : [ f32 ; 16 ] } ,
92+ Object { transformation : FullTransformation } ,
93+ }
94+
95+ #[ derive( Clone , Debug , Serialize , Deserialize ) ]
96+ pub struct FullTransformation {
97+ left_rotation : Quaternion ,
98+ right_rotation : Quaternion ,
99+ scale : [ f32 ; 3 ] ,
100+ translation : [ f32 ; 3 ] ,
101+ }
102+
103+ // TODO: Convert Object to list
104+ #[ derive( Clone , Debug , Serialize , Deserialize ) ]
105+ pub enum Quaternion {
106+ List { quaternion : [ f32 ; 4 ] } ,
107+ Object {
108+ quaternion : FullQuaternion
109+ } ,
110+ }
111+
112+ #[ derive( Clone , Debug , Serialize , Deserialize ) ]
113+ pub struct FullQuaternion {
114+ axis : [ f32 ; 3 ] ,
115+ angle : f32 ,
116+ }
117+
71118#[ derive( Clone , Debug , Serialize , Deserialize ) ]
72119pub struct SelectCase {
73120 pub when : serde_json:: Value , // Can be String or Array of Strings
@@ -137,7 +184,10 @@ pub enum SpecialModelData {
137184 #[ serde( default ) ]
138185 openness : f32 ,
139186 } ,
140- #[ serde( rename = "copper_golem_statue" , alias = "minecraft:copper_golem_statue" ) ]
187+ #[ serde(
188+ rename = "copper_golem_statue" ,
189+ alias = "minecraft:copper_golem_statue"
190+ ) ]
141191 CopperGolemStatue {
142192 texture : String , // with the ".png" suffix
143193 pose : String ,
@@ -214,12 +264,15 @@ impl std::fmt::Display for Item {
214264 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
215265 let mut val = serde_json:: to_value ( self ) . map_err ( |_| std:: fmt:: Error ) ?;
216266 clean_json_numbers ( & mut val) ;
217- write ! ( f, "{}" , serde_json:: to_string( & val) . map_err( |_| std:: fmt:: Error ) ?)
267+ write ! (
268+ f,
269+ "{}" ,
270+ serde_json:: to_string( & val) . map_err( |_| std:: fmt:: Error ) ?
271+ )
218272 }
219273}
220274
221275impl Item {
222-
223276 pub fn from_json (
224277 overlay : impl Into < String > ,
225278 identifier : Identifier ,
0 commit comments