1/**************************************************************************/
2/* gltf_document.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#include "gltf_document.h"
32
33#include "extensions/gltf_spec_gloss.h"
34
35#include "core/config/project_settings.h"
36#include "core/crypto/crypto_core.h"
37#include "core/io/config_file.h"
38#include "core/io/dir_access.h"
39#include "core/io/file_access.h"
40#include "core/io/file_access_memory.h"
41#include "core/io/json.h"
42#include "core/io/stream_peer.h"
43#include "core/math/disjoint_set.h"
44#include "core/version.h"
45#include "scene/3d/bone_attachment_3d.h"
46#include "scene/3d/camera_3d.h"
47#include "scene/3d/importer_mesh_instance_3d.h"
48#include "scene/3d/light_3d.h"
49#include "scene/3d/mesh_instance_3d.h"
50#include "scene/3d/multimesh_instance_3d.h"
51#include "scene/resources/image_texture.h"
52#include "scene/resources/portable_compressed_texture.h"
53#include "scene/resources/skin.h"
54#include "scene/resources/surface_tool.h"
55
56#include "modules/modules_enabled.gen.h" // For csg, gridmap.
57
58#ifdef TOOLS_ENABLED
59#include "editor/editor_file_system.h"
60#endif
61#ifdef MODULE_CSG_ENABLED
62#include "modules/csg/csg_shape.h"
63#endif // MODULE_CSG_ENABLED
64#ifdef MODULE_GRIDMAP_ENABLED
65#include "modules/gridmap/grid_map.h"
66#endif // MODULE_GRIDMAP_ENABLED
67
68// FIXME: Hardcoded to avoid editor dependency.
69#define GLTF_IMPORT_USE_NAMED_SKIN_BINDS 16
70#define GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS 32
71
72#include <stdio.h>
73#include <stdlib.h>
74#include <cstdint>
75#include <limits>
76
77static Ref<ImporterMesh> _mesh_to_importer_mesh(Ref<Mesh> p_mesh) {
78 Ref<ImporterMesh> importer_mesh;
79 importer_mesh.instantiate();
80 if (p_mesh.is_null()) {
81 return importer_mesh;
82 }
83
84 Ref<ArrayMesh> array_mesh = p_mesh;
85 if (p_mesh->get_blend_shape_count()) {
86 ArrayMesh::BlendShapeMode shape_mode = ArrayMesh::BLEND_SHAPE_MODE_NORMALIZED;
87 if (array_mesh.is_valid()) {
88 shape_mode = array_mesh->get_blend_shape_mode();
89 }
90 importer_mesh->set_blend_shape_mode(shape_mode);
91 for (int morph_i = 0; morph_i < p_mesh->get_blend_shape_count(); morph_i++) {
92 importer_mesh->add_blend_shape(p_mesh->get_blend_shape_name(morph_i));
93 }
94 }
95 for (int32_t surface_i = 0; surface_i < p_mesh->get_surface_count(); surface_i++) {
96 Array array = p_mesh->surface_get_arrays(surface_i);
97 Ref<Material> mat = p_mesh->surface_get_material(surface_i);
98 String mat_name;
99 if (mat.is_valid()) {
100 mat_name = mat->get_name();
101 } else {
102 // Assign default material when no material is assigned.
103 mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
104 }
105 importer_mesh->add_surface(p_mesh->surface_get_primitive_type(surface_i),
106 array, p_mesh->surface_get_blend_shape_arrays(surface_i), p_mesh->surface_get_lods(surface_i), mat,
107 mat_name, p_mesh->surface_get_format(surface_i));
108 }
109 return importer_mesh;
110}
111
112Error GLTFDocument::_serialize(Ref<GLTFState> p_state) {
113 if (!p_state->buffers.size()) {
114 p_state->buffers.push_back(Vector<uint8_t>());
115 }
116
117 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
118 ERR_CONTINUE(ext.is_null());
119 Error err = ext->export_preserialize(p_state);
120 ERR_CONTINUE(err != OK);
121 }
122
123 /* STEP CONVERT MESH INSTANCES */
124 _convert_mesh_instances(p_state);
125
126 /* STEP SERIALIZE CAMERAS */
127 Error err = _serialize_cameras(p_state);
128 if (err != OK) {
129 return Error::FAILED;
130 }
131
132 /* STEP 3 CREATE SKINS */
133 err = _serialize_skins(p_state);
134 if (err != OK) {
135 return Error::FAILED;
136 }
137
138 /* STEP SERIALIZE MESHES (we have enough info now) */
139 err = _serialize_meshes(p_state);
140 if (err != OK) {
141 return Error::FAILED;
142 }
143
144 /* STEP SERIALIZE TEXTURES */
145 err = _serialize_materials(p_state);
146 if (err != OK) {
147 return Error::FAILED;
148 }
149
150 /* STEP SERIALIZE TEXTURE SAMPLERS */
151 err = _serialize_texture_samplers(p_state);
152 if (err != OK) {
153 return Error::FAILED;
154 }
155
156 /* STEP SERIALIZE ANIMATIONS */
157 err = _serialize_animations(p_state);
158 if (err != OK) {
159 return Error::FAILED;
160 }
161
162 /* STEP SERIALIZE ACCESSORS */
163 err = _encode_accessors(p_state);
164 if (err != OK) {
165 return Error::FAILED;
166 }
167
168 /* STEP SERIALIZE IMAGES */
169 err = _serialize_images(p_state);
170 if (err != OK) {
171 return Error::FAILED;
172 }
173
174 /* STEP SERIALIZE TEXTURES */
175 err = _serialize_textures(p_state);
176 if (err != OK) {
177 return Error::FAILED;
178 }
179
180 for (GLTFBufferViewIndex i = 0; i < p_state->buffer_views.size(); i++) {
181 p_state->buffer_views.write[i]->buffer = 0;
182 }
183
184 /* STEP SERIALIZE BUFFER VIEWS */
185 err = _encode_buffer_views(p_state);
186 if (err != OK) {
187 return Error::FAILED;
188 }
189
190 /* STEP SERIALIZE NODES */
191 err = _serialize_nodes(p_state);
192 if (err != OK) {
193 return Error::FAILED;
194 }
195
196 /* STEP SERIALIZE SCENE */
197 err = _serialize_scenes(p_state);
198 if (err != OK) {
199 return Error::FAILED;
200 }
201
202 /* STEP SERIALIZE LIGHTS */
203 err = _serialize_lights(p_state);
204 if (err != OK) {
205 return Error::FAILED;
206 }
207
208 /* STEP SERIALIZE EXTENSIONS */
209 err = _serialize_gltf_extensions(p_state);
210 if (err != OK) {
211 return Error::FAILED;
212 }
213
214 /* STEP SERIALIZE VERSION */
215 err = _serialize_asset_header(p_state);
216 if (err != OK) {
217 return Error::FAILED;
218 }
219
220 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
221 ERR_CONTINUE(ext.is_null());
222 err = ext->export_post(p_state);
223 ERR_FAIL_COND_V(err != OK, err);
224 }
225
226 return OK;
227}
228
229Error GLTFDocument::_serialize_gltf_extensions(Ref<GLTFState> p_state) const {
230 Vector<String> extensions_used = p_state->extensions_used;
231 Vector<String> extensions_required = p_state->extensions_required;
232 if (!p_state->lights.is_empty()) {
233 extensions_used.push_back("KHR_lights_punctual");
234 }
235 if (p_state->use_khr_texture_transform) {
236 extensions_used.push_back("KHR_texture_transform");
237 extensions_required.push_back("KHR_texture_transform");
238 }
239 if (!extensions_used.is_empty()) {
240 extensions_used.sort();
241 p_state->json["extensionsUsed"] = extensions_used;
242 }
243 if (!extensions_required.is_empty()) {
244 extensions_required.sort();
245 p_state->json["extensionsRequired"] = extensions_required;
246 }
247 return OK;
248}
249
250Error GLTFDocument::_serialize_scenes(Ref<GLTFState> p_state) {
251 ERR_FAIL_COND_V_MSG(p_state->root_nodes.size() == 0, ERR_INVALID_DATA, "GLTF export: The scene must have at least one root node.");
252 // Godot only supports one scene per glTF file.
253 Array scenes;
254 Dictionary scene_dict;
255 scenes.append(scene_dict);
256 p_state->json["scenes"] = scenes;
257 p_state->json["scene"] = 0;
258 // Add nodes to the scene dict.
259 scene_dict["nodes"] = p_state->root_nodes;
260 if (!p_state->scene_name.is_empty()) {
261 scene_dict["name"] = p_state->scene_name;
262 }
263 return OK;
264}
265
266Error GLTFDocument::_parse_json(const String &p_path, Ref<GLTFState> p_state) {
267 Error err;
268 Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::READ, &err);
269 if (file.is_null()) {
270 return err;
271 }
272
273 Vector<uint8_t> array;
274 array.resize(file->get_length());
275 file->get_buffer(array.ptrw(), array.size());
276 String text;
277 text.parse_utf8((const char *)array.ptr(), array.size());
278
279 JSON json;
280 err = json.parse(text);
281 if (err != OK) {
282 _err_print_error("", p_path.utf8().get_data(), json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT);
283 return err;
284 }
285 p_state->json = json.get_data();
286
287 return OK;
288}
289
290Error GLTFDocument::_parse_glb(Ref<FileAccess> p_file, Ref<GLTFState> p_state) {
291 ERR_FAIL_NULL_V(p_file, ERR_INVALID_PARAMETER);
292 ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
293 ERR_FAIL_COND_V(p_file->get_position() != 0, ERR_FILE_CANT_READ);
294 uint32_t magic = p_file->get_32();
295 ERR_FAIL_COND_V(magic != 0x46546C67, ERR_FILE_UNRECOGNIZED); //glTF
296 p_file->get_32(); // version
297 p_file->get_32(); // length
298 uint32_t chunk_length = p_file->get_32();
299 uint32_t chunk_type = p_file->get_32();
300
301 ERR_FAIL_COND_V(chunk_type != 0x4E4F534A, ERR_PARSE_ERROR); //JSON
302 Vector<uint8_t> json_data;
303 json_data.resize(chunk_length);
304 uint32_t len = p_file->get_buffer(json_data.ptrw(), chunk_length);
305 ERR_FAIL_COND_V(len != chunk_length, ERR_FILE_CORRUPT);
306
307 String text;
308 text.parse_utf8((const char *)json_data.ptr(), json_data.size());
309
310 JSON json;
311 Error err = json.parse(text);
312 if (err != OK) {
313 _err_print_error("", "", json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT);
314 return err;
315 }
316
317 p_state->json = json.get_data();
318
319 //data?
320
321 chunk_length = p_file->get_32();
322 chunk_type = p_file->get_32();
323
324 if (p_file->eof_reached()) {
325 return OK; //all good
326 }
327
328 ERR_FAIL_COND_V(chunk_type != 0x004E4942, ERR_PARSE_ERROR); //BIN
329
330 p_state->glb_data.resize(chunk_length);
331 len = p_file->get_buffer(p_state->glb_data.ptrw(), chunk_length);
332 ERR_FAIL_COND_V(len != chunk_length, ERR_FILE_CORRUPT);
333
334 return OK;
335}
336
337static Array _vec3_to_arr(const Vector3 &p_vec3) {
338 Array array;
339 array.resize(3);
340 array[0] = p_vec3.x;
341 array[1] = p_vec3.y;
342 array[2] = p_vec3.z;
343 return array;
344}
345
346static Vector3 _arr_to_vec3(const Array &p_array) {
347 ERR_FAIL_COND_V(p_array.size() != 3, Vector3());
348 return Vector3(p_array[0], p_array[1], p_array[2]);
349}
350
351static Array _quaternion_to_array(const Quaternion &p_quaternion) {
352 Array array;
353 array.resize(4);
354 array[0] = p_quaternion.x;
355 array[1] = p_quaternion.y;
356 array[2] = p_quaternion.z;
357 array[3] = p_quaternion.w;
358 return array;
359}
360
361static Quaternion _arr_to_quaternion(const Array &p_array) {
362 ERR_FAIL_COND_V(p_array.size() != 4, Quaternion());
363 return Quaternion(p_array[0], p_array[1], p_array[2], p_array[3]);
364}
365
366static Transform3D _arr_to_xform(const Array &p_array) {
367 ERR_FAIL_COND_V(p_array.size() != 16, Transform3D());
368
369 Transform3D xform;
370 xform.basis.set_column(Vector3::AXIS_X, Vector3(p_array[0], p_array[1], p_array[2]));
371 xform.basis.set_column(Vector3::AXIS_Y, Vector3(p_array[4], p_array[5], p_array[6]));
372 xform.basis.set_column(Vector3::AXIS_Z, Vector3(p_array[8], p_array[9], p_array[10]));
373 xform.set_origin(Vector3(p_array[12], p_array[13], p_array[14]));
374
375 return xform;
376}
377
378static Vector<real_t> _xform_to_array(const Transform3D p_transform) {
379 Vector<real_t> array;
380 array.resize(16);
381 Vector3 axis_x = p_transform.get_basis().get_column(Vector3::AXIS_X);
382 array.write[0] = axis_x.x;
383 array.write[1] = axis_x.y;
384 array.write[2] = axis_x.z;
385 array.write[3] = 0.0f;
386 Vector3 axis_y = p_transform.get_basis().get_column(Vector3::AXIS_Y);
387 array.write[4] = axis_y.x;
388 array.write[5] = axis_y.y;
389 array.write[6] = axis_y.z;
390 array.write[7] = 0.0f;
391 Vector3 axis_z = p_transform.get_basis().get_column(Vector3::AXIS_Z);
392 array.write[8] = axis_z.x;
393 array.write[9] = axis_z.y;
394 array.write[10] = axis_z.z;
395 array.write[11] = 0.0f;
396 Vector3 origin = p_transform.get_origin();
397 array.write[12] = origin.x;
398 array.write[13] = origin.y;
399 array.write[14] = origin.z;
400 array.write[15] = 1.0f;
401 return array;
402}
403
404Error GLTFDocument::_serialize_nodes(Ref<GLTFState> p_state) {
405 Array nodes;
406 for (int i = 0; i < p_state->nodes.size(); i++) {
407 Dictionary node;
408 Ref<GLTFNode> gltf_node = p_state->nodes[i];
409 Dictionary extensions;
410 node["extensions"] = extensions;
411 if (!gltf_node->get_name().is_empty()) {
412 node["name"] = gltf_node->get_name();
413 }
414 if (gltf_node->camera != -1) {
415 node["camera"] = gltf_node->camera;
416 }
417 if (gltf_node->light != -1) {
418 Dictionary lights_punctual;
419 extensions["KHR_lights_punctual"] = lights_punctual;
420 lights_punctual["light"] = gltf_node->light;
421 }
422 if (gltf_node->mesh != -1) {
423 node["mesh"] = gltf_node->mesh;
424 }
425 if (gltf_node->skin != -1) {
426 node["skin"] = gltf_node->skin;
427 }
428 if (gltf_node->skeleton != -1 && gltf_node->skin < 0) {
429 }
430 if (gltf_node->xform != Transform3D()) {
431 node["matrix"] = _xform_to_array(gltf_node->xform);
432 }
433
434 if (!gltf_node->rotation.is_equal_approx(Quaternion())) {
435 node["rotation"] = _quaternion_to_array(gltf_node->rotation);
436 }
437
438 if (!gltf_node->scale.is_equal_approx(Vector3(1.0f, 1.0f, 1.0f))) {
439 node["scale"] = _vec3_to_arr(gltf_node->scale);
440 }
441
442 if (!gltf_node->position.is_zero_approx()) {
443 node["translation"] = _vec3_to_arr(gltf_node->position);
444 }
445 if (gltf_node->children.size()) {
446 Array children;
447 for (int j = 0; j < gltf_node->children.size(); j++) {
448 children.push_back(gltf_node->children[j]);
449 }
450 node["children"] = children;
451 }
452
453 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
454 ERR_CONTINUE(ext.is_null());
455 ERR_CONTINUE(!p_state->scene_nodes.find(i));
456 Error err = ext->export_node(p_state, gltf_node, node, p_state->scene_nodes[i]);
457 ERR_CONTINUE(err != OK);
458 }
459
460 nodes.push_back(node);
461 }
462 p_state->json["nodes"] = nodes;
463 return OK;
464}
465
466String GLTFDocument::_gen_unique_name(Ref<GLTFState> p_state, const String &p_name) {
467 const String s_name = p_name.validate_node_name();
468
469 String u_name;
470 int index = 1;
471 while (true) {
472 u_name = s_name;
473
474 if (index > 1) {
475 u_name += itos(index);
476 }
477 if (!p_state->unique_names.has(u_name)) {
478 break;
479 }
480 index++;
481 }
482
483 p_state->unique_names.insert(u_name);
484
485 return u_name;
486}
487
488String GLTFDocument::_sanitize_animation_name(const String &p_name) {
489 // Animations disallow the normal node invalid characters as well as "," and "["
490 // (See animation/animation_player.cpp::add_animation)
491
492 // TODO: Consider adding invalid_characters or a validate_animation_name to animation_player to mirror Node.
493 String anim_name = p_name.validate_node_name();
494 anim_name = anim_name.replace(",", "");
495 anim_name = anim_name.replace("[", "");
496 return anim_name;
497}
498
499String GLTFDocument::_gen_unique_animation_name(Ref<GLTFState> p_state, const String &p_name) {
500 const String s_name = _sanitize_animation_name(p_name);
501
502 String u_name;
503 int index = 1;
504 while (true) {
505 u_name = s_name;
506
507 if (index > 1) {
508 u_name += itos(index);
509 }
510 if (!p_state->unique_animation_names.has(u_name)) {
511 break;
512 }
513 index++;
514 }
515
516 p_state->unique_animation_names.insert(u_name);
517
518 return u_name;
519}
520
521String GLTFDocument::_sanitize_bone_name(const String &p_name) {
522 String bone_name = p_name;
523 bone_name = bone_name.replace(":", "_");
524 bone_name = bone_name.replace("/", "_");
525 return bone_name;
526}
527
528String GLTFDocument::_gen_unique_bone_name(Ref<GLTFState> p_state, const GLTFSkeletonIndex p_skel_i, const String &p_name) {
529 String s_name = _sanitize_bone_name(p_name);
530 if (s_name.is_empty()) {
531 s_name = "bone";
532 }
533 String u_name;
534 int index = 1;
535 while (true) {
536 u_name = s_name;
537
538 if (index > 1) {
539 u_name += "_" + itos(index);
540 }
541 if (!p_state->skeletons[p_skel_i]->unique_names.has(u_name)) {
542 break;
543 }
544 index++;
545 }
546
547 p_state->skeletons.write[p_skel_i]->unique_names.insert(u_name);
548
549 return u_name;
550}
551
552Error GLTFDocument::_parse_scenes(Ref<GLTFState> p_state) {
553 p_state->unique_names.insert("Skeleton3D"); // Reserve skeleton name.
554 ERR_FAIL_COND_V(!p_state->json.has("scenes"), ERR_FILE_CORRUPT);
555 const Array &scenes = p_state->json["scenes"];
556 int loaded_scene = 0;
557 if (p_state->json.has("scene")) {
558 loaded_scene = p_state->json["scene"];
559 } else {
560 WARN_PRINT("The load-time scene is not defined in the glTF2 file. Picking the first scene.");
561 }
562
563 if (scenes.size()) {
564 ERR_FAIL_COND_V(loaded_scene >= scenes.size(), ERR_FILE_CORRUPT);
565 const Dictionary &scene_dict = scenes[loaded_scene];
566 ERR_FAIL_COND_V(!scene_dict.has("nodes"), ERR_UNAVAILABLE);
567 const Array &nodes = scene_dict["nodes"];
568 for (int j = 0; j < nodes.size(); j++) {
569 p_state->root_nodes.push_back(nodes[j]);
570 }
571 // Determine what to use for the scene name.
572 if (scene_dict.has("name") && !String(scene_dict["name"]).is_empty() && !((String)scene_dict["name"]).begins_with("Scene")) {
573 p_state->scene_name = scene_dict["name"];
574 } else {
575 p_state->scene_name = p_state->filename;
576 }
577 }
578
579 return OK;
580}
581
582Error GLTFDocument::_parse_nodes(Ref<GLTFState> p_state) {
583 ERR_FAIL_COND_V(!p_state->json.has("nodes"), ERR_FILE_CORRUPT);
584 const Array &nodes = p_state->json["nodes"];
585 for (int i = 0; i < nodes.size(); i++) {
586 Ref<GLTFNode> node;
587 node.instantiate();
588 const Dictionary &n = nodes[i];
589
590 if (n.has("name")) {
591 node->set_name(n["name"]);
592 }
593 if (n.has("camera")) {
594 node->camera = n["camera"];
595 }
596 if (n.has("mesh")) {
597 node->mesh = n["mesh"];
598 }
599 if (n.has("skin")) {
600 node->skin = n["skin"];
601 }
602 if (n.has("matrix")) {
603 node->xform = _arr_to_xform(n["matrix"]);
604 } else {
605 if (n.has("translation")) {
606 node->position = _arr_to_vec3(n["translation"]);
607 }
608 if (n.has("rotation")) {
609 node->rotation = _arr_to_quaternion(n["rotation"]);
610 }
611 if (n.has("scale")) {
612 node->scale = _arr_to_vec3(n["scale"]);
613 }
614
615 node->xform.basis.set_quaternion_scale(node->rotation, node->scale);
616 node->xform.origin = node->position;
617 }
618
619 if (n.has("extensions")) {
620 Dictionary extensions = n["extensions"];
621 if (extensions.has("KHR_lights_punctual")) {
622 Dictionary lights_punctual = extensions["KHR_lights_punctual"];
623 if (lights_punctual.has("light")) {
624 GLTFLightIndex light = lights_punctual["light"];
625 node->light = light;
626 }
627 }
628 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
629 ERR_CONTINUE(ext.is_null());
630 Error err = ext->parse_node_extensions(p_state, node, extensions);
631 ERR_CONTINUE_MSG(err != OK, "GLTF: Encountered error " + itos(err) + " when parsing node extensions for node " + node->get_name() + " in file " + p_state->filename + ". Continuing.");
632 }
633 }
634
635 if (n.has("children")) {
636 const Array &children = n["children"];
637 for (int j = 0; j < children.size(); j++) {
638 node->children.push_back(children[j]);
639 }
640 }
641
642 p_state->nodes.push_back(node);
643 }
644
645 // build the hierarchy
646 for (GLTFNodeIndex node_i = 0; node_i < p_state->nodes.size(); node_i++) {
647 for (int j = 0; j < p_state->nodes[node_i]->children.size(); j++) {
648 GLTFNodeIndex child_i = p_state->nodes[node_i]->children[j];
649
650 ERR_FAIL_INDEX_V(child_i, p_state->nodes.size(), ERR_FILE_CORRUPT);
651 ERR_CONTINUE(p_state->nodes[child_i]->parent != -1); //node already has a parent, wtf.
652
653 p_state->nodes.write[child_i]->parent = node_i;
654 }
655 }
656
657 _compute_node_heights(p_state);
658
659 return OK;
660}
661
662void GLTFDocument::_compute_node_heights(Ref<GLTFState> p_state) {
663 p_state->root_nodes.clear();
664 for (GLTFNodeIndex node_i = 0; node_i < p_state->nodes.size(); ++node_i) {
665 Ref<GLTFNode> node = p_state->nodes[node_i];
666 node->height = 0;
667
668 GLTFNodeIndex current_i = node_i;
669 while (current_i >= 0) {
670 const GLTFNodeIndex parent_i = p_state->nodes[current_i]->parent;
671 if (parent_i >= 0) {
672 ++node->height;
673 }
674 current_i = parent_i;
675 }
676
677 if (node->height == 0) {
678 p_state->root_nodes.push_back(node_i);
679 }
680 }
681}
682
683static Vector<uint8_t> _parse_base64_uri(const String &p_uri) {
684 int start = p_uri.find(",");
685 ERR_FAIL_COND_V(start == -1, Vector<uint8_t>());
686
687 CharString substr = p_uri.substr(start + 1).ascii();
688
689 int strlen = substr.length();
690
691 Vector<uint8_t> buf;
692 buf.resize(strlen / 4 * 3 + 1 + 1);
693
694 size_t len = 0;
695 ERR_FAIL_COND_V(CryptoCore::b64_decode(buf.ptrw(), buf.size(), &len, (unsigned char *)substr.get_data(), strlen) != OK, Vector<uint8_t>());
696
697 buf.resize(len);
698
699 return buf;
700}
701
702Error GLTFDocument::_encode_buffer_glb(Ref<GLTFState> p_state, const String &p_path) {
703 print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size()));
704
705 if (!p_state->buffers.size()) {
706 return OK;
707 }
708 Array buffers;
709 if (p_state->buffers.size()) {
710 Vector<uint8_t> buffer_data = p_state->buffers[0];
711 Dictionary gltf_buffer;
712
713 gltf_buffer["byteLength"] = buffer_data.size();
714 buffers.push_back(gltf_buffer);
715 }
716
717 for (GLTFBufferIndex i = 1; i < p_state->buffers.size() - 1; i++) {
718 Vector<uint8_t> buffer_data = p_state->buffers[i];
719 Dictionary gltf_buffer;
720 String filename = p_path.get_basename().get_file() + itos(i) + ".bin";
721 String path = p_path.get_base_dir() + "/" + filename;
722 Error err;
723 Ref<FileAccess> file = FileAccess::open(path, FileAccess::WRITE, &err);
724 if (file.is_null()) {
725 return err;
726 }
727 if (buffer_data.size() == 0) {
728 return OK;
729 }
730 file->create(FileAccess::ACCESS_RESOURCES);
731 file->store_buffer(buffer_data.ptr(), buffer_data.size());
732 gltf_buffer["uri"] = filename;
733 gltf_buffer["byteLength"] = buffer_data.size();
734 buffers.push_back(gltf_buffer);
735 }
736 p_state->json["buffers"] = buffers;
737
738 return OK;
739}
740
741Error GLTFDocument::_encode_buffer_bins(Ref<GLTFState> p_state, const String &p_path) {
742 print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size()));
743
744 if (!p_state->buffers.size()) {
745 return OK;
746 }
747 Array buffers;
748
749 for (GLTFBufferIndex i = 0; i < p_state->buffers.size(); i++) {
750 Vector<uint8_t> buffer_data = p_state->buffers[i];
751 Dictionary gltf_buffer;
752 String filename = p_path.get_basename().get_file() + itos(i) + ".bin";
753 String path = p_path.get_base_dir() + "/" + filename;
754 Error err;
755 Ref<FileAccess> file = FileAccess::open(path, FileAccess::WRITE, &err);
756 if (file.is_null()) {
757 return err;
758 }
759 if (buffer_data.size() == 0) {
760 return OK;
761 }
762 file->create(FileAccess::ACCESS_RESOURCES);
763 file->store_buffer(buffer_data.ptr(), buffer_data.size());
764 gltf_buffer["uri"] = filename;
765 gltf_buffer["byteLength"] = buffer_data.size();
766 buffers.push_back(gltf_buffer);
767 }
768 p_state->json["buffers"] = buffers;
769
770 return OK;
771}
772
773Error GLTFDocument::_parse_buffers(Ref<GLTFState> p_state, const String &p_base_path) {
774 if (!p_state->json.has("buffers")) {
775 return OK;
776 }
777
778 const Array &buffers = p_state->json["buffers"];
779 for (GLTFBufferIndex i = 0; i < buffers.size(); i++) {
780 if (i == 0 && p_state->glb_data.size()) {
781 p_state->buffers.push_back(p_state->glb_data);
782
783 } else {
784 const Dictionary &buffer = buffers[i];
785 if (buffer.has("uri")) {
786 Vector<uint8_t> buffer_data;
787 String uri = buffer["uri"];
788
789 if (uri.begins_with("data:")) { // Embedded data using base64.
790 // Validate data MIME types and throw an error if it's one we don't know/support.
791 if (!uri.begins_with("data:application/octet-stream;base64") &&
792 !uri.begins_with("data:application/gltf-buffer;base64")) {
793 ERR_PRINT("glTF: Got buffer with an unknown URI data type: " + uri);
794 }
795 buffer_data = _parse_base64_uri(uri);
796 } else { // Relative path to an external image file.
797 ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER);
798 uri = uri.uri_decode();
799 uri = p_base_path.path_join(uri).replace("\\", "/"); // Fix for Windows.
800 buffer_data = FileAccess::get_file_as_bytes(uri);
801 ERR_FAIL_COND_V_MSG(buffer.size() == 0, ERR_PARSE_ERROR, "glTF: Couldn't load binary file as an array: " + uri);
802 }
803
804 ERR_FAIL_COND_V(!buffer.has("byteLength"), ERR_PARSE_ERROR);
805 int byteLength = buffer["byteLength"];
806 ERR_FAIL_COND_V(byteLength < buffer_data.size(), ERR_PARSE_ERROR);
807 p_state->buffers.push_back(buffer_data);
808 }
809 }
810 }
811
812 print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size()));
813
814 return OK;
815}
816
817Error GLTFDocument::_encode_buffer_views(Ref<GLTFState> p_state) {
818 Array buffers;
819 for (GLTFBufferViewIndex i = 0; i < p_state->buffer_views.size(); i++) {
820 Dictionary d;
821
822 Ref<GLTFBufferView> buffer_view = p_state->buffer_views[i];
823
824 d["buffer"] = buffer_view->buffer;
825 d["byteLength"] = buffer_view->byte_length;
826
827 d["byteOffset"] = buffer_view->byte_offset;
828
829 if (buffer_view->byte_stride != -1) {
830 d["byteStride"] = buffer_view->byte_stride;
831 }
832
833 // TODO Sparse
834 // d["target"] = buffer_view->indices;
835
836 ERR_FAIL_COND_V(!d.has("buffer"), ERR_INVALID_DATA);
837 ERR_FAIL_COND_V(!d.has("byteLength"), ERR_INVALID_DATA);
838 buffers.push_back(d);
839 }
840 print_verbose("glTF: Total buffer views: " + itos(p_state->buffer_views.size()));
841 if (!buffers.size()) {
842 return OK;
843 }
844 p_state->json["bufferViews"] = buffers;
845 return OK;
846}
847
848Error GLTFDocument::_parse_buffer_views(Ref<GLTFState> p_state) {
849 if (!p_state->json.has("bufferViews")) {
850 return OK;
851 }
852 const Array &buffers = p_state->json["bufferViews"];
853 for (GLTFBufferViewIndex i = 0; i < buffers.size(); i++) {
854 const Dictionary &d = buffers[i];
855
856 Ref<GLTFBufferView> buffer_view;
857 buffer_view.instantiate();
858
859 ERR_FAIL_COND_V(!d.has("buffer"), ERR_PARSE_ERROR);
860 buffer_view->buffer = d["buffer"];
861 ERR_FAIL_COND_V(!d.has("byteLength"), ERR_PARSE_ERROR);
862 buffer_view->byte_length = d["byteLength"];
863
864 if (d.has("byteOffset")) {
865 buffer_view->byte_offset = d["byteOffset"];
866 }
867
868 if (d.has("byteStride")) {
869 buffer_view->byte_stride = d["byteStride"];
870 }
871
872 if (d.has("target")) {
873 const int target = d["target"];
874 buffer_view->indices = target == GLTFDocument::ELEMENT_ARRAY_BUFFER;
875 }
876
877 p_state->buffer_views.push_back(buffer_view);
878 }
879
880 print_verbose("glTF: Total buffer views: " + itos(p_state->buffer_views.size()));
881
882 return OK;
883}
884
885Error GLTFDocument::_encode_accessors(Ref<GLTFState> p_state) {
886 Array accessors;
887 for (GLTFAccessorIndex i = 0; i < p_state->accessors.size(); i++) {
888 Dictionary d;
889
890 Ref<GLTFAccessor> accessor = p_state->accessors[i];
891 d["componentType"] = accessor->component_type;
892 d["count"] = accessor->count;
893 d["type"] = _get_accessor_type_name(accessor->type);
894 d["byteOffset"] = accessor->byte_offset;
895 d["normalized"] = accessor->normalized;
896 d["max"] = accessor->max;
897 d["min"] = accessor->min;
898 d["bufferView"] = accessor->buffer_view; //optional because it may be sparse...
899
900 // Dictionary s;
901 // s["count"] = accessor->sparse_count;
902 // ERR_FAIL_COND_V(!s.has("count"), ERR_PARSE_ERROR);
903
904 // s["indices"] = accessor->sparse_accessors;
905 // ERR_FAIL_COND_V(!s.has("indices"), ERR_PARSE_ERROR);
906
907 // Dictionary si;
908
909 // si["bufferView"] = accessor->sparse_indices_buffer_view;
910
911 // ERR_FAIL_COND_V(!si.has("bufferView"), ERR_PARSE_ERROR);
912 // si["componentType"] = accessor->sparse_indices_component_type;
913
914 // if (si.has("byteOffset")) {
915 // si["byteOffset"] = accessor->sparse_indices_byte_offset;
916 // }
917
918 // ERR_FAIL_COND_V(!si.has("componentType"), ERR_PARSE_ERROR);
919 // s["indices"] = si;
920 // Dictionary sv;
921
922 // sv["bufferView"] = accessor->sparse_values_buffer_view;
923 // if (sv.has("byteOffset")) {
924 // sv["byteOffset"] = accessor->sparse_values_byte_offset;
925 // }
926 // ERR_FAIL_COND_V(!sv.has("bufferView"), ERR_PARSE_ERROR);
927 // s["values"] = sv;
928 // ERR_FAIL_COND_V(!s.has("values"), ERR_PARSE_ERROR);
929 // d["sparse"] = s;
930 accessors.push_back(d);
931 }
932
933 if (!accessors.size()) {
934 return OK;
935 }
936 p_state->json["accessors"] = accessors;
937 ERR_FAIL_COND_V(!p_state->json.has("accessors"), ERR_FILE_CORRUPT);
938 print_verbose("glTF: Total accessors: " + itos(p_state->accessors.size()));
939
940 return OK;
941}
942
943String GLTFDocument::_get_accessor_type_name(const GLTFType p_type) {
944 if (p_type == GLTFType::TYPE_SCALAR) {
945 return "SCALAR";
946 }
947 if (p_type == GLTFType::TYPE_VEC2) {
948 return "VEC2";
949 }
950 if (p_type == GLTFType::TYPE_VEC3) {
951 return "VEC3";
952 }
953 if (p_type == GLTFType::TYPE_VEC4) {
954 return "VEC4";
955 }
956
957 if (p_type == GLTFType::TYPE_MAT2) {
958 return "MAT2";
959 }
960 if (p_type == GLTFType::TYPE_MAT3) {
961 return "MAT3";
962 }
963 if (p_type == GLTFType::TYPE_MAT4) {
964 return "MAT4";
965 }
966 ERR_FAIL_V("SCALAR");
967}
968
969GLTFType GLTFDocument::_get_type_from_str(const String &p_string) {
970 if (p_string == "SCALAR") {
971 return GLTFType::TYPE_SCALAR;
972 }
973
974 if (p_string == "VEC2") {
975 return GLTFType::TYPE_VEC2;
976 }
977 if (p_string == "VEC3") {
978 return GLTFType::TYPE_VEC3;
979 }
980 if (p_string == "VEC4") {
981 return GLTFType::TYPE_VEC4;
982 }
983
984 if (p_string == "MAT2") {
985 return GLTFType::TYPE_MAT2;
986 }
987 if (p_string == "MAT3") {
988 return GLTFType::TYPE_MAT3;
989 }
990 if (p_string == "MAT4") {
991 return GLTFType::TYPE_MAT4;
992 }
993
994 ERR_FAIL_V(GLTFType::TYPE_SCALAR);
995}
996
997Error GLTFDocument::_parse_accessors(Ref<GLTFState> p_state) {
998 if (!p_state->json.has("accessors")) {
999 return OK;
1000 }
1001 const Array &accessors = p_state->json["accessors"];
1002 for (GLTFAccessorIndex i = 0; i < accessors.size(); i++) {
1003 const Dictionary &d = accessors[i];
1004
1005 Ref<GLTFAccessor> accessor;
1006 accessor.instantiate();
1007
1008 ERR_FAIL_COND_V(!d.has("componentType"), ERR_PARSE_ERROR);
1009 accessor->component_type = d["componentType"];
1010 ERR_FAIL_COND_V(!d.has("count"), ERR_PARSE_ERROR);
1011 accessor->count = d["count"];
1012 ERR_FAIL_COND_V(!d.has("type"), ERR_PARSE_ERROR);
1013 accessor->type = _get_type_from_str(d["type"]);
1014
1015 if (d.has("bufferView")) {
1016 accessor->buffer_view = d["bufferView"]; //optional because it may be sparse...
1017 }
1018
1019 if (d.has("byteOffset")) {
1020 accessor->byte_offset = d["byteOffset"];
1021 }
1022
1023 if (d.has("normalized")) {
1024 accessor->normalized = d["normalized"];
1025 }
1026
1027 if (d.has("max")) {
1028 accessor->max = d["max"];
1029 }
1030
1031 if (d.has("min")) {
1032 accessor->min = d["min"];
1033 }
1034
1035 if (d.has("sparse")) {
1036 //eeh..
1037
1038 const Dictionary &s = d["sparse"];
1039
1040 ERR_FAIL_COND_V(!s.has("count"), ERR_PARSE_ERROR);
1041 accessor->sparse_count = s["count"];
1042 ERR_FAIL_COND_V(!s.has("indices"), ERR_PARSE_ERROR);
1043 const Dictionary &si = s["indices"];
1044
1045 ERR_FAIL_COND_V(!si.has("bufferView"), ERR_PARSE_ERROR);
1046 accessor->sparse_indices_buffer_view = si["bufferView"];
1047 ERR_FAIL_COND_V(!si.has("componentType"), ERR_PARSE_ERROR);
1048 accessor->sparse_indices_component_type = si["componentType"];
1049
1050 if (si.has("byteOffset")) {
1051 accessor->sparse_indices_byte_offset = si["byteOffset"];
1052 }
1053
1054 ERR_FAIL_COND_V(!s.has("values"), ERR_PARSE_ERROR);
1055 const Dictionary &sv = s["values"];
1056
1057 ERR_FAIL_COND_V(!sv.has("bufferView"), ERR_PARSE_ERROR);
1058 accessor->sparse_values_buffer_view = sv["bufferView"];
1059 if (sv.has("byteOffset")) {
1060 accessor->sparse_values_byte_offset = sv["byteOffset"];
1061 }
1062 }
1063
1064 p_state->accessors.push_back(accessor);
1065 }
1066
1067 print_verbose("glTF: Total accessors: " + itos(p_state->accessors.size()));
1068
1069 return OK;
1070}
1071
1072double GLTFDocument::_filter_number(double p_float) {
1073 if (Math::is_nan(p_float)) {
1074 return 0.0f;
1075 }
1076 return p_float;
1077}
1078
1079String GLTFDocument::_get_component_type_name(const uint32_t p_component) {
1080 switch (p_component) {
1081 case GLTFDocument::COMPONENT_TYPE_BYTE:
1082 return "Byte";
1083 case GLTFDocument::COMPONENT_TYPE_UNSIGNED_BYTE:
1084 return "UByte";
1085 case GLTFDocument::COMPONENT_TYPE_SHORT:
1086 return "Short";
1087 case GLTFDocument::COMPONENT_TYPE_UNSIGNED_SHORT:
1088 return "UShort";
1089 case GLTFDocument::COMPONENT_TYPE_INT:
1090 return "Int";
1091 case GLTFDocument::COMPONENT_TYPE_FLOAT:
1092 return "Float";
1093 }
1094
1095 return "<Error>";
1096}
1097
1098String GLTFDocument::_get_type_name(const GLTFType p_component) {
1099 static const char *names[] = {
1100 "float",
1101 "vec2",
1102 "vec3",
1103 "vec4",
1104 "mat2",
1105 "mat3",
1106 "mat4"
1107 };
1108
1109 return names[p_component];
1110}
1111
1112Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_src, const int p_count, const GLTFType p_type, const int p_component_type, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex, GLTFBufferViewIndex &r_accessor) {
1113 const int component_count_for_type[7] = {
1114 1, 2, 3, 4, 4, 9, 16
1115 };
1116
1117 const int component_count = component_count_for_type[p_type];
1118 const int component_size = _get_component_type_size(p_component_type);
1119 ERR_FAIL_COND_V(component_size == 0, FAILED);
1120
1121 int skip_every = 0;
1122 int skip_bytes = 0;
1123 //special case of alignments, as described in spec
1124 switch (p_component_type) {
1125 case COMPONENT_TYPE_BYTE:
1126 case COMPONENT_TYPE_UNSIGNED_BYTE: {
1127 if (p_type == TYPE_MAT2) {
1128 skip_every = 2;
1129 skip_bytes = 2;
1130 }
1131 if (p_type == TYPE_MAT3) {
1132 skip_every = 3;
1133 skip_bytes = 1;
1134 }
1135 } break;
1136 case COMPONENT_TYPE_SHORT:
1137 case COMPONENT_TYPE_UNSIGNED_SHORT: {
1138 if (p_type == TYPE_MAT3) {
1139 skip_every = 6;
1140 skip_bytes = 4;
1141 }
1142 } break;
1143 default: {
1144 }
1145 }
1146
1147 Ref<GLTFBufferView> bv;
1148 bv.instantiate();
1149 const uint32_t offset = bv->byte_offset = p_byte_offset;
1150 Vector<uint8_t> &gltf_buffer = p_state->buffers.write[0];
1151
1152 int stride = _get_component_type_size(p_component_type);
1153 if (p_for_vertex && stride % 4) {
1154 stride += 4 - (stride % 4); //according to spec must be multiple of 4
1155 }
1156 //use to debug
1157 print_verbose("glTF: encoding type " + _get_type_name(p_type) + " component type: " + _get_component_type_name(p_component_type) + " stride: " + itos(stride) + " amount " + itos(p_count));
1158
1159 print_verbose("glTF: encoding accessor offset " + itos(p_byte_offset) + " view offset: " + itos(bv->byte_offset) + " total buffer len: " + itos(gltf_buffer.size()) + " view len " + itos(bv->byte_length));
1160
1161 const int buffer_end = (stride * (p_count - 1)) + _get_component_type_size(p_component_type);
1162 // TODO define bv->byte_stride
1163 bv->byte_offset = gltf_buffer.size();
1164
1165 switch (p_component_type) {
1166 case COMPONENT_TYPE_BYTE: {
1167 Vector<int8_t> buffer;
1168 buffer.resize(p_count * component_count);
1169 int32_t dst_i = 0;
1170 for (int i = 0; i < p_count; i++) {
1171 for (int j = 0; j < component_count; j++) {
1172 if (skip_every && j > 0 && (j % skip_every) == 0) {
1173 dst_i += skip_bytes;
1174 }
1175 double d = *p_src;
1176 if (p_normalized) {
1177 buffer.write[dst_i] = d * 128.0;
1178 } else {
1179 buffer.write[dst_i] = d;
1180 }
1181 p_src++;
1182 dst_i++;
1183 }
1184 }
1185 int64_t old_size = gltf_buffer.size();
1186 gltf_buffer.resize(old_size + (buffer.size() * sizeof(int8_t)));
1187 memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(int8_t));
1188 bv->byte_length = buffer.size() * sizeof(int8_t);
1189 } break;
1190 case COMPONENT_TYPE_UNSIGNED_BYTE: {
1191 Vector<uint8_t> buffer;
1192 buffer.resize(p_count * component_count);
1193 int32_t dst_i = 0;
1194 for (int i = 0; i < p_count; i++) {
1195 for (int j = 0; j < component_count; j++) {
1196 if (skip_every && j > 0 && (j % skip_every) == 0) {
1197 dst_i += skip_bytes;
1198 }
1199 double d = *p_src;
1200 if (p_normalized) {
1201 buffer.write[dst_i] = d * 255.0;
1202 } else {
1203 buffer.write[dst_i] = d;
1204 }
1205 p_src++;
1206 dst_i++;
1207 }
1208 }
1209 gltf_buffer.append_array(buffer);
1210 bv->byte_length = buffer.size() * sizeof(uint8_t);
1211 } break;
1212 case COMPONENT_TYPE_SHORT: {
1213 Vector<int16_t> buffer;
1214 buffer.resize(p_count * component_count);
1215 int32_t dst_i = 0;
1216 for (int i = 0; i < p_count; i++) {
1217 for (int j = 0; j < component_count; j++) {
1218 if (skip_every && j > 0 && (j % skip_every) == 0) {
1219 dst_i += skip_bytes;
1220 }
1221 double d = *p_src;
1222 if (p_normalized) {
1223 buffer.write[dst_i] = d * 32768.0;
1224 } else {
1225 buffer.write[dst_i] = d;
1226 }
1227 p_src++;
1228 dst_i++;
1229 }
1230 }
1231 int64_t old_size = gltf_buffer.size();
1232 gltf_buffer.resize(old_size + (buffer.size() * sizeof(int16_t)));
1233 memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(int16_t));
1234 bv->byte_length = buffer.size() * sizeof(int16_t);
1235 } break;
1236 case COMPONENT_TYPE_UNSIGNED_SHORT: {
1237 Vector<uint16_t> buffer;
1238 buffer.resize(p_count * component_count);
1239 int32_t dst_i = 0;
1240 for (int i = 0; i < p_count; i++) {
1241 for (int j = 0; j < component_count; j++) {
1242 if (skip_every && j > 0 && (j % skip_every) == 0) {
1243 dst_i += skip_bytes;
1244 }
1245 double d = *p_src;
1246 if (p_normalized) {
1247 buffer.write[dst_i] = d * 65535.0;
1248 } else {
1249 buffer.write[dst_i] = d;
1250 }
1251 p_src++;
1252 dst_i++;
1253 }
1254 }
1255 int64_t old_size = gltf_buffer.size();
1256 gltf_buffer.resize(old_size + (buffer.size() * sizeof(uint16_t)));
1257 memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(uint16_t));
1258 bv->byte_length = buffer.size() * sizeof(uint16_t);
1259 } break;
1260 case COMPONENT_TYPE_INT: {
1261 Vector<int> buffer;
1262 buffer.resize(p_count * component_count);
1263 int32_t dst_i = 0;
1264 for (int i = 0; i < p_count; i++) {
1265 for (int j = 0; j < component_count; j++) {
1266 if (skip_every && j > 0 && (j % skip_every) == 0) {
1267 dst_i += skip_bytes;
1268 }
1269 double d = *p_src;
1270 buffer.write[dst_i] = d;
1271 p_src++;
1272 dst_i++;
1273 }
1274 }
1275 int64_t old_size = gltf_buffer.size();
1276 gltf_buffer.resize(old_size + (buffer.size() * sizeof(int32_t)));
1277 memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(int32_t));
1278 bv->byte_length = buffer.size() * sizeof(int32_t);
1279 } break;
1280 case COMPONENT_TYPE_FLOAT: {
1281 Vector<float> buffer;
1282 buffer.resize(p_count * component_count);
1283 int32_t dst_i = 0;
1284 for (int i = 0; i < p_count; i++) {
1285 for (int j = 0; j < component_count; j++) {
1286 if (skip_every && j > 0 && (j % skip_every) == 0) {
1287 dst_i += skip_bytes;
1288 }
1289 double d = *p_src;
1290 buffer.write[dst_i] = d;
1291 p_src++;
1292 dst_i++;
1293 }
1294 }
1295 int64_t old_size = gltf_buffer.size();
1296 gltf_buffer.resize(old_size + (buffer.size() * sizeof(float)));
1297 memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(float));
1298 bv->byte_length = buffer.size() * sizeof(float);
1299 } break;
1300 }
1301 ERR_FAIL_COND_V(buffer_end > bv->byte_length, ERR_INVALID_DATA);
1302
1303 ERR_FAIL_COND_V((int)(offset + buffer_end) > gltf_buffer.size(), ERR_INVALID_DATA);
1304 r_accessor = bv->buffer = p_state->buffer_views.size();
1305 p_state->buffer_views.push_back(bv);
1306 return OK;
1307}
1308
1309Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, const GLTFBufferViewIndex p_buffer_view, const int p_skip_every, const int p_skip_bytes, const int p_element_size, const int p_count, const GLTFType p_type, const int p_component_count, const int p_component_type, const int p_component_size, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex) {
1310 const Ref<GLTFBufferView> bv = p_state->buffer_views[p_buffer_view];
1311
1312 int stride = p_element_size;
1313 if (bv->byte_stride != -1) {
1314 stride = bv->byte_stride;
1315 }
1316 if (p_for_vertex && stride % 4) {
1317 stride += 4 - (stride % 4); //according to spec must be multiple of 4
1318 }
1319
1320 ERR_FAIL_INDEX_V(bv->buffer, p_state->buffers.size(), ERR_PARSE_ERROR);
1321
1322 const uint32_t offset = bv->byte_offset + p_byte_offset;
1323 Vector<uint8_t> buffer = p_state->buffers[bv->buffer]; //copy on write, so no performance hit
1324 const uint8_t *bufptr = buffer.ptr();
1325
1326 //use to debug
1327 print_verbose("glTF: type " + _get_type_name(p_type) + " component type: " + _get_component_type_name(p_component_type) + " stride: " + itos(stride) + " amount " + itos(p_count));
1328 print_verbose("glTF: accessor offset " + itos(p_byte_offset) + " view offset: " + itos(bv->byte_offset) + " total buffer len: " + itos(buffer.size()) + " view len " + itos(bv->byte_length));
1329
1330 const int buffer_end = (stride * (p_count - 1)) + p_element_size;
1331 ERR_FAIL_COND_V(buffer_end > bv->byte_length, ERR_PARSE_ERROR);
1332
1333 ERR_FAIL_COND_V((int)(offset + buffer_end) > buffer.size(), ERR_PARSE_ERROR);
1334
1335 //fill everything as doubles
1336
1337 for (int i = 0; i < p_count; i++) {
1338 const uint8_t *src = &bufptr[offset + i * stride];
1339
1340 for (int j = 0; j < p_component_count; j++) {
1341 if (p_skip_every && j > 0 && (j % p_skip_every) == 0) {
1342 src += p_skip_bytes;
1343 }
1344
1345 double d = 0;
1346
1347 switch (p_component_type) {
1348 case COMPONENT_TYPE_BYTE: {
1349 int8_t b = int8_t(*src);
1350 if (p_normalized) {
1351 d = (double(b) / 128.0);
1352 } else {
1353 d = double(b);
1354 }
1355 } break;
1356 case COMPONENT_TYPE_UNSIGNED_BYTE: {
1357 uint8_t b = *src;
1358 if (p_normalized) {
1359 d = (double(b) / 255.0);
1360 } else {
1361 d = double(b);
1362 }
1363 } break;
1364 case COMPONENT_TYPE_SHORT: {
1365 int16_t s = *(int16_t *)src;
1366 if (p_normalized) {
1367 d = (double(s) / 32768.0);
1368 } else {
1369 d = double(s);
1370 }
1371 } break;
1372 case COMPONENT_TYPE_UNSIGNED_SHORT: {
1373 uint16_t s = *(uint16_t *)src;
1374 if (p_normalized) {
1375 d = (double(s) / 65535.0);
1376 } else {
1377 d = double(s);
1378 }
1379 } break;
1380 case COMPONENT_TYPE_INT: {
1381 d = *(int *)src;
1382 } break;
1383 case COMPONENT_TYPE_FLOAT: {
1384 d = *(float *)src;
1385 } break;
1386 }
1387
1388 *p_dst++ = d;
1389 src += p_component_size;
1390 }
1391 }
1392
1393 return OK;
1394}
1395
1396int GLTFDocument::_get_component_type_size(const int p_component_type) {
1397 switch (p_component_type) {
1398 case COMPONENT_TYPE_BYTE:
1399 case COMPONENT_TYPE_UNSIGNED_BYTE:
1400 return 1;
1401 break;
1402 case COMPONENT_TYPE_SHORT:
1403 case COMPONENT_TYPE_UNSIGNED_SHORT:
1404 return 2;
1405 break;
1406 case COMPONENT_TYPE_INT:
1407 case COMPONENT_TYPE_FLOAT:
1408 return 4;
1409 break;
1410 default: {
1411 ERR_FAIL_V(0);
1412 }
1413 }
1414 return 0;
1415}
1416
1417Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
1418 //spec, for reference:
1419 //https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
1420
1421 ERR_FAIL_INDEX_V(p_accessor, p_state->accessors.size(), Vector<double>());
1422
1423 const Ref<GLTFAccessor> a = p_state->accessors[p_accessor];
1424
1425 const int component_count_for_type[7] = {
1426 1, 2, 3, 4, 4, 9, 16
1427 };
1428
1429 const int component_count = component_count_for_type[a->type];
1430 const int component_size = _get_component_type_size(a->component_type);
1431 ERR_FAIL_COND_V(component_size == 0, Vector<double>());
1432 int element_size = component_count * component_size;
1433
1434 int skip_every = 0;
1435 int skip_bytes = 0;
1436 //special case of alignments, as described in spec
1437 switch (a->component_type) {
1438 case COMPONENT_TYPE_BYTE:
1439 case COMPONENT_TYPE_UNSIGNED_BYTE: {
1440 if (a->type == TYPE_MAT2) {
1441 skip_every = 2;
1442 skip_bytes = 2;
1443 element_size = 8; //override for this case
1444 }
1445 if (a->type == TYPE_MAT3) {
1446 skip_every = 3;
1447 skip_bytes = 1;
1448 element_size = 12; //override for this case
1449 }
1450 } break;
1451 case COMPONENT_TYPE_SHORT:
1452 case COMPONENT_TYPE_UNSIGNED_SHORT: {
1453 if (a->type == TYPE_MAT3) {
1454 skip_every = 6;
1455 skip_bytes = 4;
1456 element_size = 16; //override for this case
1457 }
1458 } break;
1459 default: {
1460 }
1461 }
1462
1463 Vector<double> dst_buffer;
1464 dst_buffer.resize(component_count * a->count);
1465 double *dst = dst_buffer.ptrw();
1466
1467 if (a->buffer_view >= 0) {
1468 ERR_FAIL_INDEX_V(a->buffer_view, p_state->buffer_views.size(), Vector<double>());
1469
1470 const Error err = _decode_buffer_view(p_state, dst, a->buffer_view, skip_every, skip_bytes, element_size, a->count, a->type, component_count, a->component_type, component_size, a->normalized, a->byte_offset, p_for_vertex);
1471 if (err != OK) {
1472 return Vector<double>();
1473 }
1474 } else {
1475 //fill with zeros, as bufferview is not defined.
1476 for (int i = 0; i < (a->count * component_count); i++) {
1477 dst_buffer.write[i] = 0;
1478 }
1479 }
1480
1481 if (a->sparse_count > 0) {
1482 // I could not find any file using this, so this code is so far untested
1483 Vector<double> indices;
1484 indices.resize(a->sparse_count);
1485 const int indices_component_size = _get_component_type_size(a->sparse_indices_component_type);
1486
1487 Error err = _decode_buffer_view(p_state, indices.ptrw(), a->sparse_indices_buffer_view, 0, 0, indices_component_size, a->sparse_count, TYPE_SCALAR, 1, a->sparse_indices_component_type, indices_component_size, false, a->sparse_indices_byte_offset, false);
1488 if (err != OK) {
1489 return Vector<double>();
1490 }
1491
1492 Vector<double> data;
1493 data.resize(component_count * a->sparse_count);
1494 err = _decode_buffer_view(p_state, data.ptrw(), a->sparse_values_buffer_view, skip_every, skip_bytes, element_size, a->sparse_count, a->type, component_count, a->component_type, component_size, a->normalized, a->sparse_values_byte_offset, p_for_vertex);
1495 if (err != OK) {
1496 return Vector<double>();
1497 }
1498
1499 for (int i = 0; i < indices.size(); i++) {
1500 const int write_offset = int(indices[i]) * component_count;
1501
1502 for (int j = 0; j < component_count; j++) {
1503 dst[write_offset + j] = data[i * component_count + j];
1504 }
1505 }
1506 }
1507
1508 return dst_buffer;
1509}
1510
1511GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref<GLTFState> p_state, const Vector<int32_t> p_attribs, const bool p_for_vertex) {
1512 if (p_attribs.size() == 0) {
1513 return -1;
1514 }
1515 const int element_count = 1;
1516 const int ret_size = p_attribs.size();
1517 Vector<double> attribs;
1518 attribs.resize(ret_size);
1519 Vector<double> type_max;
1520 type_max.resize(element_count);
1521 Vector<double> type_min;
1522 type_min.resize(element_count);
1523 for (int i = 0; i < p_attribs.size(); i++) {
1524 attribs.write[i] = Math::snapped(p_attribs[i], 1.0);
1525 if (i == 0) {
1526 for (int32_t type_i = 0; type_i < element_count; type_i++) {
1527 type_max.write[type_i] = attribs[(i * element_count) + type_i];
1528 type_min.write[type_i] = attribs[(i * element_count) + type_i];
1529 }
1530 }
1531 for (int32_t type_i = 0; type_i < element_count; type_i++) {
1532 type_max.write[type_i] = MAX(attribs[(i * element_count) + type_i], type_max[type_i]);
1533 type_min.write[type_i] = MIN(attribs[(i * element_count) + type_i], type_min[type_i]);
1534 type_max.write[type_i] = _filter_number(type_max.write[type_i]);
1535 type_min.write[type_i] = _filter_number(type_min.write[type_i]);
1536 }
1537 }
1538
1539 ERR_FAIL_COND_V(attribs.size() == 0, -1);
1540
1541 Ref<GLTFAccessor> accessor;
1542 accessor.instantiate();
1543 GLTFBufferIndex buffer_view_i;
1544 int64_t size = p_state->buffers[0].size();
1545 const GLTFType type = GLTFType::TYPE_SCALAR;
1546 const int component_type = GLTFDocument::COMPONENT_TYPE_INT;
1547
1548 accessor->max = type_max;
1549 accessor->min = type_min;
1550 accessor->normalized = false;
1551 accessor->count = ret_size;
1552 accessor->type = type;
1553 accessor->component_type = component_type;
1554 accessor->byte_offset = 0;
1555 Error err = _encode_buffer_view(p_state, attribs.ptr(), attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
1556 if (err != OK) {
1557 return -1;
1558 }
1559 accessor->buffer_view = buffer_view_i;
1560 p_state->accessors.push_back(accessor);
1561 return p_state->accessors.size() - 1;
1562}
1563
1564Vector<int> GLTFDocument::_decode_accessor_as_ints(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
1565 const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
1566 Vector<int> ret;
1567
1568 if (attribs.size() == 0) {
1569 return ret;
1570 }
1571
1572 const double *attribs_ptr = attribs.ptr();
1573 const int ret_size = attribs.size();
1574 ret.resize(ret_size);
1575 {
1576 for (int i = 0; i < ret_size; i++) {
1577 ret.write[i] = int(attribs_ptr[i]);
1578 }
1579 }
1580 return ret;
1581}
1582
1583Vector<float> GLTFDocument::_decode_accessor_as_floats(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
1584 const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
1585 Vector<float> ret;
1586
1587 if (attribs.size() == 0) {
1588 return ret;
1589 }
1590
1591 const double *attribs_ptr = attribs.ptr();
1592 const int ret_size = attribs.size();
1593 ret.resize(ret_size);
1594 {
1595 for (int i = 0; i < ret_size; i++) {
1596 ret.write[i] = float(attribs_ptr[i]);
1597 }
1598 }
1599 return ret;
1600}
1601
1602GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref<GLTFState> p_state, const Vector<Vector2> p_attribs, const bool p_for_vertex) {
1603 if (p_attribs.size() == 0) {
1604 return -1;
1605 }
1606 const int element_count = 2;
1607
1608 const int ret_size = p_attribs.size() * element_count;
1609 Vector<double> attribs;
1610 attribs.resize(ret_size);
1611 Vector<double> type_max;
1612 type_max.resize(element_count);
1613 Vector<double> type_min;
1614 type_min.resize(element_count);
1615
1616 for (int i = 0; i < p_attribs.size(); i++) {
1617 Vector2 attrib = p_attribs[i];
1618 attribs.write[(i * element_count) + 0] = Math::snapped(attrib.x, CMP_NORMALIZE_TOLERANCE);
1619 attribs.write[(i * element_count) + 1] = Math::snapped(attrib.y, CMP_NORMALIZE_TOLERANCE);
1620 _calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
1621 }
1622
1623 ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
1624
1625 Ref<GLTFAccessor> accessor;
1626 accessor.instantiate();
1627 GLTFBufferIndex buffer_view_i;
1628 int64_t size = p_state->buffers[0].size();
1629 const GLTFType type = GLTFType::TYPE_VEC2;
1630 const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
1631
1632 accessor->max = type_max;
1633 accessor->min = type_min;
1634 accessor->normalized = false;
1635 accessor->count = p_attribs.size();
1636 accessor->type = type;
1637 accessor->component_type = component_type;
1638 accessor->byte_offset = 0;
1639 Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
1640 if (err != OK) {
1641 return -1;
1642 }
1643 accessor->buffer_view = buffer_view_i;
1644 p_state->accessors.push_back(accessor);
1645 return p_state->accessors.size() - 1;
1646}
1647
1648GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref<GLTFState> p_state, const Vector<Color> p_attribs, const bool p_for_vertex) {
1649 if (p_attribs.size() == 0) {
1650 return -1;
1651 }
1652
1653 const int ret_size = p_attribs.size() * 4;
1654 Vector<double> attribs;
1655 attribs.resize(ret_size);
1656
1657 const int element_count = 4;
1658 Vector<double> type_max;
1659 type_max.resize(element_count);
1660 Vector<double> type_min;
1661 type_min.resize(element_count);
1662 for (int i = 0; i < p_attribs.size(); i++) {
1663 Color attrib = p_attribs[i];
1664 attribs.write[(i * element_count) + 0] = Math::snapped(attrib.r, CMP_NORMALIZE_TOLERANCE);
1665 attribs.write[(i * element_count) + 1] = Math::snapped(attrib.g, CMP_NORMALIZE_TOLERANCE);
1666 attribs.write[(i * element_count) + 2] = Math::snapped(attrib.b, CMP_NORMALIZE_TOLERANCE);
1667 attribs.write[(i * element_count) + 3] = Math::snapped(attrib.a, CMP_NORMALIZE_TOLERANCE);
1668
1669 _calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
1670 }
1671
1672 ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
1673
1674 Ref<GLTFAccessor> accessor;
1675 accessor.instantiate();
1676 GLTFBufferIndex buffer_view_i;
1677 int64_t size = p_state->buffers[0].size();
1678 const GLTFType type = GLTFType::TYPE_VEC4;
1679 const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
1680
1681 accessor->max = type_max;
1682 accessor->min = type_min;
1683 accessor->normalized = false;
1684 accessor->count = p_attribs.size();
1685 accessor->type = type;
1686 accessor->component_type = component_type;
1687 accessor->byte_offset = 0;
1688 Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
1689 if (err != OK) {
1690 return -1;
1691 }
1692 accessor->buffer_view = buffer_view_i;
1693 p_state->accessors.push_back(accessor);
1694 return p_state->accessors.size() - 1;
1695}
1696
1697void GLTFDocument::_calc_accessor_min_max(int p_i, const int p_element_count, Vector<double> &p_type_max, Vector<double> p_attribs, Vector<double> &p_type_min) {
1698 if (p_i == 0) {
1699 for (int32_t type_i = 0; type_i < p_element_count; type_i++) {
1700 p_type_max.write[type_i] = p_attribs[(p_i * p_element_count) + type_i];
1701 p_type_min.write[type_i] = p_attribs[(p_i * p_element_count) + type_i];
1702 }
1703 }
1704 for (int32_t type_i = 0; type_i < p_element_count; type_i++) {
1705 p_type_max.write[type_i] = MAX(p_attribs[(p_i * p_element_count) + type_i], p_type_max[type_i]);
1706 p_type_min.write[type_i] = MIN(p_attribs[(p_i * p_element_count) + type_i], p_type_min[type_i]);
1707 p_type_max.write[type_i] = _filter_number(p_type_max.write[type_i]);
1708 p_type_min.write[type_i] = _filter_number(p_type_min.write[type_i]);
1709 }
1710}
1711
1712GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref<GLTFState> p_state, const Vector<Color> p_attribs, const bool p_for_vertex) {
1713 if (p_attribs.size() == 0) {
1714 return -1;
1715 }
1716
1717 const int ret_size = p_attribs.size() * 4;
1718 Vector<double> attribs;
1719 attribs.resize(ret_size);
1720
1721 const int element_count = 4;
1722
1723 Vector<double> type_max;
1724 type_max.resize(element_count);
1725 Vector<double> type_min;
1726 type_min.resize(element_count);
1727 for (int i = 0; i < p_attribs.size(); i++) {
1728 Color attrib = p_attribs[i];
1729 attribs.write[(i * element_count) + 0] = Math::snapped(attrib.r, CMP_NORMALIZE_TOLERANCE);
1730 attribs.write[(i * element_count) + 1] = Math::snapped(attrib.g, CMP_NORMALIZE_TOLERANCE);
1731 attribs.write[(i * element_count) + 2] = Math::snapped(attrib.b, CMP_NORMALIZE_TOLERANCE);
1732 attribs.write[(i * element_count) + 3] = Math::snapped(attrib.a, CMP_NORMALIZE_TOLERANCE);
1733
1734 _calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
1735 }
1736
1737 ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
1738
1739 Ref<GLTFAccessor> accessor;
1740 accessor.instantiate();
1741 GLTFBufferIndex buffer_view_i;
1742 int64_t size = p_state->buffers[0].size();
1743 const GLTFType type = GLTFType::TYPE_VEC4;
1744 const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
1745
1746 accessor->max = type_max;
1747 accessor->min = type_min;
1748 accessor->normalized = false;
1749 accessor->count = p_attribs.size();
1750 accessor->type = type;
1751 accessor->component_type = component_type;
1752 accessor->byte_offset = 0;
1753 Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
1754 if (err != OK) {
1755 return -1;
1756 }
1757 accessor->buffer_view = buffer_view_i;
1758 p_state->accessors.push_back(accessor);
1759 return p_state->accessors.size() - 1;
1760}
1761
1762GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref<GLTFState> p_state, const Vector<Color> p_attribs, const bool p_for_vertex) {
1763 if (p_attribs.size() == 0) {
1764 return -1;
1765 }
1766
1767 const int element_count = 4;
1768 const int ret_size = p_attribs.size() * element_count;
1769 Vector<double> attribs;
1770 attribs.resize(ret_size);
1771
1772 Vector<double> type_max;
1773 type_max.resize(element_count);
1774 Vector<double> type_min;
1775 type_min.resize(element_count);
1776 for (int i = 0; i < p_attribs.size(); i++) {
1777 Color attrib = p_attribs[i];
1778 attribs.write[(i * element_count) + 0] = Math::snapped(attrib.r, CMP_NORMALIZE_TOLERANCE);
1779 attribs.write[(i * element_count) + 1] = Math::snapped(attrib.g, CMP_NORMALIZE_TOLERANCE);
1780 attribs.write[(i * element_count) + 2] = Math::snapped(attrib.b, CMP_NORMALIZE_TOLERANCE);
1781 attribs.write[(i * element_count) + 3] = Math::snapped(attrib.a, CMP_NORMALIZE_TOLERANCE);
1782 _calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
1783 }
1784 ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
1785
1786 Ref<GLTFAccessor> accessor;
1787 accessor.instantiate();
1788 GLTFBufferIndex buffer_view_i;
1789 int64_t size = p_state->buffers[0].size();
1790 const GLTFType type = GLTFType::TYPE_VEC4;
1791 const int component_type = GLTFDocument::COMPONENT_TYPE_UNSIGNED_SHORT;
1792
1793 accessor->max = type_max;
1794 accessor->min = type_min;
1795 accessor->normalized = false;
1796 accessor->count = p_attribs.size();
1797 accessor->type = type;
1798 accessor->component_type = component_type;
1799 accessor->byte_offset = 0;
1800 Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
1801 if (err != OK) {
1802 return -1;
1803 }
1804 accessor->buffer_view = buffer_view_i;
1805 p_state->accessors.push_back(accessor);
1806 return p_state->accessors.size() - 1;
1807}
1808
1809GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref<GLTFState> p_state, const Vector<Quaternion> p_attribs, const bool p_for_vertex) {
1810 if (p_attribs.size() == 0) {
1811 return -1;
1812 }
1813 const int element_count = 4;
1814
1815 const int ret_size = p_attribs.size() * element_count;
1816 Vector<double> attribs;
1817 attribs.resize(ret_size);
1818
1819 Vector<double> type_max;
1820 type_max.resize(element_count);
1821 Vector<double> type_min;
1822 type_min.resize(element_count);
1823 for (int i = 0; i < p_attribs.size(); i++) {
1824 Quaternion quaternion = p_attribs[i];
1825 attribs.write[(i * element_count) + 0] = Math::snapped(quaternion.x, CMP_NORMALIZE_TOLERANCE);
1826 attribs.write[(i * element_count) + 1] = Math::snapped(quaternion.y, CMP_NORMALIZE_TOLERANCE);
1827 attribs.write[(i * element_count) + 2] = Math::snapped(quaternion.z, CMP_NORMALIZE_TOLERANCE);
1828 attribs.write[(i * element_count) + 3] = Math::snapped(quaternion.w, CMP_NORMALIZE_TOLERANCE);
1829
1830 _calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
1831 }
1832
1833 ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
1834
1835 Ref<GLTFAccessor> accessor;
1836 accessor.instantiate();
1837 GLTFBufferIndex buffer_view_i;
1838 int64_t size = p_state->buffers[0].size();
1839 const GLTFType type = GLTFType::TYPE_VEC4;
1840 const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
1841
1842 accessor->max = type_max;
1843 accessor->min = type_min;
1844 accessor->normalized = false;
1845 accessor->count = p_attribs.size();
1846 accessor->type = type;
1847 accessor->component_type = component_type;
1848 accessor->byte_offset = 0;
1849 Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
1850 if (err != OK) {
1851 return -1;
1852 }
1853 accessor->buffer_view = buffer_view_i;
1854 p_state->accessors.push_back(accessor);
1855 return p_state->accessors.size() - 1;
1856}
1857
1858Vector<Vector2> GLTFDocument::_decode_accessor_as_vec2(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
1859 const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
1860 Vector<Vector2> ret;
1861
1862 if (attribs.size() == 0) {
1863 return ret;
1864 }
1865
1866 ERR_FAIL_COND_V(attribs.size() % 2 != 0, ret);
1867 const double *attribs_ptr = attribs.ptr();
1868 const int ret_size = attribs.size() / 2;
1869 ret.resize(ret_size);
1870 {
1871 for (int i = 0; i < ret_size; i++) {
1872 ret.write[i] = Vector2(attribs_ptr[i * 2 + 0], attribs_ptr[i * 2 + 1]);
1873 }
1874 }
1875 return ret;
1876}
1877
1878GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref<GLTFState> p_state, const Vector<real_t> p_attribs, const bool p_for_vertex) {
1879 if (p_attribs.size() == 0) {
1880 return -1;
1881 }
1882 const int element_count = 1;
1883 const int ret_size = p_attribs.size();
1884 Vector<double> attribs;
1885 attribs.resize(ret_size);
1886
1887 Vector<double> type_max;
1888 type_max.resize(element_count);
1889 Vector<double> type_min;
1890 type_min.resize(element_count);
1891
1892 for (int i = 0; i < p_attribs.size(); i++) {
1893 attribs.write[i] = Math::snapped(p_attribs[i], CMP_NORMALIZE_TOLERANCE);
1894
1895 _calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
1896 }
1897
1898 ERR_FAIL_COND_V(!attribs.size(), -1);
1899
1900 Ref<GLTFAccessor> accessor;
1901 accessor.instantiate();
1902 GLTFBufferIndex buffer_view_i;
1903 int64_t size = p_state->buffers[0].size();
1904 const GLTFType type = GLTFType::TYPE_SCALAR;
1905 const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
1906
1907 accessor->max = type_max;
1908 accessor->min = type_min;
1909 accessor->normalized = false;
1910 accessor->count = ret_size;
1911 accessor->type = type;
1912 accessor->component_type = component_type;
1913 accessor->byte_offset = 0;
1914 Error err = _encode_buffer_view(p_state, attribs.ptr(), attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
1915 if (err != OK) {
1916 return -1;
1917 }
1918 accessor->buffer_view = buffer_view_i;
1919 p_state->accessors.push_back(accessor);
1920 return p_state->accessors.size() - 1;
1921}
1922
1923GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref<GLTFState> p_state, const Vector<Vector3> p_attribs, const bool p_for_vertex) {
1924 if (p_attribs.size() == 0) {
1925 return -1;
1926 }
1927 const int element_count = 3;
1928 const int ret_size = p_attribs.size() * element_count;
1929 Vector<double> attribs;
1930 attribs.resize(ret_size);
1931
1932 Vector<double> type_max;
1933 type_max.resize(element_count);
1934 Vector<double> type_min;
1935 type_min.resize(element_count);
1936 for (int i = 0; i < p_attribs.size(); i++) {
1937 Vector3 attrib = p_attribs[i];
1938 attribs.write[(i * element_count) + 0] = Math::snapped(attrib.x, CMP_NORMALIZE_TOLERANCE);
1939 attribs.write[(i * element_count) + 1] = Math::snapped(attrib.y, CMP_NORMALIZE_TOLERANCE);
1940 attribs.write[(i * element_count) + 2] = Math::snapped(attrib.z, CMP_NORMALIZE_TOLERANCE);
1941
1942 _calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
1943 }
1944 ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
1945
1946 Ref<GLTFAccessor> accessor;
1947 accessor.instantiate();
1948 GLTFBufferIndex buffer_view_i;
1949 int64_t size = p_state->buffers[0].size();
1950 const GLTFType type = GLTFType::TYPE_VEC3;
1951 const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
1952
1953 accessor->max = type_max;
1954 accessor->min = type_min;
1955 accessor->normalized = false;
1956 accessor->count = p_attribs.size();
1957 accessor->type = type;
1958 accessor->component_type = component_type;
1959 accessor->byte_offset = 0;
1960 Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
1961 if (err != OK) {
1962 return -1;
1963 }
1964 accessor->buffer_view = buffer_view_i;
1965 p_state->accessors.push_back(accessor);
1966 return p_state->accessors.size() - 1;
1967}
1968
1969GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref<GLTFState> p_state, const Vector<Transform3D> p_attribs, const bool p_for_vertex) {
1970 if (p_attribs.size() == 0) {
1971 return -1;
1972 }
1973 const int element_count = 16;
1974 const int ret_size = p_attribs.size() * element_count;
1975 Vector<double> attribs;
1976 attribs.resize(ret_size);
1977
1978 Vector<double> type_max;
1979 type_max.resize(element_count);
1980 Vector<double> type_min;
1981 type_min.resize(element_count);
1982 for (int i = 0; i < p_attribs.size(); i++) {
1983 Transform3D attrib = p_attribs[i];
1984 Basis basis = attrib.get_basis();
1985 Vector3 axis_0 = basis.get_column(Vector3::AXIS_X);
1986
1987 attribs.write[i * element_count + 0] = Math::snapped(axis_0.x, CMP_NORMALIZE_TOLERANCE);
1988 attribs.write[i * element_count + 1] = Math::snapped(axis_0.y, CMP_NORMALIZE_TOLERANCE);
1989 attribs.write[i * element_count + 2] = Math::snapped(axis_0.z, CMP_NORMALIZE_TOLERANCE);
1990 attribs.write[i * element_count + 3] = 0.0;
1991
1992 Vector3 axis_1 = basis.get_column(Vector3::AXIS_Y);
1993 attribs.write[i * element_count + 4] = Math::snapped(axis_1.x, CMP_NORMALIZE_TOLERANCE);
1994 attribs.write[i * element_count + 5] = Math::snapped(axis_1.y, CMP_NORMALIZE_TOLERANCE);
1995 attribs.write[i * element_count + 6] = Math::snapped(axis_1.z, CMP_NORMALIZE_TOLERANCE);
1996 attribs.write[i * element_count + 7] = 0.0;
1997
1998 Vector3 axis_2 = basis.get_column(Vector3::AXIS_Z);
1999 attribs.write[i * element_count + 8] = Math::snapped(axis_2.x, CMP_NORMALIZE_TOLERANCE);
2000 attribs.write[i * element_count + 9] = Math::snapped(axis_2.y, CMP_NORMALIZE_TOLERANCE);
2001 attribs.write[i * element_count + 10] = Math::snapped(axis_2.z, CMP_NORMALIZE_TOLERANCE);
2002 attribs.write[i * element_count + 11] = 0.0;
2003
2004 Vector3 origin = attrib.get_origin();
2005 attribs.write[i * element_count + 12] = Math::snapped(origin.x, CMP_NORMALIZE_TOLERANCE);
2006 attribs.write[i * element_count + 13] = Math::snapped(origin.y, CMP_NORMALIZE_TOLERANCE);
2007 attribs.write[i * element_count + 14] = Math::snapped(origin.z, CMP_NORMALIZE_TOLERANCE);
2008 attribs.write[i * element_count + 15] = 1.0;
2009
2010 _calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
2011 }
2012 ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
2013
2014 Ref<GLTFAccessor> accessor;
2015 accessor.instantiate();
2016 GLTFBufferIndex buffer_view_i;
2017 int64_t size = p_state->buffers[0].size();
2018 const GLTFType type = GLTFType::TYPE_MAT4;
2019 const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
2020
2021 accessor->max = type_max;
2022 accessor->min = type_min;
2023 accessor->normalized = false;
2024 accessor->count = p_attribs.size();
2025 accessor->type = type;
2026 accessor->component_type = component_type;
2027 accessor->byte_offset = 0;
2028 Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
2029 if (err != OK) {
2030 return -1;
2031 }
2032 accessor->buffer_view = buffer_view_i;
2033 p_state->accessors.push_back(accessor);
2034 return p_state->accessors.size() - 1;
2035}
2036
2037Vector<Vector3> GLTFDocument::_decode_accessor_as_vec3(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
2038 const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
2039 Vector<Vector3> ret;
2040
2041 if (attribs.size() == 0) {
2042 return ret;
2043 }
2044
2045 ERR_FAIL_COND_V(attribs.size() % 3 != 0, ret);
2046 const double *attribs_ptr = attribs.ptr();
2047 const int ret_size = attribs.size() / 3;
2048 ret.resize(ret_size);
2049 {
2050 for (int i = 0; i < ret_size; i++) {
2051 ret.write[i] = Vector3(attribs_ptr[i * 3 + 0], attribs_ptr[i * 3 + 1], attribs_ptr[i * 3 + 2]);
2052 }
2053 }
2054 return ret;
2055}
2056
2057Vector<Color> GLTFDocument::_decode_accessor_as_color(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
2058 const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
2059 Vector<Color> ret;
2060
2061 if (attribs.size() == 0) {
2062 return ret;
2063 }
2064
2065 const int type = p_state->accessors[p_accessor]->type;
2066 ERR_FAIL_COND_V(!(type == TYPE_VEC3 || type == TYPE_VEC4), ret);
2067 int vec_len = 3;
2068 if (type == TYPE_VEC4) {
2069 vec_len = 4;
2070 }
2071
2072 ERR_FAIL_COND_V(attribs.size() % vec_len != 0, ret);
2073 const double *attribs_ptr = attribs.ptr();
2074 const int ret_size = attribs.size() / vec_len;
2075 ret.resize(ret_size);
2076 {
2077 for (int i = 0; i < ret_size; i++) {
2078 ret.write[i] = Color(attribs_ptr[i * vec_len + 0], attribs_ptr[i * vec_len + 1], attribs_ptr[i * vec_len + 2], vec_len == 4 ? attribs_ptr[i * 4 + 3] : 1.0);
2079 }
2080 }
2081 return ret;
2082}
2083Vector<Quaternion> GLTFDocument::_decode_accessor_as_quaternion(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
2084 const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
2085 Vector<Quaternion> ret;
2086
2087 if (attribs.size() == 0) {
2088 return ret;
2089 }
2090
2091 ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
2092 const double *attribs_ptr = attribs.ptr();
2093 const int ret_size = attribs.size() / 4;
2094 ret.resize(ret_size);
2095 {
2096 for (int i = 0; i < ret_size; i++) {
2097 ret.write[i] = Quaternion(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]).normalized();
2098 }
2099 }
2100 return ret;
2101}
2102Vector<Transform2D> GLTFDocument::_decode_accessor_as_xform2d(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
2103 const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
2104 Vector<Transform2D> ret;
2105
2106 if (attribs.size() == 0) {
2107 return ret;
2108 }
2109
2110 ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
2111 ret.resize(attribs.size() / 4);
2112 for (int i = 0; i < ret.size(); i++) {
2113 ret.write[i][0] = Vector2(attribs[i * 4 + 0], attribs[i * 4 + 1]);
2114 ret.write[i][1] = Vector2(attribs[i * 4 + 2], attribs[i * 4 + 3]);
2115 }
2116 return ret;
2117}
2118
2119Vector<Basis> GLTFDocument::_decode_accessor_as_basis(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
2120 const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
2121 Vector<Basis> ret;
2122
2123 if (attribs.size() == 0) {
2124 return ret;
2125 }
2126
2127 ERR_FAIL_COND_V(attribs.size() % 9 != 0, ret);
2128 ret.resize(attribs.size() / 9);
2129 for (int i = 0; i < ret.size(); i++) {
2130 ret.write[i].set_column(0, Vector3(attribs[i * 9 + 0], attribs[i * 9 + 1], attribs[i * 9 + 2]));
2131 ret.write[i].set_column(1, Vector3(attribs[i * 9 + 3], attribs[i * 9 + 4], attribs[i * 9 + 5]));
2132 ret.write[i].set_column(2, Vector3(attribs[i * 9 + 6], attribs[i * 9 + 7], attribs[i * 9 + 8]));
2133 }
2134 return ret;
2135}
2136
2137Vector<Transform3D> GLTFDocument::_decode_accessor_as_xform(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
2138 const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
2139 Vector<Transform3D> ret;
2140
2141 if (attribs.size() == 0) {
2142 return ret;
2143 }
2144
2145 ERR_FAIL_COND_V(attribs.size() % 16 != 0, ret);
2146 ret.resize(attribs.size() / 16);
2147 for (int i = 0; i < ret.size(); i++) {
2148 ret.write[i].basis.set_column(0, Vector3(attribs[i * 16 + 0], attribs[i * 16 + 1], attribs[i * 16 + 2]));
2149 ret.write[i].basis.set_column(1, Vector3(attribs[i * 16 + 4], attribs[i * 16 + 5], attribs[i * 16 + 6]));
2150 ret.write[i].basis.set_column(2, Vector3(attribs[i * 16 + 8], attribs[i * 16 + 9], attribs[i * 16 + 10]));
2151 ret.write[i].set_origin(Vector3(attribs[i * 16 + 12], attribs[i * 16 + 13], attribs[i * 16 + 14]));
2152 }
2153 return ret;
2154}
2155
2156Error GLTFDocument::_serialize_meshes(Ref<GLTFState> p_state) {
2157 Array meshes;
2158 for (GLTFMeshIndex gltf_mesh_i = 0; gltf_mesh_i < p_state->meshes.size(); gltf_mesh_i++) {
2159 print_verbose("glTF: Serializing mesh: " + itos(gltf_mesh_i));
2160 Ref<ImporterMesh> import_mesh = p_state->meshes.write[gltf_mesh_i]->get_mesh();
2161 if (import_mesh.is_null()) {
2162 continue;
2163 }
2164 Array instance_materials = p_state->meshes.write[gltf_mesh_i]->get_instance_materials();
2165 Array primitives;
2166 Dictionary gltf_mesh;
2167 Array target_names;
2168 Array weights;
2169 for (int morph_i = 0; morph_i < import_mesh->get_blend_shape_count(); morph_i++) {
2170 target_names.push_back(import_mesh->get_blend_shape_name(morph_i));
2171 }
2172 for (int surface_i = 0; surface_i < import_mesh->get_surface_count(); surface_i++) {
2173 Array targets;
2174 Dictionary primitive;
2175 Mesh::PrimitiveType primitive_type = import_mesh->get_surface_primitive_type(surface_i);
2176 switch (primitive_type) {
2177 case Mesh::PRIMITIVE_POINTS: {
2178 primitive["mode"] = 0;
2179 break;
2180 }
2181 case Mesh::PRIMITIVE_LINES: {
2182 primitive["mode"] = 1;
2183 break;
2184 }
2185 // case Mesh::PRIMITIVE_LINE_LOOP: {
2186 // primitive["mode"] = 2;
2187 // break;
2188 // }
2189 case Mesh::PRIMITIVE_LINE_STRIP: {
2190 primitive["mode"] = 3;
2191 break;
2192 }
2193 case Mesh::PRIMITIVE_TRIANGLES: {
2194 primitive["mode"] = 4;
2195 break;
2196 }
2197 case Mesh::PRIMITIVE_TRIANGLE_STRIP: {
2198 primitive["mode"] = 5;
2199 break;
2200 }
2201 // case Mesh::PRIMITIVE_TRIANGLE_FAN: {
2202 // primitive["mode"] = 6;
2203 // break;
2204 // }
2205 default: {
2206 ERR_FAIL_V(FAILED);
2207 }
2208 }
2209
2210 Array array = import_mesh->get_surface_arrays(surface_i);
2211 uint32_t format = import_mesh->get_surface_format(surface_i);
2212 int32_t vertex_num = 0;
2213 Dictionary attributes;
2214 {
2215 Vector<Vector3> a = array[Mesh::ARRAY_VERTEX];
2216 ERR_FAIL_COND_V(!a.size(), ERR_INVALID_DATA);
2217 attributes["POSITION"] = _encode_accessor_as_vec3(p_state, a, true);
2218 vertex_num = a.size();
2219 }
2220 {
2221 Vector<real_t> a = array[Mesh::ARRAY_TANGENT];
2222 if (a.size()) {
2223 const int ret_size = a.size() / 4;
2224 Vector<Color> attribs;
2225 attribs.resize(ret_size);
2226 for (int i = 0; i < ret_size; i++) {
2227 Color out;
2228 out.r = a[(i * 4) + 0];
2229 out.g = a[(i * 4) + 1];
2230 out.b = a[(i * 4) + 2];
2231 out.a = a[(i * 4) + 3];
2232 attribs.write[i] = out;
2233 }
2234 attributes["TANGENT"] = _encode_accessor_as_color(p_state, attribs, true);
2235 }
2236 }
2237 {
2238 Vector<Vector3> a = array[Mesh::ARRAY_NORMAL];
2239 if (a.size()) {
2240 const int ret_size = a.size();
2241 Vector<Vector3> attribs;
2242 attribs.resize(ret_size);
2243 for (int i = 0; i < ret_size; i++) {
2244 attribs.write[i] = Vector3(a[i]).normalized();
2245 }
2246 attributes["NORMAL"] = _encode_accessor_as_vec3(p_state, attribs, true);
2247 }
2248 }
2249 {
2250 Vector<Vector2> a = array[Mesh::ARRAY_TEX_UV];
2251 if (a.size()) {
2252 attributes["TEXCOORD_0"] = _encode_accessor_as_vec2(p_state, a, true);
2253 }
2254 }
2255 {
2256 Vector<Vector2> a = array[Mesh::ARRAY_TEX_UV2];
2257 if (a.size()) {
2258 attributes["TEXCOORD_1"] = _encode_accessor_as_vec2(p_state, a, true);
2259 }
2260 }
2261 for (int custom_i = 0; custom_i < 3; custom_i++) {
2262 Vector<float> a = array[Mesh::ARRAY_CUSTOM0 + custom_i];
2263 if (a.size()) {
2264 int num_channels = 4;
2265 int custom_shift = Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT + custom_i * Mesh::ARRAY_FORMAT_CUSTOM_BITS;
2266 switch ((format >> custom_shift) & Mesh::ARRAY_FORMAT_CUSTOM_MASK) {
2267 case Mesh::ARRAY_CUSTOM_R_FLOAT:
2268 num_channels = 1;
2269 break;
2270 case Mesh::ARRAY_CUSTOM_RG_FLOAT:
2271 num_channels = 2;
2272 break;
2273 case Mesh::ARRAY_CUSTOM_RGB_FLOAT:
2274 num_channels = 3;
2275 break;
2276 case Mesh::ARRAY_CUSTOM_RGBA_FLOAT:
2277 num_channels = 4;
2278 break;
2279 }
2280 int texcoord_i = 2 + 2 * custom_i;
2281 String gltf_texcoord_key;
2282 for (int prev_texcoord_i = 0; prev_texcoord_i < texcoord_i; prev_texcoord_i++) {
2283 gltf_texcoord_key = vformat("TEXCOORD_%d", prev_texcoord_i);
2284 if (!attributes.has(gltf_texcoord_key)) {
2285 Vector<Vector2> empty;
2286 empty.resize(vertex_num);
2287 attributes[gltf_texcoord_key] = _encode_accessor_as_vec2(p_state, empty, true);
2288 }
2289 }
2290
2291 LocalVector<Vector2> first_channel;
2292 first_channel.resize(vertex_num);
2293 LocalVector<Vector2> second_channel;
2294 second_channel.resize(vertex_num);
2295 for (int32_t vert_i = 0; vert_i < vertex_num; vert_i++) {
2296 float u = a[vert_i * num_channels + 0];
2297 float v = (num_channels == 1 ? 0.0f : a[vert_i * num_channels + 1]);
2298 first_channel[vert_i] = Vector2(u, v);
2299 u = 0;
2300 v = 0;
2301 if (num_channels >= 3) {
2302 u = a[vert_i * num_channels + 2];
2303 v = (num_channels == 3 ? 0.0f : a[vert_i * num_channels + 3]);
2304 second_channel[vert_i] = Vector2(u, v);
2305 }
2306 }
2307 gltf_texcoord_key = vformat("TEXCOORD_%d", texcoord_i);
2308 attributes[gltf_texcoord_key] = _encode_accessor_as_vec2(p_state, first_channel, true);
2309 gltf_texcoord_key = vformat("TEXCOORD_%d", texcoord_i + 1);
2310 attributes[gltf_texcoord_key] = _encode_accessor_as_vec2(p_state, second_channel, true);
2311 }
2312 }
2313 {
2314 Vector<Color> a = array[Mesh::ARRAY_COLOR];
2315 if (a.size()) {
2316 attributes["COLOR_0"] = _encode_accessor_as_color(p_state, a, true);
2317 }
2318 }
2319 HashMap<int, int> joint_i_to_bone_i;
2320 for (GLTFNodeIndex node_i = 0; node_i < p_state->nodes.size(); node_i++) {
2321 GLTFSkinIndex skin_i = -1;
2322 if (p_state->nodes[node_i]->mesh == gltf_mesh_i) {
2323 skin_i = p_state->nodes[node_i]->skin;
2324 }
2325 if (skin_i != -1) {
2326 joint_i_to_bone_i = p_state->skins[skin_i]->joint_i_to_bone_i;
2327 break;
2328 }
2329 }
2330 {
2331 const Array &a = array[Mesh::ARRAY_BONES];
2332 const Vector<Vector3> &vertex_array = array[Mesh::ARRAY_VERTEX];
2333 if ((a.size() / JOINT_GROUP_SIZE) == vertex_array.size()) {
2334 const int ret_size = a.size() / JOINT_GROUP_SIZE;
2335 Vector<Color> attribs;
2336 attribs.resize(ret_size);
2337 {
2338 for (int array_i = 0; array_i < attribs.size(); array_i++) {
2339 int32_t joint_0 = a[(array_i * JOINT_GROUP_SIZE) + 0];
2340 int32_t joint_1 = a[(array_i * JOINT_GROUP_SIZE) + 1];
2341 int32_t joint_2 = a[(array_i * JOINT_GROUP_SIZE) + 2];
2342 int32_t joint_3 = a[(array_i * JOINT_GROUP_SIZE) + 3];
2343 attribs.write[array_i] = Color(joint_0, joint_1, joint_2, joint_3);
2344 }
2345 }
2346 attributes["JOINTS_0"] = _encode_accessor_as_joints(p_state, attribs, true);
2347 } else if ((a.size() / (JOINT_GROUP_SIZE * 2)) >= vertex_array.size()) {
2348 Vector<Color> joints_0;
2349 joints_0.resize(vertex_num);
2350 Vector<Color> joints_1;
2351 joints_1.resize(vertex_num);
2352 int32_t weights_8_count = JOINT_GROUP_SIZE * 2;
2353 for (int32_t vertex_i = 0; vertex_i < vertex_num; vertex_i++) {
2354 Color joint_0;
2355 joint_0.r = a[vertex_i * weights_8_count + 0];
2356 joint_0.g = a[vertex_i * weights_8_count + 1];
2357 joint_0.b = a[vertex_i * weights_8_count + 2];
2358 joint_0.a = a[vertex_i * weights_8_count + 3];
2359 joints_0.write[vertex_i] = joint_0;
2360 Color joint_1;
2361 joint_1.r = a[vertex_i * weights_8_count + 4];
2362 joint_1.g = a[vertex_i * weights_8_count + 5];
2363 joint_1.b = a[vertex_i * weights_8_count + 6];
2364 joint_1.a = a[vertex_i * weights_8_count + 7];
2365 joints_1.write[vertex_i] = joint_1;
2366 }
2367 attributes["JOINTS_0"] = _encode_accessor_as_joints(p_state, joints_0, true);
2368 attributes["JOINTS_1"] = _encode_accessor_as_joints(p_state, joints_1, true);
2369 }
2370 }
2371 {
2372 const Array &a = array[Mesh::ARRAY_WEIGHTS];
2373 const Vector<Vector3> &vertex_array = array[Mesh::ARRAY_VERTEX];
2374 if ((a.size() / JOINT_GROUP_SIZE) == vertex_array.size()) {
2375 int32_t vertex_count = vertex_array.size();
2376 Vector<Color> attribs;
2377 attribs.resize(vertex_count);
2378 for (int i = 0; i < vertex_count; i++) {
2379 attribs.write[i] = Color(a[(i * JOINT_GROUP_SIZE) + 0], a[(i * JOINT_GROUP_SIZE) + 1], a[(i * JOINT_GROUP_SIZE) + 2], a[(i * JOINT_GROUP_SIZE) + 3]);
2380 }
2381 attributes["WEIGHTS_0"] = _encode_accessor_as_weights(p_state, attribs, true);
2382 } else if ((a.size() / (JOINT_GROUP_SIZE * 2)) >= vertex_array.size()) {
2383 Vector<Color> weights_0;
2384 weights_0.resize(vertex_num);
2385 Vector<Color> weights_1;
2386 weights_1.resize(vertex_num);
2387 int32_t weights_8_count = JOINT_GROUP_SIZE * 2;
2388 for (int32_t vertex_i = 0; vertex_i < vertex_num; vertex_i++) {
2389 Color weight_0;
2390 weight_0.r = a[vertex_i * weights_8_count + 0];
2391 weight_0.g = a[vertex_i * weights_8_count + 1];
2392 weight_0.b = a[vertex_i * weights_8_count + 2];
2393 weight_0.a = a[vertex_i * weights_8_count + 3];
2394 weights_0.write[vertex_i] = weight_0;
2395 Color weight_1;
2396 weight_1.r = a[vertex_i * weights_8_count + 4];
2397 weight_1.g = a[vertex_i * weights_8_count + 5];
2398 weight_1.b = a[vertex_i * weights_8_count + 6];
2399 weight_1.a = a[vertex_i * weights_8_count + 7];
2400 weights_1.write[vertex_i] = weight_1;
2401 }
2402 attributes["WEIGHTS_0"] = _encode_accessor_as_weights(p_state, weights_0, true);
2403 attributes["WEIGHTS_1"] = _encode_accessor_as_weights(p_state, weights_1, true);
2404 }
2405 }
2406 {
2407 Vector<int32_t> mesh_indices = array[Mesh::ARRAY_INDEX];
2408 if (mesh_indices.size()) {
2409 if (primitive_type == Mesh::PRIMITIVE_TRIANGLES) {
2410 //swap around indices, convert ccw to cw for front face
2411 const int is = mesh_indices.size();
2412 for (int k = 0; k < is; k += 3) {
2413 SWAP(mesh_indices.write[k + 0], mesh_indices.write[k + 2]);
2414 }
2415 }
2416 primitive["indices"] = _encode_accessor_as_ints(p_state, mesh_indices, true);
2417 } else {
2418 if (primitive_type == Mesh::PRIMITIVE_TRIANGLES) {
2419 //generate indices because they need to be swapped for CW/CCW
2420 const Vector<Vector3> &vertices = array[Mesh::ARRAY_VERTEX];
2421 Ref<SurfaceTool> st;
2422 st.instantiate();
2423 st->create_from_triangle_arrays(array);
2424 st->index();
2425 Vector<int32_t> generated_indices = st->commit_to_arrays()[Mesh::ARRAY_INDEX];
2426 const int vs = vertices.size();
2427 generated_indices.resize(vs);
2428 {
2429 for (int k = 0; k < vs; k += 3) {
2430 generated_indices.write[k] = k;
2431 generated_indices.write[k + 1] = k + 2;
2432 generated_indices.write[k + 2] = k + 1;
2433 }
2434 }
2435 primitive["indices"] = _encode_accessor_as_ints(p_state, generated_indices, true);
2436 }
2437 }
2438 }
2439
2440 primitive["attributes"] = attributes;
2441
2442 //blend shapes
2443 print_verbose("glTF: Mesh has targets");
2444 if (import_mesh->get_blend_shape_count()) {
2445 ArrayMesh::BlendShapeMode shape_mode = import_mesh->get_blend_shape_mode();
2446 for (int morph_i = 0; morph_i < import_mesh->get_blend_shape_count(); morph_i++) {
2447 Array array_morph = import_mesh->get_surface_blend_shape_arrays(surface_i, morph_i);
2448 Dictionary t;
2449 Vector<Vector3> varr = array_morph[Mesh::ARRAY_VERTEX];
2450 Array mesh_arrays = import_mesh->get_surface_arrays(surface_i);
2451 if (varr.size()) {
2452 Vector<Vector3> src_varr = array[Mesh::ARRAY_VERTEX];
2453 if (shape_mode == ArrayMesh::BlendShapeMode::BLEND_SHAPE_MODE_NORMALIZED) {
2454 const int max_idx = src_varr.size();
2455 for (int blend_i = 0; blend_i < max_idx; blend_i++) {
2456 varr.write[blend_i] = Vector3(varr[blend_i]) - src_varr[blend_i];
2457 }
2458 }
2459
2460 t["POSITION"] = _encode_accessor_as_vec3(p_state, varr, true);
2461 }
2462
2463 Vector<Vector3> narr = array_morph[Mesh::ARRAY_NORMAL];
2464 if (narr.size()) {
2465 t["NORMAL"] = _encode_accessor_as_vec3(p_state, narr, true);
2466 }
2467 Vector<real_t> tarr = array_morph[Mesh::ARRAY_TANGENT];
2468 if (tarr.size()) {
2469 const int ret_size = tarr.size() / 4;
2470 Vector<Vector3> attribs;
2471 attribs.resize(ret_size);
2472 for (int i = 0; i < ret_size; i++) {
2473 Vector3 vec3;
2474 vec3.x = tarr[(i * 4) + 0];
2475 vec3.y = tarr[(i * 4) + 1];
2476 vec3.z = tarr[(i * 4) + 2];
2477 }
2478 t["TANGENT"] = _encode_accessor_as_vec3(p_state, attribs, true);
2479 }
2480 targets.push_back(t);
2481 }
2482 }
2483
2484 Variant v;
2485 if (surface_i < instance_materials.size()) {
2486 v = instance_materials.get(surface_i);
2487 }
2488 Ref<Material> mat = v;
2489 if (!mat.is_valid()) {
2490 mat = import_mesh->get_surface_material(surface_i);
2491 }
2492 if (mat.is_valid()) {
2493 HashMap<Ref<Material>, GLTFMaterialIndex>::Iterator material_cache_i = p_state->material_cache.find(mat);
2494 if (material_cache_i && material_cache_i->value != -1) {
2495 primitive["material"] = material_cache_i->value;
2496 } else {
2497 GLTFMaterialIndex mat_i = p_state->materials.size();
2498 p_state->materials.push_back(mat);
2499 primitive["material"] = mat_i;
2500 p_state->material_cache.insert(mat, mat_i);
2501 }
2502 }
2503
2504 if (targets.size()) {
2505 primitive["targets"] = targets;
2506 }
2507
2508 primitives.push_back(primitive);
2509 }
2510
2511 Dictionary e;
2512 e["targetNames"] = target_names;
2513
2514 weights.resize(target_names.size());
2515 for (int name_i = 0; name_i < target_names.size(); name_i++) {
2516 real_t weight = 0.0;
2517 if (name_i < p_state->meshes.write[gltf_mesh_i]->get_blend_weights().size()) {
2518 weight = p_state->meshes.write[gltf_mesh_i]->get_blend_weights()[name_i];
2519 }
2520 weights[name_i] = weight;
2521 }
2522 if (weights.size()) {
2523 gltf_mesh["weights"] = weights;
2524 }
2525
2526 ERR_FAIL_COND_V(target_names.size() != weights.size(), FAILED);
2527
2528 gltf_mesh["extras"] = e;
2529
2530 gltf_mesh["primitives"] = primitives;
2531
2532 meshes.push_back(gltf_mesh);
2533 }
2534
2535 if (!meshes.size()) {
2536 return OK;
2537 }
2538 p_state->json["meshes"] = meshes;
2539 print_verbose("glTF: Total meshes: " + itos(meshes.size()));
2540
2541 return OK;
2542}
2543
2544Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) {
2545 if (!p_state->json.has("meshes")) {
2546 return OK;
2547 }
2548
2549 Array meshes = p_state->json["meshes"];
2550 for (GLTFMeshIndex i = 0; i < meshes.size(); i++) {
2551 print_verbose("glTF: Parsing mesh: " + itos(i));
2552 Dictionary d = meshes[i];
2553
2554 Ref<GLTFMesh> mesh;
2555 mesh.instantiate();
2556 bool has_vertex_color = false;
2557
2558 ERR_FAIL_COND_V(!d.has("primitives"), ERR_PARSE_ERROR);
2559
2560 Array primitives = d["primitives"];
2561 const Dictionary &extras = d.has("extras") ? (Dictionary)d["extras"] : Dictionary();
2562 Ref<ImporterMesh> import_mesh;
2563 import_mesh.instantiate();
2564 String mesh_name = "mesh";
2565 if (d.has("name") && !String(d["name"]).is_empty()) {
2566 mesh_name = d["name"];
2567 }
2568 import_mesh->set_name(_gen_unique_name(p_state, vformat("%s_%s", p_state->scene_name, mesh_name)));
2569
2570 for (int j = 0; j < primitives.size(); j++) {
2571 uint32_t flags = 0;
2572 Dictionary p = primitives[j];
2573
2574 Array array;
2575 array.resize(Mesh::ARRAY_MAX);
2576
2577 ERR_FAIL_COND_V(!p.has("attributes"), ERR_PARSE_ERROR);
2578
2579 Dictionary a = p["attributes"];
2580
2581 Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_TRIANGLES;
2582 if (p.has("mode")) {
2583 const int mode = p["mode"];
2584 ERR_FAIL_INDEX_V(mode, 7, ERR_FILE_CORRUPT);
2585 // Convert mesh.primitive.mode to Godot Mesh enum. See:
2586 // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#_mesh_primitive_mode
2587 static const Mesh::PrimitiveType primitives2[7] = {
2588 Mesh::PRIMITIVE_POINTS, // 0 POINTS
2589 Mesh::PRIMITIVE_LINES, // 1 LINES
2590 Mesh::PRIMITIVE_LINES, // 2 LINE_LOOP; loop not supported, should be converted
2591 Mesh::PRIMITIVE_LINE_STRIP, // 3 LINE_STRIP
2592 Mesh::PRIMITIVE_TRIANGLES, // 4 TRIANGLES
2593 Mesh::PRIMITIVE_TRIANGLE_STRIP, // 5 TRIANGLE_STRIP
2594 Mesh::PRIMITIVE_TRIANGLES, // 6 TRIANGLE_FAN fan not supported, should be converted
2595 // TODO: Line loop and triangle fan are not supported and need to be converted to lines and triangles.
2596 };
2597
2598 primitive = primitives2[mode];
2599 }
2600
2601 ERR_FAIL_COND_V(!a.has("POSITION"), ERR_PARSE_ERROR);
2602 int32_t vertex_num = 0;
2603 if (a.has("POSITION")) {
2604 PackedVector3Array vertices = _decode_accessor_as_vec3(p_state, a["POSITION"], true);
2605 array[Mesh::ARRAY_VERTEX] = vertices;
2606 vertex_num = vertices.size();
2607 }
2608 if (a.has("NORMAL")) {
2609 array[Mesh::ARRAY_NORMAL] = _decode_accessor_as_vec3(p_state, a["NORMAL"], true);
2610 }
2611 if (a.has("TANGENT")) {
2612 array[Mesh::ARRAY_TANGENT] = _decode_accessor_as_floats(p_state, a["TANGENT"], true);
2613 }
2614 if (a.has("TEXCOORD_0")) {
2615 array[Mesh::ARRAY_TEX_UV] = _decode_accessor_as_vec2(p_state, a["TEXCOORD_0"], true);
2616 }
2617 if (a.has("TEXCOORD_1")) {
2618 array[Mesh::ARRAY_TEX_UV2] = _decode_accessor_as_vec2(p_state, a["TEXCOORD_1"], true);
2619 }
2620 for (int custom_i = 0; custom_i < 3; custom_i++) {
2621 Vector<float> cur_custom;
2622 Vector<Vector2> texcoord_first;
2623 Vector<Vector2> texcoord_second;
2624
2625 int texcoord_i = 2 + 2 * custom_i;
2626 String gltf_texcoord_key = vformat("TEXCOORD_%d", texcoord_i);
2627 int num_channels = 0;
2628 if (a.has(gltf_texcoord_key)) {
2629 texcoord_first = _decode_accessor_as_vec2(p_state, a[gltf_texcoord_key], true);
2630 num_channels = 2;
2631 }
2632 gltf_texcoord_key = vformat("TEXCOORD_%d", texcoord_i + 1);
2633 if (a.has(gltf_texcoord_key)) {
2634 texcoord_second = _decode_accessor_as_vec2(p_state, a[gltf_texcoord_key], true);
2635 num_channels = 4;
2636 }
2637 if (!num_channels) {
2638 break;
2639 }
2640 if (num_channels == 2 || num_channels == 4) {
2641 cur_custom.resize(vertex_num * num_channels);
2642 for (int32_t uv_i = 0; uv_i < texcoord_first.size() && uv_i < vertex_num; uv_i++) {
2643 cur_custom.write[uv_i * num_channels + 0] = texcoord_first[uv_i].x;
2644 cur_custom.write[uv_i * num_channels + 1] = texcoord_first[uv_i].y;
2645 }
2646 // Vector.resize seems to not zero-initialize. Ensure all unused elements are 0:
2647 for (int32_t uv_i = texcoord_first.size(); uv_i < vertex_num; uv_i++) {
2648 cur_custom.write[uv_i * num_channels + 0] = 0;
2649 cur_custom.write[uv_i * num_channels + 1] = 0;
2650 }
2651 }
2652 if (num_channels == 4) {
2653 for (int32_t uv_i = 0; uv_i < texcoord_second.size() && uv_i < vertex_num; uv_i++) {
2654 // num_channels must be 4
2655 cur_custom.write[uv_i * num_channels + 2] = texcoord_second[uv_i].x;
2656 cur_custom.write[uv_i * num_channels + 3] = texcoord_second[uv_i].y;
2657 }
2658 // Vector.resize seems to not zero-initialize. Ensure all unused elements are 0:
2659 for (int32_t uv_i = texcoord_second.size(); uv_i < vertex_num; uv_i++) {
2660 cur_custom.write[uv_i * num_channels + 2] = 0;
2661 cur_custom.write[uv_i * num_channels + 3] = 0;
2662 }
2663 }
2664 if (cur_custom.size() > 0) {
2665 array[Mesh::ARRAY_CUSTOM0 + custom_i] = cur_custom;
2666 int custom_shift = Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT + custom_i * Mesh::ARRAY_FORMAT_CUSTOM_BITS;
2667 if (num_channels == 2) {
2668 flags |= Mesh::ARRAY_CUSTOM_RG_FLOAT << custom_shift;
2669 } else {
2670 flags |= Mesh::ARRAY_CUSTOM_RGBA_FLOAT << custom_shift;
2671 }
2672 }
2673 }
2674 if (a.has("COLOR_0")) {
2675 array[Mesh::ARRAY_COLOR] = _decode_accessor_as_color(p_state, a["COLOR_0"], true);
2676 has_vertex_color = true;
2677 }
2678 if (a.has("JOINTS_0") && !a.has("JOINTS_1")) {
2679 array[Mesh::ARRAY_BONES] = _decode_accessor_as_ints(p_state, a["JOINTS_0"], true);
2680 } else if (a.has("JOINTS_0") && a.has("JOINTS_1")) {
2681 PackedInt32Array joints_0 = _decode_accessor_as_ints(p_state, a["JOINTS_0"], true);
2682 PackedInt32Array joints_1 = _decode_accessor_as_ints(p_state, a["JOINTS_1"], true);
2683 ERR_FAIL_COND_V(joints_0.size() != joints_1.size(), ERR_INVALID_DATA);
2684 int32_t weight_8_count = JOINT_GROUP_SIZE * 2;
2685 Vector<int> joints;
2686 joints.resize(vertex_num * weight_8_count);
2687 for (int32_t vertex_i = 0; vertex_i < vertex_num; vertex_i++) {
2688 joints.write[vertex_i * weight_8_count + 0] = joints_0[vertex_i * JOINT_GROUP_SIZE + 0];
2689 joints.write[vertex_i * weight_8_count + 1] = joints_0[vertex_i * JOINT_GROUP_SIZE + 1];
2690 joints.write[vertex_i * weight_8_count + 2] = joints_0[vertex_i * JOINT_GROUP_SIZE + 2];
2691 joints.write[vertex_i * weight_8_count + 3] = joints_0[vertex_i * JOINT_GROUP_SIZE + 3];
2692 joints.write[vertex_i * weight_8_count + 4] = joints_1[vertex_i * JOINT_GROUP_SIZE + 0];
2693 joints.write[vertex_i * weight_8_count + 5] = joints_1[vertex_i * JOINT_GROUP_SIZE + 1];
2694 joints.write[vertex_i * weight_8_count + 6] = joints_1[vertex_i * JOINT_GROUP_SIZE + 2];
2695 joints.write[vertex_i * weight_8_count + 7] = joints_1[vertex_i * JOINT_GROUP_SIZE + 3];
2696 }
2697 array[Mesh::ARRAY_BONES] = joints;
2698 }
2699 if (a.has("WEIGHTS_0") && !a.has("WEIGHTS_1")) {
2700 Vector<float> weights = _decode_accessor_as_floats(p_state, a["WEIGHTS_0"], true);
2701 { //gltf does not seem to normalize the weights for some reason..
2702 int wc = weights.size();
2703 float *w = weights.ptrw();
2704
2705 for (int k = 0; k < wc; k += 4) {
2706 float total = 0.0;
2707 total += w[k + 0];
2708 total += w[k + 1];
2709 total += w[k + 2];
2710 total += w[k + 3];
2711 if (total > 0.0) {
2712 w[k + 0] /= total;
2713 w[k + 1] /= total;
2714 w[k + 2] /= total;
2715 w[k + 3] /= total;
2716 }
2717 }
2718 }
2719 array[Mesh::ARRAY_WEIGHTS] = weights;
2720 } else if (a.has("WEIGHTS_0") && a.has("WEIGHTS_1")) {
2721 Vector<float> weights_0 = _decode_accessor_as_floats(p_state, a["WEIGHTS_0"], true);
2722 Vector<float> weights_1 = _decode_accessor_as_floats(p_state, a["WEIGHTS_1"], true);
2723 Vector<float> weights;
2724 ERR_FAIL_COND_V(weights_0.size() != weights_1.size(), ERR_INVALID_DATA);
2725 int32_t weight_8_count = JOINT_GROUP_SIZE * 2;
2726 weights.resize(vertex_num * weight_8_count);
2727 for (int32_t vertex_i = 0; vertex_i < vertex_num; vertex_i++) {
2728 weights.write[vertex_i * weight_8_count + 0] = weights_0[vertex_i * JOINT_GROUP_SIZE + 0];
2729 weights.write[vertex_i * weight_8_count + 1] = weights_0[vertex_i * JOINT_GROUP_SIZE + 1];
2730 weights.write[vertex_i * weight_8_count + 2] = weights_0[vertex_i * JOINT_GROUP_SIZE + 2];
2731 weights.write[vertex_i * weight_8_count + 3] = weights_0[vertex_i * JOINT_GROUP_SIZE + 3];
2732 weights.write[vertex_i * weight_8_count + 4] = weights_1[vertex_i * JOINT_GROUP_SIZE + 0];
2733 weights.write[vertex_i * weight_8_count + 5] = weights_1[vertex_i * JOINT_GROUP_SIZE + 1];
2734 weights.write[vertex_i * weight_8_count + 6] = weights_1[vertex_i * JOINT_GROUP_SIZE + 2];
2735 weights.write[vertex_i * weight_8_count + 7] = weights_1[vertex_i * JOINT_GROUP_SIZE + 3];
2736 }
2737 { //gltf does not seem to normalize the weights for some reason..
2738 int wc = weights.size();
2739 float *w = weights.ptrw();
2740
2741 for (int k = 0; k < wc; k += weight_8_count) {
2742 float total = 0.0;
2743 total += w[k + 0];
2744 total += w[k + 1];
2745 total += w[k + 2];
2746 total += w[k + 3];
2747 total += w[k + 4];
2748 total += w[k + 5];
2749 total += w[k + 6];
2750 total += w[k + 7];
2751 if (total > 0.0) {
2752 w[k + 0] /= total;
2753 w[k + 1] /= total;
2754 w[k + 2] /= total;
2755 w[k + 3] /= total;
2756 w[k + 4] /= total;
2757 w[k + 5] /= total;
2758 w[k + 6] /= total;
2759 w[k + 7] /= total;
2760 }
2761 }
2762 }
2763 array[Mesh::ARRAY_WEIGHTS] = weights;
2764 }
2765
2766 if (p.has("indices")) {
2767 Vector<int> indices = _decode_accessor_as_ints(p_state, p["indices"], false);
2768
2769 if (primitive == Mesh::PRIMITIVE_TRIANGLES) {
2770 //swap around indices, convert ccw to cw for front face
2771
2772 const int is = indices.size();
2773 int *w = indices.ptrw();
2774 for (int k = 0; k < is; k += 3) {
2775 SWAP(w[k + 1], w[k + 2]);
2776 }
2777 }
2778 array[Mesh::ARRAY_INDEX] = indices;
2779
2780 } else if (primitive == Mesh::PRIMITIVE_TRIANGLES) {
2781 //generate indices because they need to be swapped for CW/CCW
2782 const Vector<Vector3> &vertices = array[Mesh::ARRAY_VERTEX];
2783 ERR_FAIL_COND_V(vertices.size() == 0, ERR_PARSE_ERROR);
2784 Vector<int> indices;
2785 const int vs = vertices.size();
2786 indices.resize(vs);
2787 {
2788 int *w = indices.ptrw();
2789 for (int k = 0; k < vs; k += 3) {
2790 w[k] = k;
2791 w[k + 1] = k + 2;
2792 w[k + 2] = k + 1;
2793 }
2794 }
2795 array[Mesh::ARRAY_INDEX] = indices;
2796 }
2797
2798 bool generate_tangents = (primitive == Mesh::PRIMITIVE_TRIANGLES && !a.has("TANGENT") && a.has("TEXCOORD_0") && a.has("NORMAL"));
2799
2800 Ref<SurfaceTool> mesh_surface_tool;
2801 mesh_surface_tool.instantiate();
2802 mesh_surface_tool->create_from_triangle_arrays(array);
2803 if (a.has("JOINTS_0") && a.has("JOINTS_1")) {
2804 mesh_surface_tool->set_skin_weight_count(SurfaceTool::SKIN_8_WEIGHTS);
2805 }
2806 mesh_surface_tool->index();
2807 if (generate_tangents) {
2808 //must generate mikktspace tangents.. ergh..
2809 mesh_surface_tool->generate_tangents();
2810 }
2811 array = mesh_surface_tool->commit_to_arrays();
2812
2813 Array morphs;
2814 //blend shapes
2815 if (p.has("targets")) {
2816 print_verbose("glTF: Mesh has targets");
2817 const Array &targets = p["targets"];
2818
2819 //ideally BLEND_SHAPE_MODE_RELATIVE since gltf2 stores in displacement
2820 //but it could require a larger refactor?
2821 import_mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED);
2822
2823 if (j == 0) {
2824 const Array &target_names = extras.has("targetNames") ? (Array)extras["targetNames"] : Array();
2825 for (int k = 0; k < targets.size(); k++) {
2826 String bs_name;
2827 if (k < target_names.size() && ((String)target_names[k]).size() != 0) {
2828 bs_name = (String)target_names[k];
2829 } else {
2830 bs_name = String("morph_") + itos(k);
2831 }
2832 import_mesh->add_blend_shape(bs_name);
2833 }
2834 }
2835
2836 for (int k = 0; k < targets.size(); k++) {
2837 const Dictionary &t = targets[k];
2838
2839 Array array_copy;
2840 array_copy.resize(Mesh::ARRAY_MAX);
2841
2842 for (int l = 0; l < Mesh::ARRAY_MAX; l++) {
2843 array_copy[l] = array[l];
2844 }
2845
2846 if (t.has("POSITION")) {
2847 Vector<Vector3> varr = _decode_accessor_as_vec3(p_state, t["POSITION"], true);
2848 const Vector<Vector3> src_varr = array[Mesh::ARRAY_VERTEX];
2849 const int size = src_varr.size();
2850 ERR_FAIL_COND_V(size == 0, ERR_PARSE_ERROR);
2851 {
2852 const int max_idx = varr.size();
2853 varr.resize(size);
2854
2855 Vector3 *w_varr = varr.ptrw();
2856 const Vector3 *r_varr = varr.ptr();
2857 const Vector3 *r_src_varr = src_varr.ptr();
2858 for (int l = 0; l < size; l++) {
2859 if (l < max_idx) {
2860 w_varr[l] = r_varr[l] + r_src_varr[l];
2861 } else {
2862 w_varr[l] = r_src_varr[l];
2863 }
2864 }
2865 }
2866 array_copy[Mesh::ARRAY_VERTEX] = varr;
2867 }
2868 if (t.has("NORMAL")) {
2869 Vector<Vector3> narr = _decode_accessor_as_vec3(p_state, t["NORMAL"], true);
2870 const Vector<Vector3> src_narr = array[Mesh::ARRAY_NORMAL];
2871 int size = src_narr.size();
2872 ERR_FAIL_COND_V(size == 0, ERR_PARSE_ERROR);
2873 {
2874 int max_idx = narr.size();
2875 narr.resize(size);
2876
2877 Vector3 *w_narr = narr.ptrw();
2878 const Vector3 *r_narr = narr.ptr();
2879 const Vector3 *r_src_narr = src_narr.ptr();
2880 for (int l = 0; l < size; l++) {
2881 if (l < max_idx) {
2882 w_narr[l] = r_narr[l] + r_src_narr[l];
2883 } else {
2884 w_narr[l] = r_src_narr[l];
2885 }
2886 }
2887 }
2888 array_copy[Mesh::ARRAY_NORMAL] = narr;
2889 }
2890 if (t.has("TANGENT")) {
2891 const Vector<Vector3> tangents_v3 = _decode_accessor_as_vec3(p_state, t["TANGENT"], true);
2892 const Vector<float> src_tangents = array[Mesh::ARRAY_TANGENT];
2893 ERR_FAIL_COND_V(src_tangents.size() == 0, ERR_PARSE_ERROR);
2894
2895 Vector<float> tangents_v4;
2896
2897 {
2898 int max_idx = tangents_v3.size();
2899
2900 int size4 = src_tangents.size();
2901 tangents_v4.resize(size4);
2902 float *w4 = tangents_v4.ptrw();
2903
2904 const Vector3 *r3 = tangents_v3.ptr();
2905 const float *r4 = src_tangents.ptr();
2906
2907 for (int l = 0; l < size4 / 4; l++) {
2908 if (l < max_idx) {
2909 w4[l * 4 + 0] = r3[l].x + r4[l * 4 + 0];
2910 w4[l * 4 + 1] = r3[l].y + r4[l * 4 + 1];
2911 w4[l * 4 + 2] = r3[l].z + r4[l * 4 + 2];
2912 } else {
2913 w4[l * 4 + 0] = r4[l * 4 + 0];
2914 w4[l * 4 + 1] = r4[l * 4 + 1];
2915 w4[l * 4 + 2] = r4[l * 4 + 2];
2916 }
2917 w4[l * 4 + 3] = r4[l * 4 + 3]; //copy flip value
2918 }
2919 }
2920
2921 array_copy[Mesh::ARRAY_TANGENT] = tangents_v4;
2922 }
2923
2924 Ref<SurfaceTool> blend_surface_tool;
2925 blend_surface_tool.instantiate();
2926 blend_surface_tool->create_from_triangle_arrays(array_copy);
2927 if (a.has("JOINTS_0") && a.has("JOINTS_1")) {
2928 blend_surface_tool->set_skin_weight_count(SurfaceTool::SKIN_8_WEIGHTS);
2929 }
2930 blend_surface_tool->index();
2931 if (generate_tangents) {
2932 blend_surface_tool->generate_tangents();
2933 }
2934 array_copy = blend_surface_tool->commit_to_arrays();
2935
2936 // Enforce blend shape mask array format
2937 for (int l = 0; l < Mesh::ARRAY_MAX; l++) {
2938 if (!(Mesh::ARRAY_FORMAT_BLEND_SHAPE_MASK & (1 << l))) {
2939 array_copy[l] = Variant();
2940 }
2941 }
2942
2943 morphs.push_back(array_copy);
2944 }
2945 }
2946
2947 Ref<Material> mat;
2948 String mat_name;
2949 if (!p_state->discard_meshes_and_materials) {
2950 if (p.has("material")) {
2951 const int material = p["material"];
2952 ERR_FAIL_INDEX_V(material, p_state->materials.size(), ERR_FILE_CORRUPT);
2953 Ref<Material> mat3d = p_state->materials[material];
2954 ERR_FAIL_NULL_V(mat3d, ERR_FILE_CORRUPT);
2955
2956 Ref<BaseMaterial3D> base_material = mat3d;
2957 if (has_vertex_color && base_material.is_valid()) {
2958 base_material->set_flag(BaseMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
2959 }
2960 mat = mat3d;
2961
2962 } else {
2963 Ref<StandardMaterial3D> mat3d;
2964 mat3d.instantiate();
2965 if (has_vertex_color) {
2966 mat3d->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
2967 }
2968 mat = mat3d;
2969 }
2970 ERR_FAIL_NULL_V(mat, ERR_FILE_CORRUPT);
2971 mat_name = mat->get_name();
2972 }
2973 import_mesh->add_surface(primitive, array, morphs,
2974 Dictionary(), mat, mat_name, flags);
2975 }
2976
2977 Vector<float> blend_weights;
2978 blend_weights.resize(import_mesh->get_blend_shape_count());
2979 for (int32_t weight_i = 0; weight_i < blend_weights.size(); weight_i++) {
2980 blend_weights.write[weight_i] = 0.0f;
2981 }
2982
2983 if (d.has("weights")) {
2984 const Array &weights = d["weights"];
2985 for (int j = 0; j < weights.size(); j++) {
2986 if (j >= blend_weights.size()) {
2987 break;
2988 }
2989 blend_weights.write[j] = weights[j];
2990 }
2991 }
2992 mesh->set_blend_weights(blend_weights);
2993 mesh->set_mesh(import_mesh);
2994
2995 p_state->meshes.push_back(mesh);
2996 }
2997
2998 print_verbose("glTF: Total meshes: " + itos(p_state->meshes.size()));
2999
3000 return OK;
3001}
3002
3003void GLTFDocument::set_image_format(const String &p_image_format) {
3004 _image_format = p_image_format;
3005}
3006
3007String GLTFDocument::get_image_format() const {
3008 return _image_format;
3009}
3010
3011void GLTFDocument::set_lossy_quality(float p_lossy_quality) {
3012 _lossy_quality = p_lossy_quality;
3013}
3014
3015float GLTFDocument::get_lossy_quality() const {
3016 return _lossy_quality;
3017}
3018
3019Error GLTFDocument::_serialize_images(Ref<GLTFState> p_state) {
3020 Array images;
3021 // Check if any extension wants to be the image saver.
3022 _image_save_extension = Ref<GLTFDocumentExtension>();
3023 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
3024 ERR_CONTINUE(ext.is_null());
3025 Vector<String> image_formats = ext->get_saveable_image_formats();
3026 if (image_formats.has(_image_format)) {
3027 _image_save_extension = ext;
3028 break;
3029 }
3030 }
3031 // Serialize every image in the state's images array.
3032 for (int i = 0; i < p_state->images.size(); i++) {
3033 Dictionary image_dict;
3034
3035 ERR_CONTINUE(p_state->images[i].is_null());
3036
3037 Ref<Image> image = p_state->images[i]->get_image();
3038 ERR_CONTINUE(image.is_null());
3039 if (image->is_compressed()) {
3040 image->decompress();
3041 ERR_FAIL_COND_V_MSG(image->is_compressed(), ERR_INVALID_DATA, "GLTF: Image was compressed, but could not be decompressed.");
3042 }
3043
3044 if (p_state->filename.to_lower().ends_with("gltf")) {
3045 String img_name = p_state->images[i]->get_name();
3046 if (img_name.is_empty()) {
3047 img_name = itos(i);
3048 }
3049 img_name = _gen_unique_name(p_state, img_name);
3050 img_name = img_name.pad_zeros(3);
3051 String relative_texture_dir = "textures";
3052 String full_texture_dir = p_state->base_path.path_join(relative_texture_dir);
3053 Ref<DirAccess> da = DirAccess::open(p_state->base_path);
3054 if (!da->dir_exists(full_texture_dir)) {
3055 da->make_dir(full_texture_dir);
3056 }
3057 if (_image_save_extension.is_valid()) {
3058 img_name = img_name + _image_save_extension->get_image_file_extension();
3059 Error err = _image_save_extension->save_image_at_path(p_state, image, full_texture_dir.path_join(img_name), _image_format, _lossy_quality);
3060 ERR_FAIL_COND_V_MSG(err != OK, err, "GLTF: Failed to save image in '" + _image_format + "' format as a separate file.");
3061 } else if (_image_format == "PNG") {
3062 img_name = img_name + ".png";
3063 image->save_png(full_texture_dir.path_join(img_name));
3064 } else if (_image_format == "JPEG") {
3065 img_name = img_name + ".jpg";
3066 image->save_jpg(full_texture_dir.path_join(img_name), _lossy_quality);
3067 } else {
3068 ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "GLTF: Unknown image format '" + _image_format + "'.");
3069 }
3070 image_dict["uri"] = relative_texture_dir.path_join(img_name).uri_encode();
3071 } else {
3072 GLTFBufferViewIndex bvi;
3073
3074 Ref<GLTFBufferView> bv;
3075 bv.instantiate();
3076
3077 const GLTFBufferIndex bi = 0;
3078 bv->buffer = bi;
3079 bv->byte_offset = p_state->buffers[bi].size();
3080 ERR_FAIL_INDEX_V(bi, p_state->buffers.size(), ERR_PARAMETER_RANGE_ERROR);
3081
3082 Vector<uint8_t> buffer;
3083 Ref<ImageTexture> img_tex = image;
3084 if (img_tex.is_valid()) {
3085 image = img_tex->get_image();
3086 }
3087 // Save in various image formats. Note that if the format is "None",
3088 // the state's images will be empty, so this code will not be reached.
3089 if (_image_save_extension.is_valid()) {
3090 buffer = _image_save_extension->serialize_image_to_bytes(p_state, image, image_dict, _image_format, _lossy_quality);
3091 } else if (_image_format == "PNG") {
3092 buffer = image->save_png_to_buffer();
3093 image_dict["mimeType"] = "image/png";
3094 } else if (_image_format == "JPEG") {
3095 buffer = image->save_jpg_to_buffer(_lossy_quality);
3096 image_dict["mimeType"] = "image/jpeg";
3097 } else {
3098 ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "GLTF: Unknown image format '" + _image_format + "'.");
3099 }
3100 ERR_FAIL_COND_V_MSG(buffer.is_empty(), ERR_INVALID_DATA, "GLTF: Failed to save image in '" + _image_format + "' format.");
3101
3102 bv->byte_length = buffer.size();
3103 p_state->buffers.write[bi].resize(p_state->buffers[bi].size() + bv->byte_length);
3104 memcpy(&p_state->buffers.write[bi].write[bv->byte_offset], buffer.ptr(), buffer.size());
3105 ERR_FAIL_COND_V(bv->byte_offset + bv->byte_length > p_state->buffers[bi].size(), ERR_FILE_CORRUPT);
3106
3107 p_state->buffer_views.push_back(bv);
3108 bvi = p_state->buffer_views.size() - 1;
3109 image_dict["bufferView"] = bvi;
3110 }
3111 images.push_back(image_dict);
3112 }
3113
3114 print_verbose("Total images: " + itos(p_state->images.size()));
3115
3116 if (!images.size()) {
3117 return OK;
3118 }
3119 p_state->json["images"] = images;
3120
3121 return OK;
3122}
3123
3124Ref<Image> GLTFDocument::_parse_image_bytes_into_image(Ref<GLTFState> p_state, const Vector<uint8_t> &p_bytes, const String &p_mime_type, int p_index, String &r_file_extension) {
3125 Ref<Image> r_image;
3126 r_image.instantiate();
3127 // Check if any GLTFDocumentExtensions want to import this data as an image.
3128 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
3129 ERR_CONTINUE(ext.is_null());
3130 Error err = ext->parse_image_data(p_state, p_bytes, p_mime_type, r_image);
3131 ERR_CONTINUE_MSG(err != OK, "GLTF: Encountered error " + itos(err) + " when parsing image " + itos(p_index) + " in file " + p_state->filename + ". Continuing.");
3132 if (!r_image->is_empty()) {
3133 r_file_extension = ext->get_image_file_extension();
3134 return r_image;
3135 }
3136 }
3137 // If no extension wanted to import this data as an image, try to load a PNG or JPEG.
3138 // First we honor the mime types if they were defined.
3139 if (p_mime_type == "image/png") { // Load buffer as PNG.
3140 r_image->load_png_from_buffer(p_bytes);
3141 r_file_extension = ".png";
3142 } else if (p_mime_type == "image/jpeg") { // Loader buffer as JPEG.
3143 r_image->load_jpg_from_buffer(p_bytes);
3144 r_file_extension = ".jpg";
3145 }
3146 // If we didn't pass the above tests, we attempt loading as PNG and then JPEG directly.
3147 // This covers URIs with base64-encoded data with application/* type but
3148 // no optional mimeType property, or bufferViews with a bogus mimeType
3149 // (e.g. `image/jpeg` but the data is actually PNG).
3150 // That's not *exactly* what the spec mandates but this lets us be
3151 // lenient with bogus glb files which do exist in production.
3152 if (r_image->is_empty()) { // Try PNG first.
3153 r_image->load_png_from_buffer(p_bytes);
3154 }
3155 if (r_image->is_empty()) { // And then JPEG.
3156 r_image->load_jpg_from_buffer(p_bytes);
3157 }
3158 // If it still can't be loaded, give up and insert an empty image as placeholder.
3159 if (r_image->is_empty()) {
3160 ERR_PRINT(vformat("glTF: Couldn't load image index '%d' with its given mimetype: %s.", p_index, p_mime_type));
3161 }
3162 return r_image;
3163}
3164
3165void GLTFDocument::_parse_image_save_image(Ref<GLTFState> p_state, const Vector<uint8_t> &p_bytes, const String &p_file_extension, int p_index, Ref<Image> p_image) {
3166 GLTFState::GLTFHandleBinary handling = GLTFState::GLTFHandleBinary(p_state->handle_binary_image);
3167 if (p_image->is_empty() || handling == GLTFState::GLTFHandleBinary::HANDLE_BINARY_DISCARD_TEXTURES) {
3168 p_state->images.push_back(Ref<Texture2D>());
3169 p_state->source_images.push_back(Ref<Image>());
3170 return;
3171 }
3172#ifdef TOOLS_ENABLED
3173 if (Engine::get_singleton()->is_editor_hint() && handling == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EXTRACT_TEXTURES) {
3174 if (p_state->base_path.is_empty()) {
3175 p_state->images.push_back(Ref<Texture2D>());
3176 p_state->source_images.push_back(Ref<Image>());
3177 } else if (p_image->get_name().is_empty()) {
3178 WARN_PRINT(vformat("glTF: Image index '%d' couldn't be named. Skipping it.", p_index));
3179 p_state->images.push_back(Ref<Texture2D>());
3180 p_state->source_images.push_back(Ref<Image>());
3181 } else {
3182 bool must_import = true;
3183 Vector<uint8_t> img_data = p_image->get_data();
3184 Dictionary generator_parameters;
3185 String file_path = p_state->get_base_path() + "/" + p_state->filename.get_basename() + "_" + p_image->get_name();
3186 file_path += p_file_extension.is_empty() ? ".png" : p_file_extension;
3187 if (FileAccess::exists(file_path + ".import")) {
3188 Ref<ConfigFile> config;
3189 config.instantiate();
3190 config->load(file_path + ".import");
3191 if (config->has_section_key("remap", "generator_parameters")) {
3192 generator_parameters = (Dictionary)config->get_value("remap", "generator_parameters");
3193 }
3194 if (!generator_parameters.has("md5")) {
3195 must_import = false; // Didn't come from a gltf document; don't overwrite.
3196 }
3197 String existing_md5 = generator_parameters["md5"];
3198 unsigned char md5_hash[16];
3199 CryptoCore::md5(img_data.ptr(), img_data.size(), md5_hash);
3200 String new_md5 = String::hex_encode_buffer(md5_hash, 16);
3201 generator_parameters["md5"] = new_md5;
3202 if (new_md5 == existing_md5) {
3203 must_import = false;
3204 }
3205 }
3206 if (must_import) {
3207 Error err = OK;
3208 if (p_file_extension.is_empty()) {
3209 // If a file extension was not specified, save the image data to a PNG file.
3210 err = p_image->save_png(file_path);
3211 ERR_FAIL_COND(err != OK);
3212 } else {
3213 // If a file extension was specified, save the original bytes to a file with that extension.
3214 Ref<FileAccess> file = FileAccess::open(file_path, FileAccess::WRITE, &err);
3215 ERR_FAIL_COND(err != OK);
3216 file->store_buffer(p_bytes);
3217 file->close();
3218 }
3219 // ResourceLoader::import will crash if not is_editor_hint(), so this case is protected above and will fall through to uncompressed.
3220 HashMap<StringName, Variant> custom_options;
3221 custom_options[SNAME("mipmaps/generate")] = true;
3222 // Will only use project settings defaults if custom_importer is empty.
3223 EditorFileSystem::get_singleton()->update_file(file_path);
3224 EditorFileSystem::get_singleton()->reimport_append(file_path, custom_options, String(), generator_parameters);
3225 }
3226 Ref<Texture2D> saved_image = ResourceLoader::load(file_path, "Texture2D");
3227 if (saved_image.is_valid()) {
3228 p_state->images.push_back(saved_image);
3229 p_state->source_images.push_back(saved_image->get_image());
3230 } else {
3231 WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded with the name: %s. Skipping it.", p_index, p_image->get_name()));
3232 // Placeholder to keep count.
3233 p_state->images.push_back(Ref<Texture2D>());
3234 p_state->source_images.push_back(Ref<Image>());
3235 }
3236 }
3237 return;
3238 }
3239#endif // TOOLS_ENABLED
3240 if (handling == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EMBED_AS_BASISU) {
3241 Ref<PortableCompressedTexture2D> tex;
3242 tex.instantiate();
3243 tex->set_name(p_image->get_name());
3244 tex->set_keep_compressed_buffer(true);
3245 tex->create_from_image(p_image, PortableCompressedTexture2D::COMPRESSION_MODE_BASIS_UNIVERSAL);
3246 p_state->images.push_back(tex);
3247 p_state->source_images.push_back(p_image);
3248 return;
3249 }
3250 // This handles the case of HANDLE_BINARY_EMBED_AS_UNCOMPRESSED, and it also serves
3251 // as a fallback for HANDLE_BINARY_EXTRACT_TEXTURES when this is not the editor.
3252 Ref<ImageTexture> tex;
3253 tex.instantiate();
3254 tex->set_name(p_image->get_name());
3255 tex->set_image(p_image);
3256 p_state->images.push_back(tex);
3257 p_state->source_images.push_back(p_image);
3258}
3259
3260Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_path) {
3261 ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
3262 if (!p_state->json.has("images")) {
3263 return OK;
3264 }
3265
3266 // Ref: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#images
3267
3268 const Array &images = p_state->json["images"];
3269 HashSet<String> used_names;
3270 for (int i = 0; i < images.size(); i++) {
3271 const Dictionary &dict = images[i];
3272
3273 // glTF 2.0 supports PNG and JPEG types, which can be specified as (from spec):
3274 // "- a URI to an external file in one of the supported images formats, or
3275 // - a URI with embedded base64-encoded data, or
3276 // - a reference to a bufferView; in that case mimeType must be defined."
3277 // Since mimeType is optional for external files and base64 data, we'll have to
3278 // fall back on letting Godot parse the data to figure out if it's PNG or JPEG.
3279
3280 // We'll assume that we use either URI or bufferView, so let's warn the user
3281 // if their image somehow uses both. And fail if it has neither.
3282 ERR_CONTINUE_MSG(!dict.has("uri") && !dict.has("bufferView"), "Invalid image definition in glTF file, it should specify an 'uri' or 'bufferView'.");
3283 if (dict.has("uri") && dict.has("bufferView")) {
3284 WARN_PRINT("Invalid image definition in glTF file using both 'uri' and 'bufferView'. 'uri' will take precedence.");
3285 }
3286
3287 String mime_type;
3288 if (dict.has("mimeType")) { // Should be "image/png", "image/jpeg", or something handled by an extension.
3289 mime_type = dict["mimeType"];
3290 }
3291
3292 String image_name;
3293 if (dict.has("name")) {
3294 image_name = dict["name"];
3295 image_name = image_name.get_file().get_basename().validate_filename();
3296 }
3297 if (image_name.is_empty()) {
3298 image_name = itos(i);
3299 }
3300 while (used_names.has(image_name)) {
3301 image_name += "_" + itos(i);
3302 }
3303 used_names.insert(image_name);
3304 // Load the image data. If we get a byte array, store here for later.
3305 Vector<uint8_t> data;
3306 if (dict.has("uri")) {
3307 // Handles the first two bullet points from the spec (embedded data, or external file).
3308 String uri = dict["uri"];
3309 if (uri.begins_with("data:")) { // Embedded data using base64.
3310 data = _parse_base64_uri(uri);
3311 // mimeType is optional, but if we have it defined in the URI, let's use it.
3312 if (mime_type.is_empty() && uri.contains(";")) {
3313 // Trim "data:" prefix which is 5 characters long, and end at ";base64".
3314 mime_type = uri.substr(5, uri.find(";base64") - 5);
3315 }
3316 } else { // Relative path to an external image file.
3317 ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER);
3318 uri = uri.uri_decode();
3319 uri = p_base_path.path_join(uri).replace("\\", "/"); // Fix for Windows.
3320 // ResourceLoader will rely on the file extension to use the relevant loader.
3321 // The spec says that if mimeType is defined, it should take precedence (e.g.
3322 // there could be a `.png` image which is actually JPEG), but there's no easy
3323 // API for that in Godot, so we'd have to load as a buffer (i.e. embedded in
3324 // the material), so we only do that only as fallback.
3325 Ref<Texture2D> texture = ResourceLoader::load(uri);
3326 if (texture.is_valid()) {
3327 p_state->images.push_back(texture);
3328 p_state->source_images.push_back(texture->get_image());
3329 continue;
3330 }
3331 // mimeType is optional, but if we have it in the file extension, let's use it.
3332 // If the mimeType does not match with the file extension, either it should be
3333 // specified in the file, or the GLTFDocumentExtension should handle it.
3334 if (mime_type.is_empty()) {
3335 mime_type = "image/" + uri.get_extension();
3336 }
3337 // Fallback to loading as byte array. This enables us to support the
3338 // spec's requirement that we honor mimetype regardless of file URI.
3339 data = FileAccess::get_file_as_bytes(uri);
3340 if (data.size() == 0) {
3341 WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded as a buffer of MIME type '%s' from URI: %s because there was no data to load. Skipping it.", i, mime_type, uri));
3342 p_state->images.push_back(Ref<Texture2D>()); // Placeholder to keep count.
3343 p_state->source_images.push_back(Ref<Image>());
3344 continue;
3345 }
3346 }
3347 } else if (dict.has("bufferView")) {
3348 // Handles the third bullet point from the spec (bufferView).
3349 ERR_FAIL_COND_V_MSG(mime_type.is_empty(), ERR_FILE_CORRUPT, vformat("glTF: Image index '%d' specifies 'bufferView' but no 'mimeType', which is invalid.", i));
3350 const GLTFBufferViewIndex bvi = dict["bufferView"];
3351 ERR_FAIL_INDEX_V(bvi, p_state->buffer_views.size(), ERR_PARAMETER_RANGE_ERROR);
3352 Ref<GLTFBufferView> bv = p_state->buffer_views[bvi];
3353 const GLTFBufferIndex bi = bv->buffer;
3354 ERR_FAIL_INDEX_V(bi, p_state->buffers.size(), ERR_PARAMETER_RANGE_ERROR);
3355 ERR_FAIL_COND_V(bv->byte_offset + bv->byte_length > p_state->buffers[bi].size(), ERR_FILE_CORRUPT);
3356 const PackedByteArray &buffer = p_state->buffers[bi];
3357 data = buffer.slice(bv->byte_offset, bv->byte_offset + bv->byte_length);
3358 }
3359 // Done loading the image data bytes. Check that we actually got data to parse.
3360 // Note: There are paths above that return early, so this point might not be reached.
3361 if (data.is_empty()) {
3362 WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded, no data found. Skipping it.", i));
3363 p_state->images.push_back(Ref<Texture2D>()); // Placeholder to keep count.
3364 p_state->source_images.push_back(Ref<Image>());
3365 continue;
3366 }
3367 // Parse the image data from bytes into an Image resource and save if needed.
3368 String file_extension;
3369 Ref<Image> img = _parse_image_bytes_into_image(p_state, data, mime_type, i, file_extension);
3370 img->set_name(image_name);
3371 _parse_image_save_image(p_state, data, file_extension, i, img);
3372 }
3373
3374 print_verbose("glTF: Total images: " + itos(p_state->images.size()));
3375
3376 return OK;
3377}
3378
3379Error GLTFDocument::_serialize_textures(Ref<GLTFState> p_state) {
3380 if (!p_state->textures.size()) {
3381 return OK;
3382 }
3383
3384 Array textures;
3385 for (int32_t i = 0; i < p_state->textures.size(); i++) {
3386 Dictionary texture_dict;
3387 Ref<GLTFTexture> gltf_texture = p_state->textures[i];
3388 if (_image_save_extension.is_valid()) {
3389 Error err = _image_save_extension->serialize_texture_json(p_state, texture_dict, gltf_texture, _image_format);
3390 ERR_FAIL_COND_V(err != OK, err);
3391 } else {
3392 ERR_CONTINUE(gltf_texture->get_src_image() == -1);
3393 texture_dict["source"] = gltf_texture->get_src_image();
3394 }
3395 GLTFTextureSamplerIndex sampler_index = gltf_texture->get_sampler();
3396 if (sampler_index != -1) {
3397 texture_dict["sampler"] = sampler_index;
3398 }
3399 textures.push_back(texture_dict);
3400 }
3401 p_state->json["textures"] = textures;
3402
3403 return OK;
3404}
3405
3406Error GLTFDocument::_parse_textures(Ref<GLTFState> p_state) {
3407 if (!p_state->json.has("textures")) {
3408 return OK;
3409 }
3410
3411 const Array &textures = p_state->json["textures"];
3412 for (GLTFTextureIndex i = 0; i < textures.size(); i++) {
3413 const Dictionary &texture_dict = textures[i];
3414 Ref<GLTFTexture> gltf_texture;
3415 gltf_texture.instantiate();
3416 // Check if any GLTFDocumentExtensions want to handle this texture JSON.
3417 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
3418 ERR_CONTINUE(ext.is_null());
3419 Error err = ext->parse_texture_json(p_state, texture_dict, gltf_texture);
3420 ERR_CONTINUE_MSG(err != OK, "GLTF: Encountered error " + itos(err) + " when parsing texture JSON " + String(Variant(texture_dict)) + " in file " + p_state->filename + ". Continuing.");
3421 if (gltf_texture->get_src_image() != -1) {
3422 break;
3423 }
3424 }
3425 if (gltf_texture->get_src_image() == -1) {
3426 // No extensions handled it, so use the base GLTF source.
3427 // This may be the fallback, or the only option anyway.
3428 ERR_FAIL_COND_V(!texture_dict.has("source"), ERR_PARSE_ERROR);
3429 gltf_texture->set_src_image(texture_dict["source"]);
3430 }
3431 if (gltf_texture->get_sampler() == -1 && texture_dict.has("sampler")) {
3432 gltf_texture->set_sampler(texture_dict["sampler"]);
3433 }
3434 p_state->textures.push_back(gltf_texture);
3435 }
3436
3437 return OK;
3438}
3439
3440GLTFTextureIndex GLTFDocument::_set_texture(Ref<GLTFState> p_state, Ref<Texture2D> p_texture, StandardMaterial3D::TextureFilter p_filter_mode, bool p_repeats) {
3441 ERR_FAIL_COND_V(p_texture.is_null(), -1);
3442 Ref<GLTFTexture> gltf_texture;
3443 gltf_texture.instantiate();
3444 ERR_FAIL_COND_V(p_texture->get_image().is_null(), -1);
3445 GLTFImageIndex gltf_src_image_i = p_state->images.size();
3446 p_state->images.push_back(p_texture);
3447 p_state->source_images.push_back(p_texture->get_image());
3448 gltf_texture->set_src_image(gltf_src_image_i);
3449 gltf_texture->set_sampler(_set_sampler_for_mode(p_state, p_filter_mode, p_repeats));
3450 GLTFTextureIndex gltf_texture_i = p_state->textures.size();
3451 p_state->textures.push_back(gltf_texture);
3452 return gltf_texture_i;
3453}
3454
3455Ref<Texture2D> GLTFDocument::_get_texture(Ref<GLTFState> p_state, const GLTFTextureIndex p_texture, int p_texture_types) {
3456 ERR_FAIL_INDEX_V(p_texture, p_state->textures.size(), Ref<Texture2D>());
3457 const GLTFImageIndex image = p_state->textures[p_texture]->get_src_image();
3458 ERR_FAIL_INDEX_V(image, p_state->images.size(), Ref<Texture2D>());
3459 if (GLTFState::GLTFHandleBinary(p_state->handle_binary_image) == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EMBED_AS_BASISU) {
3460 ERR_FAIL_INDEX_V(image, p_state->source_images.size(), Ref<Texture2D>());
3461 Ref<PortableCompressedTexture2D> portable_texture;
3462 portable_texture.instantiate();
3463 portable_texture->set_keep_compressed_buffer(true);
3464 Ref<Image> new_img = p_state->source_images[image]->duplicate();
3465 ERR_FAIL_COND_V(new_img.is_null(), Ref<Texture2D>());
3466 new_img->generate_mipmaps();
3467 if (p_texture_types) {
3468 portable_texture->create_from_image(new_img, PortableCompressedTexture2D::COMPRESSION_MODE_BASIS_UNIVERSAL, true);
3469 } else {
3470 portable_texture->create_from_image(new_img, PortableCompressedTexture2D::COMPRESSION_MODE_BASIS_UNIVERSAL, false);
3471 }
3472 p_state->images.write[image] = portable_texture;
3473 p_state->source_images.write[image] = new_img;
3474 }
3475 return p_state->images[image];
3476}
3477
3478GLTFTextureSamplerIndex GLTFDocument::_set_sampler_for_mode(Ref<GLTFState> p_state, StandardMaterial3D::TextureFilter p_filter_mode, bool p_repeats) {
3479 for (int i = 0; i < p_state->texture_samplers.size(); ++i) {
3480 if (p_state->texture_samplers[i]->get_filter_mode() == p_filter_mode) {
3481 return i;
3482 }
3483 }
3484
3485 GLTFTextureSamplerIndex gltf_sampler_i = p_state->texture_samplers.size();
3486 Ref<GLTFTextureSampler> gltf_sampler;
3487 gltf_sampler.instantiate();
3488 gltf_sampler->set_filter_mode(p_filter_mode);
3489 gltf_sampler->set_wrap_mode(p_repeats);
3490 p_state->texture_samplers.push_back(gltf_sampler);
3491 return gltf_sampler_i;
3492}
3493
3494Ref<GLTFTextureSampler> GLTFDocument::_get_sampler_for_texture(Ref<GLTFState> p_state, const GLTFTextureIndex p_texture) {
3495 ERR_FAIL_INDEX_V(p_texture, p_state->textures.size(), Ref<Texture2D>());
3496 const GLTFTextureSamplerIndex sampler = p_state->textures[p_texture]->get_sampler();
3497
3498 if (sampler == -1) {
3499 return p_state->default_texture_sampler;
3500 } else {
3501 ERR_FAIL_INDEX_V(sampler, p_state->texture_samplers.size(), Ref<GLTFTextureSampler>());
3502
3503 return p_state->texture_samplers[sampler];
3504 }
3505}
3506
3507Error GLTFDocument::_serialize_texture_samplers(Ref<GLTFState> p_state) {
3508 if (!p_state->texture_samplers.size()) {
3509 return OK;
3510 }
3511
3512 Array samplers;
3513 for (int32_t i = 0; i < p_state->texture_samplers.size(); ++i) {
3514 Dictionary d;
3515 Ref<GLTFTextureSampler> s = p_state->texture_samplers[i];
3516 d["magFilter"] = s->get_mag_filter();
3517 d["minFilter"] = s->get_min_filter();
3518 d["wrapS"] = s->get_wrap_s();
3519 d["wrapT"] = s->get_wrap_t();
3520 samplers.push_back(d);
3521 }
3522 p_state->json["samplers"] = samplers;
3523
3524 return OK;
3525}
3526
3527Error GLTFDocument::_parse_texture_samplers(Ref<GLTFState> p_state) {
3528 p_state->default_texture_sampler.instantiate();
3529 p_state->default_texture_sampler->set_min_filter(GLTFTextureSampler::FilterMode::LINEAR_MIPMAP_LINEAR);
3530 p_state->default_texture_sampler->set_mag_filter(GLTFTextureSampler::FilterMode::LINEAR);
3531 p_state->default_texture_sampler->set_wrap_s(GLTFTextureSampler::WrapMode::REPEAT);
3532 p_state->default_texture_sampler->set_wrap_t(GLTFTextureSampler::WrapMode::REPEAT);
3533
3534 if (!p_state->json.has("samplers")) {
3535 return OK;
3536 }
3537
3538 const Array &samplers = p_state->json["samplers"];
3539 for (int i = 0; i < samplers.size(); ++i) {
3540 const Dictionary &d = samplers[i];
3541
3542 Ref<GLTFTextureSampler> sampler;
3543 sampler.instantiate();
3544
3545 if (d.has("minFilter")) {
3546 sampler->set_min_filter(d["minFilter"]);
3547 } else {
3548 sampler->set_min_filter(GLTFTextureSampler::FilterMode::LINEAR_MIPMAP_LINEAR);
3549 }
3550 if (d.has("magFilter")) {
3551 sampler->set_mag_filter(d["magFilter"]);
3552 } else {
3553 sampler->set_mag_filter(GLTFTextureSampler::FilterMode::LINEAR);
3554 }
3555
3556 if (d.has("wrapS")) {
3557 sampler->set_wrap_s(d["wrapS"]);
3558 } else {
3559 sampler->set_wrap_s(GLTFTextureSampler::WrapMode::DEFAULT);
3560 }
3561
3562 if (d.has("wrapT")) {
3563 sampler->set_wrap_t(d["wrapT"]);
3564 } else {
3565 sampler->set_wrap_t(GLTFTextureSampler::WrapMode::DEFAULT);
3566 }
3567
3568 p_state->texture_samplers.push_back(sampler);
3569 }
3570
3571 return OK;
3572}
3573
3574Error GLTFDocument::_serialize_materials(Ref<GLTFState> p_state) {
3575 Array materials;
3576 for (int32_t i = 0; i < p_state->materials.size(); i++) {
3577 Dictionary d;
3578 Ref<Material> material = p_state->materials[i];
3579 if (material.is_null()) {
3580 materials.push_back(d);
3581 continue;
3582 }
3583 if (!material->get_name().is_empty()) {
3584 d["name"] = _gen_unique_name(p_state, material->get_name());
3585 }
3586
3587 Ref<BaseMaterial3D> base_material = material;
3588 if (base_material.is_null()) {
3589 materials.push_back(d);
3590 continue;
3591 }
3592
3593 Dictionary mr;
3594 {
3595 Array arr;
3596 const Color c = base_material->get_albedo().srgb_to_linear();
3597 arr.push_back(c.r);
3598 arr.push_back(c.g);
3599 arr.push_back(c.b);
3600 arr.push_back(c.a);
3601 mr["baseColorFactor"] = arr;
3602 }
3603 if (_image_format != "None") {
3604 Dictionary bct;
3605 Ref<Texture2D> albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO);
3606 GLTFTextureIndex gltf_texture_index = -1;
3607
3608 if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) {
3609 albedo_texture->set_name(material->get_name() + "_albedo");
3610 gltf_texture_index = _set_texture(p_state, albedo_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
3611 }
3612 if (gltf_texture_index != -1) {
3613 bct["index"] = gltf_texture_index;
3614 Dictionary extensions = _serialize_texture_transform_uv1(material);
3615 if (!extensions.is_empty()) {
3616 bct["extensions"] = extensions;
3617 p_state->use_khr_texture_transform = true;
3618 }
3619 mr["baseColorTexture"] = bct;
3620 }
3621 }
3622
3623 mr["metallicFactor"] = base_material->get_metallic();
3624 mr["roughnessFactor"] = base_material->get_roughness();
3625 bool has_roughness = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS)->get_image().is_valid();
3626 bool has_ao = base_material->get_feature(BaseMaterial3D::FEATURE_AMBIENT_OCCLUSION) && base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION).is_valid();
3627 bool has_metalness = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC)->get_image().is_valid();
3628 if (has_ao || has_roughness || has_metalness) {
3629 Dictionary mrt;
3630 Ref<Texture2D> roughness_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS);
3631 BaseMaterial3D::TextureChannel roughness_channel = base_material->get_roughness_texture_channel();
3632 Ref<Texture2D> metallic_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC);
3633 BaseMaterial3D::TextureChannel metalness_channel = base_material->get_metallic_texture_channel();
3634 Ref<Texture2D> ao_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION);
3635 BaseMaterial3D::TextureChannel ao_channel = base_material->get_ao_texture_channel();
3636 Ref<ImageTexture> orm_texture;
3637 orm_texture.instantiate();
3638 Ref<Image> orm_image;
3639 orm_image.instantiate();
3640 int32_t height = 0;
3641 int32_t width = 0;
3642 Ref<Image> ao_image;
3643 if (has_ao) {
3644 height = ao_texture->get_height();
3645 width = ao_texture->get_width();
3646 ao_image = ao_texture->get_image();
3647 Ref<ImageTexture> img_tex = ao_image;
3648 if (img_tex.is_valid()) {
3649 ao_image = img_tex->get_image();
3650 }
3651 if (ao_image->is_compressed()) {
3652 ao_image->decompress();
3653 }
3654 }
3655 Ref<Image> roughness_image;
3656 if (has_roughness) {
3657 height = roughness_texture->get_height();
3658 width = roughness_texture->get_width();
3659 roughness_image = roughness_texture->get_image();
3660 Ref<ImageTexture> img_tex = roughness_image;
3661 if (img_tex.is_valid()) {
3662 roughness_image = img_tex->get_image();
3663 }
3664 if (roughness_image->is_compressed()) {
3665 roughness_image->decompress();
3666 }
3667 }
3668 Ref<Image> metallness_image;
3669 if (has_metalness) {
3670 height = metallic_texture->get_height();
3671 width = metallic_texture->get_width();
3672 metallness_image = metallic_texture->get_image();
3673 Ref<ImageTexture> img_tex = metallness_image;
3674 if (img_tex.is_valid()) {
3675 metallness_image = img_tex->get_image();
3676 }
3677 if (metallness_image->is_compressed()) {
3678 metallness_image->decompress();
3679 }
3680 }
3681 Ref<Texture2D> albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO);
3682 if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) {
3683 height = albedo_texture->get_height();
3684 width = albedo_texture->get_width();
3685 }
3686 orm_image->initialize_data(width, height, false, Image::FORMAT_RGBA8);
3687 if (ao_image.is_valid() && ao_image->get_size() != Vector2(width, height)) {
3688 ao_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
3689 }
3690 if (roughness_image.is_valid() && roughness_image->get_size() != Vector2(width, height)) {
3691 roughness_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
3692 }
3693 if (metallness_image.is_valid() && metallness_image->get_size() != Vector2(width, height)) {
3694 metallness_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
3695 }
3696 for (int32_t h = 0; h < height; h++) {
3697 for (int32_t w = 0; w < width; w++) {
3698 Color c = Color(1.0f, 1.0f, 1.0f);
3699 if (has_ao) {
3700 if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == ao_channel) {
3701 c.r = ao_image->get_pixel(w, h).r;
3702 } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == ao_channel) {
3703 c.r = ao_image->get_pixel(w, h).g;
3704 } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == ao_channel) {
3705 c.r = ao_image->get_pixel(w, h).b;
3706 } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == ao_channel) {
3707 c.r = ao_image->get_pixel(w, h).a;
3708 }
3709 }
3710 if (has_roughness) {
3711 if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == roughness_channel) {
3712 c.g = roughness_image->get_pixel(w, h).r;
3713 } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == roughness_channel) {
3714 c.g = roughness_image->get_pixel(w, h).g;
3715 } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == roughness_channel) {
3716 c.g = roughness_image->get_pixel(w, h).b;
3717 } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == roughness_channel) {
3718 c.g = roughness_image->get_pixel(w, h).a;
3719 }
3720 }
3721 if (has_metalness) {
3722 if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == metalness_channel) {
3723 c.b = metallness_image->get_pixel(w, h).r;
3724 } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == metalness_channel) {
3725 c.b = metallness_image->get_pixel(w, h).g;
3726 } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == metalness_channel) {
3727 c.b = metallness_image->get_pixel(w, h).b;
3728 } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == metalness_channel) {
3729 c.b = metallness_image->get_pixel(w, h).a;
3730 }
3731 }
3732 orm_image->set_pixel(w, h, c);
3733 }
3734 }
3735 orm_image->generate_mipmaps();
3736 orm_texture->set_image(orm_image);
3737 GLTFTextureIndex orm_texture_index = -1;
3738 if (has_ao || has_roughness || has_metalness) {
3739 orm_texture->set_name(material->get_name() + "_orm");
3740 orm_texture_index = _set_texture(p_state, orm_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
3741 }
3742 if (has_ao) {
3743 Dictionary occt;
3744 occt["index"] = orm_texture_index;
3745 d["occlusionTexture"] = occt;
3746 }
3747 if (has_roughness || has_metalness) {
3748 mrt["index"] = orm_texture_index;
3749 Dictionary extensions = _serialize_texture_transform_uv1(material);
3750 if (!extensions.is_empty()) {
3751 mrt["extensions"] = extensions;
3752 p_state->use_khr_texture_transform = true;
3753 }
3754 mr["metallicRoughnessTexture"] = mrt;
3755 }
3756 }
3757
3758 d["pbrMetallicRoughness"] = mr;
3759 if (base_material->get_feature(BaseMaterial3D::FEATURE_NORMAL_MAPPING)) {
3760 Dictionary nt;
3761 Ref<ImageTexture> tex;
3762 tex.instantiate();
3763 {
3764 Ref<Texture2D> normal_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_NORMAL);
3765 if (normal_texture.is_valid()) {
3766 // Code for uncompressing RG normal maps
3767 Ref<Image> img = normal_texture->get_image();
3768 if (img.is_valid()) {
3769 Ref<ImageTexture> img_tex = img;
3770 if (img_tex.is_valid()) {
3771 img = img_tex->get_image();
3772 }
3773 img->decompress();
3774 img->convert(Image::FORMAT_RGBA8);
3775 img->convert_ra_rgba8_to_rg();
3776 for (int32_t y = 0; y < img->get_height(); y++) {
3777 for (int32_t x = 0; x < img->get_width(); x++) {
3778 Color c = img->get_pixel(x, y);
3779 Vector2 red_green = Vector2(c.r, c.g);
3780 red_green = red_green * Vector2(2.0f, 2.0f) - Vector2(1.0f, 1.0f);
3781 float blue = 1.0f - red_green.dot(red_green);
3782 blue = MAX(0.0f, blue);
3783 c.b = Math::sqrt(blue);
3784 img->set_pixel(x, y, c);
3785 }
3786 }
3787 tex->set_image(img);
3788 }
3789 }
3790 }
3791 GLTFTextureIndex gltf_texture_index = -1;
3792 if (tex.is_valid() && tex->get_image().is_valid()) {
3793 tex->set_name(material->get_name() + "_normal");
3794 gltf_texture_index = _set_texture(p_state, tex, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
3795 }
3796 nt["scale"] = base_material->get_normal_scale();
3797 if (gltf_texture_index != -1) {
3798 nt["index"] = gltf_texture_index;
3799 d["normalTexture"] = nt;
3800 }
3801 }
3802
3803 if (base_material->get_feature(BaseMaterial3D::FEATURE_EMISSION)) {
3804 const Color c = base_material->get_emission().linear_to_srgb();
3805 Array arr;
3806 arr.push_back(c.r);
3807 arr.push_back(c.g);
3808 arr.push_back(c.b);
3809 d["emissiveFactor"] = arr;
3810 }
3811
3812 if (base_material->get_feature(BaseMaterial3D::FEATURE_EMISSION)) {
3813 Dictionary et;
3814 Ref<Texture2D> emission_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_EMISSION);
3815 GLTFTextureIndex gltf_texture_index = -1;
3816 if (emission_texture.is_valid() && emission_texture->get_image().is_valid()) {
3817 emission_texture->set_name(material->get_name() + "_emission");
3818 gltf_texture_index = _set_texture(p_state, emission_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
3819 }
3820
3821 if (gltf_texture_index != -1) {
3822 et["index"] = gltf_texture_index;
3823 d["emissiveTexture"] = et;
3824 }
3825 }
3826
3827 const bool ds = base_material->get_cull_mode() == BaseMaterial3D::CULL_DISABLED;
3828 if (ds) {
3829 d["doubleSided"] = ds;
3830 }
3831
3832 if (base_material->get_transparency() == BaseMaterial3D::TRANSPARENCY_ALPHA_SCISSOR) {
3833 d["alphaMode"] = "MASK";
3834 d["alphaCutoff"] = base_material->get_alpha_scissor_threshold();
3835 } else if (base_material->get_transparency() != BaseMaterial3D::TRANSPARENCY_DISABLED) {
3836 d["alphaMode"] = "BLEND";
3837 }
3838
3839 Dictionary extensions;
3840 if (base_material->get_shading_mode() == BaseMaterial3D::SHADING_MODE_UNSHADED) {
3841 Dictionary mat_unlit;
3842 extensions["KHR_materials_unlit"] = mat_unlit;
3843 p_state->add_used_extension("KHR_materials_unlit");
3844 }
3845 if (base_material->get_feature(BaseMaterial3D::FEATURE_EMISSION) && !Math::is_equal_approx(base_material->get_emission_energy_multiplier(), 1.0f)) {
3846 Dictionary mat_emissive_strength;
3847 mat_emissive_strength["emissiveStrength"] = base_material->get_emission_energy_multiplier();
3848 extensions["KHR_materials_emissive_strength"] = mat_emissive_strength;
3849 p_state->add_used_extension("KHR_materials_emissive_strength");
3850 }
3851 d["extensions"] = extensions;
3852
3853 materials.push_back(d);
3854 }
3855 if (!materials.size()) {
3856 return OK;
3857 }
3858 p_state->json["materials"] = materials;
3859 print_verbose("Total materials: " + itos(p_state->materials.size()));
3860
3861 return OK;
3862}
3863
3864Error GLTFDocument::_parse_materials(Ref<GLTFState> p_state) {
3865 if (!p_state->json.has("materials")) {
3866 return OK;
3867 }
3868
3869 const Array &materials = p_state->json["materials"];
3870 for (GLTFMaterialIndex i = 0; i < materials.size(); i++) {
3871 const Dictionary &material_dict = materials[i];
3872
3873 Ref<StandardMaterial3D> material;
3874 material.instantiate();
3875 if (material_dict.has("name") && !String(material_dict["name"]).is_empty()) {
3876 material->set_name(material_dict["name"]);
3877 } else {
3878 material->set_name(vformat("material_%s", itos(i)));
3879 }
3880 material->set_flag(BaseMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
3881 Dictionary material_extensions;
3882 if (material_dict.has("extensions")) {
3883 material_extensions = material_dict["extensions"];
3884 }
3885
3886 if (material_extensions.has("KHR_materials_unlit")) {
3887 material->set_shading_mode(BaseMaterial3D::SHADING_MODE_UNSHADED);
3888 }
3889
3890 if (material_extensions.has("KHR_materials_emissive_strength")) {
3891 Dictionary emissive_strength = material_extensions["KHR_materials_emissive_strength"];
3892 if (emissive_strength.has("emissiveStrength")) {
3893 material->set_emission_energy_multiplier(emissive_strength["emissiveStrength"]);
3894 }
3895 }
3896
3897 if (material_extensions.has("KHR_materials_pbrSpecularGlossiness")) {
3898 WARN_PRINT("Material uses a specular and glossiness workflow. Textures will be converted to roughness and metallic workflow, which may not be 100% accurate.");
3899 Dictionary sgm = material_extensions["KHR_materials_pbrSpecularGlossiness"];
3900
3901 Ref<GLTFSpecGloss> spec_gloss;
3902 spec_gloss.instantiate();
3903 if (sgm.has("diffuseTexture")) {
3904 const Dictionary &diffuse_texture_dict = sgm["diffuseTexture"];
3905 if (diffuse_texture_dict.has("index")) {
3906 Ref<GLTFTextureSampler> diffuse_sampler = _get_sampler_for_texture(p_state, diffuse_texture_dict["index"]);
3907 if (diffuse_sampler.is_valid()) {
3908 material->set_texture_filter(diffuse_sampler->get_filter_mode());
3909 material->set_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT, diffuse_sampler->get_wrap_mode());
3910 }
3911 Ref<Texture2D> diffuse_texture = _get_texture(p_state, diffuse_texture_dict["index"], TEXTURE_TYPE_GENERIC);
3912 if (diffuse_texture.is_valid()) {
3913 spec_gloss->diffuse_img = diffuse_texture->get_image();
3914 material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, diffuse_texture);
3915 }
3916 }
3917 }
3918 if (sgm.has("diffuseFactor")) {
3919 const Array &arr = sgm["diffuseFactor"];
3920 ERR_FAIL_COND_V(arr.size() != 4, ERR_PARSE_ERROR);
3921 const Color c = Color(arr[0], arr[1], arr[2], arr[3]).linear_to_srgb();
3922 spec_gloss->diffuse_factor = c;
3923 material->set_albedo(spec_gloss->diffuse_factor);
3924 }
3925
3926 if (sgm.has("specularFactor")) {
3927 const Array &arr = sgm["specularFactor"];
3928 ERR_FAIL_COND_V(arr.size() != 3, ERR_PARSE_ERROR);
3929 spec_gloss->specular_factor = Color(arr[0], arr[1], arr[2]);
3930 }
3931
3932 if (sgm.has("glossinessFactor")) {
3933 spec_gloss->gloss_factor = sgm["glossinessFactor"];
3934 material->set_roughness(1.0f - CLAMP(spec_gloss->gloss_factor, 0.0f, 1.0f));
3935 }
3936 if (sgm.has("specularGlossinessTexture")) {
3937 const Dictionary &spec_gloss_texture = sgm["specularGlossinessTexture"];
3938 if (spec_gloss_texture.has("index")) {
3939 const Ref<Texture2D> orig_texture = _get_texture(p_state, spec_gloss_texture["index"], TEXTURE_TYPE_GENERIC);
3940 if (orig_texture.is_valid()) {
3941 spec_gloss->spec_gloss_img = orig_texture->get_image();
3942 }
3943 }
3944 }
3945 spec_gloss_to_rough_metal(spec_gloss, material);
3946
3947 } else if (material_dict.has("pbrMetallicRoughness")) {
3948 const Dictionary &mr = material_dict["pbrMetallicRoughness"];
3949 if (mr.has("baseColorFactor")) {
3950 const Array &arr = mr["baseColorFactor"];
3951 ERR_FAIL_COND_V(arr.size() != 4, ERR_PARSE_ERROR);
3952 const Color c = Color(arr[0], arr[1], arr[2], arr[3]).linear_to_srgb();
3953 material->set_albedo(c);
3954 }
3955
3956 if (mr.has("baseColorTexture")) {
3957 const Dictionary &bct = mr["baseColorTexture"];
3958 if (bct.has("index")) {
3959 Ref<GLTFTextureSampler> bct_sampler = _get_sampler_for_texture(p_state, bct["index"]);
3960 material->set_texture_filter(bct_sampler->get_filter_mode());
3961 material->set_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT, bct_sampler->get_wrap_mode());
3962 material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, _get_texture(p_state, bct["index"], TEXTURE_TYPE_GENERIC));
3963 }
3964 if (!mr.has("baseColorFactor")) {
3965 material->set_albedo(Color(1, 1, 1));
3966 }
3967 _set_texture_transform_uv1(bct, material);
3968 }
3969
3970 if (mr.has("metallicFactor")) {
3971 material->set_metallic(mr["metallicFactor"]);
3972 } else {
3973 material->set_metallic(1.0);
3974 }
3975
3976 if (mr.has("roughnessFactor")) {
3977 material->set_roughness(mr["roughnessFactor"]);
3978 } else {
3979 material->set_roughness(1.0);
3980 }
3981
3982 if (mr.has("metallicRoughnessTexture")) {
3983 const Dictionary &bct = mr["metallicRoughnessTexture"];
3984 if (bct.has("index")) {
3985 const Ref<Texture2D> t = _get_texture(p_state, bct["index"], TEXTURE_TYPE_GENERIC);
3986 material->set_texture(BaseMaterial3D::TEXTURE_METALLIC, t);
3987 material->set_metallic_texture_channel(BaseMaterial3D::TEXTURE_CHANNEL_BLUE);
3988 material->set_texture(BaseMaterial3D::TEXTURE_ROUGHNESS, t);
3989 material->set_roughness_texture_channel(BaseMaterial3D::TEXTURE_CHANNEL_GREEN);
3990 if (!mr.has("metallicFactor")) {
3991 material->set_metallic(1);
3992 }
3993 if (!mr.has("roughnessFactor")) {
3994 material->set_roughness(1);
3995 }
3996 }
3997 }
3998 }
3999
4000 if (material_dict.has("normalTexture")) {
4001 const Dictionary &bct = material_dict["normalTexture"];
4002 if (bct.has("index")) {
4003 material->set_texture(BaseMaterial3D::TEXTURE_NORMAL, _get_texture(p_state, bct["index"], TEXTURE_TYPE_NORMAL));
4004 material->set_feature(BaseMaterial3D::FEATURE_NORMAL_MAPPING, true);
4005 }
4006 if (bct.has("scale")) {
4007 material->set_normal_scale(bct["scale"]);
4008 }
4009 }
4010 if (material_dict.has("occlusionTexture")) {
4011 const Dictionary &bct = material_dict["occlusionTexture"];
4012 if (bct.has("index")) {
4013 material->set_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION, _get_texture(p_state, bct["index"], TEXTURE_TYPE_GENERIC));
4014 material->set_ao_texture_channel(BaseMaterial3D::TEXTURE_CHANNEL_RED);
4015 material->set_feature(BaseMaterial3D::FEATURE_AMBIENT_OCCLUSION, true);
4016 }
4017 }
4018
4019 if (material_dict.has("emissiveFactor")) {
4020 const Array &arr = material_dict["emissiveFactor"];
4021 ERR_FAIL_COND_V(arr.size() != 3, ERR_PARSE_ERROR);
4022 const Color c = Color(arr[0], arr[1], arr[2]).linear_to_srgb();
4023 material->set_feature(BaseMaterial3D::FEATURE_EMISSION, true);
4024
4025 material->set_emission(c);
4026 }
4027
4028 if (material_dict.has("emissiveTexture")) {
4029 const Dictionary &bct = material_dict["emissiveTexture"];
4030 if (bct.has("index")) {
4031 material->set_texture(BaseMaterial3D::TEXTURE_EMISSION, _get_texture(p_state, bct["index"], TEXTURE_TYPE_GENERIC));
4032 material->set_feature(BaseMaterial3D::FEATURE_EMISSION, true);
4033 material->set_emission(Color(0, 0, 0));
4034 }
4035 }
4036
4037 if (material_dict.has("doubleSided")) {
4038 const bool ds = material_dict["doubleSided"];
4039 if (ds) {
4040 material->set_cull_mode(BaseMaterial3D::CULL_DISABLED);
4041 }
4042 }
4043 if (material_dict.has("alphaMode")) {
4044 const String &am = material_dict["alphaMode"];
4045 if (am == "BLEND") {
4046 material->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS);
4047 } else if (am == "MASK") {
4048 material->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA_SCISSOR);
4049 if (material_dict.has("alphaCutoff")) {
4050 material->set_alpha_scissor_threshold(material_dict["alphaCutoff"]);
4051 } else {
4052 material->set_alpha_scissor_threshold(0.5f);
4053 }
4054 }
4055 }
4056 p_state->materials.push_back(material);
4057 }
4058
4059 print_verbose("Total materials: " + itos(p_state->materials.size()));
4060
4061 return OK;
4062}
4063
4064void GLTFDocument::_set_texture_transform_uv1(const Dictionary &p_dict, Ref<BaseMaterial3D> p_material) {
4065 if (p_dict.has("extensions")) {
4066 const Dictionary &extensions = p_dict["extensions"];
4067 if (extensions.has("KHR_texture_transform")) {
4068 if (p_material.is_valid()) {
4069 const Dictionary &texture_transform = extensions["KHR_texture_transform"];
4070 const Array &offset_arr = texture_transform["offset"];
4071 if (offset_arr.size() == 2) {
4072 const Vector3 offset_vector3 = Vector3(offset_arr[0], offset_arr[1], 0.0f);
4073 p_material->set_uv1_offset(offset_vector3);
4074 }
4075
4076 const Array &scale_arr = texture_transform["scale"];
4077 if (scale_arr.size() == 2) {
4078 const Vector3 scale_vector3 = Vector3(scale_arr[0], scale_arr[1], 1.0f);
4079 p_material->set_uv1_scale(scale_vector3);
4080 }
4081 }
4082 }
4083 }
4084}
4085
4086void GLTFDocument::spec_gloss_to_rough_metal(Ref<GLTFSpecGloss> r_spec_gloss, Ref<BaseMaterial3D> p_material) {
4087 if (r_spec_gloss.is_null()) {
4088 return;
4089 }
4090 if (r_spec_gloss->spec_gloss_img.is_null()) {
4091 return;
4092 }
4093 if (r_spec_gloss->diffuse_img.is_null()) {
4094 return;
4095 }
4096 if (p_material.is_null()) {
4097 return;
4098 }
4099 bool has_roughness = false;
4100 bool has_metal = false;
4101 p_material->set_roughness(1.0f);
4102 p_material->set_metallic(1.0f);
4103 Ref<Image> rm_img = Image::create_empty(r_spec_gloss->spec_gloss_img->get_width(), r_spec_gloss->spec_gloss_img->get_height(), false, Image::FORMAT_RGBA8);
4104 r_spec_gloss->spec_gloss_img->decompress();
4105 if (r_spec_gloss->diffuse_img.is_valid()) {
4106 r_spec_gloss->diffuse_img->decompress();
4107 r_spec_gloss->diffuse_img->resize(r_spec_gloss->spec_gloss_img->get_width(), r_spec_gloss->spec_gloss_img->get_height(), Image::INTERPOLATE_LANCZOS);
4108 r_spec_gloss->spec_gloss_img->resize(r_spec_gloss->diffuse_img->get_width(), r_spec_gloss->diffuse_img->get_height(), Image::INTERPOLATE_LANCZOS);
4109 }
4110 for (int32_t y = 0; y < r_spec_gloss->spec_gloss_img->get_height(); y++) {
4111 for (int32_t x = 0; x < r_spec_gloss->spec_gloss_img->get_width(); x++) {
4112 const Color specular_pixel = r_spec_gloss->spec_gloss_img->get_pixel(x, y).srgb_to_linear();
4113 Color specular = Color(specular_pixel.r, specular_pixel.g, specular_pixel.b);
4114 specular *= r_spec_gloss->specular_factor;
4115 Color diffuse = Color(1.0f, 1.0f, 1.0f);
4116 diffuse *= r_spec_gloss->diffuse_img->get_pixel(x, y).srgb_to_linear();
4117 float metallic = 0.0f;
4118 Color base_color;
4119 spec_gloss_to_metal_base_color(specular, diffuse, base_color, metallic);
4120 Color mr = Color(1.0f, 1.0f, 1.0f);
4121 mr.g = specular_pixel.a;
4122 mr.b = metallic;
4123 if (!Math::is_equal_approx(mr.g, 1.0f)) {
4124 has_roughness = true;
4125 }
4126 if (!Math::is_zero_approx(mr.b)) {
4127 has_metal = true;
4128 }
4129 mr.g *= r_spec_gloss->gloss_factor;
4130 mr.g = 1.0f - mr.g;
4131 rm_img->set_pixel(x, y, mr);
4132 if (r_spec_gloss->diffuse_img.is_valid()) {
4133 r_spec_gloss->diffuse_img->set_pixel(x, y, base_color.linear_to_srgb());
4134 }
4135 }
4136 }
4137 rm_img->generate_mipmaps();
4138 r_spec_gloss->diffuse_img->generate_mipmaps();
4139 p_material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, ImageTexture::create_from_image(r_spec_gloss->diffuse_img));
4140 Ref<ImageTexture> rm_image_texture = ImageTexture::create_from_image(rm_img);
4141 if (has_roughness) {
4142 p_material->set_texture(BaseMaterial3D::TEXTURE_ROUGHNESS, rm_image_texture);
4143 p_material->set_roughness_texture_channel(BaseMaterial3D::TEXTURE_CHANNEL_GREEN);
4144 }
4145
4146 if (has_metal) {
4147 p_material->set_texture(BaseMaterial3D::TEXTURE_METALLIC, rm_image_texture);
4148 p_material->set_metallic_texture_channel(BaseMaterial3D::TEXTURE_CHANNEL_BLUE);
4149 }
4150}
4151
4152void GLTFDocument::spec_gloss_to_metal_base_color(const Color &p_specular_factor, const Color &p_diffuse, Color &r_base_color, float &r_metallic) {
4153 const Color DIELECTRIC_SPECULAR = Color(0.04f, 0.04f, 0.04f);
4154 Color specular = Color(p_specular_factor.r, p_specular_factor.g, p_specular_factor.b);
4155 const float one_minus_specular_strength = 1.0f - get_max_component(specular);
4156 const float dielectric_specular_red = DIELECTRIC_SPECULAR.r;
4157 float brightness_diffuse = get_perceived_brightness(p_diffuse);
4158 const float brightness_specular = get_perceived_brightness(specular);
4159 r_metallic = solve_metallic(dielectric_specular_red, brightness_diffuse, brightness_specular, one_minus_specular_strength);
4160 const float one_minus_metallic = 1.0f - r_metallic;
4161 const Color base_color_from_diffuse = p_diffuse * (one_minus_specular_strength / (1.0f - dielectric_specular_red) / MAX(one_minus_metallic, CMP_EPSILON));
4162 const Color base_color_from_specular = (specular - (DIELECTRIC_SPECULAR * (one_minus_metallic))) * (1.0f / MAX(r_metallic, CMP_EPSILON));
4163 r_base_color.r = Math::lerp(base_color_from_diffuse.r, base_color_from_specular.r, r_metallic * r_metallic);
4164 r_base_color.g = Math::lerp(base_color_from_diffuse.g, base_color_from_specular.g, r_metallic * r_metallic);
4165 r_base_color.b = Math::lerp(base_color_from_diffuse.b, base_color_from_specular.b, r_metallic * r_metallic);
4166 r_base_color.a = p_diffuse.a;
4167 r_base_color = r_base_color.clamp();
4168}
4169
4170GLTFNodeIndex GLTFDocument::_find_highest_node(Ref<GLTFState> p_state, const Vector<GLTFNodeIndex> &p_subset) {
4171 int highest = -1;
4172 GLTFNodeIndex best_node = -1;
4173
4174 for (int i = 0; i < p_subset.size(); ++i) {
4175 const GLTFNodeIndex node_i = p_subset[i];
4176 const Ref<GLTFNode> node = p_state->nodes[node_i];
4177
4178 if (highest == -1 || node->height < highest) {
4179 highest = node->height;
4180 best_node = node_i;
4181 }
4182 }
4183
4184 return best_node;
4185}
4186
4187bool GLTFDocument::_capture_nodes_in_skin(Ref<GLTFState> p_state, Ref<GLTFSkin> p_skin, const GLTFNodeIndex p_node_index) {
4188 bool found_joint = false;
4189
4190 for (int i = 0; i < p_state->nodes[p_node_index]->children.size(); ++i) {
4191 found_joint |= _capture_nodes_in_skin(p_state, p_skin, p_state->nodes[p_node_index]->children[i]);
4192 }
4193
4194 if (found_joint) {
4195 // Mark it if we happen to find another skins joint...
4196 if (p_state->nodes[p_node_index]->joint && p_skin->joints.find(p_node_index) < 0) {
4197 p_skin->joints.push_back(p_node_index);
4198 } else if (p_skin->non_joints.find(p_node_index) < 0) {
4199 p_skin->non_joints.push_back(p_node_index);
4200 }
4201 }
4202
4203 if (p_skin->joints.find(p_node_index) > 0) {
4204 return true;
4205 }
4206
4207 return false;
4208}
4209
4210void GLTFDocument::_capture_nodes_for_multirooted_skin(Ref<GLTFState> p_state, Ref<GLTFSkin> p_skin) {
4211 DisjointSet<GLTFNodeIndex> disjoint_set;
4212
4213 for (int i = 0; i < p_skin->joints.size(); ++i) {
4214 const GLTFNodeIndex node_index = p_skin->joints[i];
4215 const GLTFNodeIndex parent = p_state->nodes[node_index]->parent;
4216 disjoint_set.insert(node_index);
4217
4218 if (p_skin->joints.find(parent) >= 0) {
4219 disjoint_set.create_union(parent, node_index);
4220 }
4221 }
4222
4223 Vector<GLTFNodeIndex> roots;
4224 disjoint_set.get_representatives(roots);
4225
4226 if (roots.size() <= 1) {
4227 return;
4228 }
4229
4230 int maxHeight = -1;
4231
4232 // Determine the max height rooted tree
4233 for (int i = 0; i < roots.size(); ++i) {
4234 const GLTFNodeIndex root = roots[i];
4235
4236 if (maxHeight == -1 || p_state->nodes[root]->height < maxHeight) {
4237 maxHeight = p_state->nodes[root]->height;
4238 }
4239 }
4240
4241 // Go up the tree till all of the multiple roots of the skin are at the same hierarchy level.
4242 // This sucks, but 99% of all game engines (not just Godot) would have this same issue.
4243 for (int i = 0; i < roots.size(); ++i) {
4244 GLTFNodeIndex current_node = roots[i];
4245 while (p_state->nodes[current_node]->height > maxHeight) {
4246 GLTFNodeIndex parent = p_state->nodes[current_node]->parent;
4247
4248 if (p_state->nodes[parent]->joint && p_skin->joints.find(parent) < 0) {
4249 p_skin->joints.push_back(parent);
4250 } else if (p_skin->non_joints.find(parent) < 0) {
4251 p_skin->non_joints.push_back(parent);
4252 }
4253
4254 current_node = parent;
4255 }
4256
4257 // replace the roots
4258 roots.write[i] = current_node;
4259 }
4260
4261 // Climb up the tree until they all have the same parent
4262 bool all_same;
4263
4264 do {
4265 all_same = true;
4266 const GLTFNodeIndex first_parent = p_state->nodes[roots[0]]->parent;
4267
4268 for (int i = 1; i < roots.size(); ++i) {
4269 all_same &= (first_parent == p_state->nodes[roots[i]]->parent);
4270 }
4271
4272 if (!all_same) {
4273 for (int i = 0; i < roots.size(); ++i) {
4274 const GLTFNodeIndex current_node = roots[i];
4275 const GLTFNodeIndex parent = p_state->nodes[current_node]->parent;
4276
4277 if (p_state->nodes[parent]->joint && p_skin->joints.find(parent) < 0) {
4278 p_skin->joints.push_back(parent);
4279 } else if (p_skin->non_joints.find(parent) < 0) {
4280 p_skin->non_joints.push_back(parent);
4281 }
4282
4283 roots.write[i] = parent;
4284 }
4285 }
4286
4287 } while (!all_same);
4288}
4289
4290Error GLTFDocument::_expand_skin(Ref<GLTFState> p_state, Ref<GLTFSkin> p_skin) {
4291 _capture_nodes_for_multirooted_skin(p_state, p_skin);
4292
4293 // Grab all nodes that lay in between skin joints/nodes
4294 DisjointSet<GLTFNodeIndex> disjoint_set;
4295
4296 Vector<GLTFNodeIndex> all_skin_nodes;
4297 all_skin_nodes.append_array(p_skin->joints);
4298 all_skin_nodes.append_array(p_skin->non_joints);
4299
4300 for (int i = 0; i < all_skin_nodes.size(); ++i) {
4301 const GLTFNodeIndex node_index = all_skin_nodes[i];
4302 const GLTFNodeIndex parent = p_state->nodes[node_index]->parent;
4303 disjoint_set.insert(node_index);
4304
4305 if (all_skin_nodes.find(parent) >= 0) {
4306 disjoint_set.create_union(parent, node_index);
4307 }
4308 }
4309
4310 Vector<GLTFNodeIndex> out_owners;
4311 disjoint_set.get_representatives(out_owners);
4312
4313 Vector<GLTFNodeIndex> out_roots;
4314
4315 for (int i = 0; i < out_owners.size(); ++i) {
4316 Vector<GLTFNodeIndex> set;
4317 disjoint_set.get_members(set, out_owners[i]);
4318
4319 const GLTFNodeIndex root = _find_highest_node(p_state, set);
4320 ERR_FAIL_COND_V(root < 0, FAILED);
4321 out_roots.push_back(root);
4322 }
4323
4324 out_roots.sort();
4325
4326 for (int i = 0; i < out_roots.size(); ++i) {
4327 _capture_nodes_in_skin(p_state, p_skin, out_roots[i]);
4328 }
4329
4330 p_skin->roots = out_roots;
4331
4332 return OK;
4333}
4334
4335Error GLTFDocument::_verify_skin(Ref<GLTFState> p_state, Ref<GLTFSkin> p_skin) {
4336 // This may seem duplicated from expand_skins, but this is really a sanity check! (so it kinda is)
4337 // In case additional interpolating logic is added to the skins, this will help ensure that you
4338 // do not cause it to self implode into a fiery blaze
4339
4340 // We are going to re-calculate the root nodes and compare them to the ones saved in the skin,
4341 // then ensure the multiple trees (if they exist) are on the same sublevel
4342
4343 // Grab all nodes that lay in between skin joints/nodes
4344 DisjointSet<GLTFNodeIndex> disjoint_set;
4345
4346 Vector<GLTFNodeIndex> all_skin_nodes;
4347 all_skin_nodes.append_array(p_skin->joints);
4348 all_skin_nodes.append_array(p_skin->non_joints);
4349
4350 for (int i = 0; i < all_skin_nodes.size(); ++i) {
4351 const GLTFNodeIndex node_index = all_skin_nodes[i];
4352 const GLTFNodeIndex parent = p_state->nodes[node_index]->parent;
4353 disjoint_set.insert(node_index);
4354
4355 if (all_skin_nodes.find(parent) >= 0) {
4356 disjoint_set.create_union(parent, node_index);
4357 }
4358 }
4359
4360 Vector<GLTFNodeIndex> out_owners;
4361 disjoint_set.get_representatives(out_owners);
4362
4363 Vector<GLTFNodeIndex> out_roots;
4364
4365 for (int i = 0; i < out_owners.size(); ++i) {
4366 Vector<GLTFNodeIndex> set;
4367 disjoint_set.get_members(set, out_owners[i]);
4368
4369 const GLTFNodeIndex root = _find_highest_node(p_state, set);
4370 ERR_FAIL_COND_V(root < 0, FAILED);
4371 out_roots.push_back(root);
4372 }
4373
4374 out_roots.sort();
4375
4376 ERR_FAIL_COND_V(out_roots.size() == 0, FAILED);
4377
4378 // Make sure the roots are the exact same (they better be)
4379 ERR_FAIL_COND_V(out_roots.size() != p_skin->roots.size(), FAILED);
4380 for (int i = 0; i < out_roots.size(); ++i) {
4381 ERR_FAIL_COND_V(out_roots[i] != p_skin->roots[i], FAILED);
4382 }
4383
4384 // Single rooted skin? Perfectly ok!
4385 if (out_roots.size() == 1) {
4386 return OK;
4387 }
4388
4389 // Make sure all parents of a multi-rooted skin are the SAME
4390 const GLTFNodeIndex parent = p_state->nodes[out_roots[0]]->parent;
4391 for (int i = 1; i < out_roots.size(); ++i) {
4392 if (p_state->nodes[out_roots[i]]->parent != parent) {
4393 return FAILED;
4394 }
4395 }
4396
4397 return OK;
4398}
4399
4400Error GLTFDocument::_parse_skins(Ref<GLTFState> p_state) {
4401 if (!p_state->json.has("skins")) {
4402 return OK;
4403 }
4404
4405 const Array &skins = p_state->json["skins"];
4406
4407 // Create the base skins, and mark nodes that are joints
4408 for (int i = 0; i < skins.size(); i++) {
4409 const Dictionary &d = skins[i];
4410
4411 Ref<GLTFSkin> skin;
4412 skin.instantiate();
4413
4414 ERR_FAIL_COND_V(!d.has("joints"), ERR_PARSE_ERROR);
4415
4416 const Array &joints = d["joints"];
4417
4418 if (d.has("inverseBindMatrices")) {
4419 skin->inverse_binds = _decode_accessor_as_xform(p_state, d["inverseBindMatrices"], false);
4420 ERR_FAIL_COND_V(skin->inverse_binds.size() != joints.size(), ERR_PARSE_ERROR);
4421 }
4422
4423 for (int j = 0; j < joints.size(); j++) {
4424 const GLTFNodeIndex node = joints[j];
4425 ERR_FAIL_INDEX_V(node, p_state->nodes.size(), ERR_PARSE_ERROR);
4426
4427 skin->joints.push_back(node);
4428 skin->joints_original.push_back(node);
4429
4430 p_state->nodes.write[node]->joint = true;
4431 }
4432
4433 if (d.has("name") && !String(d["name"]).is_empty()) {
4434 skin->set_name(d["name"]);
4435 } else {
4436 skin->set_name(vformat("skin_%s", itos(i)));
4437 }
4438
4439 if (d.has("skeleton")) {
4440 skin->skin_root = d["skeleton"];
4441 }
4442
4443 p_state->skins.push_back(skin);
4444 }
4445
4446 for (GLTFSkinIndex i = 0; i < p_state->skins.size(); ++i) {
4447 Ref<GLTFSkin> skin = p_state->skins.write[i];
4448
4449 // Expand the skin to capture all the extra non-joints that lie in between the actual joints,
4450 // and expand the hierarchy to ensure multi-rooted trees lie on the same height level
4451 ERR_FAIL_COND_V(_expand_skin(p_state, skin), ERR_PARSE_ERROR);
4452 ERR_FAIL_COND_V(_verify_skin(p_state, skin), ERR_PARSE_ERROR);
4453 }
4454
4455 print_verbose("glTF: Total skins: " + itos(p_state->skins.size()));
4456
4457 return OK;
4458}
4459
4460void GLTFDocument::_recurse_children(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index,
4461 RBSet<GLTFNodeIndex> &p_all_skin_nodes, HashSet<GLTFNodeIndex> &p_child_visited_set) {
4462 if (p_child_visited_set.has(p_node_index)) {
4463 return;
4464 }
4465 p_child_visited_set.insert(p_node_index);
4466 for (int i = 0; i < p_state->nodes[p_node_index]->children.size(); ++i) {
4467 _recurse_children(p_state, p_state->nodes[p_node_index]->children[i], p_all_skin_nodes, p_child_visited_set);
4468 }
4469
4470 if (p_state->nodes[p_node_index]->skin < 0 || p_state->nodes[p_node_index]->mesh < 0 || !p_state->nodes[p_node_index]->children.is_empty()) {
4471 p_all_skin_nodes.insert(p_node_index);
4472 }
4473}
4474
4475Error GLTFDocument::_determine_skeletons(Ref<GLTFState> p_state) {
4476 // Using a disjoint set, we are going to potentially combine all skins that are actually branches
4477 // of a main skeleton, or treat skins defining the same set of nodes as ONE skeleton.
4478 // This is another unclear issue caused by the current glTF specification.
4479
4480 DisjointSet<GLTFNodeIndex> skeleton_sets;
4481
4482 for (GLTFSkinIndex skin_i = 0; skin_i < p_state->skins.size(); ++skin_i) {
4483 const Ref<GLTFSkin> skin = p_state->skins[skin_i];
4484
4485 HashSet<GLTFNodeIndex> child_visited_set;
4486 RBSet<GLTFNodeIndex> all_skin_nodes;
4487 for (int i = 0; i < skin->joints.size(); ++i) {
4488 all_skin_nodes.insert(skin->joints[i]);
4489 _recurse_children(p_state, skin->joints[i], all_skin_nodes, child_visited_set);
4490 }
4491 for (int i = 0; i < skin->non_joints.size(); ++i) {
4492 all_skin_nodes.insert(skin->non_joints[i]);
4493 _recurse_children(p_state, skin->non_joints[i], all_skin_nodes, child_visited_set);
4494 }
4495 for (GLTFNodeIndex node_index : all_skin_nodes) {
4496 const GLTFNodeIndex parent = p_state->nodes[node_index]->parent;
4497 skeleton_sets.insert(node_index);
4498
4499 if (all_skin_nodes.has(parent)) {
4500 skeleton_sets.create_union(parent, node_index);
4501 }
4502 }
4503
4504 // We are going to connect the separate skin subtrees in each skin together
4505 // so that the final roots are entire sets of valid skin trees
4506 for (int i = 1; i < skin->roots.size(); ++i) {
4507 skeleton_sets.create_union(skin->roots[0], skin->roots[i]);
4508 }
4509 }
4510
4511 { // attempt to joint all touching subsets (siblings/parent are part of another skin)
4512 Vector<GLTFNodeIndex> groups_representatives;
4513 skeleton_sets.get_representatives(groups_representatives);
4514
4515 Vector<GLTFNodeIndex> highest_group_members;
4516 Vector<Vector<GLTFNodeIndex>> groups;
4517 for (int i = 0; i < groups_representatives.size(); ++i) {
4518 Vector<GLTFNodeIndex> group;
4519 skeleton_sets.get_members(group, groups_representatives[i]);
4520 highest_group_members.push_back(_find_highest_node(p_state, group));
4521 groups.push_back(group);
4522 }
4523
4524 for (int i = 0; i < highest_group_members.size(); ++i) {
4525 const GLTFNodeIndex node_i = highest_group_members[i];
4526
4527 // Attach any siblings together (this needs to be done n^2/2 times)
4528 for (int j = i + 1; j < highest_group_members.size(); ++j) {
4529 const GLTFNodeIndex node_j = highest_group_members[j];
4530
4531 // Even if they are siblings under the root! :)
4532 if (p_state->nodes[node_i]->parent == p_state->nodes[node_j]->parent) {
4533 skeleton_sets.create_union(node_i, node_j);
4534 }
4535 }
4536
4537 // Attach any parenting going on together (we need to do this n^2 times)
4538 const GLTFNodeIndex node_i_parent = p_state->nodes[node_i]->parent;
4539 if (node_i_parent >= 0) {
4540 for (int j = 0; j < groups.size() && i != j; ++j) {
4541 const Vector<GLTFNodeIndex> &group = groups[j];
4542
4543 if (group.find(node_i_parent) >= 0) {
4544 const GLTFNodeIndex node_j = highest_group_members[j];
4545 skeleton_sets.create_union(node_i, node_j);
4546 }
4547 }
4548 }
4549 }
4550 }
4551
4552 // At this point, the skeleton groups should be finalized
4553 Vector<GLTFNodeIndex> skeleton_owners;
4554 skeleton_sets.get_representatives(skeleton_owners);
4555
4556 // Mark all the skins actual skeletons, after we have merged them
4557 for (GLTFSkeletonIndex skel_i = 0; skel_i < skeleton_owners.size(); ++skel_i) {
4558 const GLTFNodeIndex skeleton_owner = skeleton_owners[skel_i];
4559 Ref<GLTFSkeleton> skeleton;
4560 skeleton.instantiate();
4561
4562 Vector<GLTFNodeIndex> skeleton_nodes;
4563 skeleton_sets.get_members(skeleton_nodes, skeleton_owner);
4564
4565 for (GLTFSkinIndex skin_i = 0; skin_i < p_state->skins.size(); ++skin_i) {
4566 Ref<GLTFSkin> skin = p_state->skins.write[skin_i];
4567
4568 // If any of the the skeletons nodes exist in a skin, that skin now maps to the skeleton
4569 for (int i = 0; i < skeleton_nodes.size(); ++i) {
4570 GLTFNodeIndex skel_node_i = skeleton_nodes[i];
4571 if (skin->joints.find(skel_node_i) >= 0 || skin->non_joints.find(skel_node_i) >= 0) {
4572 skin->skeleton = skel_i;
4573 continue;
4574 }
4575 }
4576 }
4577
4578 Vector<GLTFNodeIndex> non_joints;
4579 for (int i = 0; i < skeleton_nodes.size(); ++i) {
4580 const GLTFNodeIndex node_i = skeleton_nodes[i];
4581
4582 if (p_state->nodes[node_i]->joint) {
4583 skeleton->joints.push_back(node_i);
4584 } else {
4585 non_joints.push_back(node_i);
4586 }
4587 }
4588
4589 p_state->skeletons.push_back(skeleton);
4590
4591 _reparent_non_joint_skeleton_subtrees(p_state, p_state->skeletons.write[skel_i], non_joints);
4592 }
4593
4594 for (GLTFSkeletonIndex skel_i = 0; skel_i < p_state->skeletons.size(); ++skel_i) {
4595 Ref<GLTFSkeleton> skeleton = p_state->skeletons.write[skel_i];
4596
4597 for (int i = 0; i < skeleton->joints.size(); ++i) {
4598 const GLTFNodeIndex node_i = skeleton->joints[i];
4599 Ref<GLTFNode> node = p_state->nodes[node_i];
4600
4601 ERR_FAIL_COND_V(!node->joint, ERR_PARSE_ERROR);
4602 ERR_FAIL_COND_V(node->skeleton >= 0, ERR_PARSE_ERROR);
4603 node->skeleton = skel_i;
4604 }
4605
4606 ERR_FAIL_COND_V(_determine_skeleton_roots(p_state, skel_i), ERR_PARSE_ERROR);
4607 }
4608
4609 return OK;
4610}
4611
4612Error GLTFDocument::_reparent_non_joint_skeleton_subtrees(Ref<GLTFState> p_state, Ref<GLTFSkeleton> p_skeleton, const Vector<GLTFNodeIndex> &p_non_joints) {
4613 DisjointSet<GLTFNodeIndex> subtree_set;
4614
4615 // Populate the disjoint set with ONLY non joints that are in the skeleton hierarchy (non_joints vector)
4616 // This way we can find any joints that lie in between joints, as the current glTF specification
4617 // mentions nothing about non-joints being in between joints of the same skin. Hopefully one day we
4618 // can remove this code.
4619
4620 // skinD depicted here explains this issue:
4621 // https://github.com/KhronosGroup/glTF-Asset-Generator/blob/master/Output/Positive/Animation_Skin
4622
4623 for (int i = 0; i < p_non_joints.size(); ++i) {
4624 const GLTFNodeIndex node_i = p_non_joints[i];
4625
4626 subtree_set.insert(node_i);
4627
4628 const GLTFNodeIndex parent_i = p_state->nodes[node_i]->parent;
4629 if (parent_i >= 0 && p_non_joints.find(parent_i) >= 0 && !p_state->nodes[parent_i]->joint) {
4630 subtree_set.create_union(parent_i, node_i);
4631 }
4632 }
4633
4634 // Find all the non joint subtrees and re-parent them to a new "fake" joint
4635
4636 Vector<GLTFNodeIndex> non_joint_subtree_roots;
4637 subtree_set.get_representatives(non_joint_subtree_roots);
4638
4639 for (int root_i = 0; root_i < non_joint_subtree_roots.size(); ++root_i) {
4640 const GLTFNodeIndex subtree_root = non_joint_subtree_roots[root_i];
4641
4642 Vector<GLTFNodeIndex> subtree_nodes;
4643 subtree_set.get_members(subtree_nodes, subtree_root);
4644
4645 for (int subtree_i = 0; subtree_i < subtree_nodes.size(); ++subtree_i) {
4646 Ref<GLTFNode> node = p_state->nodes[subtree_nodes[subtree_i]];
4647 node->joint = true;
4648 // Add the joint to the skeletons joints
4649 p_skeleton->joints.push_back(subtree_nodes[subtree_i]);
4650 }
4651 }
4652
4653 return OK;
4654}
4655
4656Error GLTFDocument::_determine_skeleton_roots(Ref<GLTFState> p_state, const GLTFSkeletonIndex p_skel_i) {
4657 DisjointSet<GLTFNodeIndex> disjoint_set;
4658
4659 for (GLTFNodeIndex i = 0; i < p_state->nodes.size(); ++i) {
4660 const Ref<GLTFNode> node = p_state->nodes[i];
4661
4662 if (node->skeleton != p_skel_i) {
4663 continue;
4664 }
4665
4666 disjoint_set.insert(i);
4667
4668 if (node->parent >= 0 && p_state->nodes[node->parent]->skeleton == p_skel_i) {
4669 disjoint_set.create_union(node->parent, i);
4670 }
4671 }
4672
4673 Ref<GLTFSkeleton> skeleton = p_state->skeletons.write[p_skel_i];
4674
4675 Vector<GLTFNodeIndex> representatives;
4676 disjoint_set.get_representatives(representatives);
4677
4678 Vector<GLTFNodeIndex> roots;
4679
4680 for (int i = 0; i < representatives.size(); ++i) {
4681 Vector<GLTFNodeIndex> set;
4682 disjoint_set.get_members(set, representatives[i]);
4683 const GLTFNodeIndex root = _find_highest_node(p_state, set);
4684 ERR_FAIL_COND_V(root < 0, FAILED);
4685 roots.push_back(root);
4686 }
4687
4688 roots.sort();
4689
4690 skeleton->roots = roots;
4691
4692 if (roots.size() == 0) {
4693 return FAILED;
4694 } else if (roots.size() == 1) {
4695 return OK;
4696 }
4697
4698 // Check that the subtrees have the same parent root
4699 const GLTFNodeIndex parent = p_state->nodes[roots[0]]->parent;
4700 for (int i = 1; i < roots.size(); ++i) {
4701 if (p_state->nodes[roots[i]]->parent != parent) {
4702 return FAILED;
4703 }
4704 }
4705
4706 return OK;
4707}
4708
4709Error GLTFDocument::_create_skeletons(Ref<GLTFState> p_state) {
4710 for (GLTFSkeletonIndex skel_i = 0; skel_i < p_state->skeletons.size(); ++skel_i) {
4711 Ref<GLTFSkeleton> gltf_skeleton = p_state->skeletons.write[skel_i];
4712
4713 Skeleton3D *skeleton = memnew(Skeleton3D);
4714 gltf_skeleton->godot_skeleton = skeleton;
4715 p_state->skeleton3d_to_gltf_skeleton[skeleton->get_instance_id()] = skel_i;
4716
4717 // Make a unique name, no gltf node represents this skeleton
4718 skeleton->set_name("Skeleton3D");
4719
4720 List<GLTFNodeIndex> bones;
4721
4722 for (int i = 0; i < gltf_skeleton->roots.size(); ++i) {
4723 bones.push_back(gltf_skeleton->roots[i]);
4724 }
4725
4726 // Make the skeleton creation deterministic by going through the roots in
4727 // a sorted order, and DEPTH FIRST
4728 bones.sort();
4729
4730 while (!bones.is_empty()) {
4731 const GLTFNodeIndex node_i = bones.front()->get();
4732 bones.pop_front();
4733
4734 Ref<GLTFNode> node = p_state->nodes[node_i];
4735 ERR_FAIL_COND_V(node->skeleton != skel_i, FAILED);
4736
4737 { // Add all child nodes to the stack (deterministically)
4738 Vector<GLTFNodeIndex> child_nodes;
4739 for (int i = 0; i < node->children.size(); ++i) {
4740 const GLTFNodeIndex child_i = node->children[i];
4741 if (p_state->nodes[child_i]->skeleton == skel_i) {
4742 child_nodes.push_back(child_i);
4743 }
4744 }
4745
4746 // Depth first insertion
4747 child_nodes.sort();
4748 for (int i = child_nodes.size() - 1; i >= 0; --i) {
4749 bones.push_front(child_nodes[i]);
4750 }
4751 }
4752
4753 const int bone_index = skeleton->get_bone_count();
4754
4755 if (node->get_name().is_empty()) {
4756 node->set_name("bone");
4757 }
4758
4759 node->set_name(_gen_unique_bone_name(p_state, skel_i, node->get_name()));
4760
4761 skeleton->add_bone(node->get_name());
4762 skeleton->set_bone_rest(bone_index, node->xform);
4763 skeleton->set_bone_pose_position(bone_index, node->position);
4764 skeleton->set_bone_pose_rotation(bone_index, node->rotation.normalized());
4765 skeleton->set_bone_pose_scale(bone_index, node->scale);
4766
4767 if (node->parent >= 0 && p_state->nodes[node->parent]->skeleton == skel_i) {
4768 const int bone_parent = skeleton->find_bone(p_state->nodes[node->parent]->get_name());
4769 ERR_FAIL_COND_V(bone_parent < 0, FAILED);
4770 skeleton->set_bone_parent(bone_index, skeleton->find_bone(p_state->nodes[node->parent]->get_name()));
4771 }
4772
4773 p_state->scene_nodes.insert(node_i, skeleton);
4774 }
4775 }
4776
4777 ERR_FAIL_COND_V(_map_skin_joints_indices_to_skeleton_bone_indices(p_state), ERR_PARSE_ERROR);
4778
4779 return OK;
4780}
4781
4782Error GLTFDocument::_map_skin_joints_indices_to_skeleton_bone_indices(Ref<GLTFState> p_state) {
4783 for (GLTFSkinIndex skin_i = 0; skin_i < p_state->skins.size(); ++skin_i) {
4784 Ref<GLTFSkin> skin = p_state->skins.write[skin_i];
4785
4786 Ref<GLTFSkeleton> skeleton = p_state->skeletons[skin->skeleton];
4787
4788 for (int joint_index = 0; joint_index < skin->joints_original.size(); ++joint_index) {
4789 const GLTFNodeIndex node_i = skin->joints_original[joint_index];
4790 const Ref<GLTFNode> node = p_state->nodes[node_i];
4791
4792 const int bone_index = skeleton->godot_skeleton->find_bone(node->get_name());
4793 ERR_FAIL_COND_V(bone_index < 0, FAILED);
4794
4795 skin->joint_i_to_bone_i.insert(joint_index, bone_index);
4796 }
4797 }
4798
4799 return OK;
4800}
4801
4802Error GLTFDocument::_serialize_skins(Ref<GLTFState> p_state) {
4803 _remove_duplicate_skins(p_state);
4804 Array json_skins;
4805 for (int skin_i = 0; skin_i < p_state->skins.size(); skin_i++) {
4806 Ref<GLTFSkin> gltf_skin = p_state->skins[skin_i];
4807 Dictionary json_skin;
4808 json_skin["inverseBindMatrices"] = _encode_accessor_as_xform(p_state, gltf_skin->inverse_binds, false);
4809 json_skin["joints"] = gltf_skin->get_joints();
4810 json_skin["name"] = gltf_skin->get_name();
4811 json_skins.push_back(json_skin);
4812 }
4813 if (!p_state->skins.size()) {
4814 return OK;
4815 }
4816
4817 p_state->json["skins"] = json_skins;
4818 return OK;
4819}
4820
4821Error GLTFDocument::_create_skins(Ref<GLTFState> p_state) {
4822 for (GLTFSkinIndex skin_i = 0; skin_i < p_state->skins.size(); ++skin_i) {
4823 Ref<GLTFSkin> gltf_skin = p_state->skins.write[skin_i];
4824
4825 Ref<Skin> skin;
4826 skin.instantiate();
4827
4828 // Some skins don't have IBM's! What absolute monsters!
4829 const bool has_ibms = !gltf_skin->inverse_binds.is_empty();
4830
4831 for (int joint_i = 0; joint_i < gltf_skin->joints_original.size(); ++joint_i) {
4832 GLTFNodeIndex node = gltf_skin->joints_original[joint_i];
4833 String bone_name = p_state->nodes[node]->get_name();
4834
4835 Transform3D xform;
4836 if (has_ibms) {
4837 xform = gltf_skin->inverse_binds[joint_i];
4838 }
4839
4840 if (p_state->use_named_skin_binds) {
4841 skin->add_named_bind(bone_name, xform);
4842 } else {
4843 int32_t bone_i = gltf_skin->joint_i_to_bone_i[joint_i];
4844 skin->add_bind(bone_i, xform);
4845 }
4846 }
4847
4848 gltf_skin->godot_skin = skin;
4849 }
4850
4851 // Purge the duplicates!
4852 _remove_duplicate_skins(p_state);
4853
4854 // Create unique names now, after removing duplicates
4855 for (GLTFSkinIndex skin_i = 0; skin_i < p_state->skins.size(); ++skin_i) {
4856 Ref<Skin> skin = p_state->skins.write[skin_i]->godot_skin;
4857 if (skin->get_name().is_empty()) {
4858 // Make a unique name, no gltf node represents this skin
4859 skin->set_name(_gen_unique_name(p_state, "Skin"));
4860 }
4861 }
4862
4863 return OK;
4864}
4865
4866bool GLTFDocument::_skins_are_same(const Ref<Skin> p_skin_a, const Ref<Skin> p_skin_b) {
4867 if (p_skin_a->get_bind_count() != p_skin_b->get_bind_count()) {
4868 return false;
4869 }
4870
4871 for (int i = 0; i < p_skin_a->get_bind_count(); ++i) {
4872 if (p_skin_a->get_bind_bone(i) != p_skin_b->get_bind_bone(i)) {
4873 return false;
4874 }
4875 if (p_skin_a->get_bind_name(i) != p_skin_b->get_bind_name(i)) {
4876 return false;
4877 }
4878
4879 Transform3D a_xform = p_skin_a->get_bind_pose(i);
4880 Transform3D b_xform = p_skin_b->get_bind_pose(i);
4881
4882 if (a_xform != b_xform) {
4883 return false;
4884 }
4885 }
4886
4887 return true;
4888}
4889
4890void GLTFDocument::_remove_duplicate_skins(Ref<GLTFState> p_state) {
4891 for (int i = 0; i < p_state->skins.size(); ++i) {
4892 for (int j = i + 1; j < p_state->skins.size(); ++j) {
4893 const Ref<Skin> skin_i = p_state->skins[i]->godot_skin;
4894 const Ref<Skin> skin_j = p_state->skins[j]->godot_skin;
4895
4896 if (_skins_are_same(skin_i, skin_j)) {
4897 // replace it and delete the old
4898 p_state->skins.write[j]->godot_skin = skin_i;
4899 }
4900 }
4901 }
4902}
4903
4904Error GLTFDocument::_serialize_lights(Ref<GLTFState> p_state) {
4905 if (p_state->lights.is_empty()) {
4906 return OK;
4907 }
4908 Array lights;
4909 for (GLTFLightIndex i = 0; i < p_state->lights.size(); i++) {
4910 lights.push_back(p_state->lights[i]->to_dictionary());
4911 }
4912
4913 Dictionary extensions;
4914 if (p_state->json.has("extensions")) {
4915 extensions = p_state->json["extensions"];
4916 } else {
4917 p_state->json["extensions"] = extensions;
4918 }
4919 Dictionary lights_punctual;
4920 extensions["KHR_lights_punctual"] = lights_punctual;
4921 lights_punctual["lights"] = lights;
4922
4923 print_verbose("glTF: Total lights: " + itos(p_state->lights.size()));
4924
4925 return OK;
4926}
4927
4928Error GLTFDocument::_serialize_cameras(Ref<GLTFState> p_state) {
4929 Array cameras;
4930 cameras.resize(p_state->cameras.size());
4931 for (GLTFCameraIndex i = 0; i < p_state->cameras.size(); i++) {
4932 cameras[i] = p_state->cameras[i]->to_dictionary();
4933 }
4934
4935 if (!p_state->cameras.size()) {
4936 return OK;
4937 }
4938
4939 p_state->json["cameras"] = cameras;
4940
4941 print_verbose("glTF: Total cameras: " + itos(p_state->cameras.size()));
4942
4943 return OK;
4944}
4945
4946Error GLTFDocument::_parse_lights(Ref<GLTFState> p_state) {
4947 if (!p_state->json.has("extensions")) {
4948 return OK;
4949 }
4950 Dictionary extensions = p_state->json["extensions"];
4951 if (!extensions.has("KHR_lights_punctual")) {
4952 return OK;
4953 }
4954 Dictionary lights_punctual = extensions["KHR_lights_punctual"];
4955 if (!lights_punctual.has("lights")) {
4956 return OK;
4957 }
4958
4959 const Array &lights = lights_punctual["lights"];
4960
4961 for (GLTFLightIndex light_i = 0; light_i < lights.size(); light_i++) {
4962 Ref<GLTFLight> light = GLTFLight::from_dictionary(lights[light_i]);
4963 if (light.is_null()) {
4964 return Error::ERR_PARSE_ERROR;
4965 }
4966 p_state->lights.push_back(light);
4967 }
4968
4969 print_verbose("glTF: Total lights: " + itos(p_state->lights.size()));
4970
4971 return OK;
4972}
4973
4974Error GLTFDocument::_parse_cameras(Ref<GLTFState> p_state) {
4975 if (!p_state->json.has("cameras")) {
4976 return OK;
4977 }
4978
4979 const Array cameras = p_state->json["cameras"];
4980
4981 for (GLTFCameraIndex i = 0; i < cameras.size(); i++) {
4982 p_state->cameras.push_back(GLTFCamera::from_dictionary(cameras[i]));
4983 }
4984
4985 print_verbose("glTF: Total cameras: " + itos(p_state->cameras.size()));
4986
4987 return OK;
4988}
4989
4990String GLTFDocument::interpolation_to_string(const GLTFAnimation::Interpolation p_interp) {
4991 String interp = "LINEAR";
4992 if (p_interp == GLTFAnimation::INTERP_STEP) {
4993 interp = "STEP";
4994 } else if (p_interp == GLTFAnimation::INTERP_LINEAR) {
4995 interp = "LINEAR";
4996 } else if (p_interp == GLTFAnimation::INTERP_CATMULLROMSPLINE) {
4997 interp = "CATMULLROMSPLINE";
4998 } else if (p_interp == GLTFAnimation::INTERP_CUBIC_SPLINE) {
4999 interp = "CUBICSPLINE";
5000 }
5001
5002 return interp;
5003}
5004
5005Error GLTFDocument::_serialize_animations(Ref<GLTFState> p_state) {
5006 if (!p_state->animation_players.size()) {
5007 return OK;
5008 }
5009 for (int32_t player_i = 0; player_i < p_state->animation_players.size(); player_i++) {
5010 AnimationPlayer *animation_player = p_state->animation_players[player_i];
5011 List<StringName> animations;
5012 animation_player->get_animation_list(&animations);
5013 for (StringName animation_name : animations) {
5014 _convert_animation(p_state, animation_player, animation_name);
5015 }
5016 }
5017 Array animations;
5018 for (GLTFAnimationIndex animation_i = 0; animation_i < p_state->animations.size(); animation_i++) {
5019 Dictionary d;
5020 Ref<GLTFAnimation> gltf_animation = p_state->animations[animation_i];
5021 if (!gltf_animation->get_tracks().size()) {
5022 continue;
5023 }
5024
5025 if (!gltf_animation->get_name().is_empty()) {
5026 d["name"] = gltf_animation->get_name();
5027 }
5028 Array channels;
5029 Array samplers;
5030
5031 for (KeyValue<int, GLTFAnimation::Track> &track_i : gltf_animation->get_tracks()) {
5032 GLTFAnimation::Track track = track_i.value;
5033 if (track.position_track.times.size()) {
5034 Dictionary t;
5035 t["sampler"] = samplers.size();
5036 Dictionary s;
5037
5038 s["interpolation"] = interpolation_to_string(track.position_track.interpolation);
5039 Vector<real_t> times = Variant(track.position_track.times);
5040 s["input"] = _encode_accessor_as_floats(p_state, times, false);
5041 Vector<Vector3> values = Variant(track.position_track.values);
5042 s["output"] = _encode_accessor_as_vec3(p_state, values, false);
5043
5044 samplers.push_back(s);
5045
5046 Dictionary target;
5047 target["path"] = "translation";
5048 target["node"] = track_i.key;
5049
5050 t["target"] = target;
5051 channels.push_back(t);
5052 }
5053 if (track.rotation_track.times.size()) {
5054 Dictionary t;
5055 t["sampler"] = samplers.size();
5056 Dictionary s;
5057
5058 s["interpolation"] = interpolation_to_string(track.rotation_track.interpolation);
5059 Vector<real_t> times = Variant(track.rotation_track.times);
5060 s["input"] = _encode_accessor_as_floats(p_state, times, false);
5061 Vector<Quaternion> values = track.rotation_track.values;
5062 s["output"] = _encode_accessor_as_quaternions(p_state, values, false);
5063
5064 samplers.push_back(s);
5065
5066 Dictionary target;
5067 target["path"] = "rotation";
5068 target["node"] = track_i.key;
5069
5070 t["target"] = target;
5071 channels.push_back(t);
5072 }
5073 if (track.scale_track.times.size()) {
5074 Dictionary t;
5075 t["sampler"] = samplers.size();
5076 Dictionary s;
5077
5078 s["interpolation"] = interpolation_to_string(track.scale_track.interpolation);
5079 Vector<real_t> times = Variant(track.scale_track.times);
5080 s["input"] = _encode_accessor_as_floats(p_state, times, false);
5081 Vector<Vector3> values = Variant(track.scale_track.values);
5082 s["output"] = _encode_accessor_as_vec3(p_state, values, false);
5083
5084 samplers.push_back(s);
5085
5086 Dictionary target;
5087 target["path"] = "scale";
5088 target["node"] = track_i.key;
5089
5090 t["target"] = target;
5091 channels.push_back(t);
5092 }
5093 if (track.weight_tracks.size()) {
5094 double length = 0.0f;
5095
5096 for (int32_t track_idx = 0; track_idx < track.weight_tracks.size(); track_idx++) {
5097 int32_t last_time_index = track.weight_tracks[track_idx].times.size() - 1;
5098 length = MAX(length, track.weight_tracks[track_idx].times[last_time_index]);
5099 }
5100
5101 Dictionary t;
5102 t["sampler"] = samplers.size();
5103 Dictionary s;
5104 Vector<real_t> times;
5105 const double increment = 1.0 / BAKE_FPS;
5106 {
5107 double time = 0.0;
5108 bool last = false;
5109 while (true) {
5110 times.push_back(time);
5111 if (last) {
5112 break;
5113 }
5114 time += increment;
5115 if (time >= length) {
5116 last = true;
5117 time = length;
5118 }
5119 }
5120 }
5121
5122 for (int32_t track_idx = 0; track_idx < track.weight_tracks.size(); track_idx++) {
5123 double time = 0.0;
5124 bool last = false;
5125 Vector<real_t> weight_track;
5126 while (true) {
5127 float weight = _interpolate_track<real_t>(track.weight_tracks[track_idx].times,
5128 track.weight_tracks[track_idx].values,
5129 time,
5130 track.weight_tracks[track_idx].interpolation);
5131 weight_track.push_back(weight);
5132 if (last) {
5133 break;
5134 }
5135 time += increment;
5136 if (time >= length) {
5137 last = true;
5138 time = length;
5139 }
5140 }
5141 track.weight_tracks.write[track_idx].times = times;
5142 track.weight_tracks.write[track_idx].values = weight_track;
5143 }
5144
5145 Vector<real_t> all_track_times = times;
5146 Vector<real_t> all_track_values;
5147 int32_t values_size = track.weight_tracks[0].values.size();
5148 int32_t weight_tracks_size = track.weight_tracks.size();
5149 all_track_values.resize(weight_tracks_size * values_size);
5150 for (int k = 0; k < track.weight_tracks.size(); k++) {
5151 Vector<real_t> wdata = track.weight_tracks[k].values;
5152 for (int l = 0; l < wdata.size(); l++) {
5153 int32_t index = l * weight_tracks_size + k;
5154 ERR_BREAK(index >= all_track_values.size());
5155 all_track_values.write[index] = wdata.write[l];
5156 }
5157 }
5158
5159 s["interpolation"] = interpolation_to_string(track.weight_tracks[track.weight_tracks.size() - 1].interpolation);
5160 s["input"] = _encode_accessor_as_floats(p_state, all_track_times, false);
5161 s["output"] = _encode_accessor_as_floats(p_state, all_track_values, false);
5162
5163 samplers.push_back(s);
5164
5165 Dictionary target;
5166 target["path"] = "weights";
5167 target["node"] = track_i.key;
5168
5169 t["target"] = target;
5170 channels.push_back(t);
5171 }
5172 }
5173 if (channels.size() && samplers.size()) {
5174 d["channels"] = channels;
5175 d["samplers"] = samplers;
5176 animations.push_back(d);
5177 }
5178 }
5179
5180 if (!animations.size()) {
5181 return OK;
5182 }
5183 p_state->json["animations"] = animations;
5184
5185 print_verbose("glTF: Total animations '" + itos(p_state->animations.size()) + "'.");
5186
5187 return OK;
5188}
5189
5190Error GLTFDocument::_parse_animations(Ref<GLTFState> p_state) {
5191 if (!p_state->json.has("animations")) {
5192 return OK;
5193 }
5194
5195 const Array &animations = p_state->json["animations"];
5196
5197 for (GLTFAnimationIndex i = 0; i < animations.size(); i++) {
5198 const Dictionary &d = animations[i];
5199
5200 Ref<GLTFAnimation> animation;
5201 animation.instantiate();
5202
5203 if (!d.has("channels") || !d.has("samplers")) {
5204 continue;
5205 }
5206
5207 Array channels = d["channels"];
5208 Array samplers = d["samplers"];
5209
5210 if (d.has("name")) {
5211 const String anim_name = d["name"];
5212 const String anim_name_lower = anim_name.to_lower();
5213 if (anim_name_lower.begins_with("loop") || anim_name_lower.ends_with("loop") || anim_name_lower.begins_with("cycle") || anim_name_lower.ends_with("cycle")) {
5214 animation->set_loop(true);
5215 }
5216 animation->set_name(_gen_unique_animation_name(p_state, anim_name));
5217 }
5218
5219 for (int j = 0; j < channels.size(); j++) {
5220 const Dictionary &c = channels[j];
5221 if (!c.has("target")) {
5222 continue;
5223 }
5224
5225 const Dictionary &t = c["target"];
5226 if (!t.has("node") || !t.has("path")) {
5227 continue;
5228 }
5229
5230 ERR_FAIL_COND_V(!c.has("sampler"), ERR_PARSE_ERROR);
5231 const int sampler = c["sampler"];
5232 ERR_FAIL_INDEX_V(sampler, samplers.size(), ERR_PARSE_ERROR);
5233
5234 GLTFNodeIndex node = t["node"];
5235 String path = t["path"];
5236
5237 ERR_FAIL_INDEX_V(node, p_state->nodes.size(), ERR_PARSE_ERROR);
5238
5239 GLTFAnimation::Track *track = nullptr;
5240
5241 if (!animation->get_tracks().has(node)) {
5242 animation->get_tracks()[node] = GLTFAnimation::Track();
5243 }
5244
5245 track = &animation->get_tracks()[node];
5246
5247 const Dictionary &s = samplers[sampler];
5248
5249 ERR_FAIL_COND_V(!s.has("input"), ERR_PARSE_ERROR);
5250 ERR_FAIL_COND_V(!s.has("output"), ERR_PARSE_ERROR);
5251
5252 const int input = s["input"];
5253 const int output = s["output"];
5254
5255 GLTFAnimation::Interpolation interp = GLTFAnimation::INTERP_LINEAR;
5256 int output_count = 1;
5257 if (s.has("interpolation")) {
5258 const String &in = s["interpolation"];
5259 if (in == "STEP") {
5260 interp = GLTFAnimation::INTERP_STEP;
5261 } else if (in == "LINEAR") {
5262 interp = GLTFAnimation::INTERP_LINEAR;
5263 } else if (in == "CATMULLROMSPLINE") {
5264 interp = GLTFAnimation::INTERP_CATMULLROMSPLINE;
5265 output_count = 3;
5266 } else if (in == "CUBICSPLINE") {
5267 interp = GLTFAnimation::INTERP_CUBIC_SPLINE;
5268 output_count = 3;
5269 }
5270 }
5271
5272 const Vector<float> times = _decode_accessor_as_floats(p_state, input, false);
5273 if (path == "translation") {
5274 const Vector<Vector3> positions = _decode_accessor_as_vec3(p_state, output, false);
5275 track->position_track.interpolation = interp;
5276 track->position_track.times = Variant(times); //convert via variant
5277 track->position_track.values = Variant(positions); //convert via variant
5278 } else if (path == "rotation") {
5279 const Vector<Quaternion> rotations = _decode_accessor_as_quaternion(p_state, output, false);
5280 track->rotation_track.interpolation = interp;
5281 track->rotation_track.times = Variant(times); //convert via variant
5282 track->rotation_track.values = rotations;
5283 } else if (path == "scale") {
5284 const Vector<Vector3> scales = _decode_accessor_as_vec3(p_state, output, false);
5285 track->scale_track.interpolation = interp;
5286 track->scale_track.times = Variant(times); //convert via variant
5287 track->scale_track.values = Variant(scales); //convert via variant
5288 } else if (path == "weights") {
5289 const Vector<float> weights = _decode_accessor_as_floats(p_state, output, false);
5290
5291 ERR_FAIL_INDEX_V(p_state->nodes[node]->mesh, p_state->meshes.size(), ERR_PARSE_ERROR);
5292 Ref<GLTFMesh> mesh = p_state->meshes[p_state->nodes[node]->mesh];
5293 ERR_CONTINUE(!mesh->get_blend_weights().size());
5294 const int wc = mesh->get_blend_weights().size();
5295
5296 track->weight_tracks.resize(wc);
5297
5298 const int expected_value_count = times.size() * output_count * wc;
5299 ERR_CONTINUE_MSG(weights.size() != expected_value_count, "Invalid weight data, expected " + itos(expected_value_count) + " weight values, got " + itos(weights.size()) + " instead.");
5300
5301 const int wlen = weights.size() / wc;
5302 for (int k = 0; k < wc; k++) { //separate tracks, having them together is not such a good idea
5303 GLTFAnimation::Channel<real_t> cf;
5304 cf.interpolation = interp;
5305 cf.times = Variant(times);
5306 Vector<real_t> wdata;
5307 wdata.resize(wlen);
5308 for (int l = 0; l < wlen; l++) {
5309 wdata.write[l] = weights[l * wc + k];
5310 }
5311
5312 cf.values = wdata;
5313 track->weight_tracks.write[k] = cf;
5314 }
5315 } else {
5316 WARN_PRINT("Invalid path '" + path + "'.");
5317 }
5318 }
5319
5320 p_state->animations.push_back(animation);
5321 }
5322
5323 print_verbose("glTF: Total animations '" + itos(p_state->animations.size()) + "'.");
5324
5325 return OK;
5326}
5327
5328void GLTFDocument::_assign_node_names(Ref<GLTFState> p_state) {
5329 for (int i = 0; i < p_state->nodes.size(); i++) {
5330 Ref<GLTFNode> gltf_node = p_state->nodes[i];
5331 // Any joints get unique names generated when the skeleton is made, unique to the skeleton
5332 if (gltf_node->skeleton >= 0) {
5333 continue;
5334 }
5335 String gltf_node_name = gltf_node->get_name();
5336 if (gltf_node_name.is_empty()) {
5337 if (gltf_node->mesh >= 0) {
5338 gltf_node_name = "Mesh";
5339 } else if (gltf_node->camera >= 0) {
5340 gltf_node_name = "Camera";
5341 } else {
5342 gltf_node_name = "Node";
5343 }
5344 }
5345 gltf_node->set_name(_gen_unique_name(p_state, gltf_node_name));
5346 }
5347}
5348
5349BoneAttachment3D *GLTFDocument::_generate_bone_attachment(Ref<GLTFState> p_state, Skeleton3D *p_skeleton, const GLTFNodeIndex p_node_index, const GLTFNodeIndex p_bone_index) {
5350 Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
5351 Ref<GLTFNode> bone_node = p_state->nodes[p_bone_index];
5352 BoneAttachment3D *bone_attachment = memnew(BoneAttachment3D);
5353 print_verbose("glTF: Creating bone attachment for: " + gltf_node->get_name());
5354
5355 ERR_FAIL_COND_V(!bone_node->joint, nullptr);
5356
5357 bone_attachment->set_bone_name(bone_node->get_name());
5358
5359 return bone_attachment;
5360}
5361
5362GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref<GLTFState> p_state, MeshInstance3D *p_mesh_instance) {
5363 ERR_FAIL_NULL_V(p_mesh_instance, -1);
5364 if (p_mesh_instance->get_mesh().is_null()) {
5365 return -1;
5366 }
5367
5368 Ref<Mesh> import_mesh = p_mesh_instance->get_mesh();
5369 Ref<ImporterMesh> current_mesh = _mesh_to_importer_mesh(import_mesh);
5370 Vector<float> blend_weights;
5371 int32_t blend_count = import_mesh->get_blend_shape_count();
5372 blend_weights.resize(blend_count);
5373 for (int32_t blend_i = 0; blend_i < blend_count; blend_i++) {
5374 blend_weights.write[blend_i] = 0.0f;
5375 }
5376
5377 Ref<GLTFMesh> gltf_mesh;
5378 gltf_mesh.instantiate();
5379 TypedArray<Material> instance_materials;
5380 for (int32_t surface_i = 0; surface_i < current_mesh->get_surface_count(); surface_i++) {
5381 Ref<Material> mat = current_mesh->get_surface_material(surface_i);
5382 if (p_mesh_instance->get_surface_override_material(surface_i).is_valid()) {
5383 mat = p_mesh_instance->get_surface_override_material(surface_i);
5384 }
5385 if (p_mesh_instance->get_material_override().is_valid()) {
5386 mat = p_mesh_instance->get_material_override();
5387 }
5388 instance_materials.append(mat);
5389 }
5390 gltf_mesh->set_instance_materials(instance_materials);
5391 gltf_mesh->set_mesh(current_mesh);
5392 gltf_mesh->set_blend_weights(blend_weights);
5393 GLTFMeshIndex mesh_i = p_state->meshes.size();
5394 p_state->meshes.push_back(gltf_mesh);
5395 return mesh_i;
5396}
5397
5398ImporterMeshInstance3D *GLTFDocument::_generate_mesh_instance(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index) {
5399 Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
5400
5401 ERR_FAIL_INDEX_V(gltf_node->mesh, p_state->meshes.size(), nullptr);
5402
5403 ImporterMeshInstance3D *mi = memnew(ImporterMeshInstance3D);
5404 print_verbose("glTF: Creating mesh for: " + gltf_node->get_name());
5405
5406 p_state->scene_mesh_instances.insert(p_node_index, mi);
5407 Ref<GLTFMesh> mesh = p_state->meshes.write[gltf_node->mesh];
5408 if (mesh.is_null()) {
5409 return mi;
5410 }
5411 Ref<ImporterMesh> import_mesh = mesh->get_mesh();
5412 if (import_mesh.is_null()) {
5413 return mi;
5414 }
5415 mi->set_mesh(import_mesh);
5416 return mi;
5417}
5418
5419Light3D *GLTFDocument::_generate_light(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index) {
5420 Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
5421
5422 ERR_FAIL_INDEX_V(gltf_node->light, p_state->lights.size(), nullptr);
5423
5424 print_verbose("glTF: Creating light for: " + gltf_node->get_name());
5425
5426 Ref<GLTFLight> l = p_state->lights[gltf_node->light];
5427 return l->to_node();
5428}
5429
5430Camera3D *GLTFDocument::_generate_camera(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index) {
5431 Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
5432
5433 ERR_FAIL_INDEX_V(gltf_node->camera, p_state->cameras.size(), nullptr);
5434
5435 print_verbose("glTF: Creating camera for: " + gltf_node->get_name());
5436
5437 Ref<GLTFCamera> c = p_state->cameras[gltf_node->camera];
5438 return c->to_node();
5439}
5440
5441GLTFCameraIndex GLTFDocument::_convert_camera(Ref<GLTFState> p_state, Camera3D *p_camera) {
5442 print_verbose("glTF: Converting camera: " + p_camera->get_name());
5443
5444 Ref<GLTFCamera> c = GLTFCamera::from_node(p_camera);
5445 GLTFCameraIndex camera_index = p_state->cameras.size();
5446 p_state->cameras.push_back(c);
5447 return camera_index;
5448}
5449
5450GLTFLightIndex GLTFDocument::_convert_light(Ref<GLTFState> p_state, Light3D *p_light) {
5451 print_verbose("glTF: Converting light: " + p_light->get_name());
5452
5453 Ref<GLTFLight> l = GLTFLight::from_node(p_light);
5454
5455 GLTFLightIndex light_index = p_state->lights.size();
5456 p_state->lights.push_back(l);
5457 return light_index;
5458}
5459
5460void GLTFDocument::_convert_spatial(Ref<GLTFState> p_state, Node3D *p_spatial, Ref<GLTFNode> p_node) {
5461 Transform3D xform = p_spatial->get_transform();
5462 p_node->scale = xform.basis.get_scale();
5463 p_node->rotation = xform.basis.get_rotation_quaternion();
5464 p_node->position = xform.origin;
5465}
5466
5467Node3D *GLTFDocument::_generate_spatial(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index) {
5468 Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
5469
5470 Node3D *spatial = memnew(Node3D);
5471 print_verbose("glTF: Converting spatial: " + gltf_node->get_name());
5472
5473 return spatial;
5474}
5475
5476void GLTFDocument::_convert_scene_node(Ref<GLTFState> p_state, Node *p_current, const GLTFNodeIndex p_gltf_parent, const GLTFNodeIndex p_gltf_root) {
5477 bool retflag = true;
5478 _check_visibility(p_current, retflag);
5479 if (retflag) {
5480 return;
5481 }
5482 Ref<GLTFNode> gltf_node;
5483 gltf_node.instantiate();
5484 gltf_node->set_name(_gen_unique_name(p_state, p_current->get_name()));
5485 if (cast_to<Node3D>(p_current)) {
5486 Node3D *spatial = cast_to<Node3D>(p_current);
5487 _convert_spatial(p_state, spatial, gltf_node);
5488 }
5489 if (cast_to<MeshInstance3D>(p_current)) {
5490 MeshInstance3D *mi = cast_to<MeshInstance3D>(p_current);
5491 _convert_mesh_instance_to_gltf(mi, p_state, gltf_node);
5492 } else if (cast_to<BoneAttachment3D>(p_current)) {
5493 BoneAttachment3D *bone = cast_to<BoneAttachment3D>(p_current);
5494 _convert_bone_attachment_to_gltf(bone, p_state, p_gltf_parent, p_gltf_root, gltf_node);
5495 return;
5496 } else if (cast_to<Skeleton3D>(p_current)) {
5497 Skeleton3D *skel = cast_to<Skeleton3D>(p_current);
5498 _convert_skeleton_to_gltf(skel, p_state, p_gltf_parent, p_gltf_root, gltf_node);
5499 // We ignore the Godot Engine node that is the skeleton.
5500 return;
5501 } else if (cast_to<MultiMeshInstance3D>(p_current)) {
5502 MultiMeshInstance3D *multi = cast_to<MultiMeshInstance3D>(p_current);
5503 _convert_multi_mesh_instance_to_gltf(multi, p_gltf_parent, p_gltf_root, gltf_node, p_state);
5504#ifdef MODULE_CSG_ENABLED
5505 } else if (cast_to<CSGShape3D>(p_current)) {
5506 CSGShape3D *shape = cast_to<CSGShape3D>(p_current);
5507 if (shape->get_parent() && shape->is_root_shape()) {
5508 _convert_csg_shape_to_gltf(shape, p_gltf_parent, gltf_node, p_state);
5509 }
5510#endif // MODULE_CSG_ENABLED
5511#ifdef MODULE_GRIDMAP_ENABLED
5512 } else if (cast_to<GridMap>(p_current)) {
5513 GridMap *gridmap = Object::cast_to<GridMap>(p_current);
5514 _convert_grid_map_to_gltf(gridmap, p_gltf_parent, p_gltf_root, gltf_node, p_state);
5515#endif // MODULE_GRIDMAP_ENABLED
5516 } else if (cast_to<Camera3D>(p_current)) {
5517 Camera3D *camera = Object::cast_to<Camera3D>(p_current);
5518 _convert_camera_to_gltf(camera, p_state, gltf_node);
5519 } else if (cast_to<Light3D>(p_current)) {
5520 Light3D *light = Object::cast_to<Light3D>(p_current);
5521 _convert_light_to_gltf(light, p_state, gltf_node);
5522 } else if (cast_to<AnimationPlayer>(p_current)) {
5523 AnimationPlayer *animation_player = Object::cast_to<AnimationPlayer>(p_current);
5524 _convert_animation_player_to_gltf(animation_player, p_state, p_gltf_parent, p_gltf_root, gltf_node, p_current);
5525 }
5526 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
5527 ERR_CONTINUE(ext.is_null());
5528 ext->convert_scene_node(p_state, gltf_node, p_current);
5529 }
5530 GLTFNodeIndex current_node_i = p_state->nodes.size();
5531 GLTFNodeIndex gltf_root = p_gltf_root;
5532 if (gltf_root == -1) {
5533 gltf_root = current_node_i;
5534 p_state->root_nodes.push_back(gltf_root);
5535 }
5536 _create_gltf_node(p_state, p_current, current_node_i, p_gltf_parent, gltf_root, gltf_node);
5537 for (int node_i = 0; node_i < p_current->get_child_count(); node_i++) {
5538 _convert_scene_node(p_state, p_current->get_child(node_i), current_node_i, gltf_root);
5539 }
5540}
5541
5542#ifdef MODULE_CSG_ENABLED
5543void GLTFDocument::_convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> p_gltf_node, Ref<GLTFState> p_state) {
5544 CSGShape3D *csg = p_current;
5545 csg->call("_update_shape");
5546 Array meshes = csg->get_meshes();
5547 if (meshes.size() != 2) {
5548 return;
5549 }
5550
5551 Ref<ImporterMesh> mesh;
5552 mesh.instantiate();
5553 {
5554 Ref<Mesh> csg_mesh = csg->get_meshes()[1];
5555
5556 for (int32_t surface_i = 0; surface_i < csg_mesh->get_surface_count(); surface_i++) {
5557 Array array = csg_mesh->surface_get_arrays(surface_i);
5558 Ref<Material> mat = csg_mesh->surface_get_material(surface_i);
5559 String mat_name;
5560 if (mat.is_valid()) {
5561 mat_name = mat->get_name();
5562 } else {
5563 // Assign default material when no material is assigned.
5564 mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
5565 }
5566 mesh->add_surface(csg_mesh->surface_get_primitive_type(surface_i),
5567 array, csg_mesh->surface_get_blend_shape_arrays(surface_i), csg_mesh->surface_get_lods(surface_i), mat,
5568 mat_name, csg_mesh->surface_get_format(surface_i));
5569 }
5570 }
5571
5572 Ref<GLTFMesh> gltf_mesh;
5573 gltf_mesh.instantiate();
5574 gltf_mesh->set_mesh(mesh);
5575 GLTFMeshIndex mesh_i = p_state->meshes.size();
5576 p_state->meshes.push_back(gltf_mesh);
5577 p_gltf_node->mesh = mesh_i;
5578 p_gltf_node->xform = csg->get_meshes()[0];
5579 p_gltf_node->set_name(_gen_unique_name(p_state, csg->get_name()));
5580}
5581#endif // MODULE_CSG_ENABLED
5582
5583void GLTFDocument::_create_gltf_node(Ref<GLTFState> p_state, Node *p_scene_parent, GLTFNodeIndex p_current_node_i,
5584 GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_gltf_node, Ref<GLTFNode> p_gltf_node) {
5585 p_state->scene_nodes.insert(p_current_node_i, p_scene_parent);
5586 p_state->nodes.push_back(p_gltf_node);
5587 ERR_FAIL_COND(p_current_node_i == p_parent_node_index);
5588 p_state->nodes.write[p_current_node_i]->parent = p_parent_node_index;
5589 if (p_parent_node_index == -1) {
5590 return;
5591 }
5592 p_state->nodes.write[p_parent_node_index]->children.push_back(p_current_node_i);
5593}
5594
5595void GLTFDocument::_convert_animation_player_to_gltf(AnimationPlayer *p_animation_player, Ref<GLTFState> p_state, GLTFNodeIndex p_gltf_current, GLTFNodeIndex p_gltf_root_index, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent) {
5596 ERR_FAIL_COND(!p_animation_player);
5597 p_state->animation_players.push_back(p_animation_player);
5598 print_verbose(String("glTF: Converting animation player: ") + p_animation_player->get_name());
5599}
5600
5601void GLTFDocument::_check_visibility(Node *p_node, bool &r_retflag) {
5602 r_retflag = true;
5603 Node3D *spatial = Object::cast_to<Node3D>(p_node);
5604 Node2D *node_2d = Object::cast_to<Node2D>(p_node);
5605 if (node_2d && !node_2d->is_visible()) {
5606 return;
5607 }
5608 if (spatial && !spatial->is_visible()) {
5609 return;
5610 }
5611 r_retflag = false;
5612}
5613
5614void GLTFDocument::_convert_camera_to_gltf(Camera3D *camera, Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node) {
5615 ERR_FAIL_COND(!camera);
5616 GLTFCameraIndex camera_index = _convert_camera(p_state, camera);
5617 if (camera_index != -1) {
5618 p_gltf_node->camera = camera_index;
5619 }
5620}
5621
5622void GLTFDocument::_convert_light_to_gltf(Light3D *light, Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node) {
5623 ERR_FAIL_COND(!light);
5624 GLTFLightIndex light_index = _convert_light(p_state, light);
5625 if (light_index != -1) {
5626 p_gltf_node->light = light_index;
5627 }
5628}
5629
5630#ifdef MODULE_GRIDMAP_ENABLED
5631void GLTFDocument::_convert_grid_map_to_gltf(GridMap *p_grid_map, GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_node_index, Ref<GLTFNode> p_gltf_node, Ref<GLTFState> p_state) {
5632 Array cells = p_grid_map->get_used_cells();
5633 for (int32_t k = 0; k < cells.size(); k++) {
5634 GLTFNode *new_gltf_node = memnew(GLTFNode);
5635 p_gltf_node->children.push_back(p_state->nodes.size());
5636 p_state->nodes.push_back(new_gltf_node);
5637 Vector3 cell_location = cells[k];
5638 int32_t cell = p_grid_map->get_cell_item(
5639 Vector3(cell_location.x, cell_location.y, cell_location.z));
5640 Transform3D cell_xform;
5641 cell_xform.basis = p_grid_map->get_basis_with_orthogonal_index(
5642 p_grid_map->get_cell_item_orientation(
5643 Vector3(cell_location.x, cell_location.y, cell_location.z)));
5644 cell_xform.basis.scale(Vector3(p_grid_map->get_cell_scale(),
5645 p_grid_map->get_cell_scale(),
5646 p_grid_map->get_cell_scale()));
5647 cell_xform.set_origin(p_grid_map->map_to_local(
5648 Vector3(cell_location.x, cell_location.y, cell_location.z)));
5649 Ref<GLTFMesh> gltf_mesh;
5650 gltf_mesh.instantiate();
5651 gltf_mesh->set_mesh(_mesh_to_importer_mesh(p_grid_map->get_mesh_library()->get_item_mesh(cell)));
5652 new_gltf_node->mesh = p_state->meshes.size();
5653 p_state->meshes.push_back(gltf_mesh);
5654 new_gltf_node->xform = cell_xform * p_grid_map->get_transform();
5655 new_gltf_node->set_name(_gen_unique_name(p_state, p_grid_map->get_mesh_library()->get_item_name(cell)));
5656 }
5657}
5658#endif // MODULE_GRIDMAP_ENABLED
5659
5660void GLTFDocument::_convert_multi_mesh_instance_to_gltf(
5661 MultiMeshInstance3D *p_multi_mesh_instance,
5662 GLTFNodeIndex p_parent_node_index,
5663 GLTFNodeIndex p_root_node_index,
5664 Ref<GLTFNode> p_gltf_node, Ref<GLTFState> p_state) {
5665 ERR_FAIL_COND(!p_multi_mesh_instance);
5666 Ref<MultiMesh> multi_mesh = p_multi_mesh_instance->get_multimesh();
5667 if (multi_mesh.is_null()) {
5668 return;
5669 }
5670 Ref<GLTFMesh> gltf_mesh;
5671 gltf_mesh.instantiate();
5672 Ref<Mesh> mesh = multi_mesh->get_mesh();
5673 if (mesh.is_null()) {
5674 return;
5675 }
5676 gltf_mesh->set_name(multi_mesh->get_name());
5677 Ref<ImporterMesh> importer_mesh;
5678 importer_mesh.instantiate();
5679 Ref<ArrayMesh> array_mesh = multi_mesh->get_mesh();
5680 if (array_mesh.is_valid()) {
5681 importer_mesh->set_blend_shape_mode(array_mesh->get_blend_shape_mode());
5682 for (int32_t blend_i = 0; blend_i < array_mesh->get_blend_shape_count(); blend_i++) {
5683 importer_mesh->add_blend_shape(array_mesh->get_blend_shape_name(blend_i));
5684 }
5685 }
5686 for (int32_t surface_i = 0; surface_i < mesh->get_surface_count(); surface_i++) {
5687 Ref<Material> mat = mesh->surface_get_material(surface_i);
5688 String material_name;
5689 if (mat.is_valid()) {
5690 material_name = mat->get_name();
5691 }
5692 Array blend_arrays;
5693 if (array_mesh.is_valid()) {
5694 blend_arrays = array_mesh->surface_get_blend_shape_arrays(surface_i);
5695 }
5696 importer_mesh->add_surface(mesh->surface_get_primitive_type(surface_i), mesh->surface_get_arrays(surface_i),
5697 blend_arrays, mesh->surface_get_lods(surface_i), mat, material_name, mesh->surface_get_format(surface_i));
5698 }
5699 gltf_mesh->set_mesh(importer_mesh);
5700 GLTFMeshIndex mesh_index = p_state->meshes.size();
5701 p_state->meshes.push_back(gltf_mesh);
5702 for (int32_t instance_i = 0; instance_i < multi_mesh->get_instance_count();
5703 instance_i++) {
5704 Transform3D transform;
5705 if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_2D) {
5706 Transform2D xform_2d = multi_mesh->get_instance_transform_2d(instance_i);
5707 transform.origin =
5708 Vector3(xform_2d.get_origin().x, 0, xform_2d.get_origin().y);
5709 real_t rotation = xform_2d.get_rotation();
5710 Quaternion quaternion(Vector3(0, 1, 0), rotation);
5711 Size2 scale = xform_2d.get_scale();
5712 transform.basis.set_quaternion_scale(quaternion,
5713 Vector3(scale.x, 0, scale.y));
5714 transform = p_multi_mesh_instance->get_transform() * transform;
5715 } else if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_3D) {
5716 transform = p_multi_mesh_instance->get_transform() *
5717 multi_mesh->get_instance_transform(instance_i);
5718 }
5719 Ref<GLTFNode> new_gltf_node;
5720 new_gltf_node.instantiate();
5721 new_gltf_node->mesh = mesh_index;
5722 new_gltf_node->xform = transform;
5723 new_gltf_node->set_name(_gen_unique_name(p_state, p_multi_mesh_instance->get_name()));
5724 p_gltf_node->children.push_back(p_state->nodes.size());
5725 p_state->nodes.push_back(new_gltf_node);
5726 }
5727}
5728
5729void GLTFDocument::_convert_skeleton_to_gltf(Skeleton3D *p_skeleton3d, Ref<GLTFState> p_state, GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_node_index, Ref<GLTFNode> p_gltf_node) {
5730 Skeleton3D *skeleton = p_skeleton3d;
5731 Ref<GLTFSkeleton> gltf_skeleton;
5732 gltf_skeleton.instantiate();
5733 // GLTFSkeleton is only used to hold internal p_state data. It will not be written to the document.
5734 //
5735 gltf_skeleton->godot_skeleton = skeleton;
5736 GLTFSkeletonIndex skeleton_i = p_state->skeletons.size();
5737 p_state->skeleton3d_to_gltf_skeleton[skeleton->get_instance_id()] = skeleton_i;
5738 p_state->skeletons.push_back(gltf_skeleton);
5739
5740 BoneId bone_count = skeleton->get_bone_count();
5741 for (BoneId bone_i = 0; bone_i < bone_count; bone_i++) {
5742 Ref<GLTFNode> joint_node;
5743 joint_node.instantiate();
5744 // Note that we cannot use _gen_unique_bone_name here, because glTF spec requires all node
5745 // names to be unique regardless of whether or not they are used as joints.
5746 joint_node->set_name(_gen_unique_name(p_state, skeleton->get_bone_name(bone_i)));
5747 Transform3D xform = skeleton->get_bone_pose(bone_i);
5748 joint_node->scale = xform.basis.get_scale();
5749 joint_node->rotation = xform.basis.get_rotation_quaternion();
5750 joint_node->position = xform.origin;
5751 joint_node->joint = true;
5752 GLTFNodeIndex current_node_i = p_state->nodes.size();
5753 p_state->scene_nodes.insert(current_node_i, skeleton);
5754 p_state->nodes.push_back(joint_node);
5755
5756 gltf_skeleton->joints.push_back(current_node_i);
5757 if (skeleton->get_bone_parent(bone_i) == -1) {
5758 gltf_skeleton->roots.push_back(current_node_i);
5759 }
5760 gltf_skeleton->godot_bone_node.insert(bone_i, current_node_i);
5761 }
5762 for (BoneId bone_i = 0; bone_i < bone_count; bone_i++) {
5763 GLTFNodeIndex current_node_i = gltf_skeleton->godot_bone_node[bone_i];
5764 BoneId parent_bone_id = skeleton->get_bone_parent(bone_i);
5765 if (parent_bone_id == -1) {
5766 if (p_parent_node_index != -1) {
5767 p_state->nodes.write[current_node_i]->parent = p_parent_node_index;
5768 p_state->nodes.write[p_parent_node_index]->children.push_back(current_node_i);
5769 }
5770 } else {
5771 GLTFNodeIndex parent_node_i = gltf_skeleton->godot_bone_node[parent_bone_id];
5772 p_state->nodes.write[current_node_i]->parent = parent_node_i;
5773 p_state->nodes.write[parent_node_i]->children.push_back(current_node_i);
5774 }
5775 }
5776 // Remove placeholder skeleton3d node by not creating the gltf node
5777 // Skins are per mesh
5778 for (int node_i = 0; node_i < skeleton->get_child_count(); node_i++) {
5779 _convert_scene_node(p_state, skeleton->get_child(node_i), p_parent_node_index, p_root_node_index);
5780 }
5781}
5782
5783void GLTFDocument::_convert_bone_attachment_to_gltf(BoneAttachment3D *p_bone_attachment, Ref<GLTFState> p_state, GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_node_index, Ref<GLTFNode> p_gltf_node) {
5784 Skeleton3D *skeleton;
5785 // Note that relative transforms to external skeletons and pose overrides are not supported.
5786 if (p_bone_attachment->get_use_external_skeleton()) {
5787 skeleton = cast_to<Skeleton3D>(p_bone_attachment->get_node_or_null(p_bone_attachment->get_external_skeleton()));
5788 } else {
5789 skeleton = cast_to<Skeleton3D>(p_bone_attachment->get_parent());
5790 }
5791 GLTFSkeletonIndex skel_gltf_i = -1;
5792 if (skeleton != nullptr && p_state->skeleton3d_to_gltf_skeleton.has(skeleton->get_instance_id())) {
5793 skel_gltf_i = p_state->skeleton3d_to_gltf_skeleton[skeleton->get_instance_id()];
5794 }
5795 int bone_idx = -1;
5796 if (skeleton != nullptr) {
5797 bone_idx = p_bone_attachment->get_bone_idx();
5798 if (bone_idx == -1) {
5799 bone_idx = skeleton->find_bone(p_bone_attachment->get_bone_name());
5800 }
5801 }
5802 GLTFNodeIndex par_node_index = p_parent_node_index;
5803 if (skeleton != nullptr && bone_idx != -1 && skel_gltf_i != -1) {
5804 Ref<GLTFSkeleton> gltf_skeleton = p_state->skeletons.write[skel_gltf_i];
5805 gltf_skeleton->bone_attachments.push_back(p_bone_attachment);
5806 par_node_index = gltf_skeleton->joints[bone_idx];
5807 }
5808
5809 for (int node_i = 0; node_i < p_bone_attachment->get_child_count(); node_i++) {
5810 _convert_scene_node(p_state, p_bone_attachment->get_child(node_i), par_node_index, p_root_node_index);
5811 }
5812}
5813
5814void GLTFDocument::_convert_mesh_instance_to_gltf(MeshInstance3D *p_scene_parent, Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node) {
5815 GLTFMeshIndex gltf_mesh_index = _convert_mesh_to_gltf(p_state, p_scene_parent);
5816 if (gltf_mesh_index != -1) {
5817 p_gltf_node->mesh = gltf_mesh_index;
5818 }
5819}
5820
5821void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root) {
5822 Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
5823
5824 if (gltf_node->skeleton >= 0) {
5825 _generate_skeleton_bone_node(p_state, p_node_index, p_scene_parent, p_scene_root);
5826 return;
5827 }
5828
5829 Node3D *current_node = nullptr;
5830
5831 // Is our parent a skeleton
5832 Skeleton3D *active_skeleton = Object::cast_to<Skeleton3D>(p_scene_parent);
5833
5834 const bool non_bone_parented_to_skeleton = active_skeleton;
5835
5836 // skinned meshes must not be placed in a bone attachment.
5837 if (non_bone_parented_to_skeleton && gltf_node->skin < 0) {
5838 // Bone Attachment - Parent Case
5839 BoneAttachment3D *bone_attachment = _generate_bone_attachment(p_state, active_skeleton, p_node_index, gltf_node->parent);
5840
5841 p_scene_parent->add_child(bone_attachment, true);
5842 bone_attachment->set_owner(p_scene_root);
5843
5844 // There is no gltf_node that represent this, so just directly create a unique name
5845 bone_attachment->set_name(gltf_node->get_name());
5846
5847 // We change the scene_parent to our bone attachment now. We do not set current_node because we want to make the node
5848 // and attach it to the bone_attachment
5849 p_scene_parent = bone_attachment;
5850 }
5851 // Check if any GLTFDocumentExtension classes want to generate a node for us.
5852 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
5853 ERR_CONTINUE(ext.is_null());
5854 current_node = ext->generate_scene_node(p_state, gltf_node, p_scene_parent);
5855 if (current_node) {
5856 break;
5857 }
5858 }
5859 // If none of our GLTFDocumentExtension classes generated us a node, we generate one.
5860 if (!current_node) {
5861 if (gltf_node->skin >= 0 && gltf_node->mesh >= 0 && !gltf_node->children.is_empty()) {
5862 // GLTF specifies that skinned meshes should ignore their node transforms,
5863 // only being controlled by the skeleton, so Godot will reparent a skinned
5864 // mesh to its skeleton. However, we still need to ensure any child nodes
5865 // keep their place in the tree, so if there are any child nodes, the skinned
5866 // mesh must not be the base node, so generate an empty spatial base.
5867 current_node = _generate_spatial(p_state, p_node_index);
5868 Node3D *mesh_inst = _generate_mesh_instance(p_state, p_node_index);
5869 mesh_inst->set_name(gltf_node->get_name());
5870 current_node->add_child(mesh_inst, true);
5871 } else if (gltf_node->mesh >= 0) {
5872 current_node = _generate_mesh_instance(p_state, p_node_index);
5873 } else if (gltf_node->camera >= 0) {
5874 current_node = _generate_camera(p_state, p_node_index);
5875 } else if (gltf_node->light >= 0) {
5876 current_node = _generate_light(p_state, p_node_index);
5877 } else {
5878 current_node = _generate_spatial(p_state, p_node_index);
5879 }
5880 }
5881 String gltf_node_name = gltf_node->get_name();
5882 if (!gltf_node_name.is_empty()) {
5883 current_node->set_name(gltf_node_name);
5884 }
5885 // Add the node we generated and set the owner to the scene root.
5886 p_scene_parent->add_child(current_node, true);
5887 if (current_node != p_scene_root) {
5888 Array args;
5889 args.append(p_scene_root);
5890 current_node->propagate_call(StringName("set_owner"), args);
5891 }
5892 current_node->set_transform(gltf_node->xform);
5893
5894 p_state->scene_nodes.insert(p_node_index, current_node);
5895 for (int i = 0; i < gltf_node->children.size(); ++i) {
5896 _generate_scene_node(p_state, gltf_node->children[i], current_node, p_scene_root);
5897 }
5898}
5899
5900void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root) {
5901 Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
5902
5903 Node3D *current_node = nullptr;
5904
5905 Skeleton3D *skeleton = p_state->skeletons[gltf_node->skeleton]->godot_skeleton;
5906 // In this case, this node is already a bone in skeleton.
5907 const bool is_skinned_mesh = (gltf_node->skin >= 0 && gltf_node->mesh >= 0);
5908 const bool requires_extra_node = (gltf_node->mesh >= 0 || gltf_node->camera >= 0 || gltf_node->light >= 0);
5909
5910 Skeleton3D *active_skeleton = Object::cast_to<Skeleton3D>(p_scene_parent);
5911 if (active_skeleton != skeleton) {
5912 if (active_skeleton) {
5913 // Should no longer be possible.
5914 ERR_PRINT(vformat("glTF: Generating scene detected direct parented Skeletons at node %d", p_node_index));
5915 BoneAttachment3D *bone_attachment = _generate_bone_attachment(p_state, active_skeleton, p_node_index, gltf_node->parent);
5916 p_scene_parent->add_child(bone_attachment, true);
5917 bone_attachment->set_owner(p_scene_root);
5918 // There is no gltf_node that represent this, so just directly create a unique name
5919 bone_attachment->set_name(_gen_unique_name(p_state, "BoneAttachment3D"));
5920 // We change the scene_parent to our bone attachment now. We do not set current_node because we want to make the node
5921 // and attach it to the bone_attachment
5922 p_scene_parent = bone_attachment;
5923 }
5924 if (skeleton->get_parent() == nullptr) {
5925 p_scene_parent->add_child(skeleton, true);
5926 skeleton->set_owner(p_scene_root);
5927 }
5928 }
5929
5930 active_skeleton = skeleton;
5931 current_node = active_skeleton;
5932
5933 if (requires_extra_node) {
5934 current_node = nullptr;
5935 // skinned meshes must not be placed in a bone attachment.
5936 if (!is_skinned_mesh) {
5937 // Bone Attachment - Same Node Case
5938 BoneAttachment3D *bone_attachment = _generate_bone_attachment(p_state, active_skeleton, p_node_index, p_node_index);
5939
5940 p_scene_parent->add_child(bone_attachment, true);
5941 bone_attachment->set_owner(p_scene_root);
5942
5943 // There is no gltf_node that represent this, so just directly create a unique name
5944 bone_attachment->set_name(gltf_node->get_name());
5945
5946 // We change the scene_parent to our bone attachment now. We do not set current_node because we want to make the node
5947 // and attach it to the bone_attachment
5948 p_scene_parent = bone_attachment;
5949 }
5950 // Check if any GLTFDocumentExtension classes want to generate a node for us.
5951 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
5952 ERR_CONTINUE(ext.is_null());
5953 current_node = ext->generate_scene_node(p_state, gltf_node, p_scene_parent);
5954 if (current_node) {
5955 break;
5956 }
5957 }
5958 // If none of our GLTFDocumentExtension classes generated us a node, we generate one.
5959 if (!current_node) {
5960 if (gltf_node->mesh >= 0) {
5961 current_node = _generate_mesh_instance(p_state, p_node_index);
5962 } else if (gltf_node->camera >= 0) {
5963 current_node = _generate_camera(p_state, p_node_index);
5964 } else if (gltf_node->light >= 0) {
5965 current_node = _generate_light(p_state, p_node_index);
5966 } else {
5967 current_node = _generate_spatial(p_state, p_node_index);
5968 }
5969 }
5970 // Add the node we generated and set the owner to the scene root.
5971 p_scene_parent->add_child(current_node, true);
5972 if (current_node != p_scene_root) {
5973 Array args;
5974 args.append(p_scene_root);
5975 current_node->propagate_call(StringName("set_owner"), args);
5976 }
5977 // Do not set transform here. Transform is already applied to our bone.
5978 current_node->set_name(gltf_node->get_name());
5979 }
5980
5981 p_state->scene_nodes.insert(p_node_index, current_node);
5982
5983 for (int i = 0; i < gltf_node->children.size(); ++i) {
5984 _generate_scene_node(p_state, gltf_node->children[i], active_skeleton, p_scene_root);
5985 }
5986}
5987
5988template <class T>
5989struct SceneFormatImporterGLTFInterpolate {
5990 T lerp(const T &a, const T &b, float c) const {
5991 return a + (b - a) * c;
5992 }
5993
5994 T catmull_rom(const T &p0, const T &p1, const T &p2, const T &p3, float t) {
5995 const float t2 = t * t;
5996 const float t3 = t2 * t;
5997
5998 return 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4.0f * p2 - p3) * t2 + (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3);
5999 }
6000
6001 T bezier(T start, T control_1, T control_2, T end, float t) {
6002 /* Formula from Wikipedia article on Bezier curves. */
6003 const real_t omt = (1.0 - t);
6004 const real_t omt2 = omt * omt;
6005 const real_t omt3 = omt2 * omt;
6006 const real_t t2 = t * t;
6007 const real_t t3 = t2 * t;
6008
6009 return start * omt3 + control_1 * omt2 * t * 3.0 + control_2 * omt * t2 * 3.0 + end * t3;
6010 }
6011};
6012
6013// thank you for existing, partial specialization
6014template <>
6015struct SceneFormatImporterGLTFInterpolate<Quaternion> {
6016 Quaternion lerp(const Quaternion &a, const Quaternion &b, const float c) const {
6017 ERR_FAIL_COND_V_MSG(!a.is_normalized(), Quaternion(), "The quaternion \"a\" must be normalized.");
6018 ERR_FAIL_COND_V_MSG(!b.is_normalized(), Quaternion(), "The quaternion \"b\" must be normalized.");
6019
6020 return a.slerp(b, c).normalized();
6021 }
6022
6023 Quaternion catmull_rom(const Quaternion &p0, const Quaternion &p1, const Quaternion &p2, const Quaternion &p3, const float c) {
6024 ERR_FAIL_COND_V_MSG(!p1.is_normalized(), Quaternion(), "The quaternion \"p1\" must be normalized.");
6025 ERR_FAIL_COND_V_MSG(!p2.is_normalized(), Quaternion(), "The quaternion \"p2\" must be normalized.");
6026
6027 return p1.slerp(p2, c).normalized();
6028 }
6029
6030 Quaternion bezier(const Quaternion start, const Quaternion control_1, const Quaternion control_2, const Quaternion end, const float t) {
6031 ERR_FAIL_COND_V_MSG(!start.is_normalized(), Quaternion(), "The start quaternion must be normalized.");
6032 ERR_FAIL_COND_V_MSG(!end.is_normalized(), Quaternion(), "The end quaternion must be normalized.");
6033
6034 return start.slerp(end, t).normalized();
6035 }
6036};
6037
6038template <class T>
6039T GLTFDocument::_interpolate_track(const Vector<real_t> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) {
6040 ERR_FAIL_COND_V(!p_values.size(), T());
6041 if (p_times.size() != (p_values.size() / (p_interp == GLTFAnimation::INTERP_CUBIC_SPLINE ? 3 : 1))) {
6042 ERR_PRINT_ONCE("The interpolated values are not corresponding to its times.");
6043 return p_values[0];
6044 }
6045 //could use binary search, worth it?
6046 int idx = -1;
6047 for (int i = 0; i < p_times.size(); i++) {
6048 if (p_times[i] > p_time) {
6049 break;
6050 }
6051 idx++;
6052 }
6053
6054 SceneFormatImporterGLTFInterpolate<T> interp;
6055
6056 switch (p_interp) {
6057 case GLTFAnimation::INTERP_LINEAR: {
6058 if (idx == -1) {
6059 return p_values[0];
6060 } else if (idx >= p_times.size() - 1) {
6061 return p_values[p_times.size() - 1];
6062 }
6063
6064 const float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]);
6065
6066 return interp.lerp(p_values[idx], p_values[idx + 1], c);
6067 } break;
6068 case GLTFAnimation::INTERP_STEP: {
6069 if (idx == -1) {
6070 return p_values[0];
6071 } else if (idx >= p_times.size() - 1) {
6072 return p_values[p_times.size() - 1];
6073 }
6074
6075 return p_values[idx];
6076 } break;
6077 case GLTFAnimation::INTERP_CATMULLROMSPLINE: {
6078 if (idx == -1) {
6079 return p_values[1];
6080 } else if (idx >= p_times.size() - 1) {
6081 return p_values[1 + p_times.size() - 1];
6082 }
6083
6084 const float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]);
6085
6086 return interp.catmull_rom(p_values[idx - 1], p_values[idx], p_values[idx + 1], p_values[idx + 3], c);
6087 } break;
6088 case GLTFAnimation::INTERP_CUBIC_SPLINE: {
6089 if (idx == -1) {
6090 return p_values[1];
6091 } else if (idx >= p_times.size() - 1) {
6092 return p_values[(p_times.size() - 1) * 3 + 1];
6093 }
6094
6095 const float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]);
6096
6097 const T from = p_values[idx * 3 + 1];
6098 const T c1 = from + p_values[idx * 3 + 2];
6099 const T to = p_values[idx * 3 + 4];
6100 const T c2 = to + p_values[idx * 3 + 3];
6101
6102 return interp.bezier(from, c1, c2, to, c);
6103 } break;
6104 }
6105
6106 ERR_FAIL_V(p_values[0]);
6107}
6108
6109void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, const GLTFAnimationIndex p_index, const float p_bake_fps, const bool p_trimming, const bool p_remove_immutable_tracks) {
6110 Ref<GLTFAnimation> anim = p_state->animations[p_index];
6111
6112 String anim_name = anim->get_name();
6113 if (anim_name.is_empty()) {
6114 // No node represent these, and they are not in the hierarchy, so just make a unique name
6115 anim_name = _gen_unique_name(p_state, "Animation");
6116 }
6117
6118 Ref<Animation> animation;
6119 animation.instantiate();
6120 animation->set_name(anim_name);
6121
6122 if (anim->get_loop()) {
6123 animation->set_loop_mode(Animation::LOOP_LINEAR);
6124 }
6125
6126 double anim_start = p_trimming ? INFINITY : 0.0;
6127 double anim_end = 0.0;
6128
6129 for (const KeyValue<int, GLTFAnimation::Track> &track_i : anim->get_tracks()) {
6130 const GLTFAnimation::Track &track = track_i.value;
6131 //need to find the path: for skeletons, weight tracks will affect the mesh
6132 NodePath node_path;
6133 //for skeletons, transform tracks always affect bones
6134 NodePath transform_node_path;
6135 //for meshes, especially skinned meshes, there are cases where it will be added as a child
6136 NodePath mesh_instance_node_path;
6137
6138 GLTFNodeIndex node_index = track_i.key;
6139
6140 const Ref<GLTFNode> gltf_node = p_state->nodes[track_i.key];
6141
6142 Node *root = p_animation_player->get_parent();
6143 ERR_FAIL_COND(root == nullptr);
6144 HashMap<GLTFNodeIndex, Node *>::Iterator node_element = p_state->scene_nodes.find(node_index);
6145 ERR_CONTINUE_MSG(!node_element, vformat("Unable to find node %d for animation.", node_index));
6146 node_path = root->get_path_to(node_element->value);
6147 HashMap<GLTFNodeIndex, ImporterMeshInstance3D *>::Iterator mesh_instance_element = p_state->scene_mesh_instances.find(node_index);
6148 if (mesh_instance_element) {
6149 mesh_instance_node_path = root->get_path_to(mesh_instance_element->value);
6150 } else {
6151 mesh_instance_node_path = node_path;
6152 }
6153
6154 if (gltf_node->skeleton >= 0) {
6155 const Skeleton3D *sk = p_state->skeletons[gltf_node->skeleton]->godot_skeleton;
6156 ERR_FAIL_COND(sk == nullptr);
6157
6158 const String path = p_animation_player->get_parent()->get_path_to(sk);
6159 const String bone = gltf_node->get_name();
6160 transform_node_path = path + ":" + bone;
6161 } else {
6162 transform_node_path = node_path;
6163 }
6164
6165 if (p_trimming) {
6166 for (int i = 0; i < track.rotation_track.times.size(); i++) {
6167 anim_start = MIN(anim_start, track.rotation_track.times[i]);
6168 anim_end = MAX(anim_end, track.rotation_track.times[i]);
6169 }
6170 for (int i = 0; i < track.position_track.times.size(); i++) {
6171 anim_start = MIN(anim_start, track.position_track.times[i]);
6172 anim_end = MAX(anim_end, track.position_track.times[i]);
6173 }
6174 for (int i = 0; i < track.scale_track.times.size(); i++) {
6175 anim_start = MIN(anim_start, track.scale_track.times[i]);
6176 anim_end = MAX(anim_end, track.scale_track.times[i]);
6177 }
6178 for (int i = 0; i < track.weight_tracks.size(); i++) {
6179 for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
6180 anim_start = MIN(anim_start, track.weight_tracks[i].times[j]);
6181 anim_end = MAX(anim_end, track.weight_tracks[i].times[j]);
6182 }
6183 }
6184 } else {
6185 // If you don't use trimming and the first key time is not at 0.0, fake keys will be inserted.
6186 for (int i = 0; i < track.rotation_track.times.size(); i++) {
6187 anim_end = MAX(anim_end, track.rotation_track.times[i]);
6188 }
6189 for (int i = 0; i < track.position_track.times.size(); i++) {
6190 anim_end = MAX(anim_end, track.position_track.times[i]);
6191 }
6192 for (int i = 0; i < track.scale_track.times.size(); i++) {
6193 anim_end = MAX(anim_end, track.scale_track.times[i]);
6194 }
6195 for (int i = 0; i < track.weight_tracks.size(); i++) {
6196 for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
6197 anim_end = MAX(anim_end, track.weight_tracks[i].times[j]);
6198 }
6199 }
6200 }
6201
6202 // Animated TRS properties will not affect a skinned mesh.
6203 const bool transform_affects_skinned_mesh_instance = gltf_node->skeleton < 0 && gltf_node->skin >= 0;
6204 if ((track.rotation_track.values.size() || track.position_track.values.size() || track.scale_track.values.size()) && !transform_affects_skinned_mesh_instance) {
6205 //make transform track
6206 int base_idx = animation->get_track_count();
6207 int position_idx = -1;
6208 int rotation_idx = -1;
6209 int scale_idx = -1;
6210
6211 if (track.position_track.values.size()) {
6212 bool is_default = true; //discard the track if all it contains is default values
6213 if (p_remove_immutable_tracks) {
6214 Vector3 base_pos = p_state->nodes[track_i.key]->position;
6215 for (int i = 0; i < track.position_track.times.size(); i++) {
6216 Vector3 value = track.position_track.values[track.position_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i];
6217 if (!value.is_equal_approx(base_pos)) {
6218 is_default = false;
6219 break;
6220 }
6221 }
6222 }
6223 if (!p_remove_immutable_tracks || !is_default) {
6224 position_idx = base_idx;
6225 animation->add_track(Animation::TYPE_POSITION_3D);
6226 animation->track_set_path(position_idx, transform_node_path);
6227 animation->track_set_imported(position_idx, true); //helps merging later
6228 base_idx++;
6229 }
6230 }
6231 if (track.rotation_track.values.size()) {
6232 bool is_default = true; //discard the track if all it contains is default values
6233 if (p_remove_immutable_tracks) {
6234 Quaternion base_rot = p_state->nodes[track_i.key]->rotation.normalized();
6235 for (int i = 0; i < track.rotation_track.times.size(); i++) {
6236 Quaternion value = track.rotation_track.values[track.rotation_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i].normalized();
6237 if (!value.is_equal_approx(base_rot)) {
6238 is_default = false;
6239 break;
6240 }
6241 }
6242 }
6243 if (!p_remove_immutable_tracks || !is_default) {
6244 rotation_idx = base_idx;
6245 animation->add_track(Animation::TYPE_ROTATION_3D);
6246 animation->track_set_path(rotation_idx, transform_node_path);
6247 animation->track_set_imported(rotation_idx, true); //helps merging later
6248 base_idx++;
6249 }
6250 }
6251 if (track.scale_track.values.size()) {
6252 bool is_default = true; //discard the track if all it contains is default values
6253 if (p_remove_immutable_tracks) {
6254 Vector3 base_scale = p_state->nodes[track_i.key]->scale;
6255 for (int i = 0; i < track.scale_track.times.size(); i++) {
6256 Vector3 value = track.scale_track.values[track.scale_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i];
6257 if (!value.is_equal_approx(base_scale)) {
6258 is_default = false;
6259 break;
6260 }
6261 }
6262 }
6263 if (!p_remove_immutable_tracks || !is_default) {
6264 scale_idx = base_idx;
6265 animation->add_track(Animation::TYPE_SCALE_3D);
6266 animation->track_set_path(scale_idx, transform_node_path);
6267 animation->track_set_imported(scale_idx, true); //helps merging later
6268 base_idx++;
6269 }
6270 }
6271
6272 const double increment = 1.0 / p_bake_fps;
6273 double time = anim_start;
6274
6275 Vector3 base_pos;
6276 Quaternion base_rot;
6277 Vector3 base_scale = Vector3(1, 1, 1);
6278
6279 if (rotation_idx == -1) {
6280 base_rot = p_state->nodes[track_i.key]->rotation.normalized();
6281 }
6282
6283 if (position_idx == -1) {
6284 base_pos = p_state->nodes[track_i.key]->position;
6285 }
6286
6287 if (scale_idx == -1) {
6288 base_scale = p_state->nodes[track_i.key]->scale;
6289 }
6290
6291 bool last = false;
6292 while (true) {
6293 Vector3 pos = base_pos;
6294 Quaternion rot = base_rot;
6295 Vector3 scale = base_scale;
6296
6297 if (position_idx >= 0) {
6298 pos = _interpolate_track<Vector3>(track.position_track.times, track.position_track.values, time, track.position_track.interpolation);
6299 animation->position_track_insert_key(position_idx, time - anim_start, pos);
6300 }
6301
6302 if (rotation_idx >= 0) {
6303 rot = _interpolate_track<Quaternion>(track.rotation_track.times, track.rotation_track.values, time, track.rotation_track.interpolation);
6304 animation->rotation_track_insert_key(rotation_idx, time - anim_start, rot);
6305 }
6306
6307 if (scale_idx >= 0) {
6308 scale = _interpolate_track<Vector3>(track.scale_track.times, track.scale_track.values, time, track.scale_track.interpolation);
6309 animation->scale_track_insert_key(scale_idx, time - anim_start, scale);
6310 }
6311
6312 if (last) {
6313 break;
6314 }
6315 time += increment;
6316 if (time >= anim_end) {
6317 last = true;
6318 time = anim_end;
6319 }
6320 }
6321 }
6322
6323 for (int i = 0; i < track.weight_tracks.size(); i++) {
6324 ERR_CONTINUE(gltf_node->mesh < 0 || gltf_node->mesh >= p_state->meshes.size());
6325 Ref<GLTFMesh> mesh = p_state->meshes[gltf_node->mesh];
6326 ERR_CONTINUE(mesh.is_null());
6327 ERR_CONTINUE(mesh->get_mesh().is_null());
6328 ERR_CONTINUE(mesh->get_mesh()->get_mesh().is_null());
6329
6330 const String blend_path = String(mesh_instance_node_path) + ":" + String(mesh->get_mesh()->get_blend_shape_name(i));
6331
6332 const int track_idx = animation->get_track_count();
6333 animation->add_track(Animation::TYPE_BLEND_SHAPE);
6334 animation->track_set_path(track_idx, blend_path);
6335 animation->track_set_imported(track_idx, true); //helps merging later
6336
6337 // Only LINEAR and STEP (NEAREST) can be supported out of the box by Godot's Animation,
6338 // the other modes have to be baked.
6339 GLTFAnimation::Interpolation gltf_interp = track.weight_tracks[i].interpolation;
6340 if (gltf_interp == GLTFAnimation::INTERP_LINEAR || gltf_interp == GLTFAnimation::INTERP_STEP) {
6341 animation->track_set_interpolation_type(track_idx, gltf_interp == GLTFAnimation::INTERP_STEP ? Animation::INTERPOLATION_NEAREST : Animation::INTERPOLATION_LINEAR);
6342 for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
6343 const float t = track.weight_tracks[i].times[j];
6344 const float attribs = track.weight_tracks[i].values[j];
6345 animation->blend_shape_track_insert_key(track_idx, t, attribs);
6346 }
6347 } else {
6348 // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
6349 const double increment = 1.0 / p_bake_fps;
6350 double time = 0.0;
6351 bool last = false;
6352 while (true) {
6353 real_t blend = _interpolate_track<real_t>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, gltf_interp);
6354 animation->blend_shape_track_insert_key(track_idx, time - anim_start, blend);
6355 if (last) {
6356 break;
6357 }
6358 time += increment;
6359 if (time >= anim_end) {
6360 last = true;
6361 time = anim_end;
6362 }
6363 }
6364 }
6365 }
6366 }
6367
6368 animation->set_length(anim_end - anim_start);
6369
6370 Ref<AnimationLibrary> library;
6371 if (!p_animation_player->has_animation_library("")) {
6372 library.instantiate();
6373 p_animation_player->add_animation_library("", library);
6374 } else {
6375 library = p_animation_player->get_animation_library("");
6376 }
6377 library->add_animation(anim_name, animation);
6378}
6379
6380void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> p_state) {
6381 for (GLTFNodeIndex mi_node_i = 0; mi_node_i < p_state->nodes.size(); ++mi_node_i) {
6382 Ref<GLTFNode> node = p_state->nodes[mi_node_i];
6383
6384 if (node->mesh < 0) {
6385 continue;
6386 }
6387 HashMap<GLTFNodeIndex, Node *>::Iterator mi_element = p_state->scene_nodes.find(mi_node_i);
6388 if (!mi_element) {
6389 continue;
6390 }
6391 MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(mi_element->value);
6392 if (!mi) {
6393 continue;
6394 }
6395 Transform3D mi_xform = mi->get_transform();
6396 node->scale = mi_xform.basis.get_scale();
6397 node->rotation = mi_xform.basis.get_rotation_quaternion();
6398 node->position = mi_xform.origin;
6399
6400 Node *skel_node = mi->get_node_or_null(mi->get_skeleton_path());
6401 Skeleton3D *godot_skeleton = Object::cast_to<Skeleton3D>(skel_node);
6402 if (!godot_skeleton || godot_skeleton->get_bone_count() == 0) {
6403 continue;
6404 }
6405 // At this point in the code, we know we have a Skeleton3D with at least one bone.
6406 Ref<Skin> skin = mi->get_skin();
6407 Ref<GLTFSkin> gltf_skin;
6408 gltf_skin.instantiate();
6409 Array json_joints;
6410 if (p_state->skeleton3d_to_gltf_skeleton.has(godot_skeleton->get_instance_id())) {
6411 // This is a skinned mesh. If the mesh has no ARRAY_WEIGHTS or ARRAY_BONES, it will be invisible.
6412 const GLTFSkeletonIndex skeleton_gltf_i = p_state->skeleton3d_to_gltf_skeleton[godot_skeleton->get_instance_id()];
6413 Ref<GLTFSkeleton> gltf_skeleton = p_state->skeletons[skeleton_gltf_i];
6414 int bone_cnt = godot_skeleton->get_bone_count();
6415 ERR_FAIL_COND(bone_cnt != gltf_skeleton->joints.size());
6416
6417 ObjectID gltf_skin_key;
6418 if (skin.is_valid()) {
6419 gltf_skin_key = skin->get_instance_id();
6420 }
6421 ObjectID gltf_skel_key = godot_skeleton->get_instance_id();
6422 GLTFSkinIndex skin_gltf_i = -1;
6423 GLTFNodeIndex root_gltf_i = -1;
6424 if (!gltf_skeleton->roots.is_empty()) {
6425 root_gltf_i = gltf_skeleton->roots[0];
6426 }
6427 if (p_state->skin_and_skeleton3d_to_gltf_skin.has(gltf_skin_key) && p_state->skin_and_skeleton3d_to_gltf_skin[gltf_skin_key].has(gltf_skel_key)) {
6428 skin_gltf_i = p_state->skin_and_skeleton3d_to_gltf_skin[gltf_skin_key][gltf_skel_key];
6429 } else {
6430 if (skin.is_null()) {
6431 // Note that gltf_skin_key should remain null, so these can share a reference.
6432 skin = godot_skeleton->create_skin_from_rest_transforms();
6433 }
6434 gltf_skin.instantiate();
6435 gltf_skin->godot_skin = skin;
6436 gltf_skin->set_name(skin->get_name());
6437 gltf_skin->skeleton = skeleton_gltf_i;
6438 gltf_skin->skin_root = root_gltf_i;
6439 //gltf_state->godot_to_gltf_node[skel_node]
6440 HashMap<StringName, int> bone_name_to_idx;
6441 for (int bone_i = 0; bone_i < bone_cnt; bone_i++) {
6442 bone_name_to_idx[godot_skeleton->get_bone_name(bone_i)] = bone_i;
6443 }
6444 for (int bind_i = 0, cnt = skin->get_bind_count(); bind_i < cnt; bind_i++) {
6445 int bone_i = skin->get_bind_bone(bind_i);
6446 Transform3D bind_pose = skin->get_bind_pose(bind_i);
6447 StringName bind_name = skin->get_bind_name(bind_i);
6448 if (bind_name != StringName()) {
6449 bone_i = bone_name_to_idx[bind_name];
6450 }
6451 ERR_CONTINUE(bone_i < 0 || bone_i >= bone_cnt);
6452 if (bind_name == StringName()) {
6453 bind_name = godot_skeleton->get_bone_name(bone_i);
6454 }
6455 GLTFNodeIndex skeleton_bone_i = gltf_skeleton->joints[bone_i];
6456 gltf_skin->joints_original.push_back(skeleton_bone_i);
6457 gltf_skin->joints.push_back(skeleton_bone_i);
6458 gltf_skin->inverse_binds.push_back(bind_pose);
6459 if (godot_skeleton->get_bone_parent(bone_i) == -1) {
6460 gltf_skin->roots.push_back(skeleton_bone_i);
6461 }
6462 gltf_skin->joint_i_to_bone_i[bind_i] = bone_i;
6463 gltf_skin->joint_i_to_name[bind_i] = bind_name;
6464 }
6465 skin_gltf_i = p_state->skins.size();
6466 p_state->skins.push_back(gltf_skin);
6467 p_state->skin_and_skeleton3d_to_gltf_skin[gltf_skin_key][gltf_skel_key] = skin_gltf_i;
6468 }
6469 node->skin = skin_gltf_i;
6470 node->skeleton = skeleton_gltf_i;
6471 }
6472 }
6473}
6474
6475float GLTFDocument::solve_metallic(float p_dielectric_specular, float p_diffuse, float p_specular, float p_one_minus_specular_strength) {
6476 if (p_specular <= p_dielectric_specular) {
6477 return 0.0f;
6478 }
6479
6480 const float a = p_dielectric_specular;
6481 const float b = p_diffuse * p_one_minus_specular_strength / (1.0f - p_dielectric_specular) + p_specular - 2.0f * p_dielectric_specular;
6482 const float c = p_dielectric_specular - p_specular;
6483 const float D = b * b - 4.0f * a * c;
6484 return CLAMP((-b + Math::sqrt(D)) / (2.0f * a), 0.0f, 1.0f);
6485}
6486
6487float GLTFDocument::get_perceived_brightness(const Color p_color) {
6488 const Color coeff = Color(R_BRIGHTNESS_COEFF, G_BRIGHTNESS_COEFF, B_BRIGHTNESS_COEFF);
6489 const Color value = coeff * (p_color * p_color);
6490
6491 const float r = value.r;
6492 const float g = value.g;
6493 const float b = value.b;
6494
6495 return Math::sqrt(r + g + b);
6496}
6497
6498float GLTFDocument::get_max_component(const Color &p_color) {
6499 const float r = p_color.r;
6500 const float g = p_color.g;
6501 const float b = p_color.b;
6502
6503 return MAX(MAX(r, g), b);
6504}
6505
6506void GLTFDocument::_process_mesh_instances(Ref<GLTFState> p_state) {
6507 for (GLTFNodeIndex node_i = 0; node_i < p_state->nodes.size(); ++node_i) {
6508 Ref<GLTFNode> node = p_state->nodes[node_i];
6509
6510 if (node->skin >= 0 && node->mesh >= 0) {
6511 const GLTFSkinIndex skin_i = node->skin;
6512
6513 ImporterMeshInstance3D *mi = nullptr;
6514 HashMap<GLTFNodeIndex, ImporterMeshInstance3D *>::Iterator mi_element = p_state->scene_mesh_instances.find(node_i);
6515 if (mi_element) {
6516 mi = mi_element->value;
6517 } else {
6518 HashMap<GLTFNodeIndex, Node *>::Iterator si_element = p_state->scene_nodes.find(node_i);
6519 ERR_CONTINUE_MSG(!si_element, vformat("Unable to find node %d", node_i));
6520 mi = Object::cast_to<ImporterMeshInstance3D>(si_element->value);
6521 ERR_CONTINUE_MSG(mi == nullptr, vformat("Unable to cast node %d of type %s to ImporterMeshInstance3D", node_i, si_element->value->get_class_name()));
6522 }
6523
6524 const GLTFSkeletonIndex skel_i = p_state->skins.write[node->skin]->skeleton;
6525 Ref<GLTFSkeleton> gltf_skeleton = p_state->skeletons.write[skel_i];
6526 Skeleton3D *skeleton = gltf_skeleton->godot_skeleton;
6527 ERR_CONTINUE_MSG(skeleton == nullptr, vformat("Unable to find Skeleton for node %d skin %d", node_i, skin_i));
6528
6529 mi->get_parent()->remove_child(mi);
6530 skeleton->add_child(mi, true);
6531 mi->set_owner(skeleton->get_owner());
6532
6533 mi->set_skin(p_state->skins.write[skin_i]->godot_skin);
6534 mi->set_skeleton_path(mi->get_path_to(skeleton));
6535 mi->set_transform(Transform3D());
6536 }
6537 }
6538}
6539
6540GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_state, GLTFAnimation::Track p_track, Ref<Animation> p_animation, int32_t p_track_i, GLTFNodeIndex p_node_i) {
6541 Animation::InterpolationType interpolation = p_animation->track_get_interpolation_type(p_track_i);
6542
6543 GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
6544 if (interpolation == Animation::InterpolationType::INTERPOLATION_LINEAR) {
6545 gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
6546 } else if (interpolation == Animation::InterpolationType::INTERPOLATION_NEAREST) {
6547 gltf_interpolation = GLTFAnimation::INTERP_STEP;
6548 } else if (interpolation == Animation::InterpolationType::INTERPOLATION_CUBIC) {
6549 gltf_interpolation = GLTFAnimation::INTERP_CUBIC_SPLINE;
6550 }
6551 Animation::TrackType track_type = p_animation->track_get_type(p_track_i);
6552 int32_t key_count = p_animation->track_get_key_count(p_track_i);
6553 Vector<real_t> times;
6554 times.resize(key_count);
6555 String path = p_animation->track_get_path(p_track_i);
6556 for (int32_t key_i = 0; key_i < key_count; key_i++) {
6557 times.write[key_i] = p_animation->track_get_key_time(p_track_i, key_i);
6558 }
6559 double anim_end = p_animation->get_length();
6560 if (track_type == Animation::TYPE_SCALE_3D) {
6561 if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) {
6562 gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
6563 p_track.scale_track.times.clear();
6564 p_track.scale_track.values.clear();
6565 // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
6566 const double increment = 1.0 / BAKE_FPS;
6567 double time = 0.0;
6568 bool last = false;
6569 while (true) {
6570 Vector3 scale;
6571 Error err = p_animation->try_scale_track_interpolate(p_track_i, time, &scale);
6572 ERR_CONTINUE(err != OK);
6573 p_track.scale_track.values.push_back(scale);
6574 p_track.scale_track.times.push_back(time);
6575 if (last) {
6576 break;
6577 }
6578 time += increment;
6579 if (time >= anim_end) {
6580 last = true;
6581 time = anim_end;
6582 }
6583 }
6584 } else {
6585 p_track.scale_track.times = times;
6586 p_track.scale_track.interpolation = gltf_interpolation;
6587 p_track.scale_track.values.resize(key_count);
6588 for (int32_t key_i = 0; key_i < key_count; key_i++) {
6589 Vector3 scale;
6590 Error err = p_animation->scale_track_get_key(p_track_i, key_i, &scale);
6591 ERR_CONTINUE(err != OK);
6592 p_track.scale_track.values.write[key_i] = scale;
6593 }
6594 }
6595 } else if (track_type == Animation::TYPE_POSITION_3D) {
6596 if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) {
6597 gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
6598 p_track.position_track.times.clear();
6599 p_track.position_track.values.clear();
6600 // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
6601 const double increment = 1.0 / BAKE_FPS;
6602 double time = 0.0;
6603 bool last = false;
6604 while (true) {
6605 Vector3 scale;
6606 Error err = p_animation->try_position_track_interpolate(p_track_i, time, &scale);
6607 ERR_CONTINUE(err != OK);
6608 p_track.position_track.values.push_back(scale);
6609 p_track.position_track.times.push_back(time);
6610 if (last) {
6611 break;
6612 }
6613 time += increment;
6614 if (time >= anim_end) {
6615 last = true;
6616 time = anim_end;
6617 }
6618 }
6619 } else {
6620 p_track.position_track.times = times;
6621 p_track.position_track.values.resize(key_count);
6622 p_track.position_track.interpolation = gltf_interpolation;
6623 for (int32_t key_i = 0; key_i < key_count; key_i++) {
6624 Vector3 position;
6625 Error err = p_animation->position_track_get_key(p_track_i, key_i, &position);
6626 ERR_CONTINUE(err != OK);
6627 p_track.position_track.values.write[key_i] = position;
6628 }
6629 }
6630 } else if (track_type == Animation::TYPE_ROTATION_3D) {
6631 if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) {
6632 gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
6633 p_track.rotation_track.times.clear();
6634 p_track.rotation_track.values.clear();
6635 // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
6636 const double increment = 1.0 / BAKE_FPS;
6637 double time = 0.0;
6638 bool last = false;
6639 while (true) {
6640 Quaternion rotation;
6641 Error err = p_animation->try_rotation_track_interpolate(p_track_i, time, &rotation);
6642 ERR_CONTINUE(err != OK);
6643 p_track.rotation_track.values.push_back(rotation);
6644 p_track.rotation_track.times.push_back(time);
6645 if (last) {
6646 break;
6647 }
6648 time += increment;
6649 if (time >= anim_end) {
6650 last = true;
6651 time = anim_end;
6652 }
6653 }
6654 } else {
6655 p_track.rotation_track.times = times;
6656 p_track.rotation_track.values.resize(key_count);
6657 p_track.rotation_track.interpolation = gltf_interpolation;
6658 for (int32_t key_i = 0; key_i < key_count; key_i++) {
6659 Quaternion rotation;
6660 Error err = p_animation->rotation_track_get_key(p_track_i, key_i, &rotation);
6661 ERR_CONTINUE(err != OK);
6662 p_track.rotation_track.values.write[key_i] = rotation;
6663 }
6664 }
6665 } else if (track_type == Animation::TYPE_VALUE) {
6666 if (path.contains(":position")) {
6667 p_track.position_track.interpolation = gltf_interpolation;
6668 p_track.position_track.times = times;
6669 p_track.position_track.values.resize(key_count);
6670
6671 if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) {
6672 gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
6673 p_track.position_track.times.clear();
6674 p_track.position_track.values.clear();
6675 // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
6676 const double increment = 1.0 / BAKE_FPS;
6677 double time = 0.0;
6678 bool last = false;
6679 while (true) {
6680 Vector3 position;
6681 Error err = p_animation->try_position_track_interpolate(p_track_i, time, &position);
6682 ERR_CONTINUE(err != OK);
6683 p_track.position_track.values.push_back(position);
6684 p_track.position_track.times.push_back(time);
6685 if (last) {
6686 break;
6687 }
6688 time += increment;
6689 if (time >= anim_end) {
6690 last = true;
6691 time = anim_end;
6692 }
6693 }
6694 } else {
6695 for (int32_t key_i = 0; key_i < key_count; key_i++) {
6696 Vector3 position = p_animation->track_get_key_value(p_track_i, key_i);
6697 p_track.position_track.values.write[key_i] = position;
6698 }
6699 }
6700 } else if (path.contains(":rotation")) {
6701 p_track.rotation_track.interpolation = gltf_interpolation;
6702 p_track.rotation_track.times = times;
6703 p_track.rotation_track.values.resize(key_count);
6704 if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) {
6705 gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
6706 p_track.rotation_track.times.clear();
6707 p_track.rotation_track.values.clear();
6708 // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
6709 const double increment = 1.0 / BAKE_FPS;
6710 double time = 0.0;
6711 bool last = false;
6712 while (true) {
6713 Quaternion rotation;
6714 Error err = p_animation->try_rotation_track_interpolate(p_track_i, time, &rotation);
6715 ERR_CONTINUE(err != OK);
6716 p_track.rotation_track.values.push_back(rotation);
6717 p_track.rotation_track.times.push_back(time);
6718 if (last) {
6719 break;
6720 }
6721 time += increment;
6722 if (time >= anim_end) {
6723 last = true;
6724 time = anim_end;
6725 }
6726 }
6727 } else {
6728 for (int32_t key_i = 0; key_i < key_count; key_i++) {
6729 Vector3 rotation_radian = p_animation->track_get_key_value(p_track_i, key_i);
6730 p_track.rotation_track.values.write[key_i] = Quaternion::from_euler(rotation_radian);
6731 }
6732 }
6733 } else if (path.contains(":scale")) {
6734 p_track.scale_track.times = times;
6735 p_track.scale_track.interpolation = gltf_interpolation;
6736
6737 p_track.scale_track.values.resize(key_count);
6738 p_track.scale_track.interpolation = gltf_interpolation;
6739
6740 if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) {
6741 gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
6742 p_track.scale_track.times.clear();
6743 p_track.scale_track.values.clear();
6744 // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
6745 const double increment = 1.0 / BAKE_FPS;
6746 double time = 0.0;
6747 bool last = false;
6748 while (true) {
6749 Vector3 scale;
6750 Error err = p_animation->try_scale_track_interpolate(p_track_i, time, &scale);
6751 ERR_CONTINUE(err != OK);
6752 p_track.scale_track.values.push_back(scale);
6753 p_track.scale_track.times.push_back(time);
6754 if (last) {
6755 break;
6756 }
6757 time += increment;
6758 if (time >= anim_end) {
6759 last = true;
6760 time = anim_end;
6761 }
6762 }
6763 } else {
6764 for (int32_t key_i = 0; key_i < key_count; key_i++) {
6765 Vector3 scale_track = p_animation->track_get_key_value(p_track_i, key_i);
6766 p_track.scale_track.values.write[key_i] = scale_track;
6767 }
6768 }
6769 }
6770 } else if (track_type == Animation::TYPE_BEZIER) {
6771 const int32_t keys = anim_end * BAKE_FPS;
6772 if (path.contains(":scale")) {
6773 if (!p_track.scale_track.times.size()) {
6774 p_track.scale_track.interpolation = gltf_interpolation;
6775 Vector<real_t> new_times;
6776 new_times.resize(keys);
6777 for (int32_t key_i = 0; key_i < keys; key_i++) {
6778 new_times.write[key_i] = key_i / BAKE_FPS;
6779 }
6780 p_track.scale_track.times = new_times;
6781
6782 p_track.scale_track.values.resize(keys);
6783
6784 for (int32_t key_i = 0; key_i < keys; key_i++) {
6785 p_track.scale_track.values.write[key_i] = Vector3(1.0f, 1.0f, 1.0f);
6786 }
6787
6788 for (int32_t key_i = 0; key_i < keys; key_i++) {
6789 Vector3 bezier_track = p_track.scale_track.values[key_i];
6790 if (path.contains(":scale:x")) {
6791 bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
6792 } else if (path.contains(":scale:y")) {
6793 bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
6794 } else if (path.contains(":scale:z")) {
6795 bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
6796 }
6797 p_track.scale_track.values.write[key_i] = bezier_track;
6798 }
6799 }
6800 } else if (path.contains(":position")) {
6801 if (!p_track.position_track.times.size()) {
6802 p_track.position_track.interpolation = gltf_interpolation;
6803 Vector<real_t> new_times;
6804 new_times.resize(keys);
6805 for (int32_t key_i = 0; key_i < keys; key_i++) {
6806 new_times.write[key_i] = key_i / BAKE_FPS;
6807 }
6808 p_track.position_track.times = new_times;
6809
6810 p_track.position_track.values.resize(keys);
6811 }
6812
6813 for (int32_t key_i = 0; key_i < keys; key_i++) {
6814 Vector3 bezier_track = p_track.position_track.values[key_i];
6815 if (path.contains(":position:x")) {
6816 bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
6817 } else if (path.contains(":position:y")) {
6818 bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
6819 } else if (path.contains(":position:z")) {
6820 bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
6821 }
6822 p_track.position_track.values.write[key_i] = bezier_track;
6823 }
6824 } else if (path.contains(":rotation")) {
6825 if (!p_track.rotation_track.times.size()) {
6826 p_track.rotation_track.interpolation = gltf_interpolation;
6827 Vector<real_t> new_times;
6828 new_times.resize(keys);
6829 for (int32_t key_i = 0; key_i < keys; key_i++) {
6830 new_times.write[key_i] = key_i / BAKE_FPS;
6831 }
6832 p_track.rotation_track.times = new_times;
6833
6834 p_track.rotation_track.values.resize(keys);
6835 }
6836 for (int32_t key_i = 0; key_i < keys; key_i++) {
6837 Quaternion bezier_track = p_track.rotation_track.values[key_i];
6838 if (path.contains(":rotation:x")) {
6839 bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
6840 } else if (path.contains(":rotation:y")) {
6841 bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
6842 } else if (path.contains(":rotation:z")) {
6843 bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
6844 } else if (path.contains(":rotation:w")) {
6845 bezier_track.w = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
6846 }
6847 p_track.rotation_track.values.write[key_i] = bezier_track;
6848 }
6849 }
6850 }
6851 return p_track;
6852}
6853
6854void GLTFDocument::_convert_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, String p_animation_track_name) {
6855 Ref<Animation> animation = p_animation_player->get_animation(p_animation_track_name);
6856 Ref<GLTFAnimation> gltf_animation;
6857 gltf_animation.instantiate();
6858 gltf_animation->set_name(_gen_unique_name(p_state, p_animation_track_name));
6859 for (int32_t track_i = 0; track_i < animation->get_track_count(); track_i++) {
6860 if (!animation->track_is_enabled(track_i)) {
6861 continue;
6862 }
6863 String final_track_path = animation->track_get_path(track_i);
6864 Node *animation_base_node = p_animation_player->get_parent();
6865 ERR_CONTINUE_MSG(!animation_base_node, "Cannot get the parent of the animation player.");
6866 if (String(final_track_path).contains(":position")) {
6867 const Vector<String> node_suffix = String(final_track_path).split(":position");
6868 const NodePath path = node_suffix[0];
6869 const Node *node = animation_base_node->get_node_or_null(path);
6870 ERR_CONTINUE_MSG(!node, "Cannot get the node from a position path.");
6871 for (const KeyValue<GLTFNodeIndex, Node *> &position_scene_node_i : p_state->scene_nodes) {
6872 if (position_scene_node_i.value == node) {
6873 GLTFNodeIndex node_index = position_scene_node_i.key;
6874 HashMap<int, GLTFAnimation::Track>::Iterator position_track_i = gltf_animation->get_tracks().find(node_index);
6875 GLTFAnimation::Track track;
6876 if (position_track_i) {
6877 track = position_track_i->value;
6878 }
6879 track = _convert_animation_track(p_state, track, animation, track_i, node_index);
6880 gltf_animation->get_tracks().insert(node_index, track);
6881 }
6882 }
6883 } else if (String(final_track_path).contains(":rotation_degrees")) {
6884 const Vector<String> node_suffix = String(final_track_path).split(":rotation_degrees");
6885 const NodePath path = node_suffix[0];
6886 const Node *node = animation_base_node->get_node_or_null(path);
6887 ERR_CONTINUE_MSG(!node, "Cannot get the node from a rotation degrees path.");
6888 for (const KeyValue<GLTFNodeIndex, Node *> &rotation_degree_scene_node_i : p_state->scene_nodes) {
6889 if (rotation_degree_scene_node_i.value == node) {
6890 GLTFNodeIndex node_index = rotation_degree_scene_node_i.key;
6891 HashMap<int, GLTFAnimation::Track>::Iterator rotation_degree_track_i = gltf_animation->get_tracks().find(node_index);
6892 GLTFAnimation::Track track;
6893 if (rotation_degree_track_i) {
6894 track = rotation_degree_track_i->value;
6895 }
6896 track = _convert_animation_track(p_state, track, animation, track_i, node_index);
6897 gltf_animation->get_tracks().insert(node_index, track);
6898 }
6899 }
6900 } else if (String(final_track_path).contains(":scale")) {
6901 const Vector<String> node_suffix = String(final_track_path).split(":scale");
6902 const NodePath path = node_suffix[0];
6903 const Node *node = animation_base_node->get_node_or_null(path);
6904 ERR_CONTINUE_MSG(!node, "Cannot get the node from a scale path.");
6905 for (const KeyValue<GLTFNodeIndex, Node *> &scale_scene_node_i : p_state->scene_nodes) {
6906 if (scale_scene_node_i.value == node) {
6907 GLTFNodeIndex node_index = scale_scene_node_i.key;
6908 HashMap<int, GLTFAnimation::Track>::Iterator scale_track_i = gltf_animation->get_tracks().find(node_index);
6909 GLTFAnimation::Track track;
6910 if (scale_track_i) {
6911 track = scale_track_i->value;
6912 }
6913 track = _convert_animation_track(p_state, track, animation, track_i, node_index);
6914 gltf_animation->get_tracks().insert(node_index, track);
6915 }
6916 }
6917 } else if (String(final_track_path).contains(":transform")) {
6918 const Vector<String> node_suffix = String(final_track_path).split(":transform");
6919 const NodePath path = node_suffix[0];
6920 const Node *node = animation_base_node->get_node_or_null(path);
6921 ERR_CONTINUE_MSG(!node, "Cannot get the node from a transform path.");
6922 for (const KeyValue<GLTFNodeIndex, Node *> &transform_track_i : p_state->scene_nodes) {
6923 if (transform_track_i.value == node) {
6924 GLTFAnimation::Track track;
6925 track = _convert_animation_track(p_state, track, animation, track_i, transform_track_i.key);
6926 gltf_animation->get_tracks().insert(transform_track_i.key, track);
6927 }
6928 }
6929 } else if (String(final_track_path).contains(":") && animation->track_get_type(track_i) == Animation::TYPE_BLEND_SHAPE) {
6930 const Vector<String> node_suffix = String(final_track_path).split(":");
6931 const NodePath path = node_suffix[0];
6932 const String suffix = node_suffix[1];
6933 Node *node = animation_base_node->get_node_or_null(path);
6934 ERR_CONTINUE_MSG(!node, "Cannot get the node from a blend shape path.");
6935 MeshInstance3D *mi = cast_to<MeshInstance3D>(node);
6936 if (!mi) {
6937 continue;
6938 }
6939 Ref<Mesh> mesh = mi->get_mesh();
6940 ERR_CONTINUE(mesh.is_null());
6941 int32_t mesh_index = -1;
6942 for (const KeyValue<GLTFNodeIndex, Node *> &mesh_track_i : p_state->scene_nodes) {
6943 if (mesh_track_i.value == node) {
6944 mesh_index = mesh_track_i.key;
6945 }
6946 }
6947 ERR_CONTINUE(mesh_index == -1);
6948 HashMap<int, GLTFAnimation::Track> &tracks = gltf_animation->get_tracks();
6949 GLTFAnimation::Track track = gltf_animation->get_tracks().has(mesh_index) ? gltf_animation->get_tracks()[mesh_index] : GLTFAnimation::Track();
6950 if (!tracks.has(mesh_index)) {
6951 for (int32_t shape_i = 0; shape_i < mesh->get_blend_shape_count(); shape_i++) {
6952 String shape_name = mesh->get_blend_shape_name(shape_i);
6953 NodePath shape_path = String(path) + ":" + shape_name;
6954 int32_t shape_track_i = animation->find_track(shape_path, Animation::TYPE_BLEND_SHAPE);
6955 if (shape_track_i == -1) {
6956 GLTFAnimation::Channel<real_t> weight;
6957 weight.interpolation = GLTFAnimation::INTERP_LINEAR;
6958 weight.times.push_back(0.0f);
6959 weight.times.push_back(0.0f);
6960 weight.values.push_back(0.0f);
6961 weight.values.push_back(0.0f);
6962 track.weight_tracks.push_back(weight);
6963 continue;
6964 }
6965 Animation::InterpolationType interpolation = animation->track_get_interpolation_type(track_i);
6966 GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
6967 if (interpolation == Animation::InterpolationType::INTERPOLATION_LINEAR) {
6968 gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
6969 } else if (interpolation == Animation::InterpolationType::INTERPOLATION_NEAREST) {
6970 gltf_interpolation = GLTFAnimation::INTERP_STEP;
6971 } else if (interpolation == Animation::InterpolationType::INTERPOLATION_CUBIC) {
6972 gltf_interpolation = GLTFAnimation::INTERP_CUBIC_SPLINE;
6973 }
6974 int32_t key_count = animation->track_get_key_count(shape_track_i);
6975 GLTFAnimation::Channel<real_t> weight;
6976 weight.interpolation = gltf_interpolation;
6977 weight.times.resize(key_count);
6978 for (int32_t time_i = 0; time_i < key_count; time_i++) {
6979 weight.times.write[time_i] = animation->track_get_key_time(shape_track_i, time_i);
6980 }
6981 weight.values.resize(key_count);
6982 for (int32_t value_i = 0; value_i < key_count; value_i++) {
6983 weight.values.write[value_i] = animation->track_get_key_value(shape_track_i, value_i);
6984 }
6985 track.weight_tracks.push_back(weight);
6986 }
6987 tracks[mesh_index] = track;
6988 }
6989 } else if (String(final_track_path).contains(":")) {
6990 //Process skeleton
6991 const Vector<String> node_suffix = String(final_track_path).split(":");
6992 const String node = node_suffix[0];
6993 const NodePath node_path = node;
6994 const String suffix = node_suffix[1];
6995 Node *godot_node = animation_base_node->get_node_or_null(node_path);
6996 if (!godot_node) {
6997 continue;
6998 }
6999 Skeleton3D *skeleton = cast_to<Skeleton3D>(animation_base_node->get_node_or_null(node));
7000 if (!skeleton) {
7001 continue;
7002 }
7003 GLTFSkeletonIndex skeleton_gltf_i = -1;
7004 for (GLTFSkeletonIndex skeleton_i = 0; skeleton_i < p_state->skeletons.size(); skeleton_i++) {
7005 if (p_state->skeletons[skeleton_i]->godot_skeleton == cast_to<Skeleton3D>(godot_node)) {
7006 skeleton = p_state->skeletons[skeleton_i]->godot_skeleton;
7007 skeleton_gltf_i = skeleton_i;
7008 ERR_CONTINUE(!skeleton);
7009 Ref<GLTFSkeleton> skeleton_gltf = p_state->skeletons[skeleton_gltf_i];
7010 int32_t bone = skeleton->find_bone(suffix);
7011 ERR_CONTINUE_MSG(bone == -1, vformat("Cannot find the bone %s.", suffix));
7012 if (!skeleton_gltf->godot_bone_node.has(bone)) {
7013 continue;
7014 }
7015 GLTFNodeIndex node_i = skeleton_gltf->godot_bone_node[bone];
7016 HashMap<int, GLTFAnimation::Track>::Iterator property_track_i = gltf_animation->get_tracks().find(node_i);
7017 GLTFAnimation::Track track;
7018 if (property_track_i) {
7019 track = property_track_i->value;
7020 }
7021 track = _convert_animation_track(p_state, track, animation, track_i, node_i);
7022 gltf_animation->get_tracks()[node_i] = track;
7023 }
7024 }
7025 } else if (!String(final_track_path).contains(":")) {
7026 ERR_CONTINUE(!animation_base_node);
7027 Node *godot_node = animation_base_node->get_node_or_null(final_track_path);
7028 ERR_CONTINUE_MSG(!godot_node, vformat("Cannot get the node from a skeleton path %s.", final_track_path));
7029 for (const KeyValue<GLTFNodeIndex, Node *> &scene_node_i : p_state->scene_nodes) {
7030 if (scene_node_i.value == godot_node) {
7031 GLTFNodeIndex node_i = scene_node_i.key;
7032 HashMap<int, GLTFAnimation::Track>::Iterator node_track_i = gltf_animation->get_tracks().find(node_i);
7033 GLTFAnimation::Track track;
7034 if (node_track_i) {
7035 track = node_track_i->value;
7036 }
7037 track = _convert_animation_track(p_state, track, animation, track_i, node_i);
7038 gltf_animation->get_tracks()[node_i] = track;
7039 break;
7040 }
7041 }
7042 }
7043 }
7044 if (gltf_animation->get_tracks().size()) {
7045 p_state->animations.push_back(gltf_animation);
7046 }
7047}
7048
7049Error GLTFDocument::_parse(Ref<GLTFState> p_state, String p_path, Ref<FileAccess> p_file) {
7050 Error err;
7051 if (p_file.is_null()) {
7052 return FAILED;
7053 }
7054 p_file->seek(0);
7055 uint32_t magic = p_file->get_32();
7056 if (magic == 0x46546C67) {
7057 //binary file
7058 //text file
7059 p_file->seek(0);
7060 err = _parse_glb(p_file, p_state);
7061 if (err != OK) {
7062 return err;
7063 }
7064 } else {
7065 p_file->seek(0);
7066 String text = p_file->get_as_utf8_string();
7067 JSON json;
7068 err = json.parse(text);
7069 if (err != OK) {
7070 _err_print_error("", "", json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT);
7071 }
7072 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7073 p_state->json = json.get_data();
7074 }
7075
7076 err = _parse_asset_header(p_state);
7077 ERR_FAIL_COND_V(err != OK, err);
7078
7079 document_extensions.clear();
7080 for (Ref<GLTFDocumentExtension> ext : all_document_extensions) {
7081 ERR_CONTINUE(ext.is_null());
7082 err = ext->import_preflight(p_state, p_state->json["extensionsUsed"]);
7083 if (err == OK) {
7084 document_extensions.push_back(ext);
7085 }
7086 }
7087
7088 err = _parse_gltf_state(p_state, p_path);
7089 ERR_FAIL_COND_V(err != OK, err);
7090
7091 return OK;
7092}
7093
7094Dictionary _serialize_texture_transform_uv(Vector2 p_offset, Vector2 p_scale) {
7095 Dictionary texture_transform;
7096 bool is_offset = p_offset != Vector2(0.0, 0.0);
7097 if (is_offset) {
7098 Array offset;
7099 offset.resize(2);
7100 offset[0] = p_offset.x;
7101 offset[1] = p_offset.y;
7102 texture_transform["offset"] = offset;
7103 }
7104 bool is_scaled = p_scale != Vector2(1.0, 1.0);
7105 if (is_scaled) {
7106 Array scale;
7107 scale.resize(2);
7108 scale[0] = p_scale.x;
7109 scale[1] = p_scale.y;
7110 texture_transform["scale"] = scale;
7111 }
7112 Dictionary extension;
7113 // Note: Godot doesn't support texture rotation.
7114 if (is_offset || is_scaled) {
7115 extension["KHR_texture_transform"] = texture_transform;
7116 }
7117 return extension;
7118}
7119
7120Dictionary GLTFDocument::_serialize_texture_transform_uv1(Ref<BaseMaterial3D> p_material) {
7121 ERR_FAIL_NULL_V(p_material, Dictionary());
7122 Vector3 offset = p_material->get_uv1_offset();
7123 Vector3 scale = p_material->get_uv1_scale();
7124 return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y));
7125}
7126
7127Dictionary GLTFDocument::_serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material) {
7128 ERR_FAIL_NULL_V(p_material, Dictionary());
7129 Vector3 offset = p_material->get_uv2_offset();
7130 Vector3 scale = p_material->get_uv2_scale();
7131 return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y));
7132}
7133
7134Error GLTFDocument::_serialize_asset_header(Ref<GLTFState> p_state) {
7135 const String version = "2.0";
7136 p_state->major_version = version.get_slice(".", 0).to_int();
7137 p_state->minor_version = version.get_slice(".", 1).to_int();
7138 Dictionary asset;
7139 asset["version"] = version;
7140 if (!p_state->copyright.is_empty()) {
7141 asset["copyright"] = p_state->copyright;
7142 }
7143 String hash = String(VERSION_HASH);
7144 asset["generator"] = String(VERSION_FULL_NAME) + String("@") + (hash.is_empty() ? String("unknown") : hash);
7145 p_state->json["asset"] = asset;
7146 ERR_FAIL_COND_V(!asset.has("version"), Error::FAILED);
7147 ERR_FAIL_COND_V(!p_state->json.has("asset"), Error::FAILED);
7148 return OK;
7149}
7150
7151Error GLTFDocument::_serialize_file(Ref<GLTFState> p_state, const String p_path) {
7152 Error err = FAILED;
7153 if (p_path.to_lower().ends_with("glb")) {
7154 err = _encode_buffer_glb(p_state, p_path);
7155 ERR_FAIL_COND_V(err != OK, err);
7156 Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err);
7157 ERR_FAIL_COND_V(file.is_null(), FAILED);
7158
7159 String json = Variant(p_state->json).to_json_string();
7160
7161 const uint32_t magic = 0x46546C67; // GLTF
7162 const int32_t header_size = 12;
7163 const int32_t chunk_header_size = 8;
7164 CharString cs = json.utf8();
7165 const uint32_t text_data_length = cs.length();
7166 const uint32_t text_chunk_length = ((text_data_length + 3) & (~3));
7167 const uint32_t text_chunk_type = 0x4E4F534A; //JSON
7168
7169 uint32_t binary_data_length = 0;
7170 if (p_state->buffers.size()) {
7171 binary_data_length = p_state->buffers[0].size();
7172 }
7173 const uint32_t binary_chunk_length = ((binary_data_length + 3) & (~3));
7174 const uint32_t binary_chunk_type = 0x004E4942; //BIN
7175
7176 file->create(FileAccess::ACCESS_RESOURCES);
7177 file->store_32(magic);
7178 file->store_32(p_state->major_version); // version
7179 file->store_32(header_size + chunk_header_size + text_chunk_length + chunk_header_size + binary_chunk_length); // length
7180 file->store_32(text_chunk_length);
7181 file->store_32(text_chunk_type);
7182 file->store_buffer((uint8_t *)&cs[0], cs.length());
7183 for (uint32_t pad_i = text_data_length; pad_i < text_chunk_length; pad_i++) {
7184 file->store_8(' ');
7185 }
7186 if (binary_chunk_length) {
7187 file->store_32(binary_chunk_length);
7188 file->store_32(binary_chunk_type);
7189 file->store_buffer(p_state->buffers[0].ptr(), binary_data_length);
7190 }
7191 for (uint32_t pad_i = binary_data_length; pad_i < binary_chunk_length; pad_i++) {
7192 file->store_8(0);
7193 }
7194 } else {
7195 err = _encode_buffer_bins(p_state, p_path);
7196 ERR_FAIL_COND_V(err != OK, err);
7197 Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err);
7198 ERR_FAIL_COND_V(file.is_null(), FAILED);
7199
7200 file->create(FileAccess::ACCESS_RESOURCES);
7201 String json = Variant(p_state->json).to_json_string();
7202 file->store_string(json);
7203 }
7204 return err;
7205}
7206
7207void GLTFDocument::_bind_methods() {
7208 ClassDB::bind_method(D_METHOD("append_from_file", "path", "state", "flags", "base_path"),
7209 &GLTFDocument::append_from_file, DEFVAL(0), DEFVAL(String()));
7210 ClassDB::bind_method(D_METHOD("append_from_buffer", "bytes", "base_path", "state", "flags"),
7211 &GLTFDocument::append_from_buffer, DEFVAL(0));
7212 ClassDB::bind_method(D_METHOD("append_from_scene", "node", "state", "flags"),
7213 &GLTFDocument::append_from_scene, DEFVAL(0));
7214 ClassDB::bind_method(D_METHOD("generate_scene", "state", "bake_fps", "trimming", "remove_immutable_tracks"),
7215 &GLTFDocument::generate_scene, DEFVAL(30), DEFVAL(false), DEFVAL(true));
7216 ClassDB::bind_method(D_METHOD("generate_buffer", "state"),
7217 &GLTFDocument::generate_buffer);
7218 ClassDB::bind_method(D_METHOD("write_to_filesystem", "state", "path"),
7219 &GLTFDocument::write_to_filesystem);
7220
7221 ClassDB::bind_method(D_METHOD("set_image_format", "image_format"), &GLTFDocument::set_image_format);
7222 ClassDB::bind_method(D_METHOD("get_image_format"), &GLTFDocument::get_image_format);
7223 ClassDB::bind_method(D_METHOD("set_lossy_quality", "lossy_quality"), &GLTFDocument::set_lossy_quality);
7224 ClassDB::bind_method(D_METHOD("get_lossy_quality"), &GLTFDocument::get_lossy_quality);
7225
7226 ADD_PROPERTY(PropertyInfo(Variant::STRING, "image_format"), "set_image_format", "get_image_format");
7227 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lossy_quality"), "set_lossy_quality", "get_lossy_quality");
7228
7229 ClassDB::bind_static_method("GLTFDocument", D_METHOD("register_gltf_document_extension", "extension", "first_priority"),
7230 &GLTFDocument::register_gltf_document_extension, DEFVAL(false));
7231 ClassDB::bind_static_method("GLTFDocument", D_METHOD("unregister_gltf_document_extension", "extension"),
7232 &GLTFDocument::unregister_gltf_document_extension);
7233}
7234
7235void GLTFDocument::_build_parent_hierachy(Ref<GLTFState> p_state) {
7236 // build the hierarchy
7237 for (GLTFNodeIndex node_i = 0; node_i < p_state->nodes.size(); node_i++) {
7238 for (int j = 0; j < p_state->nodes[node_i]->children.size(); j++) {
7239 GLTFNodeIndex child_i = p_state->nodes[node_i]->children[j];
7240 ERR_FAIL_INDEX(child_i, p_state->nodes.size());
7241 if (p_state->nodes.write[child_i]->parent != -1) {
7242 continue;
7243 }
7244 p_state->nodes.write[child_i]->parent = node_i;
7245 }
7246 }
7247}
7248
7249Vector<Ref<GLTFDocumentExtension>> GLTFDocument::all_document_extensions;
7250
7251void GLTFDocument::register_gltf_document_extension(Ref<GLTFDocumentExtension> p_extension, bool p_first_priority) {
7252 if (all_document_extensions.find(p_extension) == -1) {
7253 if (p_first_priority) {
7254 all_document_extensions.insert(0, p_extension);
7255 } else {
7256 all_document_extensions.push_back(p_extension);
7257 }
7258 }
7259}
7260
7261void GLTFDocument::unregister_gltf_document_extension(Ref<GLTFDocumentExtension> p_extension) {
7262 all_document_extensions.erase(p_extension);
7263}
7264
7265void GLTFDocument::unregister_all_gltf_document_extensions() {
7266 all_document_extensions.clear();
7267}
7268
7269PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref<GLTFState> p_state, Error *r_err) {
7270 Error err = _encode_buffer_glb(p_state, "");
7271 if (r_err) {
7272 *r_err = err;
7273 }
7274 ERR_FAIL_COND_V(err != OK, PackedByteArray());
7275 String json = Variant(p_state->json).to_json_string();
7276
7277 const uint32_t magic = 0x46546C67; // GLTF
7278 const int32_t header_size = 12;
7279 const int32_t chunk_header_size = 8;
7280
7281 int32_t padding = (chunk_header_size + json.utf8().length()) % 4;
7282 json += String(" ").repeat(padding);
7283
7284 CharString cs = json.utf8();
7285 const uint32_t text_chunk_length = cs.length();
7286
7287 const uint32_t text_chunk_type = 0x4E4F534A; //JSON
7288 int32_t binary_data_length = 0;
7289 if (p_state->buffers.size()) {
7290 binary_data_length = p_state->buffers[0].size();
7291 }
7292 const int32_t binary_chunk_length = binary_data_length;
7293 const int32_t binary_chunk_type = 0x004E4942; //BIN
7294
7295 Ref<StreamPeerBuffer> buffer;
7296 buffer.instantiate();
7297 buffer->put_32(magic);
7298 buffer->put_32(p_state->major_version); // version
7299 buffer->put_32(header_size + chunk_header_size + text_chunk_length + chunk_header_size + binary_data_length); // length
7300 buffer->put_32(text_chunk_length);
7301 buffer->put_32(text_chunk_type);
7302 buffer->put_data((uint8_t *)&cs[0], cs.length());
7303 if (binary_chunk_length) {
7304 buffer->put_32(binary_chunk_length);
7305 buffer->put_32(binary_chunk_type);
7306 buffer->put_data(p_state->buffers[0].ptr(), binary_data_length);
7307 }
7308 return buffer->get_data_array();
7309}
7310
7311PackedByteArray GLTFDocument::generate_buffer(Ref<GLTFState> p_state) {
7312 ERR_FAIL_NULL_V(p_state, PackedByteArray());
7313 // For buffers, set the state filename to an empty string, but
7314 // don't touch the base path, in case the user set it manually.
7315 p_state->filename = "";
7316 Error err = _serialize(p_state);
7317 ERR_FAIL_COND_V(err != OK, PackedByteArray());
7318 PackedByteArray bytes = _serialize_glb_buffer(p_state, &err);
7319 return bytes;
7320}
7321
7322Error GLTFDocument::write_to_filesystem(Ref<GLTFState> p_state, const String &p_path) {
7323 ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
7324 p_state->base_path = p_path.get_base_dir();
7325 p_state->filename = p_path.get_file();
7326 Error err = _serialize(p_state);
7327 if (err != OK) {
7328 return err;
7329 }
7330 err = _serialize_file(p_state, p_path);
7331 if (err != OK) {
7332 return Error::FAILED;
7333 }
7334 return OK;
7335}
7336
7337Node *GLTFDocument::_generate_scene_node_tree(Ref<GLTFState> p_state) {
7338 Node *single_root = memnew(Node3D);
7339 for (int32_t root_i = 0; root_i < p_state->root_nodes.size(); root_i++) {
7340 _generate_scene_node(p_state, p_state->root_nodes[root_i], single_root, single_root);
7341 }
7342 // Assign the scene name and single root name to each other
7343 // if one is missing, or do nothing if both are already set.
7344 if (unlikely(p_state->scene_name.is_empty())) {
7345 p_state->scene_name = single_root->get_name();
7346 } else if (single_root->get_name() == StringName()) {
7347 single_root->set_name(_gen_unique_name(p_state, p_state->scene_name));
7348 }
7349 return single_root;
7350}
7351
7352Node *GLTFDocument::generate_scene(Ref<GLTFState> p_state, float p_bake_fps, bool p_trimming, bool p_remove_immutable_tracks) {
7353 ERR_FAIL_NULL_V(p_state, nullptr);
7354 ERR_FAIL_INDEX_V(0, p_state->root_nodes.size(), nullptr);
7355 Error err = OK;
7356 Node *root = _generate_scene_node_tree(p_state);
7357 ERR_FAIL_NULL_V(root, nullptr);
7358 _process_mesh_instances(p_state);
7359 if (p_state->get_create_animations() && p_state->animations.size()) {
7360 AnimationPlayer *ap = memnew(AnimationPlayer);
7361 root->add_child(ap, true);
7362 ap->set_owner(root);
7363 for (int i = 0; i < p_state->animations.size(); i++) {
7364 _import_animation(p_state, ap, i, p_bake_fps, p_trimming, p_remove_immutable_tracks);
7365 }
7366 }
7367 for (KeyValue<GLTFNodeIndex, Node *> E : p_state->scene_nodes) {
7368 ERR_CONTINUE(!E.value);
7369 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
7370 ERR_CONTINUE(ext.is_null());
7371 ERR_CONTINUE(!p_state->json.has("nodes"));
7372 Array nodes = p_state->json["nodes"];
7373 ERR_CONTINUE(E.key >= nodes.size());
7374 ERR_CONTINUE(E.key < 0);
7375 Dictionary node_json = nodes[E.key];
7376 Ref<GLTFNode> gltf_node = p_state->nodes[E.key];
7377 err = ext->import_node(p_state, gltf_node, node_json, E.value);
7378 ERR_CONTINUE(err != OK);
7379 }
7380 }
7381 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
7382 ERR_CONTINUE(ext.is_null());
7383 err = ext->import_post(p_state, root);
7384 ERR_CONTINUE(err != OK);
7385 }
7386 ERR_FAIL_NULL_V(root, nullptr);
7387 return root;
7388}
7389
7390Error GLTFDocument::append_from_scene(Node *p_node, Ref<GLTFState> p_state, uint32_t p_flags) {
7391 ERR_FAIL_COND_V(p_state.is_null(), FAILED);
7392 p_state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS;
7393 p_state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS;
7394 if (!p_state->buffers.size()) {
7395 p_state->buffers.push_back(Vector<uint8_t>());
7396 }
7397 // Perform export preflight for document extensions. Only extensions that
7398 // return OK will be used for the rest of the export steps.
7399 document_extensions.clear();
7400 for (Ref<GLTFDocumentExtension> ext : all_document_extensions) {
7401 ERR_CONTINUE(ext.is_null());
7402 Error err = ext->export_preflight(p_state, p_node);
7403 if (err == OK) {
7404 document_extensions.push_back(ext);
7405 }
7406 }
7407 // Add the root node(s) and their descendants to the state.
7408 _convert_scene_node(p_state, p_node, -1, -1);
7409 return OK;
7410}
7411
7412Error GLTFDocument::append_from_buffer(PackedByteArray p_bytes, String p_base_path, Ref<GLTFState> p_state, uint32_t p_flags) {
7413 ERR_FAIL_COND_V(p_state.is_null(), FAILED);
7414 // TODO Add missing texture and missing .bin file paths to r_missing_deps 2021-09-10 fire
7415 Error err = FAILED;
7416 p_state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS;
7417 p_state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS;
7418
7419 Ref<FileAccessMemory> file_access;
7420 file_access.instantiate();
7421 file_access->open_custom(p_bytes.ptr(), p_bytes.size());
7422 p_state->base_path = p_base_path.get_base_dir();
7423 err = _parse(p_state, p_state->base_path, file_access);
7424 ERR_FAIL_COND_V(err != OK, err);
7425 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
7426 ERR_CONTINUE(ext.is_null());
7427 err = ext->import_post_parse(p_state);
7428 ERR_FAIL_COND_V(err != OK, err);
7429 }
7430 return OK;
7431}
7432
7433Error GLTFDocument::_parse_asset_header(Ref<GLTFState> p_state) {
7434 if (!p_state->json.has("asset")) {
7435 return ERR_PARSE_ERROR;
7436 }
7437 Dictionary asset = p_state->json["asset"];
7438 if (!asset.has("version")) {
7439 return ERR_PARSE_ERROR;
7440 }
7441 String version = asset["version"];
7442 p_state->major_version = version.get_slice(".", 0).to_int();
7443 p_state->minor_version = version.get_slice(".", 1).to_int();
7444 if (asset.has("copyright")) {
7445 p_state->copyright = asset["copyright"];
7446 }
7447 return OK;
7448}
7449
7450Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> p_state, const String &p_search_path) {
7451 Error err;
7452
7453 /* PARSE EXTENSIONS */
7454 err = _parse_gltf_extensions(p_state);
7455 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7456
7457 /* PARSE SCENE */
7458 err = _parse_scenes(p_state);
7459 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7460
7461 /* PARSE NODES */
7462 err = _parse_nodes(p_state);
7463 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7464
7465 /* PARSE BUFFERS */
7466 err = _parse_buffers(p_state, p_search_path);
7467
7468 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7469
7470 /* PARSE BUFFER VIEWS */
7471 err = _parse_buffer_views(p_state);
7472
7473 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7474
7475 /* PARSE ACCESSORS */
7476 err = _parse_accessors(p_state);
7477
7478 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7479
7480 if (!p_state->discard_meshes_and_materials) {
7481 /* PARSE IMAGES */
7482 err = _parse_images(p_state, p_search_path);
7483
7484 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7485
7486 /* PARSE TEXTURE SAMPLERS */
7487 err = _parse_texture_samplers(p_state);
7488
7489 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7490
7491 /* PARSE TEXTURES */
7492 err = _parse_textures(p_state);
7493
7494 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7495
7496 /* PARSE TEXTURES */
7497 err = _parse_materials(p_state);
7498
7499 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7500 }
7501
7502 /* PARSE SKINS */
7503 err = _parse_skins(p_state);
7504
7505 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7506
7507 /* DETERMINE SKELETONS */
7508 err = _determine_skeletons(p_state);
7509 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7510
7511 /* CREATE SKELETONS */
7512 err = _create_skeletons(p_state);
7513 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7514
7515 /* CREATE SKINS */
7516 err = _create_skins(p_state);
7517 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7518
7519 /* PARSE MESHES (we have enough info now) */
7520 err = _parse_meshes(p_state);
7521 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7522
7523 /* PARSE LIGHTS */
7524 err = _parse_lights(p_state);
7525 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7526
7527 /* PARSE CAMERAS */
7528 err = _parse_cameras(p_state);
7529 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7530
7531 /* PARSE ANIMATIONS */
7532 err = _parse_animations(p_state);
7533 ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
7534
7535 /* ASSIGN SCENE NAMES */
7536 _assign_node_names(p_state);
7537
7538 return OK;
7539}
7540
7541Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> p_state, uint32_t p_flags, String p_base_path) {
7542 // TODO Add missing texture and missing .bin file paths to r_missing_deps 2021-09-10 fire
7543 if (p_state == Ref<GLTFState>()) {
7544 p_state.instantiate();
7545 }
7546 p_state->filename = p_path.get_file().get_basename();
7547 p_state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS;
7548 p_state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS;
7549 Error err;
7550 Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::READ, &err);
7551 ERR_FAIL_COND_V(err != OK, ERR_FILE_CANT_OPEN);
7552 ERR_FAIL_NULL_V(file, ERR_FILE_CANT_OPEN);
7553 String base_path = p_base_path;
7554 if (base_path.is_empty()) {
7555 base_path = p_path.get_base_dir();
7556 }
7557 p_state->base_path = base_path;
7558 err = _parse(p_state, base_path, file);
7559 ERR_FAIL_COND_V(err != OK, err);
7560 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
7561 ERR_CONTINUE(ext.is_null());
7562 err = ext->import_post_parse(p_state);
7563 ERR_FAIL_COND_V(err != OK, err);
7564 }
7565 return OK;
7566}
7567
7568Error GLTFDocument::_parse_gltf_extensions(Ref<GLTFState> p_state) {
7569 ERR_FAIL_NULL_V(p_state, ERR_PARSE_ERROR);
7570 if (p_state->json.has("extensionsUsed")) {
7571 Vector<String> ext_array = p_state->json["extensionsUsed"];
7572 p_state->extensions_used = ext_array;
7573 }
7574 if (p_state->json.has("extensionsRequired")) {
7575 Vector<String> ext_array = p_state->json["extensionsRequired"];
7576 p_state->extensions_required = ext_array;
7577 }
7578 HashSet<String> supported_extensions;
7579 supported_extensions.insert("KHR_lights_punctual");
7580 supported_extensions.insert("KHR_materials_pbrSpecularGlossiness");
7581 supported_extensions.insert("KHR_texture_transform");
7582 supported_extensions.insert("KHR_materials_unlit");
7583 supported_extensions.insert("KHR_materials_emissive_strength");
7584 for (Ref<GLTFDocumentExtension> ext : document_extensions) {
7585 ERR_CONTINUE(ext.is_null());
7586 Vector<String> ext_supported_extensions = ext->get_supported_extensions();
7587 for (int i = 0; i < ext_supported_extensions.size(); ++i) {
7588 supported_extensions.insert(ext_supported_extensions[i]);
7589 }
7590 }
7591 Error ret = OK;
7592 for (int i = 0; i < p_state->extensions_required.size(); i++) {
7593 if (!supported_extensions.has(p_state->extensions_required[i])) {
7594 ERR_PRINT("GLTF: Can't import file '" + p_state->filename + "', required extension '" + String(p_state->extensions_required[i]) + "' is not supported. Are you missing a GLTFDocumentExtension plugin?");
7595 ret = ERR_UNAVAILABLE;
7596 }
7597 }
7598 return ret;
7599}
7600