92 #ifndef CGLTF_H_INCLUDED__
93 #define CGLTF_H_INCLUDED__
101 typedef size_t cgltf_size;
102 typedef float cgltf_float;
103 typedef int cgltf_int;
104 typedef unsigned int cgltf_uint;
105 typedef int cgltf_bool;
107 typedef enum cgltf_file_type
109 cgltf_file_type_invalid,
110 cgltf_file_type_gltf,
114 typedef enum cgltf_result
116 cgltf_result_success,
117 cgltf_result_data_too_short,
118 cgltf_result_unknown_format,
119 cgltf_result_invalid_json,
120 cgltf_result_invalid_gltf,
121 cgltf_result_invalid_options,
122 cgltf_result_file_not_found,
123 cgltf_result_io_error,
124 cgltf_result_out_of_memory,
125 cgltf_result_legacy_gltf,
130 void* (*alloc)(
void* user, cgltf_size size);
131 void (*free) (
void* user,
void* ptr);
144 cgltf_file_type type;
145 cgltf_size json_token_count;
150 typedef enum cgltf_buffer_view_type
152 cgltf_buffer_view_type_invalid,
153 cgltf_buffer_view_type_indices,
154 cgltf_buffer_view_type_vertices,
155 } cgltf_buffer_view_type;
157 typedef enum cgltf_attribute_type
159 cgltf_attribute_type_invalid,
160 cgltf_attribute_type_position,
161 cgltf_attribute_type_normal,
162 cgltf_attribute_type_tangent,
163 cgltf_attribute_type_texcoord,
164 cgltf_attribute_type_color,
165 cgltf_attribute_type_joints,
166 cgltf_attribute_type_weights,
167 } cgltf_attribute_type;
169 typedef enum cgltf_component_type
171 cgltf_component_type_invalid,
172 cgltf_component_type_r_8,
173 cgltf_component_type_r_8u,
174 cgltf_component_type_r_16,
175 cgltf_component_type_r_16u,
176 cgltf_component_type_r_32u,
177 cgltf_component_type_r_32f,
178 } cgltf_component_type;
180 typedef enum cgltf_type
192 typedef enum cgltf_primitive_type
194 cgltf_primitive_type_points,
195 cgltf_primitive_type_lines,
196 cgltf_primitive_type_line_loop,
197 cgltf_primitive_type_line_strip,
198 cgltf_primitive_type_triangles,
199 cgltf_primitive_type_triangle_strip,
200 cgltf_primitive_type_triangle_fan,
201 } cgltf_primitive_type;
203 typedef enum cgltf_alpha_mode
205 cgltf_alpha_mode_opaque,
206 cgltf_alpha_mode_mask,
207 cgltf_alpha_mode_blend,
210 typedef enum cgltf_animation_path_type {
211 cgltf_animation_path_type_invalid,
212 cgltf_animation_path_type_translation,
213 cgltf_animation_path_type_rotation,
214 cgltf_animation_path_type_scale,
215 cgltf_animation_path_type_weights,
216 } cgltf_animation_path_type;
218 typedef enum cgltf_interpolation_type {
219 cgltf_interpolation_type_linear,
220 cgltf_interpolation_type_step,
221 cgltf_interpolation_type_cubic_spline,
222 } cgltf_interpolation_type;
224 typedef enum cgltf_camera_type {
225 cgltf_camera_type_invalid,
226 cgltf_camera_type_perspective,
227 cgltf_camera_type_orthographic,
230 typedef enum cgltf_light_type {
231 cgltf_light_type_invalid,
232 cgltf_light_type_directional,
233 cgltf_light_type_point,
234 cgltf_light_type_spot,
237 typedef enum cgltf_data_free_method {
238 cgltf_data_free_method_none,
239 cgltf_data_free_method_file_release,
240 cgltf_data_free_method_memory_free,
241 } cgltf_data_free_method;
244 cgltf_size start_offset;
245 cgltf_size end_offset;
259 cgltf_data_free_method data_free_method;
261 cgltf_size extensions_count;
265 typedef enum cgltf_meshopt_compression_mode {
266 cgltf_meshopt_compression_mode_invalid,
267 cgltf_meshopt_compression_mode_attributes,
268 cgltf_meshopt_compression_mode_triangles,
269 cgltf_meshopt_compression_mode_indices,
270 } cgltf_meshopt_compression_mode;
272 typedef enum cgltf_meshopt_compression_filter {
273 cgltf_meshopt_compression_filter_none,
274 cgltf_meshopt_compression_filter_octahedral,
275 cgltf_meshopt_compression_filter_quaternion,
276 cgltf_meshopt_compression_filter_exponential,
277 } cgltf_meshopt_compression_filter;
286 cgltf_meshopt_compression_mode mode;
287 cgltf_meshopt_compression_filter filter;
297 cgltf_buffer_view_type type;
299 cgltf_bool has_meshopt_compression;
302 cgltf_size extensions_count;
310 cgltf_size indices_byte_offset;
311 cgltf_component_type indices_component_type;
313 cgltf_size values_byte_offset;
317 cgltf_size extensions_count;
319 cgltf_size indices_extensions_count;
321 cgltf_size values_extensions_count;
328 cgltf_component_type component_type;
329 cgltf_bool normalized;
339 cgltf_bool is_sparse;
342 cgltf_size extensions_count;
349 cgltf_attribute_type type;
361 cgltf_size extensions_count;
368 cgltf_int mag_filter;
369 cgltf_int min_filter;
373 cgltf_size extensions_count;
382 cgltf_bool has_basisu;
385 cgltf_size extensions_count;
391 cgltf_float offset[2];
392 cgltf_float rotation;
393 cgltf_float scale[2];
394 cgltf_bool has_texcoord;
403 cgltf_bool has_transform;
406 cgltf_size extensions_count;
415 cgltf_float base_color_factor[4];
416 cgltf_float metallic_factor;
417 cgltf_float roughness_factor;
427 cgltf_float diffuse_factor[4];
428 cgltf_float specular_factor[3];
429 cgltf_float glossiness_factor;
438 cgltf_float clearcoat_factor;
439 cgltf_float clearcoat_roughness_factor;
445 cgltf_float transmission_factor;
457 cgltf_float specular_color_factor[3];
458 cgltf_float specular_factor;
464 cgltf_float thickness_factor;
465 cgltf_float attenuation_color[3];
466 cgltf_float attenuation_distance;
472 cgltf_float sheen_color_factor[3];
474 cgltf_float sheen_roughness_factor;
479 cgltf_float emissive_strength;
484 cgltf_float iridescence_factor;
486 cgltf_float iridescence_ior;
487 cgltf_float iridescence_thickness_min;
488 cgltf_float iridescence_thickness_max;
495 cgltf_bool has_pbr_metallic_roughness;
496 cgltf_bool has_pbr_specular_glossiness;
497 cgltf_bool has_clearcoat;
498 cgltf_bool has_transmission;
499 cgltf_bool has_volume;
501 cgltf_bool has_specular;
502 cgltf_bool has_sheen;
503 cgltf_bool has_emissive_strength;
504 cgltf_bool has_iridescence;
518 cgltf_float emissive_factor[3];
519 cgltf_alpha_mode alpha_mode;
520 cgltf_float alpha_cutoff;
521 cgltf_bool double_sided;
524 cgltf_size extensions_count;
537 cgltf_size attributes_count;
543 cgltf_size attributes_count;
549 cgltf_size attributes_count;
553 cgltf_primitive_type type;
557 cgltf_size attributes_count;
559 cgltf_size targets_count;
561 cgltf_bool has_draco_mesh_compression;
564 cgltf_size mappings_count;
565 cgltf_size extensions_count;
572 cgltf_size primitives_count;
573 cgltf_float* weights;
574 cgltf_size weights_count;
576 cgltf_size target_names_count;
578 cgltf_size extensions_count;
587 cgltf_size joints_count;
591 cgltf_size extensions_count;
596 cgltf_bool has_aspect_ratio;
597 cgltf_float aspect_ratio;
615 cgltf_camera_type type;
621 cgltf_size extensions_count;
627 cgltf_float color[3];
628 cgltf_float intensity;
629 cgltf_light_type type;
631 cgltf_float spot_inner_cone_angle;
632 cgltf_float spot_outer_cone_angle;
640 cgltf_size children_count;
645 cgltf_float* weights;
646 cgltf_size weights_count;
647 cgltf_bool has_translation;
648 cgltf_bool has_rotation;
649 cgltf_bool has_scale;
650 cgltf_bool has_matrix;
651 cgltf_float translation[3];
652 cgltf_float rotation[4];
653 cgltf_float scale[3];
654 cgltf_float matrix[16];
656 cgltf_bool has_mesh_gpu_instancing;
658 cgltf_size extensions_count;
665 cgltf_size nodes_count;
667 cgltf_size extensions_count;
674 cgltf_interpolation_type interpolation;
676 cgltf_size extensions_count;
683 cgltf_animation_path_type target_path;
685 cgltf_size extensions_count;
692 cgltf_size samplers_count;
694 cgltf_size channels_count;
696 cgltf_size extensions_count;
712 cgltf_size extensions_count;
718 cgltf_file_type file_type;
724 cgltf_size meshes_count;
727 cgltf_size materials_count;
730 cgltf_size accessors_count;
733 cgltf_size buffer_views_count;
736 cgltf_size buffers_count;
739 cgltf_size images_count;
742 cgltf_size textures_count;
745 cgltf_size samplers_count;
748 cgltf_size skins_count;
751 cgltf_size cameras_count;
754 cgltf_size lights_count;
757 cgltf_size nodes_count;
760 cgltf_size scenes_count;
765 cgltf_size animations_count;
768 cgltf_size variants_count;
772 cgltf_size data_extensions_count;
775 char** extensions_used;
776 cgltf_size extensions_used_count;
778 char** extensions_required;
779 cgltf_size extensions_required_count;
782 cgltf_size json_size;
791 cgltf_result cgltf_parse(
797 cgltf_result cgltf_parse_file(
802 cgltf_result cgltf_load_buffers(
805 const char* gltf_path);
807 cgltf_result cgltf_load_buffer_base64(
const cgltf_options* options, cgltf_size size,
const char* base64,
void** out_data);
809 cgltf_size cgltf_decode_string(
char*
string);
810 cgltf_size cgltf_decode_uri(
char* uri);
812 cgltf_result cgltf_validate(
cgltf_data* data);
816 void cgltf_node_transform_local(
const cgltf_node* node, cgltf_float* out_matrix);
817 void cgltf_node_transform_world(
const cgltf_node* node, cgltf_float* out_matrix);
819 cgltf_bool cgltf_accessor_read_float(
const cgltf_accessor* accessor, cgltf_size index, cgltf_float* out, cgltf_size element_size);
820 cgltf_bool cgltf_accessor_read_uint(
const cgltf_accessor* accessor, cgltf_size index, cgltf_uint* out, cgltf_size element_size);
821 cgltf_size cgltf_accessor_read_index(
const cgltf_accessor* accessor, cgltf_size index);
823 cgltf_size cgltf_num_components(cgltf_type type);
825 cgltf_size cgltf_accessor_unpack_floats(
const cgltf_accessor* accessor, cgltf_float* out, cgltf_size float_count);
827 cgltf_result cgltf_copy_extras_json(
const cgltf_data* data,
const cgltf_extras* extras,
char* dest, cgltf_size* dest_size);
842 #if defined(__INTELLISENSE__) || defined(__JETBRAINS_IDE__)
844 #define CGLTF_IMPLEMENTATION
847 #ifdef CGLTF_IMPLEMENTATION
855 #if !defined(CGLTF_MALLOC) || !defined(CGLTF_FREE) || !defined(CGLTF_ATOI) || !defined(CGLTF_ATOF) || !defined(CGLTF_ATOLL)
860 #define JSMN_PARENT_LINKS
879 JSMN_ERROR_NOMEM = -1,
881 JSMN_ERROR_INVAL = -2,
890 #ifdef JSMN_PARENT_LINKS
896 unsigned int toknext;
899 static void jsmn_init(jsmn_parser *parser);
900 static int jsmn_parse(jsmn_parser *parser,
const char *js,
size_t len, jsmntok_t *tokens,
size_t num_tokens);
906 static const cgltf_size GlbHeaderSize = 12;
907 static const cgltf_size GlbChunkHeaderSize = 8;
908 static const uint32_t GlbVersion = 2;
909 static const uint32_t GlbMagic = 0x46546C67;
910 static const uint32_t GlbMagicJsonChunk = 0x4E4F534A;
911 static const uint32_t GlbMagicBinChunk = 0x004E4942;
914 #define CGLTF_MALLOC(size) malloc(size)
917 #define CGLTF_FREE(ptr) free(ptr)
920 #define CGLTF_ATOI(str) atoi(str)
923 #define CGLTF_ATOF(str) atof(str)
926 #define CGLTF_ATOLL(str) atoll(str)
928 #ifndef CGLTF_VALIDATE_ENABLE_ASSERTS
929 #define CGLTF_VALIDATE_ENABLE_ASSERTS 0
932 static void* cgltf_default_alloc(
void* user, cgltf_size size)
935 return CGLTF_MALLOC(size);
938 static void cgltf_default_free(
void* user,
void* ptr)
944 static void* cgltf_calloc(
cgltf_options* options,
size_t element_size, cgltf_size count)
946 if (SIZE_MAX / element_size < count)
950 void* result = options->memory.alloc(options->memory.user_data, element_size * count);
955 memset(result, 0, element_size * count);
959 static cgltf_result cgltf_default_file_read(
const struct cgltf_memory_options* memory_options,
const struct cgltf_file_options* file_options,
const char* path, cgltf_size* size,
void** data)
962 void* (*memory_alloc)(
void*, cgltf_size) = memory_options->alloc ? memory_options->alloc : &cgltf_default_alloc;
963 void (*memory_free)(
void*,
void*) = memory_options->free ? memory_options->free : &cgltf_default_free;
965 FILE* file = fopen(path,
"rb");
968 return cgltf_result_file_not_found;
971 cgltf_size file_size = size ? *size : 0;
975 fseek(file, 0, SEEK_END);
978 __int64
length = _ftelli64(file);
980 long length = ftell(file);
986 return cgltf_result_io_error;
989 fseek(file, 0, SEEK_SET);
990 file_size = (cgltf_size)
length;
993 char* file_data = (
char*)memory_alloc(memory_options->user_data, file_size);
997 return cgltf_result_out_of_memory;
1000 cgltf_size read_size = fread(file_data, 1, file_size, file);
1004 if (read_size != file_size)
1006 memory_free(memory_options->user_data, file_data);
1007 return cgltf_result_io_error;
1019 return cgltf_result_success;
1025 void (*memfree)(
void*,
void*) = memory_options->free ? memory_options->free : &cgltf_default_free;
1026 memfree(memory_options->user_data, data);
1029 static cgltf_result cgltf_parse_json(
cgltf_options* options,
const uint8_t* json_chunk, cgltf_size size,
cgltf_data** out_data);
1031 cgltf_result cgltf_parse(
const cgltf_options* options,
const void* data, cgltf_size size,
cgltf_data** out_data)
1033 if (size < GlbHeaderSize)
1035 return cgltf_result_data_too_short;
1038 if (options == NULL)
1040 return cgltf_result_invalid_options;
1044 if (fixed_options.memory.alloc == NULL)
1046 fixed_options.memory.alloc = &cgltf_default_alloc;
1048 if (fixed_options.memory.free == NULL)
1050 fixed_options.memory.free = &cgltf_default_free;
1055 memcpy(&tmp, data, 4);
1056 if (tmp != GlbMagic)
1058 if (fixed_options.type == cgltf_file_type_invalid)
1060 fixed_options.type = cgltf_file_type_gltf;
1062 else if (fixed_options.type == cgltf_file_type_glb)
1064 return cgltf_result_unknown_format;
1068 if (fixed_options.type == cgltf_file_type_gltf)
1070 cgltf_result json_result = cgltf_parse_json(&fixed_options, (
const uint8_t*)data, size, out_data);
1071 if (json_result != cgltf_result_success)
1076 (*out_data)->file_type = cgltf_file_type_gltf;
1078 return cgltf_result_success;
1081 const uint8_t* ptr = (
const uint8_t*)data;
1083 memcpy(&tmp, ptr + 4, 4);
1084 uint32_t version = tmp;
1085 if (version != GlbVersion)
1087 return version < GlbVersion ? cgltf_result_legacy_gltf : cgltf_result_unknown_format;
1091 memcpy(&tmp, ptr + 8, 4);
1094 return cgltf_result_data_too_short;
1097 const uint8_t* json_chunk = ptr + GlbHeaderSize;
1099 if (GlbHeaderSize + GlbChunkHeaderSize > size)
1101 return cgltf_result_data_too_short;
1105 uint32_t json_length;
1106 memcpy(&json_length, json_chunk, 4);
1107 if (GlbHeaderSize + GlbChunkHeaderSize + json_length > size)
1109 return cgltf_result_data_too_short;
1113 memcpy(&tmp, json_chunk + 4, 4);
1114 if (tmp != GlbMagicJsonChunk)
1116 return cgltf_result_unknown_format;
1119 json_chunk += GlbChunkHeaderSize;
1121 const void* bin = 0;
1122 cgltf_size bin_size = 0;
1124 if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize <= size)
1127 const uint8_t* bin_chunk = json_chunk + json_length;
1130 uint32_t bin_length;
1131 memcpy(&bin_length, bin_chunk, 4);
1132 if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize + bin_length > size)
1134 return cgltf_result_data_too_short;
1138 memcpy(&tmp, bin_chunk + 4, 4);
1139 if (tmp != GlbMagicBinChunk)
1141 return cgltf_result_unknown_format;
1144 bin_chunk += GlbChunkHeaderSize;
1147 bin_size = bin_length;
1150 cgltf_result json_result = cgltf_parse_json(&fixed_options, json_chunk, json_length, out_data);
1151 if (json_result != cgltf_result_success)
1156 (*out_data)->file_type = cgltf_file_type_glb;
1157 (*out_data)->bin = bin;
1158 (*out_data)->bin_size = bin_size;
1160 return cgltf_result_success;
1165 if (options == NULL)
1167 return cgltf_result_invalid_options;
1170 cgltf_result (*file_read)(
const struct cgltf_memory_options*,
const struct cgltf_file_options*,
const char*, cgltf_size*,
void**) = options->file.read ? options->file.read : &cgltf_default_file_read;
1173 void* file_data = NULL;
1174 cgltf_size file_size = 0;
1175 cgltf_result result = file_read(&options->memory, &options->file, path, &file_size, &file_data);
1176 if (result != cgltf_result_success)
1181 result = cgltf_parse(options, file_data, file_size, out_data);
1183 if (result != cgltf_result_success)
1185 file_release(&options->memory, &options->file, file_data);
1189 (*out_data)->file_data = file_data;
1191 return cgltf_result_success;
1194 static void cgltf_combine_paths(
char* path,
const char* base,
const char* uri)
1196 const char* s0 = strrchr(base,
'/');
1197 const char* s1 = strrchr(base,
'\\');
1198 const char* slash = s0 ? (s1 && s1 > s0 ? s1 : s0) : s1;
1202 size_t prefix = slash - base + 1;
1204 strncpy(path, base, prefix);
1205 strcpy(path + prefix, uri);
1213 static cgltf_result cgltf_load_buffer_file(
const cgltf_options* options, cgltf_size size,
const char* uri,
const char* gltf_path,
void** out_data)
1215 void* (*memory_alloc)(
void*, cgltf_size) = options->memory.alloc ? options->memory.alloc : &cgltf_default_alloc;
1216 void (*memory_free)(
void*,
void*) = options->memory.free ? options->memory.free : &cgltf_default_free;
1217 cgltf_result (*file_read)(
const struct cgltf_memory_options*,
const struct cgltf_file_options*,
const char*, cgltf_size*,
void**) = options->file.read ? options->file.read : &cgltf_default_file_read;
1219 char* path = (
char*)memory_alloc(options->memory.user_data, strlen(uri) + strlen(gltf_path) + 1);
1222 return cgltf_result_out_of_memory;
1225 cgltf_combine_paths(path, gltf_path, uri);
1228 cgltf_decode_uri(path + strlen(path) - strlen(uri));
1230 void* file_data = NULL;
1231 cgltf_result result = file_read(&options->memory, &options->file, path, &size, &file_data);
1233 memory_free(options->memory.user_data, path);
1235 *out_data = (result == cgltf_result_success) ? file_data : NULL;
1240 cgltf_result cgltf_load_buffer_base64(
const cgltf_options* options, cgltf_size size,
const char* base64,
void** out_data)
1242 void* (*memory_alloc)(
void*, cgltf_size) = options->memory.alloc ? options->memory.alloc : &cgltf_default_alloc;
1243 void (*memory_free)(
void*,
void*) = options->memory.free ? options->memory.free : &cgltf_default_free;
1245 unsigned char* data = (
unsigned char*)memory_alloc(options->memory.user_data, size);
1248 return cgltf_result_out_of_memory;
1251 unsigned int buffer = 0;
1252 unsigned int buffer_bits = 0;
1254 for (cgltf_size i = 0; i < size; ++i)
1256 while (buffer_bits < 8)
1258 char ch = *base64++;
1261 (unsigned)(ch -
'A') < 26 ? (ch -
'A') :
1262 (
unsigned)(ch -
'a') < 26 ? (ch -
'a') + 26 :
1263 (unsigned)(ch -
'0') < 10 ? (ch -
'0') + 52 :
1270 memory_free(options->memory.user_data, data);
1271 return cgltf_result_io_error;
1274 buffer = (buffer << 6) | index;
1278 data[i] = (
unsigned char)(buffer >> (buffer_bits - 8));
1284 return cgltf_result_success;
1287 static int cgltf_unhex(
char ch)
1290 (
unsigned)(ch -
'0') < 10 ? (ch -
'0') :
1291 (unsigned)(ch -
'A') < 6 ? (ch -
'A') + 10 :
1292 (
unsigned)(ch -
'a') < 6 ? (ch -
'a') + 10 :
1296 cgltf_size cgltf_decode_string(
char*
string)
1298 char* read =
string + strcspn(
string,
"\\");
1301 return read - string;
1303 char* write = string;
1304 char* last = string;
1309 cgltf_size written = read - last;
1310 memmove(write, last, written);
1321 case '\"': *write++ =
'\"';
break;
1322 case '/': *write++ =
'/';
break;
1323 case '\\': *write++ =
'\\';
break;
1324 case 'b': *write++ =
'\b';
break;
1325 case 'f': *write++ =
'\f';
break;
1326 case 'r': *write++ =
'\r';
break;
1327 case 'n': *write++ =
'\n';
break;
1328 case 't': *write++ =
'\t';
break;
1333 for (cgltf_size i = 0; i < 4; ++i)
1335 character = (character << 4) + cgltf_unhex(*read++);
1338 if (character <= 0x7F)
1340 *write++ = character & 0xFF;
1342 else if (character <= 0x7FF)
1344 *write++ = 0xC0 | ((character >> 6) & 0xFF);
1345 *write++ = 0x80 | (character & 0x3F);
1349 *write++ = 0xE0 | ((character >> 12) & 0xFF);
1350 *write++ = 0x80 | ((character >> 6) & 0x3F);
1351 *write++ = 0x80 | (character & 0x3F);
1360 read += strcspn(read,
"\\");
1364 return write - string;
1367 cgltf_size cgltf_decode_uri(
char* uri)
1376 int ch1 = cgltf_unhex(i[1]);
1380 int ch2 = cgltf_unhex(i[2]);
1384 *write++ = (char)(ch1 * 16 + ch2);
1400 if (options == NULL)
1402 return cgltf_result_invalid_options;
1405 if (data->buffers_count && data->buffers[0].data == NULL && data->buffers[0].uri == NULL && data->bin)
1407 if (data->bin_size < data->buffers[0].size)
1409 return cgltf_result_data_too_short;
1412 data->buffers[0].data = (
void*)data->bin;
1413 data->buffers[0].data_free_method = cgltf_data_free_method_none;
1416 for (cgltf_size i = 0; i < data->buffers_count; ++i)
1418 if (data->buffers[i].data)
1423 const char* uri = data->buffers[i].uri;
1430 if (strncmp(uri,
"data:", 5) == 0)
1432 const char* comma = strchr(uri,
',');
1434 if (comma && comma - uri >= 7 && strncmp(comma - 7,
";base64", 7) == 0)
1436 cgltf_result res = cgltf_load_buffer_base64(options, data->buffers[i].size, comma + 1, &data->buffers[i].data);
1437 data->buffers[i].data_free_method = cgltf_data_free_method_memory_free;
1439 if (res != cgltf_result_success)
1446 return cgltf_result_unknown_format;
1449 else if (strstr(uri,
"://") == NULL && gltf_path)
1451 cgltf_result res = cgltf_load_buffer_file(options, data->buffers[i].size, uri, gltf_path, &data->buffers[i].data);
1452 data->buffers[i].data_free_method = cgltf_data_free_method_file_release;
1454 if (res != cgltf_result_success)
1461 return cgltf_result_unknown_format;
1465 return cgltf_result_success;
1468 static cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type);
1470 static cgltf_size cgltf_calc_index_bound(
cgltf_buffer_view* buffer_view, cgltf_size offset, cgltf_component_type component_type, cgltf_size count)
1472 char* data = (
char*)buffer_view->buffer->data + offset + buffer_view->offset;
1473 cgltf_size bound = 0;
1475 switch (component_type)
1477 case cgltf_component_type_r_8u:
1478 for (
size_t i = 0; i < count; ++i)
1480 cgltf_size v = ((
unsigned char*)data)[i];
1481 bound = bound > v ? bound : v;
1485 case cgltf_component_type_r_16u:
1486 for (
size_t i = 0; i < count; ++i)
1488 cgltf_size v = ((
unsigned short*)data)[i];
1489 bound = bound > v ? bound : v;
1493 case cgltf_component_type_r_32u:
1494 for (
size_t i = 0; i < count; ++i)
1496 cgltf_size v = ((
unsigned int*)data)[i];
1497 bound = bound > v ? bound : v;
1508 #if CGLTF_VALIDATE_ENABLE_ASSERTS
1509 #define CGLTF_ASSERT_IF(cond, result) assert(!(cond)); if (cond) return result;
1511 #define CGLTF_ASSERT_IF(cond, result) if (cond) return result;
1514 cgltf_result cgltf_validate(
cgltf_data* data)
1516 for (cgltf_size i = 0; i < data->accessors_count; ++i)
1520 cgltf_size element_size = cgltf_calc_size(accessor->type, accessor->component_type);
1522 if (accessor->buffer_view)
1524 cgltf_size req_size = accessor->offset + accessor->stride * (accessor->count - 1) + element_size;
1526 CGLTF_ASSERT_IF(accessor->buffer_view->size < req_size, cgltf_result_data_too_short);
1529 if (accessor->is_sparse)
1533 cgltf_size indices_component_size = cgltf_calc_size(cgltf_type_scalar, sparse->indices_component_type);
1534 cgltf_size indices_req_size = sparse->indices_byte_offset + indices_component_size * sparse->count;
1535 cgltf_size values_req_size = sparse->values_byte_offset + element_size * sparse->count;
1537 CGLTF_ASSERT_IF(sparse->indices_buffer_view->size < indices_req_size ||
1538 sparse->values_buffer_view->size < values_req_size, cgltf_result_data_too_short);
1540 CGLTF_ASSERT_IF(sparse->indices_component_type != cgltf_component_type_r_8u &&
1541 sparse->indices_component_type != cgltf_component_type_r_16u &&
1542 sparse->indices_component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);
1544 if (sparse->indices_buffer_view->buffer->data)
1546 cgltf_size index_bound = cgltf_calc_index_bound(sparse->indices_buffer_view, sparse->indices_byte_offset, sparse->indices_component_type, sparse->count);
1548 CGLTF_ASSERT_IF(index_bound >= accessor->count, cgltf_result_data_too_short);
1553 for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
1555 cgltf_size req_size = data->buffer_views[i].offset + data->buffer_views[i].size;
1557 CGLTF_ASSERT_IF(data->buffer_views[i].buffer && data->buffer_views[i].buffer->size < req_size, cgltf_result_data_too_short);
1559 if (data->buffer_views[i].has_meshopt_compression)
1563 CGLTF_ASSERT_IF(mc->buffer == NULL || mc->buffer->size < mc->offset + mc->size, cgltf_result_data_too_short);
1565 CGLTF_ASSERT_IF(data->buffer_views[i].stride && mc->stride != data->buffer_views[i].stride, cgltf_result_invalid_gltf);
1567 CGLTF_ASSERT_IF(data->buffer_views[i].size != mc->stride * mc->count, cgltf_result_invalid_gltf);
1569 CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_invalid, cgltf_result_invalid_gltf);
1571 CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_attributes && !(mc->stride % 4 == 0 && mc->stride <= 256), cgltf_result_invalid_gltf);
1573 CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_triangles && mc->count % 3 != 0, cgltf_result_invalid_gltf);
1575 CGLTF_ASSERT_IF((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->stride != 2 && mc->stride != 4, cgltf_result_invalid_gltf);
1577 CGLTF_ASSERT_IF((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->filter != cgltf_meshopt_compression_filter_none, cgltf_result_invalid_gltf);
1579 CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_octahedral && mc->stride != 4 && mc->stride != 8, cgltf_result_invalid_gltf);
1581 CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_quaternion && mc->stride != 8, cgltf_result_invalid_gltf);
1585 for (cgltf_size i = 0; i < data->meshes_count; ++i)
1587 if (data->meshes[i].weights)
1589 CGLTF_ASSERT_IF(data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].weights_count, cgltf_result_invalid_gltf);
1592 if (data->meshes[i].target_names)
1594 CGLTF_ASSERT_IF(data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].target_names_count, cgltf_result_invalid_gltf);
1597 for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
1599 CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count, cgltf_result_invalid_gltf);
1601 if (data->meshes[i].primitives[j].attributes_count)
1603 cgltf_accessor* first = data->meshes[i].primitives[j].attributes[0].data;
1605 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
1607 CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes[k].data->count != first->count, cgltf_result_invalid_gltf);
1610 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
1612 for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
1614 CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count, cgltf_result_invalid_gltf);
1620 CGLTF_ASSERT_IF(indices &&
1621 indices->component_type != cgltf_component_type_r_8u &&
1622 indices->component_type != cgltf_component_type_r_16u &&
1623 indices->component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);
1625 if (indices && indices->buffer_view && indices->buffer_view->buffer->data)
1627 cgltf_size index_bound = cgltf_calc_index_bound(indices->buffer_view, indices->offset, indices->component_type, indices->count);
1629 CGLTF_ASSERT_IF(index_bound >= first->count, cgltf_result_data_too_short);
1632 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
1634 CGLTF_ASSERT_IF(data->meshes[i].primitives[j].mappings[k].variant >= data->variants_count, cgltf_result_invalid_gltf);
1640 for (cgltf_size i = 0; i < data->nodes_count; ++i)
1642 if (data->nodes[i].weights && data->nodes[i].mesh)
1644 CGLTF_ASSERT_IF (data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count, cgltf_result_invalid_gltf);
1648 for (cgltf_size i = 0; i < data->nodes_count; ++i)
1655 CGLTF_ASSERT_IF(p1 == p2, cgltf_result_invalid_gltf);
1658 p2 = p2->parent ? p2->parent->parent : NULL;
1662 for (cgltf_size i = 0; i < data->scenes_count; ++i)
1664 for (cgltf_size j = 0; j < data->scenes[i].nodes_count; ++j)
1666 CGLTF_ASSERT_IF(data->scenes[i].nodes[j]->parent, cgltf_result_invalid_gltf);
1670 for (cgltf_size i = 0; i < data->animations_count; ++i)
1672 for (cgltf_size j = 0; j < data->animations[i].channels_count; ++j)
1676 if (!channel->target_node)
1681 cgltf_size components = 1;
1683 if (channel->target_path == cgltf_animation_path_type_weights)
1685 CGLTF_ASSERT_IF(!channel->target_node->mesh || !channel->target_node->mesh->primitives_count, cgltf_result_invalid_gltf);
1687 components = channel->target_node->mesh->primitives[0].targets_count;
1690 cgltf_size values = channel->sampler->interpolation == cgltf_interpolation_type_cubic_spline ? 3 : 1;
1692 CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_data_too_short);
1696 return cgltf_result_success;
1699 cgltf_result cgltf_copy_extras_json(
const cgltf_data* data,
const cgltf_extras* extras,
char* dest, cgltf_size* dest_size)
1701 cgltf_size json_size = extras->end_offset - extras->start_offset;
1707 *dest_size = json_size + 1;
1708 return cgltf_result_success;
1710 return cgltf_result_invalid_options;
1713 if (*dest_size + 1 < json_size)
1715 strncpy(dest, data->json + extras->start_offset, *dest_size - 1);
1716 dest[*dest_size - 1] = 0;
1720 strncpy(dest, data->json + extras->start_offset, json_size);
1721 dest[json_size] = 0;
1724 return cgltf_result_success;
1729 for (cgltf_size i = 0; i < extensions_count; ++i)
1731 data->memory.free(data->memory.user_data, extensions[i].name);
1732 data->memory.free(data->memory.user_data, extensions[i].data);
1734 data->memory.free(data->memory.user_data, extensions);
1746 data->memory.free(data->memory.user_data, data->asset.copyright);
1747 data->memory.free(data->memory.user_data, data->asset.generator);
1748 data->memory.free(data->memory.user_data, data->asset.version);
1749 data->memory.free(data->memory.user_data, data->asset.min_version);
1751 cgltf_free_extensions(data, data->asset.extensions, data->asset.extensions_count);
1753 for (cgltf_size i = 0; i < data->accessors_count; ++i)
1755 data->memory.free(data->memory.user_data, data->accessors[i].name);
1757 if(data->accessors[i].is_sparse)
1759 cgltf_free_extensions(data, data->accessors[i].sparse.extensions, data->accessors[i].sparse.extensions_count);
1760 cgltf_free_extensions(data, data->accessors[i].sparse.indices_extensions, data->accessors[i].sparse.indices_extensions_count);
1761 cgltf_free_extensions(data, data->accessors[i].sparse.values_extensions, data->accessors[i].sparse.values_extensions_count);
1763 cgltf_free_extensions(data, data->accessors[i].extensions, data->accessors[i].extensions_count);
1765 data->memory.free(data->memory.user_data, data->accessors);
1767 for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
1769 data->memory.free(data->memory.user_data, data->buffer_views[i].name);
1770 data->memory.free(data->memory.user_data, data->buffer_views[i].data);
1772 cgltf_free_extensions(data, data->buffer_views[i].extensions, data->buffer_views[i].extensions_count);
1774 data->memory.free(data->memory.user_data, data->buffer_views);
1776 for (cgltf_size i = 0; i < data->buffers_count; ++i)
1778 data->memory.free(data->memory.user_data, data->buffers[i].name);
1780 if (data->buffers[i].data_free_method == cgltf_data_free_method_file_release)
1782 file_release(&data->memory, &data->file, data->buffers[i].data);
1784 else if (data->buffers[i].data_free_method == cgltf_data_free_method_memory_free)
1786 data->memory.free(data->memory.user_data, data->buffers[i].data);
1789 data->memory.free(data->memory.user_data, data->buffers[i].uri);
1791 cgltf_free_extensions(data, data->buffers[i].extensions, data->buffers[i].extensions_count);
1794 data->memory.free(data->memory.user_data, data->buffers);
1796 for (cgltf_size i = 0; i < data->meshes_count; ++i)
1798 data->memory.free(data->memory.user_data, data->meshes[i].name);
1800 for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
1802 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
1804 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].attributes[k].name);
1807 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].attributes);
1809 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
1811 for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
1813 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].targets[k].attributes[m].name);
1816 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].targets[k].attributes);
1819 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].targets);
1821 if (data->meshes[i].primitives[j].has_draco_mesh_compression)
1823 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].draco_mesh_compression.attributes_count; ++k)
1825 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].draco_mesh_compression.attributes[k].name);
1828 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].draco_mesh_compression.attributes);
1831 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].mappings);
1833 cgltf_free_extensions(data, data->meshes[i].primitives[j].extensions, data->meshes[i].primitives[j].extensions_count);
1836 data->memory.free(data->memory.user_data, data->meshes[i].primitives);
1837 data->memory.free(data->memory.user_data, data->meshes[i].weights);
1839 for (cgltf_size j = 0; j < data->meshes[i].target_names_count; ++j)
1841 data->memory.free(data->memory.user_data, data->meshes[i].target_names[j]);
1844 cgltf_free_extensions(data, data->meshes[i].extensions, data->meshes[i].extensions_count);
1846 data->memory.free(data->memory.user_data, data->meshes[i].target_names);
1849 data->memory.free(data->memory.user_data, data->meshes);
1851 for (cgltf_size i = 0; i < data->materials_count; ++i)
1853 data->memory.free(data->memory.user_data, data->materials[i].name);
1855 if(data->materials[i].has_pbr_metallic_roughness)
1857 cgltf_free_extensions(data, data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.extensions, data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.extensions_count);
1858 cgltf_free_extensions(data, data->materials[i].pbr_metallic_roughness.base_color_texture.extensions, data->materials[i].pbr_metallic_roughness.base_color_texture.extensions_count);
1860 if(data->materials[i].has_pbr_specular_glossiness)
1862 cgltf_free_extensions(data, data->materials[i].pbr_specular_glossiness.diffuse_texture.extensions, data->materials[i].pbr_specular_glossiness.diffuse_texture.extensions_count);
1863 cgltf_free_extensions(data, data->materials[i].pbr_specular_glossiness.specular_glossiness_texture.extensions, data->materials[i].pbr_specular_glossiness.specular_glossiness_texture.extensions_count);
1865 if(data->materials[i].has_clearcoat)
1867 cgltf_free_extensions(data, data->materials[i].clearcoat.clearcoat_texture.extensions, data->materials[i].clearcoat.clearcoat_texture.extensions_count);
1868 cgltf_free_extensions(data, data->materials[i].clearcoat.clearcoat_roughness_texture.extensions, data->materials[i].clearcoat.clearcoat_roughness_texture.extensions_count);
1869 cgltf_free_extensions(data, data->materials[i].clearcoat.clearcoat_normal_texture.extensions, data->materials[i].clearcoat.clearcoat_normal_texture.extensions_count);
1871 if(data->materials[i].has_specular)
1873 cgltf_free_extensions(data, data->materials[i].specular.specular_texture.extensions, data->materials[i].specular.specular_texture.extensions_count);
1874 cgltf_free_extensions(data, data->materials[i].specular.specular_color_texture.extensions, data->materials[i].specular.specular_color_texture.extensions_count);
1876 if(data->materials[i].has_transmission)
1878 cgltf_free_extensions(data, data->materials[i].transmission.transmission_texture.extensions, data->materials[i].transmission.transmission_texture.extensions_count);
1880 if (data->materials[i].has_volume)
1882 cgltf_free_extensions(data, data->materials[i].volume.thickness_texture.extensions, data->materials[i].volume.thickness_texture.extensions_count);
1884 if(data->materials[i].has_sheen)
1886 cgltf_free_extensions(data, data->materials[i].sheen.sheen_color_texture.extensions, data->materials[i].sheen.sheen_color_texture.extensions_count);
1887 cgltf_free_extensions(data, data->materials[i].sheen.sheen_roughness_texture.extensions, data->materials[i].sheen.sheen_roughness_texture.extensions_count);
1889 if(data->materials[i].has_iridescence)
1891 cgltf_free_extensions(data, data->materials[i].iridescence.iridescence_texture.extensions, data->materials[i].iridescence.iridescence_texture.extensions_count);
1892 cgltf_free_extensions(data, data->materials[i].iridescence.iridescence_thickness_texture.extensions, data->materials[i].iridescence.iridescence_thickness_texture.extensions_count);
1895 cgltf_free_extensions(data, data->materials[i].normal_texture.extensions, data->materials[i].normal_texture.extensions_count);
1896 cgltf_free_extensions(data, data->materials[i].occlusion_texture.extensions, data->materials[i].occlusion_texture.extensions_count);
1897 cgltf_free_extensions(data, data->materials[i].emissive_texture.extensions, data->materials[i].emissive_texture.extensions_count);
1899 cgltf_free_extensions(data, data->materials[i].extensions, data->materials[i].extensions_count);
1902 data->memory.free(data->memory.user_data, data->materials);
1904 for (cgltf_size i = 0; i < data->images_count; ++i)
1906 data->memory.free(data->memory.user_data, data->images[i].name);
1907 data->memory.free(data->memory.user_data, data->images[i].uri);
1908 data->memory.free(data->memory.user_data, data->images[i].mime_type);
1910 cgltf_free_extensions(data, data->images[i].extensions, data->images[i].extensions_count);
1913 data->memory.free(data->memory.user_data, data->images);
1915 for (cgltf_size i = 0; i < data->textures_count; ++i)
1917 data->memory.free(data->memory.user_data, data->textures[i].name);
1918 cgltf_free_extensions(data, data->textures[i].extensions, data->textures[i].extensions_count);
1921 data->memory.free(data->memory.user_data, data->textures);
1923 for (cgltf_size i = 0; i < data->samplers_count; ++i)
1925 data->memory.free(data->memory.user_data, data->samplers[i].name);
1926 cgltf_free_extensions(data, data->samplers[i].extensions, data->samplers[i].extensions_count);
1929 data->memory.free(data->memory.user_data, data->samplers);
1931 for (cgltf_size i = 0; i < data->skins_count; ++i)
1933 data->memory.free(data->memory.user_data, data->skins[i].name);
1934 data->memory.free(data->memory.user_data, data->skins[i].joints);
1936 cgltf_free_extensions(data, data->skins[i].extensions, data->skins[i].extensions_count);
1939 data->memory.free(data->memory.user_data, data->skins);
1941 for (cgltf_size i = 0; i < data->cameras_count; ++i)
1943 data->memory.free(data->memory.user_data, data->cameras[i].name);
1944 cgltf_free_extensions(data, data->cameras[i].extensions, data->cameras[i].extensions_count);
1947 data->memory.free(data->memory.user_data, data->cameras);
1949 for (cgltf_size i = 0; i < data->lights_count; ++i)
1951 data->memory.free(data->memory.user_data, data->lights[i].name);
1954 data->memory.free(data->memory.user_data, data->lights);
1956 for (cgltf_size i = 0; i < data->nodes_count; ++i)
1958 data->memory.free(data->memory.user_data, data->nodes[i].name);
1959 data->memory.free(data->memory.user_data, data->nodes[i].children);
1960 data->memory.free(data->memory.user_data, data->nodes[i].weights);
1961 cgltf_free_extensions(data, data->nodes[i].extensions, data->nodes[i].extensions_count);
1964 data->memory.free(data->memory.user_data, data->nodes);
1966 for (cgltf_size i = 0; i < data->scenes_count; ++i)
1968 data->memory.free(data->memory.user_data, data->scenes[i].name);
1969 data->memory.free(data->memory.user_data, data->scenes[i].nodes);
1971 cgltf_free_extensions(data, data->scenes[i].extensions, data->scenes[i].extensions_count);
1974 data->memory.free(data->memory.user_data, data->scenes);
1976 for (cgltf_size i = 0; i < data->animations_count; ++i)
1978 data->memory.free(data->memory.user_data, data->animations[i].name);
1979 for (cgltf_size j = 0; j < data->animations[i].samplers_count; ++j)
1981 cgltf_free_extensions(data, data->animations[i].samplers[j].extensions, data->animations[i].samplers[j].extensions_count);
1983 data->memory.free(data->memory.user_data, data->animations[i].samplers);
1985 for (cgltf_size j = 0; j < data->animations[i].channels_count; ++j)
1987 cgltf_free_extensions(data, data->animations[i].channels[j].extensions, data->animations[i].channels[j].extensions_count);
1989 data->memory.free(data->memory.user_data, data->animations[i].channels);
1991 cgltf_free_extensions(data, data->animations[i].extensions, data->animations[i].extensions_count);
1994 data->memory.free(data->memory.user_data, data->animations);
1996 for (cgltf_size i = 0; i < data->variants_count; ++i)
1998 data->memory.free(data->memory.user_data, data->variants[i].name);
2001 data->memory.free(data->memory.user_data, data->variants);
2003 cgltf_free_extensions(data, data->data_extensions, data->data_extensions_count);
2005 for (cgltf_size i = 0; i < data->extensions_used_count; ++i)
2007 data->memory.free(data->memory.user_data, data->extensions_used[i]);
2010 data->memory.free(data->memory.user_data, data->extensions_used);
2012 for (cgltf_size i = 0; i < data->extensions_required_count; ++i)
2014 data->memory.free(data->memory.user_data, data->extensions_required[i]);
2017 data->memory.free(data->memory.user_data, data->extensions_required);
2019 file_release(&data->memory, &data->file, data->file_data);
2021 data->memory.free(data->memory.user_data, data);
2024 void cgltf_node_transform_local(
const cgltf_node* node, cgltf_float* out_matrix)
2026 cgltf_float* lm = out_matrix;
2028 if (node->has_matrix)
2030 memcpy(lm, node->matrix,
sizeof(
float) * 16);
2034 float tx = node->translation[0];
2035 float ty = node->translation[1];
2036 float tz = node->translation[2];
2038 float qx = node->rotation[0];
2039 float qy = node->rotation[1];
2040 float qz = node->rotation[2];
2041 float qw = node->rotation[3];
2043 float sx = node->scale[0];
2044 float sy = node->scale[1];
2045 float sz = node->scale[2];
2047 lm[0] = (1 - 2 * qy*qy - 2 * qz*qz) * sx;
2048 lm[1] = (2 * qx*qy + 2 * qz*qw) * sx;
2049 lm[2] = (2 * qx*qz - 2 * qy*qw) * sx;
2052 lm[4] = (2 * qx*qy - 2 * qz*qw) * sy;
2053 lm[5] = (1 - 2 * qx*qx - 2 * qz*qz) * sy;
2054 lm[6] = (2 * qy*qz + 2 * qx*qw) * sy;
2057 lm[8] = (2 * qx*qz + 2 * qy*qw) * sz;
2058 lm[9] = (2 * qy*qz - 2 * qx*qw) * sz;
2059 lm[10] = (1 - 2 * qx*qx - 2 * qy*qy) * sz;
2069 void cgltf_node_transform_world(
const cgltf_node* node, cgltf_float* out_matrix)
2071 cgltf_float* lm = out_matrix;
2072 cgltf_node_transform_local(node, lm);
2079 cgltf_node_transform_local(parent, pm);
2081 for (
int i = 0; i < 4; ++i)
2083 float l0 = lm[i * 4 + 0];
2084 float l1 = lm[i * 4 + 1];
2085 float l2 = lm[i * 4 + 2];
2087 float r0 = l0 * pm[0] + l1 * pm[4] + l2 * pm[8];
2088 float r1 = l0 * pm[1] + l1 * pm[5] + l2 * pm[9];
2089 float r2 = l0 * pm[2] + l1 * pm[6] + l2 * pm[10];
2100 parent = parent->parent;
2104 static cgltf_size cgltf_component_read_index(
const void* in, cgltf_component_type component_type)
2106 switch (component_type)
2108 case cgltf_component_type_r_16:
2109 return *((
const int16_t*) in);
2110 case cgltf_component_type_r_16u:
2111 return *((
const uint16_t*) in);
2112 case cgltf_component_type_r_32u:
2113 return *((
const uint32_t*) in);
2114 case cgltf_component_type_r_32f:
2115 return (cgltf_size)*((
const float*) in);
2116 case cgltf_component_type_r_8:
2117 return *((
const int8_t*) in);
2118 case cgltf_component_type_r_8u:
2119 return *((
const uint8_t*) in);
2125 static cgltf_float cgltf_component_read_float(
const void* in, cgltf_component_type component_type, cgltf_bool normalized)
2127 if (component_type == cgltf_component_type_r_32f)
2129 return *((
const float*) in);
2134 switch (component_type)
2137 case cgltf_component_type_r_16:
2138 return *((
const int16_t*) in) / (cgltf_float)32767;
2139 case cgltf_component_type_r_16u:
2140 return *((
const uint16_t*) in) / (cgltf_float)65535;
2141 case cgltf_component_type_r_8:
2142 return *((
const int8_t*) in) / (cgltf_float)127;
2143 case cgltf_component_type_r_8u:
2144 return *((
const uint8_t*) in) / (cgltf_float)255;
2150 return (cgltf_float)cgltf_component_read_index(in, component_type);
2153 static cgltf_size cgltf_component_size(cgltf_component_type component_type);
2155 static cgltf_bool cgltf_element_read_float(
const uint8_t* element, cgltf_type type, cgltf_component_type component_type, cgltf_bool normalized, cgltf_float* out, cgltf_size element_size)
2157 cgltf_size num_components = cgltf_num_components(type);
2159 if (element_size < num_components) {
2165 cgltf_size component_size = cgltf_component_size(component_type);
2167 if (type == cgltf_type_mat2 && component_size == 1)
2169 out[0] = cgltf_component_read_float(element, component_type, normalized);
2170 out[1] = cgltf_component_read_float(element + 1, component_type, normalized);
2171 out[2] = cgltf_component_read_float(element + 4, component_type, normalized);
2172 out[3] = cgltf_component_read_float(element + 5, component_type, normalized);
2176 if (type == cgltf_type_mat3 && component_size == 1)
2178 out[0] = cgltf_component_read_float(element, component_type, normalized);
2179 out[1] = cgltf_component_read_float(element + 1, component_type, normalized);
2180 out[2] = cgltf_component_read_float(element + 2, component_type, normalized);
2181 out[3] = cgltf_component_read_float(element + 4, component_type, normalized);
2182 out[4] = cgltf_component_read_float(element + 5, component_type, normalized);
2183 out[5] = cgltf_component_read_float(element + 6, component_type, normalized);
2184 out[6] = cgltf_component_read_float(element + 8, component_type, normalized);
2185 out[7] = cgltf_component_read_float(element + 9, component_type, normalized);
2186 out[8] = cgltf_component_read_float(element + 10, component_type, normalized);
2190 if (type == cgltf_type_mat3 && component_size == 2)
2192 out[0] = cgltf_component_read_float(element, component_type, normalized);
2193 out[1] = cgltf_component_read_float(element + 2, component_type, normalized);
2194 out[2] = cgltf_component_read_float(element + 4, component_type, normalized);
2195 out[3] = cgltf_component_read_float(element + 8, component_type, normalized);
2196 out[4] = cgltf_component_read_float(element + 10, component_type, normalized);
2197 out[5] = cgltf_component_read_float(element + 12, component_type, normalized);
2198 out[6] = cgltf_component_read_float(element + 16, component_type, normalized);
2199 out[7] = cgltf_component_read_float(element + 18, component_type, normalized);
2200 out[8] = cgltf_component_read_float(element + 20, component_type, normalized);
2204 for (cgltf_size i = 0; i < num_components; ++i)
2206 out[i] = cgltf_component_read_float(element + component_size * i, component_type, normalized);
2214 return (
const uint8_t*)view->data;
2216 if (!view->buffer->data)
2219 const uint8_t* result = (
const uint8_t*)view->buffer->data;
2220 result += view->offset;
2224 cgltf_bool cgltf_accessor_read_float(
const cgltf_accessor* accessor, cgltf_size index, cgltf_float* out, cgltf_size element_size)
2226 if (accessor->is_sparse)
2230 if (accessor->buffer_view == NULL)
2232 memset(out, 0, element_size *
sizeof(cgltf_float));
2235 const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
2236 if (element == NULL)
2240 element += accessor->offset + accessor->stride * index;
2241 return cgltf_element_read_float(element, accessor->type, accessor->component_type, accessor->normalized, out, element_size);
2244 cgltf_size cgltf_accessor_unpack_floats(
const cgltf_accessor* accessor, cgltf_float* out, cgltf_size float_count)
2246 cgltf_size floats_per_element = cgltf_num_components(accessor->type);
2247 cgltf_size available_floats = accessor->count * floats_per_element;
2250 return available_floats;
2253 float_count = available_floats < float_count ? available_floats : float_count;
2254 cgltf_size element_count = float_count / floats_per_element;
2257 cgltf_float* dest = out;
2259 dense.is_sparse = 0;
2260 for (cgltf_size index = 0; index < element_count; index++, dest += floats_per_element)
2262 if (!cgltf_accessor_read_float(&dense, index, dest, floats_per_element))
2269 if (accessor->is_sparse)
2273 const uint8_t* index_data = cgltf_buffer_view_data(sparse->indices_buffer_view);
2274 const uint8_t* reader_head = cgltf_buffer_view_data(sparse->values_buffer_view);
2276 if (index_data == NULL || reader_head == NULL)
2281 index_data += sparse->indices_byte_offset;
2282 reader_head += sparse->values_byte_offset;
2284 cgltf_size index_stride = cgltf_component_size(sparse->indices_component_type);
2285 for (cgltf_size reader_index = 0; reader_index < sparse->count; reader_index++, index_data += index_stride)
2287 size_t writer_index = cgltf_component_read_index(index_data, sparse->indices_component_type);
2288 float* writer_head = out + writer_index * floats_per_element;
2290 if (!cgltf_element_read_float(reader_head, dense.type, dense.component_type, dense.normalized, writer_head, floats_per_element))
2295 reader_head += dense.stride;
2299 return element_count * floats_per_element;
2302 static cgltf_uint cgltf_component_read_uint(
const void* in, cgltf_component_type component_type)
2304 switch (component_type)
2306 case cgltf_component_type_r_8:
2307 return *((
const int8_t*) in);
2309 case cgltf_component_type_r_8u:
2310 return *((
const uint8_t*) in);
2312 case cgltf_component_type_r_16:
2313 return *((
const int16_t*) in);
2315 case cgltf_component_type_r_16u:
2316 return *((
const uint16_t*) in);
2318 case cgltf_component_type_r_32u:
2319 return *((
const uint32_t*) in);
2326 static cgltf_bool cgltf_element_read_uint(
const uint8_t* element, cgltf_type type, cgltf_component_type component_type, cgltf_uint* out, cgltf_size element_size)
2328 cgltf_size num_components = cgltf_num_components(type);
2330 if (element_size < num_components)
2336 if (type == cgltf_type_mat2 || type == cgltf_type_mat3 || type == cgltf_type_mat4)
2341 cgltf_size component_size = cgltf_component_size(component_type);
2343 for (cgltf_size i = 0; i < num_components; ++i)
2345 out[i] = cgltf_component_read_uint(element + component_size * i, component_type);
2350 cgltf_bool cgltf_accessor_read_uint(
const cgltf_accessor* accessor, cgltf_size index, cgltf_uint* out, cgltf_size element_size)
2352 if (accessor->is_sparse)
2356 if (accessor->buffer_view == NULL)
2358 memset(out, 0, element_size *
sizeof( cgltf_uint ));
2361 const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
2362 if (element == NULL)
2366 element += accessor->offset + accessor->stride * index;
2367 return cgltf_element_read_uint(element, accessor->type, accessor->component_type, out, element_size);
2370 cgltf_size cgltf_accessor_read_index(
const cgltf_accessor* accessor, cgltf_size index)
2372 if (accessor->is_sparse)
2376 if (accessor->buffer_view == NULL)
2380 const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
2381 if (element == NULL)
2385 element += accessor->offset + accessor->stride * index;
2386 return cgltf_component_read_index(element, accessor->component_type);
2389 #define CGLTF_ERROR_JSON -1
2390 #define CGLTF_ERROR_NOMEM -2
2391 #define CGLTF_ERROR_LEGACY -3
2393 #define CGLTF_CHECK_TOKTYPE(tok_, type_) if ((tok_).type != (type_)) { return CGLTF_ERROR_JSON; }
2394 #define CGLTF_CHECK_TOKTYPE_RETTYPE(tok_, type_, ret_) if ((tok_).type != (type_)) { return (ret_)CGLTF_ERROR_JSON; }
2395 #define CGLTF_CHECK_KEY(tok_) if ((tok_).type != JSMN_STRING || (tok_).size == 0) { return CGLTF_ERROR_JSON; }
2397 #define CGLTF_PTRINDEX(type, idx) (type*)((cgltf_size)idx + 1)
2398 #define CGLTF_PTRFIXUP(var, data, size) if (var) { if ((cgltf_size)var > size) { return CGLTF_ERROR_JSON; } var = &data[(cgltf_size)var-1]; }
2399 #define CGLTF_PTRFIXUP_REQ(var, data, size) if (!var || (cgltf_size)var > size) { return CGLTF_ERROR_JSON; } var = &data[(cgltf_size)var-1];
2401 static int cgltf_json_strcmp(jsmntok_t
const* tok,
const uint8_t* json_chunk,
const char* str)
2403 CGLTF_CHECK_TOKTYPE(*tok, JSMN_STRING);
2404 size_t const str_len = strlen(str);
2405 size_t const name_length = tok->end - tok->start;
2406 return (str_len == name_length) ? strncmp((
const char*)json_chunk + tok->start, str, str_len) : 128;
2409 static int cgltf_json_to_int(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2411 CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE);
2413 int size = (cgltf_size)(tok->end - tok->start) <
sizeof(tmp) ? tok->end - tok->start : (
int)(
sizeof(tmp) - 1);
2414 strncpy(tmp, (
const char*)json_chunk + tok->start, size);
2416 return CGLTF_ATOI(tmp);
2419 static cgltf_size cgltf_json_to_size(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2421 CGLTF_CHECK_TOKTYPE_RETTYPE(*tok, JSMN_PRIMITIVE, cgltf_size);
2423 int size = (cgltf_size)(tok->end - tok->start) <
sizeof(tmp) ? tok->end - tok->start : (
int)(
sizeof(tmp) - 1);
2424 strncpy(tmp, (
const char*)json_chunk + tok->start, size);
2426 return (cgltf_size)CGLTF_ATOLL(tmp);
2429 static cgltf_float cgltf_json_to_float(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2431 CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE);
2433 int size = (cgltf_size)(tok->end - tok->start) <
sizeof(tmp) ? tok->end - tok->start : (
int)(
sizeof(tmp) - 1);
2434 strncpy(tmp, (
const char*)json_chunk + tok->start, size);
2436 return (cgltf_float)CGLTF_ATOF(tmp);
2439 static cgltf_bool cgltf_json_to_bool(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2441 int size = tok->end - tok->start;
2442 return size == 4 && memcmp(json_chunk + tok->start,
"true", 4) == 0;
2445 static int cgltf_skip_json(jsmntok_t
const* tokens,
int i)
2451 switch (tokens[i].type)
2454 end += tokens[i].size * 2;
2458 end += tokens[i].size;
2461 case JSMN_PRIMITIVE:
2475 static void cgltf_fill_float_array(
float* out_array,
int size,
float value)
2477 for (
int j = 0; j < size; ++j)
2479 out_array[j] =
value;
2483 static int cgltf_parse_json_float_array(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
float* out_array,
int size)
2485 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
2486 if (tokens[i].size != size)
2488 return CGLTF_ERROR_JSON;
2491 for (
int j = 0; j < size; ++j)
2493 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
2494 out_array[j] = cgltf_json_to_float(tokens + i, json_chunk);
2500 static int cgltf_parse_json_string(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
char** out_string)
2502 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_STRING);
2505 return CGLTF_ERROR_JSON;
2507 int size = tokens[i].end - tokens[i].start;
2508 char* result = (
char*)options->memory.alloc(options->memory.user_data, size + 1);
2511 return CGLTF_ERROR_NOMEM;
2513 strncpy(result, (
const char*)json_chunk + tokens[i].start, size);
2515 *out_string = result;
2519 static int cgltf_parse_json_array(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
size_t element_size,
void** out_array, cgltf_size* out_size)
2522 if (tokens[i].type != JSMN_ARRAY)
2524 return tokens[i].type == JSMN_OBJECT ? CGLTF_ERROR_LEGACY : CGLTF_ERROR_JSON;
2528 return CGLTF_ERROR_JSON;
2530 int size = tokens[i].size;
2531 void* result = cgltf_calloc(options, element_size, size);
2534 return CGLTF_ERROR_NOMEM;
2536 *out_array = result;
2541 static int cgltf_parse_json_string_array(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
char*** out_array, cgltf_size* out_size)
2543 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
2544 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
char*), (
void**)out_array, out_size);
2550 for (cgltf_size j = 0; j < *out_size; ++j)
2552 i = cgltf_parse_json_string(options, tokens, i, json_chunk, j + (*out_array));
2561 static void cgltf_parse_attribute_type(
const char* name, cgltf_attribute_type* out_type,
int* out_index)
2563 const char* us = strchr(name,
'_');
2564 size_t len = us ? (size_t)(us - name) : strlen(name);
2566 if (len == 8 && strncmp(name,
"POSITION", 8) == 0)
2568 *out_type = cgltf_attribute_type_position;
2570 else if (len == 6 && strncmp(name,
"NORMAL", 6) == 0)
2572 *out_type = cgltf_attribute_type_normal;
2574 else if (len == 7 && strncmp(name,
"TANGENT", 7) == 0)
2576 *out_type = cgltf_attribute_type_tangent;
2578 else if (len == 8 && strncmp(name,
"TEXCOORD", 8) == 0)
2580 *out_type = cgltf_attribute_type_texcoord;
2582 else if (len == 5 && strncmp(name,
"COLOR", 5) == 0)
2584 *out_type = cgltf_attribute_type_color;
2586 else if (len == 6 && strncmp(name,
"JOINTS", 6) == 0)
2588 *out_type = cgltf_attribute_type_joints;
2590 else if (len == 7 && strncmp(name,
"WEIGHTS", 7) == 0)
2592 *out_type = cgltf_attribute_type_weights;
2596 *out_type = cgltf_attribute_type_invalid;
2599 if (us && *out_type != cgltf_attribute_type_invalid)
2601 *out_index = CGLTF_ATOI(us + 1);
2605 static int cgltf_parse_json_attribute_list(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_attribute** out_attributes, cgltf_size* out_attributes_count)
2607 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2609 if (*out_attributes)
2611 return CGLTF_ERROR_JSON;
2614 *out_attributes_count = tokens[i].size;
2618 if (!*out_attributes)
2620 return CGLTF_ERROR_NOMEM;
2623 for (cgltf_size j = 0; j < *out_attributes_count; ++j)
2625 CGLTF_CHECK_KEY(tokens[i]);
2627 i = cgltf_parse_json_string(options, tokens, i, json_chunk, &(*out_attributes)[j].name);
2630 return CGLTF_ERROR_JSON;
2633 cgltf_parse_attribute_type((*out_attributes)[j].name, &(*out_attributes)[j].type, &(*out_attributes)[j].index);
2635 (*out_attributes)[j].data = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
2642 static int cgltf_parse_json_extras(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_extras* out_extras)
2645 out_extras->start_offset = tokens[i].start;
2646 out_extras->end_offset = tokens[i].end;
2647 i = cgltf_skip_json(tokens, i);
2651 static int cgltf_parse_json_unprocessed_extension(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_extension* out_extension)
2653 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_STRING);
2654 CGLTF_CHECK_TOKTYPE(tokens[i+1], JSMN_OBJECT);
2655 if (out_extension->name)
2657 return CGLTF_ERROR_JSON;
2660 cgltf_size name_length = tokens[i].end - tokens[i].start;
2661 out_extension->name = (
char*)options->memory.alloc(options->memory.user_data, name_length + 1);
2662 if (!out_extension->name)
2664 return CGLTF_ERROR_NOMEM;
2666 strncpy(out_extension->name, (
const char*)json_chunk + tokens[i].start, name_length);
2667 out_extension->name[name_length] = 0;
2670 size_t start = tokens[i].start;
2671 size_t size = tokens[i].end - start;
2672 out_extension->data = (
char*)options->memory.alloc(options->memory.user_data, size + 1);
2673 if (!out_extension->data)
2675 return CGLTF_ERROR_NOMEM;
2677 strncpy(out_extension->data, (
const char*)json_chunk + start, size);
2678 out_extension->data[size] =
'\0';
2680 i = cgltf_skip_json(tokens, i);
2685 static int cgltf_parse_json_unprocessed_extensions(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk, cgltf_size* out_extensions_count,
cgltf_extension** out_extensions)
2689 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2692 return CGLTF_ERROR_JSON;
2695 int extensions_size = tokens[i].size;
2696 *out_extensions_count = 0;
2699 if (!*out_extensions)
2701 return CGLTF_ERROR_NOMEM;
2706 for (
int j = 0; j < extensions_size; ++j)
2708 CGLTF_CHECK_KEY(tokens[i]);
2710 cgltf_size extension_index = (*out_extensions_count)++;
2712 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, extension);
2724 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2726 int size = tokens[i].size;
2729 for (
int j = 0; j < size; ++j)
2731 CGLTF_CHECK_KEY(tokens[i]);
2733 if (cgltf_json_strcmp(tokens + i, json_chunk,
"attributes") == 0)
2735 i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_draco_mesh_compression->attributes, &out_draco_mesh_compression->attributes_count);
2737 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"bufferView") == 0)
2740 out_draco_mesh_compression->buffer_view = CGLTF_PTRINDEX(
cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
2755 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2757 int size = tokens[i].size;
2760 for (
int j = 0; j < size; ++j)
2762 CGLTF_CHECK_KEY(tokens[i]);
2764 if (cgltf_json_strcmp(tokens + i, json_chunk,
"attributes") == 0)
2766 i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_mesh_gpu_instancing->attributes, &out_mesh_gpu_instancing->attributes_count);
2768 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"bufferView") == 0)
2771 out_mesh_gpu_instancing->buffer_view = CGLTF_PTRINDEX(
cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
2784 static int cgltf_parse_json_material_mapping_data(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_material_mapping* out_mappings, cgltf_size* offset)
2787 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
2789 int size = tokens[i].size;
2792 for (
int j = 0; j < size; ++j)
2794 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2796 int obj_size = tokens[i].size;
2800 int variants_tok = -1;
2803 for (
int k = 0; k < obj_size; ++k)
2805 CGLTF_CHECK_KEY(tokens[i]);
2807 if (cgltf_json_strcmp(tokens + i, json_chunk,
"material") == 0)
2810 material = cgltf_json_to_int(tokens + i, json_chunk);
2813 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"variants") == 0)
2816 CGLTF_CHECK_TOKTYPE(tokens[variants_tok], JSMN_ARRAY);
2818 i = cgltf_skip_json(tokens, i+1);
2820 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
2822 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &extras);
2826 i = cgltf_skip_json(tokens, i+1);
2835 if (material < 0 || variants_tok < 0)
2837 return CGLTF_ERROR_JSON;
2842 for (
int k = 0; k < tokens[variants_tok].size; ++k)
2844 int variant = cgltf_json_to_int(&tokens[variants_tok + 1 + k], json_chunk);
2848 out_mappings[*offset].material = CGLTF_PTRINDEX(
cgltf_material, material);
2849 out_mappings[*offset].variant = variant;
2850 out_mappings[*offset].extras = extras;
2857 (*offset) += tokens[variants_tok].size;
2864 static int cgltf_parse_json_material_mappings(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_primitive* out_prim)
2866 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2868 int size = tokens[i].size;
2871 for (
int j = 0; j < size; ++j)
2873 CGLTF_CHECK_KEY(tokens[i]);
2875 if (cgltf_json_strcmp(tokens + i, json_chunk,
"mappings") == 0)
2877 if (out_prim->mappings)
2879 return CGLTF_ERROR_JSON;
2882 cgltf_size mappings_offset = 0;
2883 int k = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, NULL, &mappings_offset);
2889 out_prim->mappings_count = mappings_offset;
2892 mappings_offset = 0;
2893 i = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, out_prim->mappings, &mappings_offset);
2897 i = cgltf_skip_json(tokens, i+1);
2909 static int cgltf_parse_json_primitive(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_primitive* out_prim)
2911 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2913 out_prim->type = cgltf_primitive_type_triangles;
2915 int size = tokens[i].size;
2918 for (
int j = 0; j < size; ++j)
2920 CGLTF_CHECK_KEY(tokens[i]);
2922 if (cgltf_json_strcmp(tokens+i, json_chunk,
"mode") == 0)
2926 = (cgltf_primitive_type)
2927 cgltf_json_to_int(tokens+i, json_chunk);
2930 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"indices") == 0)
2933 out_prim->indices = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
2936 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"material") == 0)
2939 out_prim->material = CGLTF_PTRINDEX(
cgltf_material, cgltf_json_to_int(tokens + i, json_chunk));
2942 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"attributes") == 0)
2944 i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_prim->attributes, &out_prim->attributes_count);
2946 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"targets") == 0)
2948 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_morph_target), (
void**)&out_prim->targets, &out_prim->targets_count);
2954 for (cgltf_size k = 0; k < out_prim->targets_count; ++k)
2956 i = cgltf_parse_json_attribute_list(options, tokens, i, json_chunk, &out_prim->targets[k].attributes, &out_prim->targets[k].attributes_count);
2963 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
2965 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_prim->extras);
2967 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
2971 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2972 if(out_prim->extensions)
2974 return CGLTF_ERROR_JSON;
2977 int extensions_size = tokens[i].size;
2978 out_prim->extensions_count = 0;
2981 if (!out_prim->extensions)
2983 return CGLTF_ERROR_NOMEM;
2987 for (
int k = 0; k < extensions_size; ++k)
2989 CGLTF_CHECK_KEY(tokens[i]);
2991 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_draco_mesh_compression") == 0)
2993 out_prim->has_draco_mesh_compression = 1;
2994 i = cgltf_parse_json_draco_mesh_compression(options, tokens, i + 1, json_chunk, &out_prim->draco_mesh_compression);
2996 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_variants") == 0)
2998 i = cgltf_parse_json_material_mappings(options, tokens, i + 1, json_chunk, out_prim);
3002 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_prim->extensions[out_prim->extensions_count++]));
3013 i = cgltf_skip_json(tokens, i+1);
3025 static int cgltf_parse_json_mesh(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_mesh* out_mesh)
3027 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3029 int size = tokens[i].size;
3032 for (
int j = 0; j < size; ++j)
3034 CGLTF_CHECK_KEY(tokens[i]);
3036 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
3038 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_mesh->name);
3040 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"primitives") == 0)
3042 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_primitive), (
void**)&out_mesh->primitives, &out_mesh->primitives_count);
3048 for (cgltf_size prim_index = 0; prim_index < out_mesh->primitives_count; ++prim_index)
3050 i = cgltf_parse_json_primitive(options, tokens, i, json_chunk, &out_mesh->primitives[prim_index]);
3057 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"weights") == 0)
3059 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(cgltf_float), (
void**)&out_mesh->weights, &out_mesh->weights_count);
3065 i = cgltf_parse_json_float_array(tokens, i - 1, json_chunk, out_mesh->weights, (
int)out_mesh->weights_count);
3067 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3071 out_mesh->extras.start_offset = tokens[i].start;
3072 out_mesh->extras.end_offset = tokens[i].end;
3074 if (tokens[i].type == JSMN_OBJECT)
3076 int extras_size = tokens[i].size;
3079 for (
int k = 0; k < extras_size; ++k)
3081 CGLTF_CHECK_KEY(tokens[i]);
3083 if (cgltf_json_strcmp(tokens+i, json_chunk,
"targetNames") == 0 && tokens[i+1].type == JSMN_ARRAY)
3085 i = cgltf_parse_json_string_array(options, tokens, i + 1, json_chunk, &out_mesh->target_names, &out_mesh->target_names_count);
3089 i = cgltf_skip_json(tokens, i+1);
3100 i = cgltf_skip_json(tokens, i);
3103 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3105 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_mesh->extensions_count, &out_mesh->extensions);
3109 i = cgltf_skip_json(tokens, i+1);
3121 static int cgltf_parse_json_meshes(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
3123 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_mesh), (
void**)&out_data->meshes, &out_data->meshes_count);
3129 for (cgltf_size j = 0; j < out_data->meshes_count; ++j)
3131 i = cgltf_parse_json_mesh(options, tokens, i, json_chunk, &out_data->meshes[j]);
3140 static cgltf_component_type cgltf_json_to_component_type(jsmntok_t
const* tok,
const uint8_t* json_chunk)
3142 int type = cgltf_json_to_int(tok, json_chunk);
3147 return cgltf_component_type_r_8;
3149 return cgltf_component_type_r_8u;
3151 return cgltf_component_type_r_16;
3153 return cgltf_component_type_r_16u;
3155 return cgltf_component_type_r_32u;
3157 return cgltf_component_type_r_32f;
3159 return cgltf_component_type_invalid;
3165 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3167 int size = tokens[i].size;
3170 for (
int j = 0; j < size; ++j)
3172 CGLTF_CHECK_KEY(tokens[i]);
3174 if (cgltf_json_strcmp(tokens+i, json_chunk,
"count") == 0)
3177 out_sparse->count = cgltf_json_to_int(tokens + i, json_chunk);
3180 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"indices") == 0)
3183 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3185 int indices_size = tokens[i].size;
3188 for (
int k = 0; k < indices_size; ++k)
3190 CGLTF_CHECK_KEY(tokens[i]);
3192 if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
3195 out_sparse->indices_buffer_view = CGLTF_PTRINDEX(
cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
3198 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
3201 out_sparse->indices_byte_offset = cgltf_json_to_size(tokens + i, json_chunk);
3204 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"componentType") == 0)
3207 out_sparse->indices_component_type = cgltf_json_to_component_type(tokens + i, json_chunk);
3210 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3212 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sparse->indices_extras);
3214 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3216 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->indices_extensions_count, &out_sparse->indices_extensions);
3220 i = cgltf_skip_json(tokens, i+1);
3229 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"values") == 0)
3232 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3234 int values_size = tokens[i].size;
3237 for (
int k = 0; k < values_size; ++k)
3239 CGLTF_CHECK_KEY(tokens[i]);
3241 if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
3244 out_sparse->values_buffer_view = CGLTF_PTRINDEX(
cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
3247 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
3250 out_sparse->values_byte_offset = cgltf_json_to_size(tokens + i, json_chunk);
3253 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3255 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sparse->values_extras);
3257 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3259 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->values_extensions_count, &out_sparse->values_extensions);
3263 i = cgltf_skip_json(tokens, i+1);
3272 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3274 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sparse->extras);
3276 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3278 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->extensions_count, &out_sparse->extensions);
3282 i = cgltf_skip_json(tokens, i+1);
3294 static int cgltf_parse_json_accessor(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_accessor* out_accessor)
3296 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3298 int size = tokens[i].size;
3301 for (
int j = 0; j < size; ++j)
3303 CGLTF_CHECK_KEY(tokens[i]);
3305 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
3307 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_accessor->name);
3309 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
3312 out_accessor->buffer_view = CGLTF_PTRINDEX(
cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
3315 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
3318 out_accessor->offset =
3319 cgltf_json_to_size(tokens+i, json_chunk);
3322 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"componentType") == 0)
3325 out_accessor->component_type = cgltf_json_to_component_type(tokens + i, json_chunk);
3328 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"normalized") == 0)
3331 out_accessor->normalized = cgltf_json_to_bool(tokens+i, json_chunk);
3334 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"count") == 0)
3337 out_accessor->count =
3338 cgltf_json_to_int(tokens+i, json_chunk);
3341 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"type") == 0)
3344 if (cgltf_json_strcmp(tokens+i, json_chunk,
"SCALAR") == 0)
3346 out_accessor->type = cgltf_type_scalar;
3348 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"VEC2") == 0)
3350 out_accessor->type = cgltf_type_vec2;
3352 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"VEC3") == 0)
3354 out_accessor->type = cgltf_type_vec3;
3356 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"VEC4") == 0)
3358 out_accessor->type = cgltf_type_vec4;
3360 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"MAT2") == 0)
3362 out_accessor->type = cgltf_type_mat2;
3364 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"MAT3") == 0)
3366 out_accessor->type = cgltf_type_mat3;
3368 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"MAT4") == 0)
3370 out_accessor->type = cgltf_type_mat4;
3374 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"min") == 0)
3377 out_accessor->has_min = 1;
3379 int min_size = tokens[i].size > 16 ? 16 : tokens[i].size;
3380 i = cgltf_parse_json_float_array(tokens, i, json_chunk, out_accessor->min, min_size);
3382 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"max") == 0)
3385 out_accessor->has_max = 1;
3387 int max_size = tokens[i].size > 16 ? 16 : tokens[i].size;
3388 i = cgltf_parse_json_float_array(tokens, i, json_chunk, out_accessor->max, max_size);
3390 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"sparse") == 0)
3392 out_accessor->is_sparse = 1;
3393 i = cgltf_parse_json_accessor_sparse(options, tokens, i + 1, json_chunk, &out_accessor->sparse);
3395 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3397 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_accessor->extras);
3399 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3401 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_accessor->extensions_count, &out_accessor->extensions);
3405 i = cgltf_skip_json(tokens, i+1);
3417 static int cgltf_parse_json_texture_transform(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_texture_transform* out_texture_transform)
3419 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3421 int size = tokens[i].size;
3424 for (
int j = 0; j < size; ++j)
3426 CGLTF_CHECK_KEY(tokens[i]);
3428 if (cgltf_json_strcmp(tokens + i, json_chunk,
"offset") == 0)
3430 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_texture_transform->offset, 2);
3432 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"rotation") == 0)
3435 out_texture_transform->rotation = cgltf_json_to_float(tokens + i, json_chunk);
3438 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scale") == 0)
3440 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_texture_transform->scale, 2);
3442 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"texCoord") == 0)
3445 out_texture_transform->has_texcoord = 1;
3446 out_texture_transform->texcoord = cgltf_json_to_int(tokens + i, json_chunk);
3451 i = cgltf_skip_json(tokens, i + 1);
3463 static int cgltf_parse_json_texture_view(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_texture_view* out_texture_view)
3465 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3467 out_texture_view->scale = 1.0f;
3468 cgltf_fill_float_array(out_texture_view->transform.scale, 2, 1.0f);
3470 int size = tokens[i].size;
3473 for (
int j = 0; j < size; ++j)
3475 CGLTF_CHECK_KEY(tokens[i]);
3477 if (cgltf_json_strcmp(tokens + i, json_chunk,
"index") == 0)
3480 out_texture_view->texture = CGLTF_PTRINDEX(
cgltf_texture, cgltf_json_to_int(tokens + i, json_chunk));
3483 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"texCoord") == 0)
3486 out_texture_view->texcoord = cgltf_json_to_int(tokens + i, json_chunk);
3489 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scale") == 0)
3492 out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk);
3495 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"strength") == 0)
3498 out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk);
3501 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3503 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_texture_view->extras);
3505 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3509 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3510 if(out_texture_view->extensions)
3512 return CGLTF_ERROR_JSON;
3515 int extensions_size = tokens[i].size;
3516 out_texture_view->extensions_count = 0;
3519 if (!out_texture_view->extensions)
3521 return CGLTF_ERROR_NOMEM;
3526 for (
int k = 0; k < extensions_size; ++k)
3528 CGLTF_CHECK_KEY(tokens[i]);
3530 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_texture_transform") == 0)
3532 out_texture_view->has_transform = 1;
3533 i = cgltf_parse_json_texture_transform(tokens, i + 1, json_chunk, &out_texture_view->transform);
3537 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture_view->extensions[out_texture_view->extensions_count++]));
3548 i = cgltf_skip_json(tokens, i + 1);
3562 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3564 int size = tokens[i].size;
3567 for (
int j = 0; j < size; ++j)
3569 CGLTF_CHECK_KEY(tokens[i]);
3571 if (cgltf_json_strcmp(tokens+i, json_chunk,
"metallicFactor") == 0)
3574 out_pbr->metallic_factor =
3575 cgltf_json_to_float(tokens + i, json_chunk);
3578 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"roughnessFactor") == 0)
3581 out_pbr->roughness_factor =
3582 cgltf_json_to_float(tokens+i, json_chunk);
3585 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"baseColorFactor") == 0)
3587 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->base_color_factor, 4);
3589 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"baseColorTexture") == 0)
3591 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
3592 &out_pbr->base_color_texture);
3594 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"metallicRoughnessTexture") == 0)
3596 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
3597 &out_pbr->metallic_roughness_texture);
3599 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3601 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_pbr->extras);
3605 i = cgltf_skip_json(tokens, i+1);
3619 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3620 int size = tokens[i].size;
3623 for (
int j = 0; j < size; ++j)
3625 CGLTF_CHECK_KEY(tokens[i]);
3627 if (cgltf_json_strcmp(tokens+i, json_chunk,
"diffuseFactor") == 0)
3629 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->diffuse_factor, 4);
3631 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularFactor") == 0)
3633 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->specular_factor, 3);
3635 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"glossinessFactor") == 0)
3638 out_pbr->glossiness_factor = cgltf_json_to_float(tokens + i, json_chunk);
3641 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"diffuseTexture") == 0)
3643 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->diffuse_texture);
3645 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularGlossinessTexture") == 0)
3647 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->specular_glossiness_texture);
3651 i = cgltf_skip_json(tokens, i+1);
3663 static int cgltf_parse_json_clearcoat(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_clearcoat* out_clearcoat)
3665 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3666 int size = tokens[i].size;
3669 for (
int j = 0; j < size; ++j)
3671 CGLTF_CHECK_KEY(tokens[i]);
3673 if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatFactor") == 0)
3676 out_clearcoat->clearcoat_factor = cgltf_json_to_float(tokens + i, json_chunk);
3679 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatRoughnessFactor") == 0)
3682 out_clearcoat->clearcoat_roughness_factor = cgltf_json_to_float(tokens + i, json_chunk);
3685 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatTexture") == 0)
3687 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->clearcoat_texture);
3689 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatRoughnessTexture") == 0)
3691 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->clearcoat_roughness_texture);
3693 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatNormalTexture") == 0)
3695 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->clearcoat_normal_texture);
3699 i = cgltf_skip_json(tokens, i+1);
3711 static int cgltf_parse_json_ior(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_ior* out_ior)
3713 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3714 int size = tokens[i].size;
3718 out_ior->ior = 1.5f;
3720 for (
int j = 0; j < size; ++j)
3722 CGLTF_CHECK_KEY(tokens[i]);
3724 if (cgltf_json_strcmp(tokens+i, json_chunk,
"ior") == 0)
3727 out_ior->ior = cgltf_json_to_float(tokens + i, json_chunk);
3732 i = cgltf_skip_json(tokens, i+1);
3744 static int cgltf_parse_json_specular(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_specular* out_specular)
3746 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3747 int size = tokens[i].size;
3751 out_specular->specular_factor = 1.0f;
3752 cgltf_fill_float_array(out_specular->specular_color_factor, 3, 1.0f);
3754 for (
int j = 0; j < size; ++j)
3756 CGLTF_CHECK_KEY(tokens[i]);
3758 if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularFactor") == 0)
3761 out_specular->specular_factor = cgltf_json_to_float(tokens + i, json_chunk);
3764 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularColorFactor") == 0)
3766 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_specular->specular_color_factor, 3);
3768 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularTexture") == 0)
3770 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->specular_texture);
3772 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"specularColorTexture") == 0)
3774 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->specular_color_texture);
3778 i = cgltf_skip_json(tokens, i+1);
3790 static int cgltf_parse_json_transmission(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_transmission* out_transmission)
3792 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3793 int size = tokens[i].size;
3796 for (
int j = 0; j < size; ++j)
3798 CGLTF_CHECK_KEY(tokens[i]);
3800 if (cgltf_json_strcmp(tokens+i, json_chunk,
"transmissionFactor") == 0)
3803 out_transmission->transmission_factor = cgltf_json_to_float(tokens + i, json_chunk);
3806 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"transmissionTexture") == 0)
3808 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_transmission->transmission_texture);
3812 i = cgltf_skip_json(tokens, i+1);
3824 static int cgltf_parse_json_volume(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_volume* out_volume)
3826 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3827 int size = tokens[i].size;
3830 for (
int j = 0; j < size; ++j)
3832 CGLTF_CHECK_KEY(tokens[i]);
3834 if (cgltf_json_strcmp(tokens + i, json_chunk,
"thicknessFactor") == 0)
3837 out_volume->thickness_factor = cgltf_json_to_float(tokens + i, json_chunk);
3840 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"thicknessTexture") == 0)
3842 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_volume->thickness_texture);
3844 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"attenuationColor") == 0)
3846 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_volume->attenuation_color, 3);
3848 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"attenuationDistance") == 0)
3851 out_volume->attenuation_distance = cgltf_json_to_float(tokens + i, json_chunk);
3856 i = cgltf_skip_json(tokens, i + 1);
3868 static int cgltf_parse_json_sheen(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_sheen* out_sheen)
3870 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3871 int size = tokens[i].size;
3874 for (
int j = 0; j < size; ++j)
3876 CGLTF_CHECK_KEY(tokens[i]);
3878 if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenColorFactor") == 0)
3880 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_sheen->sheen_color_factor, 3);
3882 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenColorTexture") == 0)
3884 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_sheen->sheen_color_texture);
3886 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenRoughnessFactor") == 0)
3889 out_sheen->sheen_roughness_factor = cgltf_json_to_float(tokens + i, json_chunk);
3892 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenRoughnessTexture") == 0)
3894 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_sheen->sheen_roughness_texture);
3898 i = cgltf_skip_json(tokens, i+1);
3910 static int cgltf_parse_json_emissive_strength(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_emissive_strength* out_emissive_strength)
3912 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3913 int size = tokens[i].size;
3917 out_emissive_strength->emissive_strength = 1.f;
3919 for (
int j = 0; j < size; ++j)
3921 CGLTF_CHECK_KEY(tokens[i]);
3923 if (cgltf_json_strcmp(tokens + i, json_chunk,
"emissiveStrength") == 0)
3926 out_emissive_strength->emissive_strength = cgltf_json_to_float(tokens + i, json_chunk);
3931 i = cgltf_skip_json(tokens, i + 1);
3943 static int cgltf_parse_json_iridescence(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_iridescence* out_iridescence)
3945 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3946 int size = tokens[i].size;
3950 out_iridescence->iridescence_ior = 1.3f;
3951 out_iridescence->iridescence_thickness_min = 100.f;
3952 out_iridescence->iridescence_thickness_max = 400.f;
3954 for (
int j = 0; j < size; ++j)
3956 CGLTF_CHECK_KEY(tokens[i]);
3958 if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceFactor") == 0)
3961 out_iridescence->iridescence_factor = cgltf_json_to_float(tokens + i, json_chunk);
3964 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceTexture") == 0)
3966 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_iridescence->iridescence_texture);
3968 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceIor") == 0)
3971 out_iridescence->iridescence_ior = cgltf_json_to_float(tokens + i, json_chunk);
3974 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceThicknessMinimum") == 0)
3977 out_iridescence->iridescence_thickness_min = cgltf_json_to_float(tokens + i, json_chunk);
3980 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceThicknessMaximum") == 0)
3983 out_iridescence->iridescence_thickness_max = cgltf_json_to_float(tokens + i, json_chunk);
3986 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceThicknessTexture") == 0)
3988 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_iridescence->iridescence_thickness_texture);
3992 i = cgltf_skip_json(tokens, i + 1);
4004 static int cgltf_parse_json_image(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_image* out_image)
4006 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4008 int size = tokens[i].size;
4011 for (
int j = 0; j < size; ++j)
4013 CGLTF_CHECK_KEY(tokens[i]);
4015 if (cgltf_json_strcmp(tokens + i, json_chunk,
"uri") == 0)
4017 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->uri);
4019 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
4022 out_image->buffer_view = CGLTF_PTRINDEX(
cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
4025 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"mimeType") == 0)
4027 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->mime_type);
4029 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
4031 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->name);
4033 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4035 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_image->extras);
4037 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4039 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_image->extensions_count, &out_image->extensions);
4043 i = cgltf_skip_json(tokens, i + 1);
4055 static int cgltf_parse_json_sampler(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_sampler* out_sampler)
4058 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4060 out_sampler->wrap_s = 10497;
4061 out_sampler->wrap_t = 10497;
4063 int size = tokens[i].size;
4066 for (
int j = 0; j < size; ++j)
4068 CGLTF_CHECK_KEY(tokens[i]);
4070 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
4072 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_sampler->name);
4074 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"magFilter") == 0)
4077 out_sampler->mag_filter
4078 = cgltf_json_to_int(tokens + i, json_chunk);
4081 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"minFilter") == 0)
4084 out_sampler->min_filter
4085 = cgltf_json_to_int(tokens + i, json_chunk);
4088 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"wrapS") == 0)
4092 = cgltf_json_to_int(tokens + i, json_chunk);
4095 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"wrapT") == 0)
4099 = cgltf_json_to_int(tokens + i, json_chunk);
4102 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4104 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sampler->extras);
4106 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4108 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sampler->extensions_count, &out_sampler->extensions);
4112 i = cgltf_skip_json(tokens, i + 1);
4124 static int cgltf_parse_json_texture(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_texture* out_texture)
4126 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4128 int size = tokens[i].size;
4131 for (
int j = 0; j < size; ++j)
4133 CGLTF_CHECK_KEY(tokens[i]);
4135 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4137 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_texture->name);
4139 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"sampler") == 0)
4142 out_texture->sampler = CGLTF_PTRINDEX(
cgltf_sampler, cgltf_json_to_int(tokens + i, json_chunk));
4145 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"source") == 0)
4148 out_texture->image = CGLTF_PTRINDEX(
cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
4151 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4153 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_texture->extras);
4155 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4159 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4160 if (out_texture->extensions)
4162 return CGLTF_ERROR_JSON;
4165 int extensions_size = tokens[i].size;
4168 out_texture->extensions_count = 0;
4170 if (!out_texture->extensions)
4172 return CGLTF_ERROR_NOMEM;
4175 for (
int k = 0; k < extensions_size; ++k)
4177 CGLTF_CHECK_KEY(tokens[i]);
4179 if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_texture_basisu") == 0)
4181 out_texture->has_basisu = 1;
4183 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4184 int num_properties = tokens[i].size;
4187 for (
int t = 0; t < num_properties; ++t)
4189 CGLTF_CHECK_KEY(tokens[i]);
4191 if (cgltf_json_strcmp(tokens + i, json_chunk,
"source") == 0)
4194 out_texture->basisu_image = CGLTF_PTRINDEX(
cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
4199 i = cgltf_skip_json(tokens, i + 1);
4209 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture->extensions[out_texture->extensions_count++]));
4220 i = cgltf_skip_json(tokens, i + 1);
4232 static int cgltf_parse_json_material(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_material* out_material)
4234 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4236 cgltf_fill_float_array(out_material->pbr_metallic_roughness.base_color_factor, 4, 1.0f);
4237 out_material->pbr_metallic_roughness.metallic_factor = 1.0f;
4238 out_material->pbr_metallic_roughness.roughness_factor = 1.0f;
4240 cgltf_fill_float_array(out_material->pbr_specular_glossiness.diffuse_factor, 4, 1.0f);
4241 cgltf_fill_float_array(out_material->pbr_specular_glossiness.specular_factor, 3, 1.0f);
4242 out_material->pbr_specular_glossiness.glossiness_factor = 1.0f;
4244 cgltf_fill_float_array(out_material->volume.attenuation_color, 3, 1.0f);
4245 out_material->volume.attenuation_distance = FLT_MAX;
4247 out_material->alpha_cutoff = 0.5f;
4249 int size = tokens[i].size;
4252 for (
int j = 0; j < size; ++j)
4254 CGLTF_CHECK_KEY(tokens[i]);
4256 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4258 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_material->name);
4260 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"pbrMetallicRoughness") == 0)
4262 out_material->has_pbr_metallic_roughness = 1;
4263 i = cgltf_parse_json_pbr_metallic_roughness(options, tokens, i + 1, json_chunk, &out_material->pbr_metallic_roughness);
4265 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"emissiveFactor") == 0)
4267 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_material->emissive_factor, 3);
4269 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"normalTexture") == 0)
4271 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
4272 &out_material->normal_texture);
4274 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"occlusionTexture") == 0)
4276 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
4277 &out_material->occlusion_texture);
4279 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"emissiveTexture") == 0)
4281 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
4282 &out_material->emissive_texture);
4284 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"alphaMode") == 0)
4287 if (cgltf_json_strcmp(tokens + i, json_chunk,
"OPAQUE") == 0)
4289 out_material->alpha_mode = cgltf_alpha_mode_opaque;
4291 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"MASK") == 0)
4293 out_material->alpha_mode = cgltf_alpha_mode_mask;
4295 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"BLEND") == 0)
4297 out_material->alpha_mode = cgltf_alpha_mode_blend;
4301 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"alphaCutoff") == 0)
4304 out_material->alpha_cutoff = cgltf_json_to_float(tokens + i, json_chunk);
4307 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"doubleSided") == 0)
4310 out_material->double_sided =
4311 cgltf_json_to_bool(tokens + i, json_chunk);
4314 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4316 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_material->extras);
4318 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4322 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4323 if(out_material->extensions)
4325 return CGLTF_ERROR_JSON;
4328 int extensions_size = tokens[i].size;
4331 out_material->extensions_count= 0;
4333 if (!out_material->extensions)
4335 return CGLTF_ERROR_NOMEM;
4338 for (
int k = 0; k < extensions_size; ++k)
4340 CGLTF_CHECK_KEY(tokens[i]);
4342 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_pbrSpecularGlossiness") == 0)
4344 out_material->has_pbr_specular_glossiness = 1;
4345 i = cgltf_parse_json_pbr_specular_glossiness(options, tokens, i + 1, json_chunk, &out_material->pbr_specular_glossiness);
4347 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_unlit") == 0)
4349 out_material->unlit = 1;
4350 i = cgltf_skip_json(tokens, i+1);
4352 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_clearcoat") == 0)
4354 out_material->has_clearcoat = 1;
4355 i = cgltf_parse_json_clearcoat(options, tokens, i + 1, json_chunk, &out_material->clearcoat);
4357 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_ior") == 0)
4359 out_material->has_ior = 1;
4360 i = cgltf_parse_json_ior(tokens, i + 1, json_chunk, &out_material->ior);
4362 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_specular") == 0)
4364 out_material->has_specular = 1;
4365 i = cgltf_parse_json_specular(options, tokens, i + 1, json_chunk, &out_material->specular);
4367 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_transmission") == 0)
4369 out_material->has_transmission = 1;
4370 i = cgltf_parse_json_transmission(options, tokens, i + 1, json_chunk, &out_material->transmission);
4372 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_volume") == 0)
4374 out_material->has_volume = 1;
4375 i = cgltf_parse_json_volume(options, tokens, i + 1, json_chunk, &out_material->volume);
4377 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_sheen") == 0)
4379 out_material->has_sheen = 1;
4380 i = cgltf_parse_json_sheen(options, tokens, i + 1, json_chunk, &out_material->sheen);
4382 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_emissive_strength") == 0)
4384 out_material->has_emissive_strength = 1;
4385 i = cgltf_parse_json_emissive_strength(tokens, i + 1, json_chunk, &out_material->emissive_strength);
4387 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_iridescence") == 0)
4389 out_material->has_iridescence = 1;
4390 i = cgltf_parse_json_iridescence(options, tokens, i + 1, json_chunk, &out_material->iridescence);
4394 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++]));
4405 i = cgltf_skip_json(tokens, i+1);
4417 static int cgltf_parse_json_accessors(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4419 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_accessor), (
void**)&out_data->accessors, &out_data->accessors_count);
4425 for (cgltf_size j = 0; j < out_data->accessors_count; ++j)
4427 i = cgltf_parse_json_accessor(options, tokens, i, json_chunk, &out_data->accessors[j]);
4436 static int cgltf_parse_json_materials(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4438 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_material), (
void**)&out_data->materials, &out_data->materials_count);
4444 for (cgltf_size j = 0; j < out_data->materials_count; ++j)
4446 i = cgltf_parse_json_material(options, tokens, i, json_chunk, &out_data->materials[j]);
4455 static int cgltf_parse_json_images(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4457 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_image), (
void**)&out_data->images, &out_data->images_count);
4463 for (cgltf_size j = 0; j < out_data->images_count; ++j)
4465 i = cgltf_parse_json_image(options, tokens, i, json_chunk, &out_data->images[j]);
4474 static int cgltf_parse_json_textures(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4476 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_texture), (
void**)&out_data->textures, &out_data->textures_count);
4482 for (cgltf_size j = 0; j < out_data->textures_count; ++j)
4484 i = cgltf_parse_json_texture(options, tokens, i, json_chunk, &out_data->textures[j]);
4493 static int cgltf_parse_json_samplers(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4495 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_sampler), (
void**)&out_data->samplers, &out_data->samplers_count);
4501 for (cgltf_size j = 0; j < out_data->samplers_count; ++j)
4503 i = cgltf_parse_json_sampler(options, tokens, i, json_chunk, &out_data->samplers[j]);
4515 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4517 int size = tokens[i].size;
4520 for (
int j = 0; j < size; ++j)
4522 CGLTF_CHECK_KEY(tokens[i]);
4524 if (cgltf_json_strcmp(tokens+i, json_chunk,
"buffer") == 0)
4527 out_meshopt_compression->buffer = CGLTF_PTRINDEX(
cgltf_buffer, cgltf_json_to_int(tokens + i, json_chunk));
4530 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
4533 out_meshopt_compression->offset = cgltf_json_to_size(tokens+i, json_chunk);
4536 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteLength") == 0)
4539 out_meshopt_compression->size = cgltf_json_to_size(tokens+i, json_chunk);
4542 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteStride") == 0)
4545 out_meshopt_compression->stride = cgltf_json_to_size(tokens+i, json_chunk);
4548 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"count") == 0)
4551 out_meshopt_compression->count = cgltf_json_to_int(tokens+i, json_chunk);
4554 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"mode") == 0)
4557 if (cgltf_json_strcmp(tokens+i, json_chunk,
"ATTRIBUTES") == 0)
4559 out_meshopt_compression->mode = cgltf_meshopt_compression_mode_attributes;
4561 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"TRIANGLES") == 0)
4563 out_meshopt_compression->mode = cgltf_meshopt_compression_mode_triangles;
4565 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"INDICES") == 0)
4567 out_meshopt_compression->mode = cgltf_meshopt_compression_mode_indices;
4571 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"filter") == 0)
4574 if (cgltf_json_strcmp(tokens+i, json_chunk,
"NONE") == 0)
4576 out_meshopt_compression->filter = cgltf_meshopt_compression_filter_none;
4578 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"OCTAHEDRAL") == 0)
4580 out_meshopt_compression->filter = cgltf_meshopt_compression_filter_octahedral;
4582 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"QUATERNION") == 0)
4584 out_meshopt_compression->filter = cgltf_meshopt_compression_filter_quaternion;
4586 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"EXPONENTIAL") == 0)
4588 out_meshopt_compression->filter = cgltf_meshopt_compression_filter_exponential;
4594 i = cgltf_skip_json(tokens, i+1);
4606 static int cgltf_parse_json_buffer_view(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_buffer_view* out_buffer_view)
4608 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4610 int size = tokens[i].size;
4613 for (
int j = 0; j < size; ++j)
4615 CGLTF_CHECK_KEY(tokens[i]);
4617 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
4619 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer_view->name);
4621 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"buffer") == 0)
4624 out_buffer_view->buffer = CGLTF_PTRINDEX(
cgltf_buffer, cgltf_json_to_int(tokens + i, json_chunk));
4627 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
4630 out_buffer_view->offset =
4631 cgltf_json_to_size(tokens+i, json_chunk);
4634 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteLength") == 0)
4637 out_buffer_view->size =
4638 cgltf_json_to_size(tokens+i, json_chunk);
4641 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteStride") == 0)
4644 out_buffer_view->stride =
4645 cgltf_json_to_size(tokens+i, json_chunk);
4648 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"target") == 0)
4651 int type = cgltf_json_to_int(tokens+i, json_chunk);
4655 type = cgltf_buffer_view_type_vertices;
4658 type = cgltf_buffer_view_type_indices;
4661 type = cgltf_buffer_view_type_invalid;
4664 out_buffer_view->type = (cgltf_buffer_view_type)type;
4667 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4669 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_buffer_view->extras);
4671 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4675 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4676 if(out_buffer_view->extensions)
4678 return CGLTF_ERROR_JSON;
4681 int extensions_size = tokens[i].size;
4682 out_buffer_view->extensions_count = 0;
4685 if (!out_buffer_view->extensions)
4687 return CGLTF_ERROR_NOMEM;
4691 for (
int k = 0; k < extensions_size; ++k)
4693 CGLTF_CHECK_KEY(tokens[i]);
4695 if (cgltf_json_strcmp(tokens+i, json_chunk,
"EXT_meshopt_compression") == 0)
4697 out_buffer_view->has_meshopt_compression = 1;
4698 i = cgltf_parse_json_meshopt_compression(options, tokens, i + 1, json_chunk, &out_buffer_view->meshopt_compression);
4702 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_buffer_view->extensions[out_buffer_view->extensions_count++]));
4713 i = cgltf_skip_json(tokens, i+1);
4725 static int cgltf_parse_json_buffer_views(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4727 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_buffer_view), (
void**)&out_data->buffer_views, &out_data->buffer_views_count);
4733 for (cgltf_size j = 0; j < out_data->buffer_views_count; ++j)
4735 i = cgltf_parse_json_buffer_view(options, tokens, i, json_chunk, &out_data->buffer_views[j]);
4744 static int cgltf_parse_json_buffer(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_buffer* out_buffer)
4746 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4748 int size = tokens[i].size;
4751 for (
int j = 0; j < size; ++j)
4753 CGLTF_CHECK_KEY(tokens[i]);
4755 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
4757 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer->name);
4759 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteLength") == 0)
4763 cgltf_json_to_size(tokens+i, json_chunk);
4766 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"uri") == 0)
4768 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer->uri);
4770 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4772 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_buffer->extras);
4774 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4776 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_buffer->extensions_count, &out_buffer->extensions);
4780 i = cgltf_skip_json(tokens, i+1);
4792 static int cgltf_parse_json_buffers(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4794 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_buffer), (
void**)&out_data->buffers, &out_data->buffers_count);
4800 for (cgltf_size j = 0; j < out_data->buffers_count; ++j)
4802 i = cgltf_parse_json_buffer(options, tokens, i, json_chunk, &out_data->buffers[j]);
4811 static int cgltf_parse_json_skin(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_skin* out_skin)
4813 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4815 int size = tokens[i].size;
4818 for (
int j = 0; j < size; ++j)
4820 CGLTF_CHECK_KEY(tokens[i]);
4822 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4824 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_skin->name);
4826 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"joints") == 0)
4828 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_node*), (
void**)&out_skin->joints, &out_skin->joints_count);
4834 for (cgltf_size k = 0; k < out_skin->joints_count; ++k)
4836 out_skin->joints[k] = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
4840 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"skeleton") == 0)
4843 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
4844 out_skin->skeleton = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
4847 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"inverseBindMatrices") == 0)
4850 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
4851 out_skin->inverse_bind_matrices = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
4854 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4856 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_skin->extras);
4858 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4860 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_skin->extensions_count, &out_skin->extensions);
4864 i = cgltf_skip_json(tokens, i+1);
4876 static int cgltf_parse_json_skins(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4878 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_skin), (
void**)&out_data->skins, &out_data->skins_count);
4884 for (cgltf_size j = 0; j < out_data->skins_count; ++j)
4886 i = cgltf_parse_json_skin(options, tokens, i, json_chunk, &out_data->skins[j]);
4895 static int cgltf_parse_json_camera(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_camera* out_camera)
4897 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4899 int size = tokens[i].size;
4902 for (
int j = 0; j < size; ++j)
4904 CGLTF_CHECK_KEY(tokens[i]);
4906 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4908 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_camera->name);
4910 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"type") == 0)
4913 if (cgltf_json_strcmp(tokens + i, json_chunk,
"perspective") == 0)
4915 out_camera->type = cgltf_camera_type_perspective;
4917 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"orthographic") == 0)
4919 out_camera->type = cgltf_camera_type_orthographic;
4923 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"perspective") == 0)
4927 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4929 int data_size = tokens[i].size;
4932 out_camera->type = cgltf_camera_type_perspective;
4934 for (
int k = 0; k < data_size; ++k)
4936 CGLTF_CHECK_KEY(tokens[i]);
4938 if (cgltf_json_strcmp(tokens+i, json_chunk,
"aspectRatio") == 0)
4941 out_camera->data.perspective.has_aspect_ratio = 1;
4942 out_camera->data.perspective.aspect_ratio = cgltf_json_to_float(tokens + i, json_chunk);
4945 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"yfov") == 0)
4948 out_camera->data.perspective.yfov = cgltf_json_to_float(tokens + i, json_chunk);
4951 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"zfar") == 0)
4954 out_camera->data.perspective.has_zfar = 1;
4955 out_camera->data.perspective.zfar = cgltf_json_to_float(tokens + i, json_chunk);
4958 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"znear") == 0)
4961 out_camera->data.perspective.znear = cgltf_json_to_float(tokens + i, json_chunk);
4964 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4966 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_camera->data.perspective.extras);
4970 i = cgltf_skip_json(tokens, i+1);
4979 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"orthographic") == 0)
4983 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4985 int data_size = tokens[i].size;
4988 out_camera->type = cgltf_camera_type_orthographic;
4990 for (
int k = 0; k < data_size; ++k)
4992 CGLTF_CHECK_KEY(tokens[i]);
4994 if (cgltf_json_strcmp(tokens+i, json_chunk,
"xmag") == 0)
4997 out_camera->data.orthographic.xmag = cgltf_json_to_float(tokens + i, json_chunk);
5000 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"ymag") == 0)
5003 out_camera->data.orthographic.ymag = cgltf_json_to_float(tokens + i, json_chunk);
5006 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"zfar") == 0)
5009 out_camera->data.orthographic.zfar = cgltf_json_to_float(tokens + i, json_chunk);
5012 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"znear") == 0)
5015 out_camera->data.orthographic.znear = cgltf_json_to_float(tokens + i, json_chunk);
5018 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5020 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_camera->data.orthographic.extras);
5024 i = cgltf_skip_json(tokens, i+1);
5033 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5035 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_camera->extras);
5037 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5039 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_camera->extensions_count, &out_camera->extensions);
5043 i = cgltf_skip_json(tokens, i+1);
5055 static int cgltf_parse_json_cameras(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5057 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_camera), (
void**)&out_data->cameras, &out_data->cameras_count);
5063 for (cgltf_size j = 0; j < out_data->cameras_count; ++j)
5065 i = cgltf_parse_json_camera(options, tokens, i, json_chunk, &out_data->cameras[j]);
5074 static int cgltf_parse_json_light(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_light* out_light)
5076 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5078 out_light->color[0] = 1.f;
5079 out_light->color[1] = 1.f;
5080 out_light->color[2] = 1.f;
5081 out_light->intensity = 1.f;
5083 out_light->spot_inner_cone_angle = 0.f;
5084 out_light->spot_outer_cone_angle = 3.1415926535f / 4.0f;
5086 int size = tokens[i].size;
5089 for (
int j = 0; j < size; ++j)
5091 CGLTF_CHECK_KEY(tokens[i]);
5093 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5095 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_light->name);
5097 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"color") == 0)
5099 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_light->color, 3);
5101 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"intensity") == 0)
5104 out_light->intensity = cgltf_json_to_float(tokens + i, json_chunk);
5107 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"type") == 0)
5110 if (cgltf_json_strcmp(tokens + i, json_chunk,
"directional") == 0)
5112 out_light->type = cgltf_light_type_directional;
5114 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"point") == 0)
5116 out_light->type = cgltf_light_type_point;
5118 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"spot") == 0)
5120 out_light->type = cgltf_light_type_spot;
5124 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"range") == 0)
5127 out_light->range = cgltf_json_to_float(tokens + i, json_chunk);
5130 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"spot") == 0)
5134 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5136 int data_size = tokens[i].size;
5139 for (
int k = 0; k < data_size; ++k)
5141 CGLTF_CHECK_KEY(tokens[i]);
5143 if (cgltf_json_strcmp(tokens+i, json_chunk,
"innerConeAngle") == 0)
5146 out_light->spot_inner_cone_angle = cgltf_json_to_float(tokens + i, json_chunk);
5149 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"outerConeAngle") == 0)
5152 out_light->spot_outer_cone_angle = cgltf_json_to_float(tokens + i, json_chunk);
5157 i = cgltf_skip_json(tokens, i+1);
5166 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5168 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_light->extras);
5172 i = cgltf_skip_json(tokens, i+1);
5184 static int cgltf_parse_json_lights(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5186 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_light), (
void**)&out_data->lights, &out_data->lights_count);
5192 for (cgltf_size j = 0; j < out_data->lights_count; ++j)
5194 i = cgltf_parse_json_light(options, tokens, i, json_chunk, &out_data->lights[j]);
5203 static int cgltf_parse_json_node(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_node* out_node)
5205 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5207 out_node->rotation[3] = 1.0f;
5208 out_node->scale[0] = 1.0f;
5209 out_node->scale[1] = 1.0f;
5210 out_node->scale[2] = 1.0f;
5211 out_node->matrix[0] = 1.0f;
5212 out_node->matrix[5] = 1.0f;
5213 out_node->matrix[10] = 1.0f;
5214 out_node->matrix[15] = 1.0f;
5216 int size = tokens[i].size;
5219 for (
int j = 0; j < size; ++j)
5221 CGLTF_CHECK_KEY(tokens[i]);
5223 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5225 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_node->name);
5227 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"children") == 0)
5229 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_node*), (
void**)&out_node->children, &out_node->children_count);
5235 for (cgltf_size k = 0; k < out_node->children_count; ++k)
5237 out_node->children[k] = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
5241 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"mesh") == 0)
5244 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5245 out_node->mesh = CGLTF_PTRINDEX(
cgltf_mesh, cgltf_json_to_int(tokens + i, json_chunk));
5248 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"skin") == 0)
5251 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5252 out_node->skin = CGLTF_PTRINDEX(
cgltf_skin, cgltf_json_to_int(tokens + i, json_chunk));
5255 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"camera") == 0)
5258 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5259 out_node->camera = CGLTF_PTRINDEX(
cgltf_camera, cgltf_json_to_int(tokens + i, json_chunk));
5262 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"translation") == 0)
5264 out_node->has_translation = 1;
5265 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->translation, 3);
5267 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"rotation") == 0)
5269 out_node->has_rotation = 1;
5270 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->rotation, 4);
5272 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"scale") == 0)
5274 out_node->has_scale = 1;
5275 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->scale, 3);
5277 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"matrix") == 0)
5279 out_node->has_matrix = 1;
5280 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->matrix, 16);
5282 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"weights") == 0)
5284 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(cgltf_float), (
void**)&out_node->weights, &out_node->weights_count);
5290 i = cgltf_parse_json_float_array(tokens, i - 1, json_chunk, out_node->weights, (
int)out_node->weights_count);
5292 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5294 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_node->extras);
5296 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5300 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5301 if(out_node->extensions)
5303 return CGLTF_ERROR_JSON;
5306 int extensions_size = tokens[i].size;
5307 out_node->extensions_count= 0;
5310 if (!out_node->extensions)
5312 return CGLTF_ERROR_NOMEM;
5317 for (
int k = 0; k < extensions_size; ++k)
5319 CGLTF_CHECK_KEY(tokens[i]);
5321 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_lights_punctual") == 0)
5325 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5327 int data_size = tokens[i].size;
5330 for (
int m = 0; m < data_size; ++m)
5332 CGLTF_CHECK_KEY(tokens[i]);
5334 if (cgltf_json_strcmp(tokens + i, json_chunk,
"light") == 0)
5337 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5338 out_node->light = CGLTF_PTRINDEX(
cgltf_light, cgltf_json_to_int(tokens + i, json_chunk));
5343 i = cgltf_skip_json(tokens, i + 1);
5352 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"EXT_mesh_gpu_instancing") == 0)
5354 out_node->has_mesh_gpu_instancing = 1;
5355 i = cgltf_parse_json_mesh_gpu_instancing(options, tokens, i + 1, json_chunk, &out_node->mesh_gpu_instancing);
5359 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_node->extensions[out_node->extensions_count++]));
5370 i = cgltf_skip_json(tokens, i+1);
5382 static int cgltf_parse_json_nodes(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5384 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_node), (
void**)&out_data->nodes, &out_data->nodes_count);
5390 for (cgltf_size j = 0; j < out_data->nodes_count; ++j)
5392 i = cgltf_parse_json_node(options, tokens, i, json_chunk, &out_data->nodes[j]);
5401 static int cgltf_parse_json_scene(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_scene* out_scene)
5403 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5405 int size = tokens[i].size;
5408 for (
int j = 0; j < size; ++j)
5410 CGLTF_CHECK_KEY(tokens[i]);
5412 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5414 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_scene->name);
5416 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"nodes") == 0)
5418 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_node*), (
void**)&out_scene->nodes, &out_scene->nodes_count);
5424 for (cgltf_size k = 0; k < out_scene->nodes_count; ++k)
5426 out_scene->nodes[k] = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
5430 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5432 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_scene->extras);
5434 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5436 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_scene->extensions_count, &out_scene->extensions);
5440 i = cgltf_skip_json(tokens, i+1);
5452 static int cgltf_parse_json_scenes(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5454 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_scene), (
void**)&out_data->scenes, &out_data->scenes_count);
5460 for (cgltf_size j = 0; j < out_data->scenes_count; ++j)
5462 i = cgltf_parse_json_scene(options, tokens, i, json_chunk, &out_data->scenes[j]);
5474 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5476 int size = tokens[i].size;
5479 for (
int j = 0; j < size; ++j)
5481 CGLTF_CHECK_KEY(tokens[i]);
5483 if (cgltf_json_strcmp(tokens+i, json_chunk,
"input") == 0)
5486 out_sampler->input = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
5489 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"output") == 0)
5492 out_sampler->output = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
5495 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"interpolation") == 0)
5498 if (cgltf_json_strcmp(tokens + i, json_chunk,
"LINEAR") == 0)
5500 out_sampler->interpolation = cgltf_interpolation_type_linear;
5502 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"STEP") == 0)
5504 out_sampler->interpolation = cgltf_interpolation_type_step;
5506 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"CUBICSPLINE") == 0)
5508 out_sampler->interpolation = cgltf_interpolation_type_cubic_spline;
5512 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5514 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sampler->extras);
5516 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5518 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sampler->extensions_count, &out_sampler->extensions);
5522 i = cgltf_skip_json(tokens, i+1);
5537 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5539 int size = tokens[i].size;
5542 for (
int j = 0; j < size; ++j)
5544 CGLTF_CHECK_KEY(tokens[i]);
5546 if (cgltf_json_strcmp(tokens+i, json_chunk,
"sampler") == 0)
5552 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"target") == 0)
5556 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5558 int target_size = tokens[i].size;
5561 for (
int k = 0; k < target_size; ++k)
5563 CGLTF_CHECK_KEY(tokens[i]);
5565 if (cgltf_json_strcmp(tokens+i, json_chunk,
"node") == 0)
5568 out_channel->target_node = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
5571 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"path") == 0)
5574 if (cgltf_json_strcmp(tokens+i, json_chunk,
"translation") == 0)
5576 out_channel->target_path = cgltf_animation_path_type_translation;
5578 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"rotation") == 0)
5580 out_channel->target_path = cgltf_animation_path_type_rotation;
5582 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"scale") == 0)
5584 out_channel->target_path = cgltf_animation_path_type_scale;
5586 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"weights") == 0)
5588 out_channel->target_path = cgltf_animation_path_type_weights;
5592 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5594 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_channel->extras);
5596 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5598 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_channel->extensions_count, &out_channel->extensions);
5602 i = cgltf_skip_json(tokens, i+1);
5613 i = cgltf_skip_json(tokens, i+1);
5625 static int cgltf_parse_json_animation(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_animation* out_animation)
5627 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5629 int size = tokens[i].size;
5632 for (
int j = 0; j < size; ++j)
5634 CGLTF_CHECK_KEY(tokens[i]);
5636 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5638 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_animation->name);
5640 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"samplers") == 0)
5642 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_animation_sampler), (
void**)&out_animation->samplers, &out_animation->samplers_count);
5648 for (cgltf_size k = 0; k < out_animation->samplers_count; ++k)
5650 i = cgltf_parse_json_animation_sampler(options, tokens, i, json_chunk, &out_animation->samplers[k]);
5657 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"channels") == 0)
5659 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_animation_channel), (
void**)&out_animation->channels, &out_animation->channels_count);
5665 for (cgltf_size k = 0; k < out_animation->channels_count; ++k)
5667 i = cgltf_parse_json_animation_channel(options, tokens, i, json_chunk, &out_animation->channels[k]);
5674 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5676 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_animation->extras);
5678 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5680 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_animation->extensions_count, &out_animation->extensions);
5684 i = cgltf_skip_json(tokens, i+1);
5696 static int cgltf_parse_json_animations(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5698 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_animation), (
void**)&out_data->animations, &out_data->animations_count);
5704 for (cgltf_size j = 0; j < out_data->animations_count; ++j)
5706 i = cgltf_parse_json_animation(options, tokens, i, json_chunk, &out_data->animations[j]);
5717 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5719 int size = tokens[i].size;
5722 for (
int j = 0; j < size; ++j)
5724 CGLTF_CHECK_KEY(tokens[i]);
5726 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5728 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_variant->name);
5730 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5732 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_variant->extras);
5736 i = cgltf_skip_json(tokens, i+1);
5748 static int cgltf_parse_json_variants(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5750 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_material_variant), (
void**)&out_data->variants, &out_data->variants_count);
5756 for (cgltf_size j = 0; j < out_data->variants_count; ++j)
5758 i = cgltf_parse_json_variant(options, tokens, i, json_chunk, &out_data->variants[j]);
5767 static int cgltf_parse_json_asset(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_asset* out_asset)
5769 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5771 int size = tokens[i].size;
5774 for (
int j = 0; j < size; ++j)
5776 CGLTF_CHECK_KEY(tokens[i]);
5778 if (cgltf_json_strcmp(tokens+i, json_chunk,
"copyright") == 0)
5780 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->copyright);
5782 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"generator") == 0)
5784 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->generator);
5786 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"version") == 0)
5788 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->version);
5790 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"minVersion") == 0)
5792 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->min_version);
5794 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5796 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_asset->extras);
5798 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5800 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_asset->extensions_count, &out_asset->extensions);
5804 i = cgltf_skip_json(tokens, i+1);
5813 if (out_asset->version && CGLTF_ATOF(out_asset->version) < 2)
5815 return CGLTF_ERROR_LEGACY;
5821 cgltf_size cgltf_num_components(cgltf_type type) {
5824 case cgltf_type_vec2:
5826 case cgltf_type_vec3:
5828 case cgltf_type_vec4:
5830 case cgltf_type_mat2:
5832 case cgltf_type_mat3:
5834 case cgltf_type_mat4:
5836 case cgltf_type_invalid:
5837 case cgltf_type_scalar:
5843 static cgltf_size cgltf_component_size(cgltf_component_type component_type) {
5844 switch (component_type)
5846 case cgltf_component_type_r_8:
5847 case cgltf_component_type_r_8u:
5849 case cgltf_component_type_r_16:
5850 case cgltf_component_type_r_16u:
5852 case cgltf_component_type_r_32u:
5853 case cgltf_component_type_r_32f:
5855 case cgltf_component_type_invalid:
5861 static cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type)
5863 cgltf_size component_size = cgltf_component_size(component_type);
5864 if (type == cgltf_type_mat2 && component_size == 1)
5866 return 8 * component_size;
5868 else if (type == cgltf_type_mat3 && (component_size == 1 || component_size == 2))
5870 return 12 * component_size;
5872 return component_size * cgltf_num_components(type);
5875 static int cgltf_fixup_pointers(
cgltf_data* out_data);
5877 static int cgltf_parse_json_root(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5879 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5881 int size = tokens[i].size;
5884 for (
int j = 0; j < size; ++j)
5886 CGLTF_CHECK_KEY(tokens[i]);
5888 if (cgltf_json_strcmp(tokens + i, json_chunk,
"asset") == 0)
5890 i = cgltf_parse_json_asset(options, tokens, i + 1, json_chunk, &out_data->asset);
5892 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"meshes") == 0)
5894 i = cgltf_parse_json_meshes(options, tokens, i + 1, json_chunk, out_data);
5896 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"accessors") == 0)
5898 i = cgltf_parse_json_accessors(options, tokens, i + 1, json_chunk, out_data);
5900 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"bufferViews") == 0)
5902 i = cgltf_parse_json_buffer_views(options, tokens, i + 1, json_chunk, out_data);
5904 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"buffers") == 0)
5906 i = cgltf_parse_json_buffers(options, tokens, i + 1, json_chunk, out_data);
5908 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"materials") == 0)
5910 i = cgltf_parse_json_materials(options, tokens, i + 1, json_chunk, out_data);
5912 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"images") == 0)
5914 i = cgltf_parse_json_images(options, tokens, i + 1, json_chunk, out_data);
5916 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"textures") == 0)
5918 i = cgltf_parse_json_textures(options, tokens, i + 1, json_chunk, out_data);
5920 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"samplers") == 0)
5922 i = cgltf_parse_json_samplers(options, tokens, i + 1, json_chunk, out_data);
5924 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"skins") == 0)
5926 i = cgltf_parse_json_skins(options, tokens, i + 1, json_chunk, out_data);
5928 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"cameras") == 0)
5930 i = cgltf_parse_json_cameras(options, tokens, i + 1, json_chunk, out_data);
5932 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"nodes") == 0)
5934 i = cgltf_parse_json_nodes(options, tokens, i + 1, json_chunk, out_data);
5936 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scenes") == 0)
5938 i = cgltf_parse_json_scenes(options, tokens, i + 1, json_chunk, out_data);
5940 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scene") == 0)
5943 out_data->scene = CGLTF_PTRINDEX(
cgltf_scene, cgltf_json_to_int(tokens + i, json_chunk));
5946 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"animations") == 0)
5948 i = cgltf_parse_json_animations(options, tokens, i + 1, json_chunk, out_data);
5950 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"extras") == 0)
5952 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_data->extras);
5954 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5958 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5959 if(out_data->data_extensions)
5961 return CGLTF_ERROR_JSON;
5964 int extensions_size = tokens[i].size;
5965 out_data->data_extensions_count = 0;
5968 if (!out_data->data_extensions)
5970 return CGLTF_ERROR_NOMEM;
5975 for (
int k = 0; k < extensions_size; ++k)
5977 CGLTF_CHECK_KEY(tokens[i]);
5979 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_lights_punctual") == 0)
5983 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5985 int data_size = tokens[i].size;
5988 for (
int m = 0; m < data_size; ++m)
5990 CGLTF_CHECK_KEY(tokens[i]);
5992 if (cgltf_json_strcmp(tokens + i, json_chunk,
"lights") == 0)
5994 i = cgltf_parse_json_lights(options, tokens, i + 1, json_chunk, out_data);
5998 i = cgltf_skip_json(tokens, i + 1);
6007 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_variants") == 0)
6011 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
6013 int data_size = tokens[i].size;
6016 for (
int m = 0; m < data_size; ++m)
6018 CGLTF_CHECK_KEY(tokens[i]);
6020 if (cgltf_json_strcmp(tokens + i, json_chunk,
"variants") == 0)
6022 i = cgltf_parse_json_variants(options, tokens, i + 1, json_chunk, out_data);
6026 i = cgltf_skip_json(tokens, i + 1);
6037 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_data->data_extensions[out_data->data_extensions_count++]));
6046 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensionsUsed") == 0)
6048 i = cgltf_parse_json_string_array(options, tokens, i + 1, json_chunk, &out_data->extensions_used, &out_data->extensions_used_count);
6050 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensionsRequired") == 0)
6052 i = cgltf_parse_json_string_array(options, tokens, i + 1, json_chunk, &out_data->extensions_required, &out_data->extensions_required_count);
6056 i = cgltf_skip_json(tokens, i + 1);
6068 cgltf_result cgltf_parse_json(
cgltf_options* options,
const uint8_t* json_chunk, cgltf_size size,
cgltf_data** out_data)
6070 jsmn_parser parser = { 0, 0, 0 };
6072 if (options->json_token_count == 0)
6074 int token_count = jsmn_parse(&parser, (
const char*)json_chunk, size, NULL, 0);
6076 if (token_count <= 0)
6078 return cgltf_result_invalid_json;
6081 options->json_token_count = token_count;
6084 jsmntok_t* tokens = (jsmntok_t*)options->memory.alloc(options->memory.user_data,
sizeof(jsmntok_t) * (options->json_token_count + 1));
6088 return cgltf_result_out_of_memory;
6093 int token_count = jsmn_parse(&parser, (
const char*)json_chunk, size, tokens, options->json_token_count);
6095 if (token_count <= 0)
6097 options->memory.free(options->memory.user_data, tokens);
6098 return cgltf_result_invalid_json;
6103 tokens[token_count].type = JSMN_UNDEFINED;
6109 options->memory.free(options->memory.user_data, tokens);
6110 return cgltf_result_out_of_memory;
6114 data->memory = options->memory;
6115 data->file = options->file;
6117 int i = cgltf_parse_json_root(options, tokens, 0, json_chunk, data);
6119 options->memory.free(options->memory.user_data, tokens);
6127 case CGLTF_ERROR_NOMEM:
return cgltf_result_out_of_memory;
6128 case CGLTF_ERROR_LEGACY:
return cgltf_result_legacy_gltf;
6129 default:
return cgltf_result_invalid_gltf;
6133 if (cgltf_fixup_pointers(data) < 0)
6136 return cgltf_result_invalid_gltf;
6139 data->json = (
const char*)json_chunk;
6140 data->json_size = size;
6144 return cgltf_result_success;
6147 static int cgltf_fixup_pointers(
cgltf_data* data)
6149 for (cgltf_size i = 0; i < data->meshes_count; ++i)
6151 for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
6153 CGLTF_PTRFIXUP(data->meshes[i].primitives[j].indices, data->accessors, data->accessors_count);
6154 CGLTF_PTRFIXUP(data->meshes[i].primitives[j].material, data->materials, data->materials_count);
6156 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
6158 CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].attributes[k].data, data->accessors, data->accessors_count);
6161 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
6163 for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
6165 CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].targets[k].attributes[m].data, data->accessors, data->accessors_count);
6169 if (data->meshes[i].primitives[j].has_draco_mesh_compression)
6171 CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].draco_mesh_compression.buffer_view, data->buffer_views, data->buffer_views_count);
6172 for (cgltf_size m = 0; m < data->meshes[i].primitives[j].draco_mesh_compression.attributes_count; ++m)
6174 CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].draco_mesh_compression.attributes[m].data, data->accessors, data->accessors_count);
6178 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
6180 CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].mappings[k].material, data->materials, data->materials_count);
6185 for (cgltf_size i = 0; i < data->accessors_count; ++i)
6187 CGLTF_PTRFIXUP(data->accessors[i].buffer_view, data->buffer_views, data->buffer_views_count);
6189 if (data->accessors[i].is_sparse)
6191 CGLTF_PTRFIXUP_REQ(data->accessors[i].sparse.indices_buffer_view, data->buffer_views, data->buffer_views_count);
6192 CGLTF_PTRFIXUP_REQ(data->accessors[i].sparse.values_buffer_view, data->buffer_views, data->buffer_views_count);
6195 if (data->accessors[i].buffer_view)
6197 data->accessors[i].stride = data->accessors[i].buffer_view->stride;
6200 if (data->accessors[i].stride == 0)
6202 data->accessors[i].stride = cgltf_calc_size(data->accessors[i].type, data->accessors[i].component_type);
6206 for (cgltf_size i = 0; i < data->textures_count; ++i)
6208 CGLTF_PTRFIXUP(data->textures[i].image, data->images, data->images_count);
6209 CGLTF_PTRFIXUP(data->textures[i].basisu_image, data->images, data->images_count);
6210 CGLTF_PTRFIXUP(data->textures[i].sampler, data->samplers, data->samplers_count);
6213 for (cgltf_size i = 0; i < data->images_count; ++i)
6215 CGLTF_PTRFIXUP(data->images[i].buffer_view, data->buffer_views, data->buffer_views_count);
6218 for (cgltf_size i = 0; i < data->materials_count; ++i)
6220 CGLTF_PTRFIXUP(data->materials[i].normal_texture.texture, data->textures, data->textures_count);
6221 CGLTF_PTRFIXUP(data->materials[i].emissive_texture.texture, data->textures, data->textures_count);
6222 CGLTF_PTRFIXUP(data->materials[i].occlusion_texture.texture, data->textures, data->textures_count);
6224 CGLTF_PTRFIXUP(data->materials[i].pbr_metallic_roughness.base_color_texture.texture, data->textures, data->textures_count);
6225 CGLTF_PTRFIXUP(data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture, data->textures, data->textures_count);
6227 CGLTF_PTRFIXUP(data->materials[i].pbr_specular_glossiness.diffuse_texture.texture, data->textures, data->textures_count);
6228 CGLTF_PTRFIXUP(data->materials[i].pbr_specular_glossiness.specular_glossiness_texture.texture, data->textures, data->textures_count);
6230 CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_texture.texture, data->textures, data->textures_count);
6231 CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_roughness_texture.texture, data->textures, data->textures_count);
6232 CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_normal_texture.texture, data->textures, data->textures_count);
6234 CGLTF_PTRFIXUP(data->materials[i].specular.specular_texture.texture, data->textures, data->textures_count);
6235 CGLTF_PTRFIXUP(data->materials[i].specular.specular_color_texture.texture, data->textures, data->textures_count);
6237 CGLTF_PTRFIXUP(data->materials[i].transmission.transmission_texture.texture, data->textures, data->textures_count);
6239 CGLTF_PTRFIXUP(data->materials[i].volume.thickness_texture.texture, data->textures, data->textures_count);
6241 CGLTF_PTRFIXUP(data->materials[i].sheen.sheen_color_texture.texture, data->textures, data->textures_count);
6242 CGLTF_PTRFIXUP(data->materials[i].sheen.sheen_roughness_texture.texture, data->textures, data->textures_count);
6244 CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_texture.texture, data->textures, data->textures_count);
6245 CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_thickness_texture.texture, data->textures, data->textures_count);
6248 for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
6250 CGLTF_PTRFIXUP_REQ(data->buffer_views[i].buffer, data->buffers, data->buffers_count);
6252 if (data->buffer_views[i].has_meshopt_compression)
6254 CGLTF_PTRFIXUP_REQ(data->buffer_views[i].meshopt_compression.buffer, data->buffers, data->buffers_count);
6258 for (cgltf_size i = 0; i < data->skins_count; ++i)
6260 for (cgltf_size j = 0; j < data->skins[i].joints_count; ++j)
6262 CGLTF_PTRFIXUP_REQ(data->skins[i].joints[j], data->nodes, data->nodes_count);
6265 CGLTF_PTRFIXUP(data->skins[i].skeleton, data->nodes, data->nodes_count);
6266 CGLTF_PTRFIXUP(data->skins[i].inverse_bind_matrices, data->accessors, data->accessors_count);
6269 for (cgltf_size i = 0; i < data->nodes_count; ++i)
6271 for (cgltf_size j = 0; j < data->nodes[i].children_count; ++j)
6273 CGLTF_PTRFIXUP_REQ(data->nodes[i].children[j], data->nodes, data->nodes_count);
6275 if (data->nodes[i].children[j]->parent)
6277 return CGLTF_ERROR_JSON;
6280 data->nodes[i].children[j]->parent = &data->nodes[i];
6283 CGLTF_PTRFIXUP(data->nodes[i].mesh, data->meshes, data->meshes_count);
6284 CGLTF_PTRFIXUP(data->nodes[i].skin, data->skins, data->skins_count);
6285 CGLTF_PTRFIXUP(data->nodes[i].camera, data->cameras, data->cameras_count);
6286 CGLTF_PTRFIXUP(data->nodes[i].light, data->lights, data->lights_count);
6288 if (data->nodes[i].has_mesh_gpu_instancing)
6290 CGLTF_PTRFIXUP_REQ(data->nodes[i].mesh_gpu_instancing.buffer_view, data->buffer_views, data->buffer_views_count);
6291 for (cgltf_size m = 0; m < data->nodes[i].mesh_gpu_instancing.attributes_count; ++m)
6293 CGLTF_PTRFIXUP_REQ(data->nodes[i].mesh_gpu_instancing.attributes[m].data, data->accessors, data->accessors_count);
6298 for (cgltf_size i = 0; i < data->scenes_count; ++i)
6300 for (cgltf_size j = 0; j < data->scenes[i].nodes_count; ++j)
6302 CGLTF_PTRFIXUP_REQ(data->scenes[i].nodes[j], data->nodes, data->nodes_count);
6304 if (data->scenes[i].nodes[j]->parent)
6306 return CGLTF_ERROR_JSON;
6311 CGLTF_PTRFIXUP(data->scene, data->scenes, data->scenes_count);
6313 for (cgltf_size i = 0; i < data->animations_count; ++i)
6315 for (cgltf_size j = 0; j < data->animations[i].samplers_count; ++j)
6317 CGLTF_PTRFIXUP_REQ(data->animations[i].samplers[j].input, data->accessors, data->accessors_count);
6318 CGLTF_PTRFIXUP_REQ(data->animations[i].samplers[j].output, data->accessors, data->accessors_count);
6321 for (cgltf_size j = 0; j < data->animations[i].channels_count; ++j)
6323 CGLTF_PTRFIXUP_REQ(data->animations[i].channels[j].sampler, data->animations[i].samplers, data->animations[i].samplers_count);
6324 CGLTF_PTRFIXUP(data->animations[i].channels[j].target_node, data->nodes, data->nodes_count);
6360 static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
6361 jsmntok_t *tokens,
size_t num_tokens) {
6363 if (parser->toknext >= num_tokens) {
6366 tok = &tokens[parser->toknext++];
6367 tok->start = tok->end = -1;
6369 #ifdef JSMN_PARENT_LINKS
6378 static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
6379 int start,
int end) {
6381 token->start = start;
6389 static int jsmn_parse_primitive(jsmn_parser *parser,
const char *js,
6390 size_t len, jsmntok_t *tokens,
size_t num_tokens) {
6394 start = parser->pos;
6396 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
6397 switch (js[parser->pos]) {
6402 case '\t' :
case '\r' :
case '\n' :
case ' ' :
6403 case ',' :
case ']' :
case '}' :
6406 if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
6407 parser->pos = start;
6408 return JSMN_ERROR_INVAL;
6413 parser->pos = start;
6414 return JSMN_ERROR_PART;
6418 if (tokens == NULL) {
6422 token = jsmn_alloc_token(parser, tokens, num_tokens);
6423 if (token == NULL) {
6424 parser->pos = start;
6425 return JSMN_ERROR_NOMEM;
6427 jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
6428 #ifdef JSMN_PARENT_LINKS
6429 token->parent = parser->toksuper;
6438 static int jsmn_parse_string(jsmn_parser *parser,
const char *js,
6439 size_t len, jsmntok_t *tokens,
size_t num_tokens) {
6442 int start = parser->pos;
6447 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
6448 char c = js[parser->pos];
6452 if (tokens == NULL) {
6455 token = jsmn_alloc_token(parser, tokens, num_tokens);
6456 if (token == NULL) {
6457 parser->pos = start;
6458 return JSMN_ERROR_NOMEM;
6460 jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
6461 #ifdef JSMN_PARENT_LINKS
6462 token->parent = parser->toksuper;
6468 if (c ==
'\\' && parser->pos + 1 < len) {
6471 switch (js[parser->pos]) {
6473 case '\"':
case '/' :
case '\\' :
case 'b' :
6474 case 'f' :
case 'r' :
case 'n' :
case 't' :
6479 for(i = 0; i < 4 && parser->pos < len && js[parser->pos] !=
'\0'; i++) {
6481 if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) ||
6482 (js[parser->pos] >= 65 && js[parser->pos] <= 70) ||
6483 (js[parser->pos] >= 97 && js[parser->pos] <= 102))) {
6484 parser->pos = start;
6485 return JSMN_ERROR_INVAL;
6493 parser->pos = start;
6494 return JSMN_ERROR_INVAL;
6498 parser->pos = start;
6499 return JSMN_ERROR_PART;
6505 static int jsmn_parse(jsmn_parser *parser,
const char *js,
size_t len,
6506 jsmntok_t *tokens,
size_t num_tokens) {
6510 int count = parser->toknext;
6512 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
6516 c = js[parser->pos];
6520 if (tokens == NULL) {
6523 token = jsmn_alloc_token(parser, tokens, num_tokens);
6525 return JSMN_ERROR_NOMEM;
6526 if (parser->toksuper != -1) {
6527 tokens[parser->toksuper].size++;
6528 #ifdef JSMN_PARENT_LINKS
6529 token->parent = parser->toksuper;
6532 token->type = (c ==
'{' ? JSMN_OBJECT : JSMN_ARRAY);
6533 token->start = parser->pos;
6534 parser->toksuper = parser->toknext - 1;
6539 type = (c ==
'}' ? JSMN_OBJECT : JSMN_ARRAY);
6540 #ifdef JSMN_PARENT_LINKS
6541 if (parser->toknext < 1) {
6542 return JSMN_ERROR_INVAL;
6544 token = &tokens[parser->toknext - 1];
6546 if (token->start != -1 && token->end == -1) {
6547 if (token->type != type) {
6548 return JSMN_ERROR_INVAL;
6550 token->end = parser->pos + 1;
6551 parser->toksuper = token->parent;
6554 if (token->parent == -1) {
6555 if(token->type != type || parser->toksuper == -1) {
6556 return JSMN_ERROR_INVAL;
6560 token = &tokens[token->parent];
6563 for (i = parser->toknext - 1; i >= 0; i--) {
6565 if (token->start != -1 && token->end == -1) {
6566 if (token->type != type) {
6567 return JSMN_ERROR_INVAL;
6569 parser->toksuper = -1;
6570 token->end = parser->pos + 1;
6575 if (i == -1)
return JSMN_ERROR_INVAL;
6576 for (; i >= 0; i--) {
6578 if (token->start != -1 && token->end == -1) {
6579 parser->toksuper = i;
6586 r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
6587 if (r < 0)
return r;
6589 if (parser->toksuper != -1 && tokens != NULL)
6590 tokens[parser->toksuper].size++;
6592 case '\t' :
case '\r' :
case '\n' :
case ' ':
6595 parser->toksuper = parser->toknext - 1;
6598 if (tokens != NULL && parser->toksuper != -1 &&
6599 tokens[parser->toksuper].type != JSMN_ARRAY &&
6600 tokens[parser->toksuper].type != JSMN_OBJECT) {
6601 #ifdef JSMN_PARENT_LINKS
6602 parser->toksuper = tokens[parser->toksuper].parent;
6604 for (i = parser->toknext - 1; i >= 0; i--) {
6605 if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
6606 if (tokens[i].start != -1 && tokens[i].
end == -1) {
6607 parser->toksuper = i;
6617 case '-':
case '0':
case '1' :
case '2':
case '3' :
case '4':
6618 case '5':
case '6':
case '7' :
case '8':
case '9':
6619 case 't':
case 'f':
case 'n' :
6621 if (tokens != NULL && parser->toksuper != -1) {
6622 jsmntok_t *t = &tokens[parser->toksuper];
6623 if (t->type == JSMN_OBJECT ||
6624 (t->type == JSMN_STRING && t->size != 0)) {
6625 return JSMN_ERROR_INVAL;
6632 r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
6633 if (r < 0)
return r;
6635 if (parser->toksuper != -1 && tokens != NULL)
6636 tokens[parser->toksuper].size++;
6642 return JSMN_ERROR_INVAL;
6647 if (tokens != NULL) {
6648 for (i = parser->toknext - 1; i >= 0; i--) {
6650 if (tokens[i].start != -1 && tokens[i].
end == -1) {
6651 return JSMN_ERROR_PART;
6663 static void jsmn_init(jsmn_parser *parser) {
6665 parser->toknext = 0;
6666 parser->toksuper = -1;
bool value(Widgets &w, const char *label, int &value, const int value_min, const int value_max, const int value_step)
valeur editable par increment.
void end(Widgets &w)
termine la description des elements de l'interface graphique.
float length(const Vector &v)
renvoie la longueur d'un vecteur.