2222 * SOFTWARE.
2323 */
2424
25- #pragma author H. Utku Maden
25+ #pragma author H. Utku Maden, xZise
2626#pragma description GL Transmission Format binary 3D model (.glb)
2727#pragma MIME model/gltf-binary
28+ #pragma magic [67 6C 54 46] @ 0x00
2829
2930import std.mem;
3031import std.io;
3132import type.magic;
33+ import hex.type.json;
34+ import std.core;
3235
3336/**
3437 * @brief The glTF magic section.
@@ -53,7 +56,10 @@ enum gltf_chunk_type_t : u32 {
5356struct gltf_chunk_t {
5457 u32 length; /**< Length of this chunk. */
5558 gltf_chunk_type_t type [[format("gltf_format")]]; /**< Type of the chunk. JSON or BIN expected. */
56- u8 string[length]; /**< The chunk data. */
59+ match (type) {
60+ (gltf_chunk_type_t::JSON): hex::type::Json<length> json;
61+ (gltf_chunk_type_t::BIN): u8 data[length];
62+ } /**< The chunk data. */
5763};
5864
5965fn gltf_format(gltf_chunk_type_t x)
@@ -64,7 +70,200 @@ fn gltf_format(gltf_chunk_type_t x)
6470 return "";
6571};
6672
67- gltf_magic_t magic @ 0x00 ;
68- gltf_chunk_t chunks[while(!std::mem::eof())] @ $ ;
73+ u64 json_offset = 0 ;
74+ u64 json_length = 0 ;
6975
70- std::assert_warn(std::mem::size() == magic.length, "file size mismatch");
76+ struct StrideType<InnerType, auto Stride> {
77+ InnerType value [[inline]];
78+ if (Stride > 0) {
79+ padding[Stride - sizeof(value)];
80+ }
81+ };
82+
83+ struct Scalar<ComponentType> {
84+ ComponentType scalar;
85+ } [[static, sealed]];
86+
87+ struct Vec2<ComponentType> {
88+ ComponentType x;
89+ ComponentType y;
90+ } [[static]];
91+
92+ struct Vec3<ComponentType> {
93+ ComponentType x;
94+ ComponentType y;
95+ ComponentType z;
96+ } [[static]];
97+
98+ struct Vec4<ComponentType> {
99+ ComponentType x;
100+ ComponentType y;
101+ ComponentType z;
102+ ComponentType w;
103+ } [[static]];
104+
105+ struct Mat2<ComponentType> {
106+ ComponentType a11;
107+ ComponentType a21;
108+ ComponentType a12;
109+ ComponentType a22;
110+ } [[static]];
111+
112+ struct Mat3<ComponentType> {
113+ ComponentType a11;
114+ ComponentType a21;
115+ ComponentType a31;
116+ ComponentType a12;
117+ ComponentType a22;
118+ ComponentType a32;
119+ ComponentType a13;
120+ ComponentType a23;
121+ ComponentType a33;
122+ } [[static]];
123+
124+ struct Mat4<ComponentType> {
125+ ComponentType a11;
126+ ComponentType a21;
127+ ComponentType a31;
128+ ComponentType a41;
129+ ComponentType a12;
130+ ComponentType a22;
131+ ComponentType a32;
132+ ComponentType a42;
133+ ComponentType a13;
134+ ComponentType a23;
135+ ComponentType a33;
136+ ComponentType a43;
137+ ComponentType a14;
138+ ComponentType a24;
139+ ComponentType a34;
140+ ComponentType a44;
141+ } [[static]];
142+
143+ enum ComponentType : u64 {
144+ BYTE = 5120,
145+ UNSIGNED_BYTE = 5121,
146+ SHORT = 5122,
147+ UNSIGNED_SHORT = 5123,
148+ UNSIGNED_INT = 5125,
149+ FLOAT = 5126,
150+ };
151+
152+ fn get_byte_stride(auto bufferView) {
153+ if (std::core::has_member(bufferView, "byteStride")) {
154+ return bufferView.byteStride;
155+ } else {
156+ return 0;
157+ }
158+ };
159+
160+ struct Accessor<auto Offset> {
161+ hex::type::Json<json_length> Json @ json_offset;
162+ hex::type::Json<json_length> Json2 @ json_offset;
163+ hex::type::Json<json_length> Json3 @ json_offset;
164+ u64 accessor_index = std::core::array_index();
165+ u64 view_index = Json.accessors[accessor_index].bufferView [[export]];
166+ u64 view_offset = Json.bufferViews[view_index].byteOffset [[export]];
167+ if (std::core::has_member(Json2.bufferViews[view_index], "byteStride")) {
168+ u64 byteStride = Json.bufferViews[view_index].byteStride [[export]];
169+ } else {
170+ u64 byteStride = 0 [[export]];
171+ }
172+ if (std::core::has_member(Json3.accessors[accessor_index], "byteOffset")) {
173+ u64 accessor_offset = Json.accessors[accessor_index].byteOffset [[export]];
174+ } else {
175+ u64 accessor_offset = 0 [[export]];
176+ }
177+ view_offset = view_offset + accessor_offset;
178+ u64 count_elements = Json.accessors[accessor_index].count;
179+ ComponentType component_type = Json.accessors[accessor_index].componentType [[export]];
180+
181+ match (Json.accessors[accessor_index].type, component_type) {
182+ ("SCALAR", ComponentType::BYTE): StrideType<Scalar<s8>, byteStride> content[count_elements] @ view_offset + Offset;
183+ ("SCALAR", ComponentType::UNSIGNED_BYTE): StrideType<Scalar<u8>, byteStride> content[count_elements] @ view_offset + Offset;
184+ ("SCALAR", ComponentType::SHORT): StrideType<Scalar<s16>, byteStride> content[count_elements] @ view_offset + Offset;
185+ ("SCALAR", ComponentType::UNSIGNED_SHORT): StrideType<Scalar<u16>, byteStride> content[count_elements] @ view_offset + Offset;
186+ ("SCALAR", ComponentType::UNSIGNED_INT): StrideType<Scalar<u32>, byteStride> content[count_elements] @ view_offset + Offset;
187+ ("SCALAR", ComponentType::FLOAT): StrideType<Scalar<float>, byteStride> content[count_elements] @ view_offset + Offset;
188+ ("VEC2", ComponentType::FLOAT): StrideType<Vec2<s8>, byteStride> content[count_elements] @ view_offset + Offset;
189+ ("VEC2", ComponentType::UNSIGNED_INT): StrideType<Vec2<u8>, byteStride> content[count_elements] @ view_offset + Offset;
190+ ("VEC2", ComponentType::UNSIGNED_SHORT): StrideType<Vec2<s16>, byteStride> content[count_elements] @ view_offset + Offset;
191+ ("VEC2", ComponentType::SHORT): StrideType<Vec2<u16>, byteStride> content[count_elements] @ view_offset + Offset;
192+ ("VEC2", ComponentType::UNSIGNED_BYTE): StrideType<Vec2<u32>, byteStride> content[count_elements] @ view_offset + Offset;
193+ ("VEC2", ComponentType::BYTE): StrideType<Vec2<float>, byteStride> content[count_elements] @ view_offset + Offset;
194+ ("VEC3", ComponentType::FLOAT): StrideType<Vec3<float>, byteStride> content[count_elements] @ view_offset + Offset;
195+ ("VEC3", ComponentType::UNSIGNED_INT): StrideType<Vec3<u32>, byteStride> content[count_elements] @ view_offset + Offset;
196+ ("VEC3", ComponentType::UNSIGNED_SHORT): StrideType<Vec3<u16>, byteStride> content[count_elements] @ view_offset + Offset;
197+ ("VEC3", ComponentType::SHORT): StrideType<Vec3<s16>, byteStride> content[count_elements] @ view_offset + Offset;
198+ ("VEC3", ComponentType::UNSIGNED_BYTE): StrideType<Vec3<u8>, byteStride> content[count_elements] @ view_offset + Offset;
199+ ("VEC3", ComponentType::BYTE): StrideType<Vec3<s8>, byteStride> content[count_elements] @ view_offset + Offset;
200+ ("VEC4", ComponentType::FLOAT): StrideType<Vec4<float>, byteStride> content[count_elements] @ view_offset + Offset;
201+ ("VEC4", ComponentType::UNSIGNED_INT): StrideType<Vec4<u32>, byteStride> content[count_elements] @ view_offset + Offset;
202+ ("VEC4", ComponentType::UNSIGNED_SHORT): StrideType<Vec4<u16>, byteStride> content[count_elements] @ view_offset + Offset;
203+ ("VEC4", ComponentType::SHORT): StrideType<Vec4<s16>, byteStride> content[count_elements] @ view_offset + Offset;
204+ ("VEC4", ComponentType::UNSIGNED_BYTE): StrideType<Vec4<u8>, byteStride> content[count_elements] @ view_offset + Offset;
205+ ("VEC4", ComponentType::BYTE): StrideType<Vec4<s8>, byteStride> content[count_elements] @ view_offset + Offset;
206+ ("MAT2", ComponentType::FLOAT): StrideType<Mat2<float>, byteStride> content[count_elements] @ view_offset + Offset;
207+ ("MAT2", ComponentType::UNSIGNED_INT): StrideType<Mat2<u32>, byteStride> content[count_elements] @ view_offset + Offset;
208+ ("MAT2", ComponentType::UNSIGNED_SHORT): StrideType<Mat2<u16>, byteStride> content[count_elements] @ view_offset + Offset;
209+ ("MAT2", ComponentType::SHORT): StrideType<Mat2<s16>, byteStride> content[count_elements] @ view_offset + Offset;
210+ ("MAT2", ComponentType::UNSIGNED_BYTE): StrideType<Mat2<u8>, byteStride> content[count_elements] @ view_offset + Offset;
211+ ("MAT2", ComponentType::BYTE): StrideType<Mat2<s8>, byteStride> content[count_elements] @ view_offset + Offset;
212+ ("MAT3", ComponentType::FLOAT): StrideType<Mat3<float>, byteStride> content[count_elements] @ view_offset + Offset;
213+ ("MAT3", ComponentType::UNSIGNED_INT): StrideType<Mat3<u32>, byteStride> content[count_elements] @ view_offset + Offset;
214+ ("MAT3", ComponentType::UNSIGNED_SHORT): StrideType<Mat3<u16>, byteStride> content[count_elements] @ view_offset + Offset;
215+ ("MAT3", ComponentType::SHORT): StrideType<Mat3<s16>, byteStride> content[count_elements] @ view_offset + Offset;
216+ ("MAT3", ComponentType::UNSIGNED_BYTE): StrideType<Mat3<u8>, byteStride> content[count_elements] @ view_offset + Offset;
217+ ("MAT3", ComponentType::BYTE): StrideType<Mat3<s8>, byteStride> content[count_elements] @ view_offset + Offset;
218+ ("MAT4", ComponentType::FLOAT): StrideType<Mat4<float>, byteStride> content[count_elements] @ view_offset + Offset;
219+ ("MAT4", ComponentType::UNSIGNED_INT): StrideType<Mat4<u32>, byteStride> content[count_elements] @ view_offset + Offset;
220+ ("MAT4", ComponentType::UNSIGNED_SHORT): StrideType<Mat4<u16>, byteStride> content[count_elements] @ view_offset + Offset;
221+ ("MAT4", ComponentType::SHORT): StrideType<Mat4<s16>, byteStride> content[count_elements] @ view_offset + Offset;
222+ ("MAT4", ComponentType::UNSIGNED_BYTE): StrideType<Mat4<u8>, byteStride> content[count_elements] @ view_offset + Offset;
223+ ("MAT4", ComponentType::BYTE): StrideType<Mat4<s8>, byteStride> content[count_elements] @ view_offset + Offset;
224+ }
225+ };
226+
227+ fn mem_cnt(auto value) {
228+ return std::core::member_count(value);
229+ };
230+
231+ struct ImageBuffer<auto Offset> {
232+ hex::type::Json<json_length> Json @ json_offset;
233+ u64 image_index = std::core::array_index();
234+ u64 buffer_view_index = Json.images[image_index].bufferView;
235+ u64 byte_offset = Json.bufferViews[buffer_view_index].byteOffset;
236+ u64 byte_length = Json.bufferViews[buffer_view_index].byteLength;
237+ u8 image[byte_length] @ Offset + byte_offset;
238+ } [[hex::visualize("image", image)]];
239+
240+ struct BufferView<auto Offset> {
241+ hex::type::Json<json_length> Json @ json_offset;
242+ u64 buffer_view_index = std::core::array_index();
243+ u64 byte_offset = Json.bufferViews[buffer_view_index].byteOffset;
244+ u64 byte_length = Json.bufferViews[buffer_view_index].byteLength;
245+ u8 data[byte_length] @ Offset + byte_offset;
246+ };
247+
248+ struct Glb {
249+ gltf_magic_t magic;
250+ gltf_chunk_t jsonChunk;
251+ gltf_chunk_t chunks[while(!std::mem::eof())];
252+
253+ json_offset = addressof(jsonChunk.json);
254+ json_length = jsonChunk.length;
255+
256+ std::assert_warn(std::mem::size() == magic.length, "file size mismatch");
257+
258+ if (std::core::member_count(chunks) == 1) {
259+ u128 binChunk = addressof(chunks[0].data);
260+ hex::type::Json<json_length> Json @ json_offset;
261+ if (std::core::has_member(Json, "images")) {
262+ ImageBuffer<binChunk> images[mem_cnt(jsonChunk.json.images)];
263+ }
264+ BufferView<binChunk> buffer_views[mem_cnt(jsonChunk.json.bufferViews)];
265+ Accessor<binChunk> accessors[mem_cnt(jsonChunk.json.accessors)];
266+ }
267+ };
268+
269+ Glb glb @ 0x00;
0 commit comments