1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef CORE__GLTF__GLTF2_DATA_STRUCTURES_H
17 #define CORE__GLTF__GLTF2_DATA_STRUCTURES_H
18 
19 #include <cstdint>
20 
21 #include <base/containers/string.h>
22 #include <base/containers/unique_ptr.h>
23 #include <base/containers/vector.h>
24 #include <base/math/matrix.h>
25 #include <base/math/quaternion.h>
26 #include <base/math/vector.h>
27 #include <core/namespace.h>
28 
29 #define GLTF2_EXTENSION_IGFX_COMPRESSED
30 #define GLTF2_EXTENSION_KHR_LIGHTS
31 #define GLTF2_EXTENSION_KHR_LIGHTS_PBR
32 #define GLTF2_EXTENSION_KHR_MATERIALS_CLEARCOAT
33 #define GLTF2_EXTENSION_KHR_MATERIALS_EMISSIVE_STRENGTH
34 #define GLTF2_EXTENSION_KHR_MATERIALS_IOR
35 #define GLTF2_EXTENSION_KHR_MATERIALS_PBRSPECULARGLOSSINESS
36 #define GLTF2_EXTENSION_KHR_MATERIALS_SHEEN
37 #define GLTF2_EXTENSION_KHR_MATERIALS_SPECULAR
38 #define GLTF2_EXTENSION_KHR_MATERIALS_TRANSMISSION
39 #define GLTF2_EXTENSION_KHR_MATERIALS_UNLIT
40 #define GLTF2_EXTENSION_KHR_MESH_QUANTIZATION
41 #define GLTF2_EXTENSION_KHR_TEXTURE_BASISU
42 #define GLTF2_EXTENSION_KHR_TEXTURE_TRANSFORM
43 #define GLTF2_EXTENSION_EXT_LIGHTS_IMAGE_BASED
44 #define GLTF2_EXTRAS_CLEAR_COAT_MATERIAL
45 #define GLTF2_EXTENSION_HW_XR_EXT
46 #define GLTF2_EXTRAS_RSDZ
47 
48 #ifdef OPAQUE
49 // hrpm win32 gdi..
50 #undef OPAQUE
51 #endif
52 
CORE3D_BEGIN_NAMESPACE()53 CORE3D_BEGIN_NAMESPACE()
54 namespace GLTF2 {
55 constexpr const uint32_t GLTF_INVALID_INDEX = 0xFFFFFFFF;
56 constexpr const uint32_t GLTF_MAGIC = 0x46546C67; // ASCII string "glTF"
57 
58 struct Skin;
59 struct AttributeBase;
60 struct Node;
61 
62 // extensions
63 #if defined(GLTF2_EXTENSION_KHR_LIGHTS) || defined(GLTF2_EXTENSION_KHR_LIGHTS_PBR)
64 struct KHRLight;
65 #endif
66 
67 enum class BufferTarget : int {
68     NOT_DEFINED = 0,
69     ARRAY_BUFFER = 34962,
70     ELEMENT_ARRAY_BUFFER = 34963,
71 };
72 
73 enum class ChunkType : int {
74     JSON = 0x4E4F534A, //  JSON
75     BIN = 0x004E4942,  //  BIN Binary buffer
76 };
77 
78 enum class AttributeType : int {
79     NORMAL = 0,
80     POSITION = 1,
81     TANGENT = 2,
82     TEXCOORD = 3,
83     COLOR = 4,
84     JOINTS = 5,
85     WEIGHTS = 6,
86     INVALID = 0xff
87 };
88 
89 enum class RenderMode : int {
90     // WebGL enums
91     BEGIN = 0,
92     POINTS = 0,
93     LINES = 1,
94     LINE_LOOP = 2,
95     LINE_STRIP = 3,
96     TRIANGLES = 4,
97     TRIANGLE_STRIP = 5,
98     TRIANGLE_FAN = 6,
99     COUNT = 7,
100     INVALID = 0xff
101 };
102 
103 enum class ComponentType : int {
104     INVALID,
105     BYTE = 5120,
106     UNSIGNED_BYTE = 5121,
107     SHORT = 5122,
108     UNSIGNED_SHORT = 5123,
109     INT = 5124, // not used in GLTF2
110     UNSIGNED_INT = 5125,
111     FLOAT = 5126,
112 };
113 
114 enum class DataType : int { INVALID, SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4 };
115 
116 enum class AlphaMode : int {
117     // The alpha value is ignored and the rendered output is fully opaque.
118     OPAQUE,
119     // The rendered output is either fully opaque or fully transparent
120     // depending on the alpha value and the specified alpha cutoff value.
121     MASK,
122     // The alpha value is used to composite the source and destination areas.
123     // The rendered output is combined with the background using the normal
124     // painting operation (i.e. the Porter and Duff over operator).
125     BLEND,
126 };
127 
128 enum class BlendMode : int {
129     TRANSPARENT_ALPHA, // transparentAlpha
130     TRANSPARENT_COLOR, // transparentColor
131     ADD,               // add
132     MODULATE,          // modulate
133     REPLACE,           // replace
134     NONE               // use alphaMode if blendMode not mentioned, (default)
135 };
136 
137 enum class MimeType : int { INVALID, JPEG, PNG, KTX, DDS, KTX2 };
138 
139 enum class CameraType : int { INVALID, PERSPECTIVE, ORTHOGRAPHIC };
140 
141 enum class LightType : int { INVALID, DIRECTIONAL, POINT, SPOT, AMBIENT };
142 
143 enum class FilterMode : int {
144     NEAREST = 9728,
145     LINEAR = 9729,
146     NEAREST_MIPMAP_NEAREST = 9984,
147     LINEAR_MIPMAP_NEAREST = 9985,
148     NEAREST_MIPMAP_LINEAR = 9986,
149     LINEAR_MIPMAP_LINEAR = 9987
150 };
151 
152 enum class WrapMode : int { CLAMP_TO_EDGE = 33071, MIRRORED_REPEAT = 33648, REPEAT = 10497 };
153 
154 enum class AnimationInterpolation : int { INVALID, STEP, LINEAR, SPLINE };
155 
156 enum class AnimationPath : int {
157     INVALID,
158     TRANSLATION,
159     ROTATION,
160     SCALE,
161     WEIGHTS,
162     // RDSZ specific
163     VISIBLE,
164     OPACITY,
165 };
166 
167 struct GLBHeader {
168     uint32_t magic = 0;
169     uint32_t version = 0;
170     uint32_t length = 0;
171 };
172 
173 struct GLBChunk {
174     uint32_t chunkLength = 0;
175     uint32_t chunkType = 0;
176 };
177 
178 struct Buffer {
179     // [required field]
180     size_t byteLength = 0;
181 
182     // either empty (indicating GLB buffer)
183     // or path to file
184     // or data:[<mediatype>][;base64],<data> as defined
185     // in https://tools.ietf.org/html/rfc2397
186     BASE_NS::string uri;
187 
188     // Data for this buffer.
189     BASE_NS::vector<uint8_t> data;
190 };
191 
192 struct BufferView {
193     // [required field], with the index to the buffer.
194     // Note: referenced buffers needs to be loaded first.
195     Buffer* buffer { nullptr };
196 
197     // required, "minimum": 1
198     size_t byteLength = 0;
199 
200     // "minimum": 0, "default": 0
201     size_t byteOffset = 0;
202 
203     // "minimum": 4, "maximum": 252, "multipleOf": 4
204     // The stride, in bytes, between vertex attributes.
205     // When this is not defined (0), data is tightly packed.
206     // When two or more accessors use the same bufferView, this field must be defined.
207     size_t byteStride = 0;
208 
209     BufferTarget target = BufferTarget::NOT_DEFINED; // ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER
210 
211     // Data for this buffer view.
212     const uint8_t* data { nullptr };
213 };
214 
215 struct SparseIndices {
216     // The bufferView with sparse indices.
217     // Referenced bufferView can't have ARRAY_BUFFER or
218     // ELEMENT_ARRAY_BUFFER target.
219     BufferView* bufferView { nullptr };
220 
221     // The offset relative to the start of the bufferView in bytes.
222     // Must be aligned.
223     // "minimum": 0,
224     // "default": 0
225     uint32_t byteOffset = 0;
226 
227     // The indices data type.
228     // Valid values correspond to WebGL enums:
229     // `5121` means UNSIGNED_BYTE, `5123` means UNSIGNED_SHORT
230     // `5125` means UNSIGNED_INT.
231     ComponentType componentType = ComponentType::UNSIGNED_INT;
232 };
233 
234 struct SparseValues {
235     // The bufferView with sparse values.
236     // Referenced bufferView can't have ARRAY_BUFFER or
237     // ELEMENT_ARRAY_BUFFER target."
238     BufferView* bufferView { nullptr };
239 
240     // The offset relative to the start of the bufferView in bytes.
241     // Must be aligned.
242     uint32_t byteOffset = 0;
243 };
244 
245 struct Sparse {
246     // The number of attributes encoded in this sparse accessor.
247     uint32_t count = 0;
248 
249     // Index array of size `count` that points to those accessor attributes
250     // that deviate from their initialization value. Indices must strictly increase.
251     SparseIndices indices;
252 
253     // Array of size `count` times number of components,
254     // storing the displaced accessor attributes pointed by `indices`.
255     // Substituted values must have the same `componentType` and
256     // number of components as the base accessor."
257     SparseValues values;
258 };
259 
260 struct Accessor {
261     // The bufferView.
262     // When not defined, accessor must be initialized with zeros;
263     // `sparse` property or extensions could override zeros with actual values.
264     BufferView* bufferView { nullptr };
265 
266     // [required] The datatype of components in the attribute.
267     // All valid values correspond to WebGL enums.
268     // The corresponding typed arrays are
269     // `Int8Array`, `Uint8Array`, `Int16Array`, `Uint16Array`,
270     // `Uint32Array`, and `Float32Array`, respectively.
271     // 5125 (UNSIGNED_INT) is only allowed when the accessor contains indices,
272     // i.e., the accessor is only referenced by `primitive.indices`.
273     ComponentType componentType = ComponentType::UNSIGNED_INT;
274 
275     // [required] The number of attributes referenced by this accessor,
276     // not to be confused with the number of bytes or number of components.
277     // "minimum": 1
278     uint32_t count = 0;
279 
280     // [required] Specifies if the attribute is a scalar, vector, or matrix.
281     DataType type = DataType::INVALID;
282 
283     // The offset relative to the start of the bufferView in bytes.
284     // This must be a multiple of the size of the component datatype.
285     // minimum: 0
286     // default: 0
287     uint32_t byteOffset = 0;
288 
289     // Specifies whether integer data values should be normalized
290     // (`true`) to [0, 1] (for unsigned types) or [-1, 1] (for signed types),
291     // or converted directly (`false`) when they are accessed.
292     // This property is defined only for accessors that contain vertex attributes
293     // or animation output data.
294     // "default": false
295     bool normalized = false;
296 
297     // Maximum value of each component in this attribute.
298     // Array elements must be treated as having the same data type as
299     // accessor's `componentType`. Both min and max arrays have the same length.
300     // The length is determined by the value of the type property;
301     // it can be 1, 2, 3, 4, 9, or 16.
302     // `normalized` property has no effect on array values:
303     // they always correspond to the actual values stored in the buffer.
304     // When accessor is sparse, this property must contain max values of
305     // accessor data with sparse substitution applied.
306     // "minItems": 1,
307     // "maxItems": 16,
308     BASE_NS::vector<float> max;
309 
310     // Minimum value of each component in this attribute.
311     // Array elements must be treated as having the same data type as
312     // accessor's `componentType`. Both min and max arrays have the same length.
313     // The length is determined by the value of the type property;
314     // it can be 1, 2, 3, 4, 9, or 16.
315     // `normalized` property has no effect on array values:
316     // they always correspond to the actual values stored in the buffer.
317     // When accessor is sparse, this property must contain min values of
318     // accessor data with sparse substitution applied.
319     // "minItems": 1,
320     // "maxItems": 16,
321     BASE_NS::vector<float> min;
322 
323     // Sparse storage of attributes that deviate from their initialization value.
324     Sparse sparse;
325 };
326 
327 struct AttributeBase {
328     AttributeType type;
329     uint32_t index; // for example texcoord 0,1,2...
330 };
331 
332 struct Attribute {
333     AttributeBase attribute;
334     Accessor* accessor { nullptr };
335 };
336 
337 struct Image {
338     // The uri of the image.
339     // Relative paths are relative to the .gltf file.
340     // Instead of referencing an external file,
341     // the uri can also be a data-uri.
342     // The image format must be jpg or png.
343     BASE_NS::string uri;
344 
345     // The bufferView that contains the image.
346     // Use this instead of the image's uri property.
347     BufferView* bufferView { nullptr };
348 
349     // The image's MIME type. Needed when BufferView is used.
350     MimeType type;
351 };
352 
353 struct Sampler {
354     FilterMode magFilter = FilterMode::LINEAR;
355     FilterMode minFilter = FilterMode::LINEAR;
356 
357     WrapMode wrapS = WrapMode::REPEAT;
358     WrapMode wrapT = WrapMode::REPEAT;
359 };
360 
361 struct Texture {
362     // The sampler used by this texture.
363     // When nullptr, a sampler with repeat wrapping
364     // and auto filtering should be used.
365     Sampler* sampler { nullptr };
366 
367     // The image used by this texture.
368     Image* image { nullptr };
369 };
370 
371 struct TextureInfo {
372     // The texture.
373     Texture* texture { nullptr };
374 
375     // index defined in gltf.
376     uint32_t index = GLTF_INVALID_INDEX;
377 
378     // The set index of texture's TEXCOORD attribute
379     //  used for texture coordinate mapping.
380     // "default": 0
381     uint32_t texCoordIndex = 0;
382 
383 #if defined(GLTF2_EXTENSION_KHR_TEXTURE_TRANSFORM)
384     struct TextureTransform {
385         BASE_NS::Math::Vec2 offset { 0.0f, 0.0f };
386         BASE_NS::Math::Vec2 scale { 1.f, 1.f };
387         float rotation = 0.0f;
388         uint32_t texCoordIndex = GLTF_INVALID_INDEX;
389     } transform;
390 #endif
391 };
392 
393 struct MetallicRoughness {
394     // The RGBA components of the base color of the material.
395     // The fourth component (A) is the alpha coverage of the material.
396     // The `alphaMode` property specifies how alpha is interpreted.
397     //  These values are linear. If a baseColorTexture is specified,
398     //  this value is multiplied with the texel values.
399     //  "default": [ 1.0, 1.0, 1.0, 1.0 ]
400     BASE_NS::Math::Vec4 baseColorFactor { 1.f, 1.f, 1.f, 1.f };
401 
402     // The base color texture.
403     // This texture contains RGB(A) components in sRGB color space.
404     // The first three components (RGB) specify the base color of the
405     // material. If the fourth component (A) is present, it represents
406     // the alpha coverage of the material. Otherwise, an alpha of 1.0 is
407     // assumed. The `alphaMode` property specifies how alpha is
408     // interpreted. The stored texels must not be premultiplied.
409     // "default": 1.0
410     TextureInfo baseColorTexture;
411 
412     // The metalness  of the material.
413     // A value of 1.0 means the material is a metal.
414     // A value of 0.0 means the material is a dielectric.
415     // Values in between are for blending between metals
416     // and dielectrics such as dirty metallic surfaces.
417     // This value is linear. If a metallicRoughnessTexture is specified,
418     // this value is multiplied with the metallic texel values.
419     float metallicFactor { 1.f };
420 
421     // The roughness of the material.
422     // A value of 1.0 means the material is completely rough.
423     // A value of 0.0 means the material is completely smooth.
424     // This value is linear. If a metallicRoughnessTexture is specified,
425     // this value is multiplied with the roughness texel values.
426     // "default": 1.0
427     float roughnessFactor { 1.f };
428 
429     // The metallic-roughness texture.
430     // The metalness values are sampled from the B channel.
431     // The roughness values are sampled from the G channel.
432     // These values are linear. If other channels are present (R or A),
433     // they are ignored for metallic-roughness calculations.
434     TextureInfo metallicRoughnessTexture;
435 };
436 
437 struct NormalTexture {
438     TextureInfo textureInfo;
439     float scale = 1.0f;
440 };
441 
442 struct OcclusionTexture {
443     TextureInfo textureInfo;
444     float strength = 1.0f;
445 };
446 
447 struct Material {
448     enum class Type { MetallicRoughness, SpecularGlossiness, Unlit, TextureSheetAnimation };
449 
450     Type type { Type::MetallicRoughness };
451 
452     BASE_NS::string name; // name
453     MetallicRoughness metallicRoughness;
454 
455     // "The scalar multiplier applied to each normal vector of the texture.
456     // This value scales the normal vector using the formula:
457     // `scaledNormal =  normalize((normalize(<sampled normal texture value>) * 2.0
458     // - 1.0) * vec3(<normal scale>, <normal scale>, 1.0))`. This value is ignored if
459     // normalTexture is not specified. This value is linear."
460     NormalTexture normalTexture;
461 
462     // A scalar multiplier controlling the amount of occlusion applied.
463     // A value of 0.0 means no occlusion. A value of 1.0 means full occlusion.
464     // This value affects the resulting color using the formula:
465     // `occludedColor = lerp(color, color * <sampled occlusion texture value>,
466     // <occlusion strength>)`. This value is ignored if the corresponding texture
467     // is not specified. This value is linear. "default": 1.0, "minimum": 0.0,
468     // "maximum": 1.0,
469     OcclusionTexture occlusionTexture;
470 
471     TextureInfo emissiveTexture;
472 
473     BASE_NS::Math::Vec4 emissiveFactor = BASE_NS::Math::Vec4(0.f, 0.f, 0.f, 1.f); // "default": [ 0.0, 0.0, 0.0 ],
474 
475     AlphaMode alphaMode = AlphaMode::OPAQUE;
476 
477     BlendMode blendMode = BlendMode::NONE;
478 
479     float alphaCutoff = 0.5f; // "minimum": 0.0,
480 
481     // default": false,
482     // Specifies whether the material is double sided.
483     // When this value is false, back-face culling is enabled.
484     // When this value is true, back-face culling is disabled
485     // and double sided lighting is enabled.
486     // The back-face must have its normals reversed before
487     // the lighting equation is evaluated.
488     bool doubleSided = false;
489 
490 #if defined(GLTF2_EXTENSION_KHR_MATERIALS_CLEARCOAT) || defined(GLTF2_EXTRAS_CLEAR_COAT_MATERIAL)
491     struct Clearcoat {
492         // The clearcoat layer intensity.
493         float factor = 0.0f;
494         // The clearcoat layer intensity texture.
495         TextureInfo texture;
496         // The clearcoat layer roughness.
497         float roughness = 0.0f;
498         // The clearcoat layer roughness texture.
499         TextureInfo roughnessTexture;
500         // The clearcoat normal map texture.
501         NormalTexture normalTexture;
502     } clearcoat;
503 #endif
504 
505 #if defined(GLTF2_EXTENSION_KHR_MATERIALS_IOR)
506     struct Ior {
507         // Material's index of refraction.
508         float ior = 1.5f;
509     } ior;
510 #endif
511 
512 #if defined(GLTF2_EXTENSION_KHR_MATERIALS_PBRSPECULARGLOSSINESS)
513     struct SpecularGlossiness {
514         // The RGBA components of the reflected diffuse color of the material.
515         // Metals have a diffuse value of `[0.0, 0.0, 0.0]`. The fourth component (A) is the alpha coverage of the
516         // material. The 'alphaMode' property specifies how alpha is interpreted. The values are linear.
517         BASE_NS::Math::Vec4 diffuseFactor { 1.f, 1.f, 1.f, 1.f }; // "default": [ 1.0, 1.0, 1.0, 1.0 ]
518 
519         // The diffuse texture. This texture contains RGB(A) components of the reflected diffuse color of the material
520         // in sRGB color space. If the fourth component (A) is present, it represents the alpha coverage of the
521         // material. Otherwise, an alpha of 1.0 is assumed. The `alphaMode` property specifies how alpha is interpreted.
522         // The stored texels must not be premultiplied.
523         TextureInfo diffuseTexture;
524 
525         // The specular RGB color of the material. This value is linear.
526         BASE_NS::Math::Vec3 specularFactor { 1.f, 1.f, 1.f }; // "default": [ 1.0, 1.0, 1.0 ]
527 
528         // The glossiness or smoothness of the material.A value of 1.0 means the material has full glossiness
529         // or is perfectly smooth.A value of 0.0 means the material has no glossiness or is completely rough.This value
530         // is linear.
531         float glossinessFactor = 1.0f;
532 
533         // The specular-glossiness texture is RGBA texture, containing the specular color of the material (RGB
534         // components) and its glossiness (A component). The values are in sRGB space.
535         TextureInfo specularGlossinessTexture;
536     } specularGlossiness;
537 #endif
538 
539 #if defined(GLTF2_EXTENSION_KHR_MATERIALS_SHEEN)
540     struct Sheen {
541         // The sheen color in linear space
542         BASE_NS::Math::Vec3 factor;
543         // The sheen color (sRGB)
544         TextureInfo texture;
545         // The sheen roughness.
546         float roughness = 0.0f;
547         // The sheen roughness texture, stored in the alpha channel.
548         TextureInfo roughnessTexture;
549     } sheen;
550 #endif
551 
552 #if defined(GLTF2_EXTENSION_KHR_MATERIALS_SPECULAR)
553     struct Specular {
554         // The specular reflection strength.
555         float factor = 1.f;
556         // The specular reflection strength texture, stored in the alpha channel.
557         TextureInfo texture;
558         // The specular color in linear space.
559         BASE_NS::Math::Vec3 color { 1.f, 1.f, 1.f };
560         // The specular color texture. The values are in sRGB space.
561         TextureInfo colorTexture;
562     } specular;
563 #endif
564 
565 #if defined(GLTF2_EXTENSION_KHR_MATERIALS_TRANSMISSION)
566     struct Transmission {
567         // Percentage of light that is transmitted through the surface
568         float factor = 0.0f;
569         // Transmission percentage of the surface, stored in the R channel. This will be multiplied by
570         // transmissionFactor.
571         TextureInfo texture;
572     } transmission;
573 #endif
574 };
575 
576 struct MorphTarget {
577     // extension of spec
578     // see https://github.com/KhronosGroup/glTF-Blender-Exporter/pull/153)
579     //     https://github.com/KhronosGroup/glTF/issues/1036
580     BASE_NS::string name;
581     BASE_NS::vector<Attribute> target;
582 #if defined(GLTF2_EXTENSION_IGFX_COMPRESSED)
583     // true when morph target is using IGFX_compressed extension.
584     bool iGfxCompressed = false;
585 #endif
586 };
587 
588 struct MeshPrimitive {
589     // [required fields]
590     // A dictionary object, where each key corresponds
591     // to mesh attribute semantic and each value is the index
592     // of the accessor containing attribute's data.
593     BASE_NS::vector<Attribute> attributes;
594 
595     // "The index of the accessor that contains mesh indices.
596     // When this is not defined, the primitives should be rendered
597     // without indices using drawArrays.
598     // When defined, the accessor must contain indices:
599     // the `bufferView` referenced by the accessor should have
600     // a `target` equal to 34963 (ELEMENT_ARRAY_BUFFER)
601     // `componentType` must be 5121 (UNSIGNED_BYTE),
602     // 5123 (UNSIGNED_SHORT) or 5125 (UNSIGNED_INT),
603     // the latter may require enabling additional hardware support;
604     // `type` must be `\"SCALAR\"`.
605     // For triangle primitives, the front face has
606     // a counter-clockwise (CCW) winding order."
607     Accessor* indices { nullptr };
608 
609     // "The index of the material to apply to this primitive when rendering.
610     Material* material { nullptr };
611 
612     // index defined in gltf.
613     uint32_t materialIndex = GLTF_INVALID_INDEX;
614 
615     // The type of primitives to render. All valid values correspond to WebGL enums.
616     RenderMode mode = RenderMode::TRIANGLES;
617 
618     // An array of Morph Targets,
619     // each  Morph Target is a dictionary mapping attributes
620     // (only `POSITION`, `NORMAL`, and `TANGENT` supported)
621     // to their deviations in the Morph Target.
622     BASE_NS::vector<MorphTarget> targets;
623 };
624 
625 struct Mesh {
626     // Name.
627     BASE_NS::string name;
628     // [required field], primitives
629     BASE_NS::vector<MeshPrimitive> primitives;
630     // Array of weights to be applied to the Morph Targets.
631     BASE_NS::vector<float> weights;
632 };
633 
634 struct Camera {
635     // Name.
636     BASE_NS::string name;
637 
638     CameraType type;
639 
640     union Attributes {
641         struct Perspective {
642             // PERSPECTIVE
643             // minimum value for each is 0
644             // => in this implementation negative is used to disable parameter
645             float aspect;
646             float yfov; // required
647             float zfar;
648             float znear; // required
649         } perspective;
650 
651         struct Ortho {
652             // ORTHOGRAPHIC
653             // xmag, ymag cant't be zero
654             // zfar, znear : minimum is zero
655             // all are required
656             float xmag;
657             float ymag;
658             float zfar;
659             float znear;
660         } ortho;
661     } attributes;
662 };
663 
664 struct Skin {
665     BASE_NS::string name;
666 
667     // The accessor containing the floating-point 4X4 inverse-bind matrices.
668     // The default is that each matrix is a 4X4 identity matrix,
669     // which implies that inverse-bind matrices were pre-applied.
670     Accessor* inverseBindMatrices { nullptr };
671 
672     // The node used as a skeleton root. When undefined, joints transforms resolve to scene root.
673     Node* skeleton { nullptr };
674 
675     // The skeleton nodes, used as joints in this skin.
676     BASE_NS::vector<Node*> joints;
677 };
678 
679 struct Node {
680     BASE_NS::string name;
681 
682     Mesh* mesh { nullptr };
683 
684     Camera* camera { nullptr };
685 
686 #if defined(GLTF2_EXTENSION_KHR_LIGHTS) || defined(GLTF2_EXTENSION_KHR_LIGHTS_PBR)
687     KHRLight* light { nullptr };
688 #endif
689 
690 #if defined(GLTF2_EXTRAS_RSDZ)
691     BASE_NS::string modelIdRSDZ;
692 #endif
693 
694     // Helpers mostly for skeleton support
695     Node* parent { nullptr };
696     bool isJoint = false;
697 
698     BASE_NS::vector<Node*> children;
699     BASE_NS::vector<size_t> tmpChildren; // indices, used when gltf is parsed. (NOTE: move outside of node)
700 
701     Skin* skin { nullptr };
702     uint32_t tmpSkin; // index to skin (NOTE: move outside of node)
703 
704     bool usesTRS = true;
705 
706     BASE_NS::Math::Vec3 translation { 0.f, 0.f, 0.f };
707     BASE_NS::Math::Quat rotation { 0.f, 0.f, 0.f, 1.f };
708     BASE_NS::Math::Vec3 scale { 1.f, 1.f, 1.f };
709 
710     BASE_NS::Math::Mat4X4 matrix;
711 
712     BASE_NS::vector<float> weights;
713 };
714 
715 struct Scene {
716     BASE_NS::string name;
717     BASE_NS::vector<Node*> nodes;
718 
719 #if defined(GLTF2_EXTENSION_KHR_LIGHTS) || defined(GLTF2_EXTENSION_KHR_LIGHTS_PBR)
720     KHRLight* light { nullptr }; // Ambient light
721 #endif
722 
723 #if defined(GLTF2_EXTENSION_EXT_LIGHTS_IMAGE_BASED)
724     size_t imageBasedLightIndex = GLTF_INVALID_INDEX;
725 #endif
726 };
727 
728 struct AnimationSampler {
729     Accessor* input { nullptr };
730     Accessor* output { nullptr };
731     AnimationInterpolation interpolation;
732 };
733 
734 struct AnimationChannel // = animation.channel.target
735 {
736     Node* node { nullptr };
737     AnimationPath path;
738 };
739 
740 struct AnimationTrack // = animation.channel
741 {
742     AnimationChannel channel;
743     AnimationSampler* sampler { nullptr };
744 };
745 
746 struct Animation {
747     BASE_NS::string name;
748     BASE_NS::vector<AnimationTrack> tracks;
749     BASE_NS::vector<BASE_NS::unique_ptr<AnimationSampler>> samplers;
750 };
751 
752 // extensions
753 #if defined(GLTF2_EXTENSION_KHR_LIGHTS) || defined(GLTF2_EXTENSION_KHR_LIGHTS_PBR)
754 struct KHRLight {
755     BASE_NS::string name;
756     LightType type = LightType::DIRECTIONAL;
757     BASE_NS::Math::Vec3 color = BASE_NS::Math::Vec3(1.f, 1.f, 1.f); // RGB
758     float intensity = 1.0f; // Intensity of the light source in lumens. default 1.0
759 
760     struct {
761         float range = .0f;
762 
763         struct {
764             // SPOT
765             float innerAngle = 0.f;
766             float outerAngle = 0.785398163397448f; // PI / 4
767         } spot;
768 
769     } positional;
770 
771     struct {
772         bool shadowCaster = false;
773         float nearClipDistance = 100.f;
774         float farClipDistance = 10000.f;
775     } shadow;
776 };
777 #endif
778 
779 #if defined(GLTF2_EXTENSION_EXT_LIGHTS_IMAGE_BASED)
780 struct ImageBasedLight {
781     // Represents one mip level of a cube map.
782     using CubemapMipLevel = BASE_NS::vector<size_t>;
783     // Represents one set of irrandiance coefficients.
784     using LightingCoeff = BASE_NS::vector<float>;
785 
786     // Name of the light.
787     BASE_NS::string name;
788     // Quaternion that represents the rotation of the IBL environment.
789     BASE_NS::Math::Quat rotation { 0.0f, 0.0f, 0.0f, 1.0f };
790     // Brightness multiplier for environment.
791     float intensity { 1.0f };
792     // Declares spherical harmonic coefficients for irradiance up to l=2. This is a 9x3 array.
793     BASE_NS::vector<LightingCoeff> irradianceCoefficients;
794     // Declares an array of the first N mips of the prefiltered cubemap.
795     // Each mip is, in turn, defined with an array of 6 images, one for each cube face. i.e. this is an Nx6 array.
796     BASE_NS::vector<CubemapMipLevel> specularImages;
797     // The dimension (in pixels) of the first specular mip. This is needed to determine, pre-load, the total number of
798     // mips needed.
799     uint32_t specularImageSize { 0 };
800     // Specular cubemap image, optional.
801     size_t specularCubeImage { GLTF_INVALID_INDEX };
802     // Skymap cubemap image, optional.
803     size_t skymapImage { GLTF_INVALID_INDEX };
804     // Skymap image lod level, optional.
805     float skymapImageLodLevel { 0.0f };
806 };
807 #endif
808 
809 } // namespace GLTF2
810 CORE3D_END_NAMESPACE()
811 
812 #endif // CORE__GLTF__GLTF2_DATA_STRUCTURES_H