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