11using System . Text ;
2+ using System . Text . Json . Nodes ;
23
34using FEZRepacker . Core . Definitions . Game . ArtObject ;
45using FEZRepacker . Core . Definitions . Game . Graphics ;
89using FEZRepacker . Core . Helpers ;
910using FEZRepacker . Core . Helpers . Json ;
1011
12+ using SharpGLTF . Schema2 ;
13+
1114using SixLabors . ImageSharp . Formats . Png ;
1215
1316namespace FEZRepacker . Core . Conversion . Formats
@@ -16,8 +19,15 @@ internal class TrileSetConverter : FormatConverter<TrileSet>
1619 {
1720 public override string FileFormat => ".fezts" ;
1821
22+ private const string TrileIdKey = "TrileId" ;
23+
1924 public override FileBundle ConvertTyped ( TrileSet data )
2025 {
26+ if ( ! Settings . UseLegacyTrileSetBundle )
27+ {
28+ return FileBundle . Single ( GetTransmissionFormatStream ( data ) , FileFormat , ".glb" ) ;
29+ }
30+
2131 var bundle = ConfiguredJsonSerializer . SerializeToFileBundle ( FileFormat , data ) ;
2232
2333 bundle . AddFile ( GetTextureStream ( data , TexturesUtil . CubemapPart . Albedo ) , ".png" ) ;
@@ -29,12 +39,20 @@ public override FileBundle ConvertTyped(TrileSet data)
2939
3040 public override TrileSet DeconvertTyped ( FileBundle bundle )
3141 {
32- var trileSet = ConfiguredJsonSerializer . DeserializeFromFileBundle < TrileSet > ( bundle ) ;
33-
34- AppendGeometryStream ( ref trileSet , bundle . RequireData ( ".obj" ) ) ;
35- LoadCubemap ( ref trileSet , bundle . GetData ( ".png" ) , bundle . GetData ( ".apng" ) ) ;
36-
37- return trileSet ;
42+ try
43+ {
44+ return LoadFromTransmissionFormat ( bundle . RequireData ( ".glb" ) ) ;
45+ }
46+ catch ( FileNotFoundException )
47+ {
48+ Console . WriteLine ( " The glTF bundle was not found! Using legacy trile set bundle format..." ) ;
49+ var trileSet = ConfiguredJsonSerializer . DeserializeFromFileBundle < TrileSet > ( bundle ) ;
50+
51+ AppendGeometryStream ( ref trileSet , bundle . RequireData ( ".obj" ) ) ;
52+ LoadCubemap ( ref trileSet , bundle . GetData ( ".png" ) , bundle . GetData ( ".apng" ) ) ;
53+
54+ return trileSet ;
55+ }
3856 }
3957
4058 private static Stream GetTextureStream ( TrileSet data , TexturesUtil . CubemapPart part )
@@ -51,10 +69,51 @@ private static Stream GetModelStream(TrileSet data)
5169 {
5270 geometryDict [ trileRecord . Key . ToString ( ) ] = trileRecord . Value . Geometry ;
5371 }
72+
5473 var objString = WavefrontObjUtil . ToWavefrontObj ( geometryDict ) ;
5574 return new MemoryStream ( Encoding . UTF8 . GetBytes ( objString ) ) ;
5675 }
5776
77+ private static Stream GetTransmissionFormatStream ( TrileSet data )
78+ {
79+ var entries = new List < GltfEntry < Vector4 > > ( ) ;
80+ foreach ( var trileRecord in data . Triles )
81+ {
82+ var extras = ConfiguredJsonSerializer . SerializeToNode ( trileRecord . Value ) ;
83+ extras [ TrileIdKey ] = trileRecord . Key ;
84+ entries . Add ( new GltfEntry < Vector4 > ( trileRecord . Value . Name , trileRecord . Value . Geometry , extras ) ) ;
85+ }
86+
87+ using var albedo =
88+ TexturesUtil . ExtractCubemapPartFromTexture ( data . TextureAtlas , TexturesUtil . CubemapPart . Albedo ) ;
89+ using var emission =
90+ TexturesUtil . ExtractCubemapPartFromTexture ( data . TextureAtlas , TexturesUtil . CubemapPart . Emission ) ;
91+
92+ return GltfUtil . ToGltfModel ( data . Name , entries , albedo , emission ) . SaveAsGlb ( ) ;
93+ }
94+
95+ private static TrileSet LoadFromTransmissionFormat ( Stream modelStream )
96+ {
97+ var modelRoot = ModelRoot . ReadGLB ( modelStream ) ;
98+ var trileSet = new TrileSet { Name = modelRoot . DefaultScene . Name } ;
99+
100+ var entries = GltfUtil . FromGltfModel < Vector4 > ( modelRoot ) ;
101+ foreach ( var entry in entries )
102+ {
103+ var id = entry . Extras [ TrileIdKey ] ! . GetValue < int > ( ) ;
104+ if ( ! trileSet . Triles . ContainsKey ( id ) )
105+ {
106+ trileSet . Triles [ id ] = ConfiguredJsonSerializer . DeserializeFromNode < Trile > ( entry . Extras ) ;
107+ }
108+
109+ trileSet . Triles [ id ] . Geometry = entry . Geometry ;
110+ }
111+
112+ ( Stream ? albedo , Stream ? emission ) = GltfUtil . ExtractCubemapStreams ( modelRoot ) ;
113+ LoadCubemap ( ref trileSet , albedo , emission ) ;
114+
115+ return trileSet ;
116+ }
58117
59118 private static void AppendGeometryStream ( ref TrileSet data , Stream geometryStream )
60119 {
@@ -67,14 +126,15 @@ private static void AppendGeometryStream(ref TrileSet data, Stream geometryStrea
67126 {
68127 data . Triles [ id ] = new Trile ( ) ;
69128 }
129+
70130 data . Triles [ id ] . Geometry = objRecord . Value ;
71131 }
72132 }
73133
74- private static void LoadCubemap ( ref TrileSet data , Stream albedoStream , Stream emissionStream )
134+ private static void LoadCubemap ( ref TrileSet data , Stream ? albedoStream , Stream ? emissionStream )
75135 {
76136 using var image = TexturesUtil . ConstructCubemap ( albedoStream , emissionStream ) ;
77137 data . TextureAtlas = TexturesUtil . ImageToTexture2D ( image ) ;
78138 }
79139 }
80- }
140+ }
0 commit comments