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