Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/modules/gltf/gltf_document.cpp
11352 views
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_document_extension_convert_importer_mesh.h"
34
#include "extensions/gltf_spec_gloss.h"
35
#include "gltf_state.h"
36
#include "skin_tool.h"
37
38
#include "core/config/project_settings.h"
39
#include "core/crypto/crypto_core.h"
40
#include "core/io/config_file.h"
41
#include "core/io/dir_access.h"
42
#include "core/io/file_access.h"
43
#include "core/io/file_access_memory.h"
44
#include "core/io/json.h"
45
#include "core/io/stream_peer.h"
46
#include "core/object/object_id.h"
47
#include "core/version.h"
48
#include "scene/2d/node_2d.h"
49
#include "scene/3d/bone_attachment_3d.h"
50
#include "scene/3d/camera_3d.h"
51
#include "scene/3d/importer_mesh_instance_3d.h"
52
#include "scene/3d/light_3d.h"
53
#include "scene/3d/mesh_instance_3d.h"
54
#include "scene/3d/multimesh_instance_3d.h"
55
#include "scene/animation/animation_player.h"
56
#include "scene/resources/3d/skin.h"
57
#include "scene/resources/image_texture.h"
58
#include "scene/resources/portable_compressed_texture.h"
59
#include "scene/resources/surface_tool.h"
60
61
#ifdef TOOLS_ENABLED
62
#include "editor/file_system/editor_file_system.h"
63
#endif
64
65
#include "modules/modules_enabled.gen.h" // For csg, gridmap.
66
67
#ifdef MODULE_CSG_ENABLED
68
#include "modules/csg/csg_shape.h"
69
#endif
70
#ifdef MODULE_GRIDMAP_ENABLED
71
#include "modules/gridmap/grid_map.h"
72
#endif
73
74
// FIXME: Hardcoded to avoid editor dependency.
75
#define GLTF_IMPORT_GENERATE_TANGENT_ARRAYS 8
76
#define GLTF_IMPORT_USE_NAMED_SKIN_BINDS 16
77
#define GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS 32
78
#define GLTF_IMPORT_FORCE_DISABLE_MESH_COMPRESSION 64
79
80
#include <cstdio>
81
#include <cstdlib>
82
83
constexpr int COMPONENT_COUNT_FOR_ACCESSOR_TYPE[7] = {
84
1, 2, 3, 4, 4, 9, 16
85
};
86
87
static void _attach_extras_to_meta(const Dictionary &p_extras, Ref<Resource> p_node) {
88
if (!p_extras.is_empty()) {
89
p_node->set_meta("extras", p_extras);
90
}
91
}
92
93
static void _attach_meta_to_extras(Ref<Resource> p_node, Dictionary &p_json) {
94
if (p_node->has_meta("extras")) {
95
Dictionary node_extras = p_node->get_meta("extras");
96
if (p_json.has("extras")) {
97
Dictionary extras = p_json["extras"];
98
extras.merge(node_extras);
99
} else {
100
p_json["extras"] = node_extras;
101
}
102
}
103
}
104
105
static Ref<ImporterMesh> _mesh_to_importer_mesh(Ref<Mesh> p_mesh) {
106
Ref<ImporterMesh> importer_mesh;
107
importer_mesh.instantiate();
108
if (p_mesh.is_null()) {
109
return importer_mesh;
110
}
111
112
Ref<ArrayMesh> array_mesh = p_mesh;
113
if (p_mesh->get_blend_shape_count()) {
114
ArrayMesh::BlendShapeMode shape_mode = ArrayMesh::BLEND_SHAPE_MODE_NORMALIZED;
115
if (array_mesh.is_valid()) {
116
shape_mode = array_mesh->get_blend_shape_mode();
117
}
118
importer_mesh->set_blend_shape_mode(shape_mode);
119
for (int morph_i = 0; morph_i < p_mesh->get_blend_shape_count(); morph_i++) {
120
importer_mesh->add_blend_shape(p_mesh->get_blend_shape_name(morph_i));
121
}
122
}
123
for (int32_t surface_i = 0; surface_i < p_mesh->get_surface_count(); surface_i++) {
124
Array array = p_mesh->surface_get_arrays(surface_i);
125
Ref<Material> mat = p_mesh->surface_get_material(surface_i);
126
String mat_name;
127
if (mat.is_valid()) {
128
mat_name = mat->get_name();
129
} else {
130
// Assign default material when no material is assigned.
131
mat.instantiate();
132
}
133
importer_mesh->add_surface(p_mesh->surface_get_primitive_type(surface_i),
134
array, p_mesh->surface_get_blend_shape_arrays(surface_i), p_mesh->surface_get_lods(surface_i), mat,
135
mat_name, p_mesh->surface_get_format(surface_i));
136
}
137
importer_mesh->merge_meta_from(*p_mesh);
138
return importer_mesh;
139
}
140
141
Error GLTFDocument::_serialize(Ref<GLTFState> p_state) {
142
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
143
ERR_CONTINUE(ext.is_null());
144
Error err = ext->export_preserialize(p_state);
145
ERR_CONTINUE(err != OK);
146
}
147
148
/* STEP CONVERT MESH INSTANCES */
149
_convert_mesh_instances(p_state);
150
151
/* STEP SERIALIZE CAMERAS */
152
Error err = _serialize_cameras(p_state);
153
if (err != OK) {
154
return Error::FAILED;
155
}
156
157
/* STEP 3 CREATE SKINS */
158
err = _serialize_skins(p_state);
159
if (err != OK) {
160
return Error::FAILED;
161
}
162
163
/* STEP SERIALIZE MESHES (we have enough info now) */
164
err = _serialize_meshes(p_state);
165
if (err != OK) {
166
return Error::FAILED;
167
}
168
169
/* STEP SERIALIZE TEXTURES */
170
err = _serialize_materials(p_state);
171
if (err != OK) {
172
return Error::FAILED;
173
}
174
175
/* STEP SERIALIZE TEXTURE SAMPLERS */
176
err = _serialize_texture_samplers(p_state);
177
if (err != OK) {
178
return Error::FAILED;
179
}
180
181
/* STEP SERIALIZE ANIMATIONS */
182
err = _serialize_animations(p_state);
183
if (err != OK) {
184
return Error::FAILED;
185
}
186
187
/* STEP SERIALIZE ACCESSORS */
188
err = _encode_accessors(p_state);
189
if (err != OK) {
190
return Error::FAILED;
191
}
192
193
/* STEP SERIALIZE IMAGES */
194
err = _serialize_images(p_state);
195
if (err != OK) {
196
return Error::FAILED;
197
}
198
199
/* STEP SERIALIZE TEXTURES */
200
err = _serialize_textures(p_state);
201
if (err != OK) {
202
return Error::FAILED;
203
}
204
205
/* STEP SERIALIZE BUFFER VIEWS */
206
err = _encode_buffer_views(p_state);
207
if (err != OK) {
208
return Error::FAILED;
209
}
210
211
/* STEP SERIALIZE NODES */
212
err = _serialize_nodes(p_state);
213
if (err != OK) {
214
return Error::FAILED;
215
}
216
217
/* STEP SERIALIZE SCENE */
218
err = _serialize_scenes(p_state);
219
if (err != OK) {
220
return Error::FAILED;
221
}
222
223
/* STEP SERIALIZE LIGHTS */
224
err = _serialize_lights(p_state);
225
if (err != OK) {
226
return Error::FAILED;
227
}
228
229
/* STEP SERIALIZE EXTENSIONS */
230
err = _serialize_gltf_extensions(p_state);
231
if (err != OK) {
232
return Error::FAILED;
233
}
234
235
/* STEP SERIALIZE VERSION */
236
err = _serialize_asset_header(p_state);
237
if (err != OK) {
238
return Error::FAILED;
239
}
240
241
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
242
ERR_CONTINUE(ext.is_null());
243
err = ext->export_post(p_state);
244
ERR_FAIL_COND_V(err != OK, err);
245
}
246
247
return OK;
248
}
249
250
Error GLTFDocument::_serialize_gltf_extensions(Ref<GLTFState> p_state) const {
251
Vector<String> extensions_used = p_state->extensions_used;
252
Vector<String> extensions_required = p_state->extensions_required;
253
if (!p_state->lights.is_empty()) {
254
extensions_used.push_back("KHR_lights_punctual");
255
}
256
if (p_state->use_khr_texture_transform) {
257
extensions_used.push_back("KHR_texture_transform");
258
extensions_required.push_back("KHR_texture_transform");
259
}
260
if (!extensions_used.is_empty()) {
261
extensions_used.sort();
262
p_state->json["extensionsUsed"] = extensions_used;
263
}
264
if (!extensions_required.is_empty()) {
265
extensions_required.sort();
266
p_state->json["extensionsRequired"] = extensions_required;
267
}
268
return OK;
269
}
270
271
Error GLTFDocument::_serialize_scenes(Ref<GLTFState> p_state) {
272
// Godot only supports one scene per glTF file.
273
Array scenes;
274
Dictionary scene_dict;
275
scenes.append(scene_dict);
276
p_state->json["scenes"] = scenes;
277
p_state->json["scene"] = 0;
278
// Add nodes to the scene dict.
279
if (!p_state->root_nodes.is_empty()) {
280
scene_dict["nodes"] = p_state->root_nodes;
281
}
282
if (!p_state->scene_name.is_empty()) {
283
scene_dict["name"] = p_state->scene_name;
284
}
285
return OK;
286
}
287
288
Error GLTFDocument::_parse_json(const String &p_path, Ref<GLTFState> p_state) {
289
Error err;
290
Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::READ, &err);
291
if (file.is_null()) {
292
return err;
293
}
294
295
Vector<uint8_t> array;
296
array.resize(file->get_length());
297
file->get_buffer(array.ptrw(), array.size());
298
String text = String::utf8((const char *)array.ptr(), array.size());
299
300
JSON json;
301
err = json.parse(text);
302
if (err != OK) {
303
_err_print_error("", p_path.utf8().get_data(), json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT);
304
return err;
305
}
306
p_state->json = json.get_data();
307
308
return OK;
309
}
310
311
Error GLTFDocument::_parse_glb(Ref<FileAccess> p_file, Ref<GLTFState> p_state) {
312
ERR_FAIL_COND_V(p_file.is_null(), ERR_INVALID_PARAMETER);
313
ERR_FAIL_COND_V(p_state.is_null(), ERR_INVALID_PARAMETER);
314
ERR_FAIL_COND_V(p_file->get_position() != 0, ERR_FILE_CANT_READ);
315
uint32_t magic = p_file->get_32();
316
ERR_FAIL_COND_V(magic != 0x46546C67, ERR_FILE_UNRECOGNIZED); //glTF
317
p_file->get_32(); // version
318
p_file->get_32(); // length
319
uint32_t chunk_length = p_file->get_32();
320
uint32_t chunk_type = p_file->get_32();
321
322
ERR_FAIL_COND_V(chunk_type != 0x4E4F534A, ERR_PARSE_ERROR); //JSON
323
Vector<uint8_t> json_data;
324
json_data.resize(chunk_length);
325
uint32_t len = p_file->get_buffer(json_data.ptrw(), chunk_length);
326
ERR_FAIL_COND_V(len != chunk_length, ERR_FILE_CORRUPT);
327
328
String text = String::utf8((const char *)json_data.ptr(), json_data.size());
329
330
JSON json;
331
Error err = json.parse(text);
332
ERR_FAIL_COND_V_MSG(err != OK, err, "glTF Binary: Error parsing .glb file's JSON data: " + json.get_error_message() + " at line: " + itos(json.get_error_line()));
333
334
p_state->json = json.get_data();
335
336
//data?
337
338
chunk_length = p_file->get_32();
339
chunk_type = p_file->get_32();
340
341
if (p_file->eof_reached()) {
342
return OK; //all good
343
}
344
345
ERR_FAIL_COND_V(chunk_type != 0x004E4942, ERR_PARSE_ERROR); //BIN
346
347
p_state->glb_data.resize(chunk_length);
348
len = p_file->get_buffer(p_state->glb_data.ptrw(), chunk_length);
349
ERR_FAIL_COND_V(len != chunk_length, ERR_FILE_CORRUPT);
350
351
return OK;
352
}
353
354
static Array _vec3_to_arr(const Vector3 &p_vec3) {
355
Array array;
356
array.resize(3);
357
array[0] = p_vec3.x;
358
array[1] = p_vec3.y;
359
array[2] = p_vec3.z;
360
return array;
361
}
362
363
static Vector3 _arr_to_vec3(const Array &p_array) {
364
ERR_FAIL_COND_V(p_array.size() != 3, Vector3());
365
return Vector3(p_array[0], p_array[1], p_array[2]);
366
}
367
368
static Array _quaternion_to_array(const Quaternion &p_quaternion) {
369
Array array;
370
array.resize(4);
371
array[0] = p_quaternion.x;
372
array[1] = p_quaternion.y;
373
array[2] = p_quaternion.z;
374
array[3] = p_quaternion.w;
375
return array;
376
}
377
378
static Quaternion _arr_to_quaternion(const Array &p_array) {
379
ERR_FAIL_COND_V(p_array.size() != 4, Quaternion());
380
return Quaternion(p_array[0], p_array[1], p_array[2], p_array[3]);
381
}
382
383
static Transform3D _arr_to_xform(const Array &p_array) {
384
ERR_FAIL_COND_V(p_array.size() != 16, Transform3D());
385
386
Transform3D xform;
387
xform.basis.set_column(Vector3::AXIS_X, Vector3(p_array[0], p_array[1], p_array[2]));
388
xform.basis.set_column(Vector3::AXIS_Y, Vector3(p_array[4], p_array[5], p_array[6]));
389
xform.basis.set_column(Vector3::AXIS_Z, Vector3(p_array[8], p_array[9], p_array[10]));
390
xform.set_origin(Vector3(p_array[12], p_array[13], p_array[14]));
391
392
return xform;
393
}
394
395
static Vector<real_t> _xform_to_array(const Transform3D p_transform) {
396
Vector<real_t> array;
397
array.resize(16);
398
Vector3 axis_x = p_transform.get_basis().get_column(Vector3::AXIS_X);
399
array.write[0] = axis_x.x;
400
array.write[1] = axis_x.y;
401
array.write[2] = axis_x.z;
402
array.write[3] = 0.0f;
403
Vector3 axis_y = p_transform.get_basis().get_column(Vector3::AXIS_Y);
404
array.write[4] = axis_y.x;
405
array.write[5] = axis_y.y;
406
array.write[6] = axis_y.z;
407
array.write[7] = 0.0f;
408
Vector3 axis_z = p_transform.get_basis().get_column(Vector3::AXIS_Z);
409
array.write[8] = axis_z.x;
410
array.write[9] = axis_z.y;
411
array.write[10] = axis_z.z;
412
array.write[11] = 0.0f;
413
Vector3 origin = p_transform.get_origin();
414
array.write[12] = origin.x;
415
array.write[13] = origin.y;
416
array.write[14] = origin.z;
417
array.write[15] = 1.0f;
418
return array;
419
}
420
421
Error GLTFDocument::_serialize_nodes(Ref<GLTFState> p_state) {
422
Array nodes;
423
for (int i = 0; i < p_state->nodes.size(); i++) {
424
Dictionary node;
425
Ref<GLTFNode> gltf_node = p_state->nodes[i];
426
Dictionary extensions;
427
node["extensions"] = extensions;
428
if (!gltf_node->get_name().is_empty()) {
429
node["name"] = gltf_node->get_name();
430
}
431
if (gltf_node->camera != -1) {
432
node["camera"] = gltf_node->camera;
433
}
434
if (gltf_node->light != -1) {
435
Dictionary lights_punctual;
436
extensions["KHR_lights_punctual"] = lights_punctual;
437
lights_punctual["light"] = gltf_node->light;
438
}
439
if (!gltf_node->visible) {
440
Dictionary khr_node_visibility;
441
extensions["KHR_node_visibility"] = khr_node_visibility;
442
khr_node_visibility["visible"] = gltf_node->visible;
443
if (!p_state->extensions_used.has("KHR_node_visibility")) {
444
p_state->extensions_used.push_back("KHR_node_visibility");
445
if (_visibility_mode == VISIBILITY_MODE_INCLUDE_REQUIRED) {
446
p_state->extensions_required.push_back("KHR_node_visibility");
447
}
448
}
449
}
450
if (gltf_node->mesh != -1) {
451
node["mesh"] = gltf_node->mesh;
452
}
453
if (gltf_node->skin != -1) {
454
node["skin"] = gltf_node->skin;
455
}
456
if (gltf_node->skeleton != -1 && gltf_node->skin < 0) {
457
}
458
if (gltf_node->transform.basis.is_orthogonal()) {
459
// An orthogonal transform is decomposable into TRS, so prefer that.
460
const Vector3 position = gltf_node->get_position();
461
if (!position.is_zero_approx()) {
462
node["translation"] = _vec3_to_arr(position);
463
}
464
const Quaternion rotation = gltf_node->get_rotation();
465
if (!rotation.is_equal_approx(Quaternion())) {
466
node["rotation"] = _quaternion_to_array(rotation);
467
}
468
const Vector3 scale = gltf_node->get_scale();
469
if (!scale.is_equal_approx(Vector3(1.0f, 1.0f, 1.0f))) {
470
node["scale"] = _vec3_to_arr(scale);
471
}
472
} else {
473
node["matrix"] = _xform_to_array(gltf_node->transform);
474
}
475
if (gltf_node->children.size()) {
476
Array children;
477
for (int j = 0; j < gltf_node->children.size(); j++) {
478
children.push_back(gltf_node->children[j]);
479
}
480
node["children"] = children;
481
}
482
483
Node *scene_node = nullptr;
484
if (i < (int)p_state->scene_nodes.size()) {
485
scene_node = p_state->scene_nodes[i];
486
}
487
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
488
ERR_CONTINUE(ext.is_null());
489
Error err = ext->export_node(p_state, gltf_node, node, scene_node);
490
ERR_CONTINUE(err != OK);
491
}
492
493
if (extensions.is_empty()) {
494
node.erase("extensions");
495
}
496
_attach_meta_to_extras(gltf_node, node);
497
nodes.push_back(node);
498
}
499
if (!nodes.is_empty()) {
500
p_state->json["nodes"] = nodes;
501
}
502
return OK;
503
}
504
505
String GLTFDocument::_gen_unique_name(Ref<GLTFState> p_state, const String &p_name) {
506
return _gen_unique_name_static(p_state->unique_names, p_name);
507
}
508
509
String GLTFDocument::_sanitize_animation_name(const String &p_name) {
510
String anim_name = p_name.validate_node_name();
511
return AnimationLibrary::validate_library_name(anim_name);
512
}
513
514
String GLTFDocument::_gen_unique_animation_name(Ref<GLTFState> p_state, const String &p_name) {
515
const String s_name = _sanitize_animation_name(p_name);
516
517
String u_name;
518
int index = 1;
519
while (true) {
520
u_name = s_name;
521
522
if (index > 1) {
523
u_name += itos(index);
524
}
525
if (!p_state->unique_animation_names.has(u_name)) {
526
break;
527
}
528
index++;
529
}
530
531
p_state->unique_animation_names.insert(u_name);
532
533
return u_name;
534
}
535
536
String GLTFDocument::_sanitize_bone_name(const String &p_name) {
537
String bone_name = p_name;
538
bone_name = bone_name.replace_chars(":/", '_');
539
return bone_name;
540
}
541
542
String GLTFDocument::_gen_unique_bone_name(Ref<GLTFState> p_state, const GLTFSkeletonIndex p_skel_i, const String &p_name) {
543
String s_name = _sanitize_bone_name(p_name);
544
if (s_name.is_empty()) {
545
s_name = "bone";
546
}
547
String u_name;
548
int index = 1;
549
while (true) {
550
u_name = s_name;
551
552
if (index > 1) {
553
u_name += "_" + itos(index);
554
}
555
if (!p_state->skeletons[p_skel_i]->unique_names.has(u_name)) {
556
break;
557
}
558
index++;
559
}
560
561
p_state->skeletons.write[p_skel_i]->unique_names.insert(u_name);
562
563
return u_name;
564
}
565
566
Error GLTFDocument::_parse_scenes(Ref<GLTFState> p_state) {
567
p_state->unique_names.insert("Skeleton3D"); // Reserve skeleton name.
568
ERR_FAIL_COND_V(!p_state->json.has("scenes"), ERR_FILE_CORRUPT);
569
const Array &scenes = p_state->json["scenes"];
570
int loaded_scene = 0;
571
if (p_state->json.has("scene")) {
572
loaded_scene = p_state->json["scene"];
573
} else {
574
WARN_PRINT("The load-time scene is not defined in the glTF2 file. Picking the first scene.");
575
}
576
577
if (scenes.size()) {
578
ERR_FAIL_COND_V(loaded_scene >= scenes.size(), ERR_FILE_CORRUPT);
579
const Dictionary &scene_dict = scenes[loaded_scene];
580
ERR_FAIL_COND_V(!scene_dict.has("nodes"), ERR_UNAVAILABLE);
581
const Array &nodes = scene_dict["nodes"];
582
for (int j = 0; j < nodes.size(); j++) {
583
p_state->root_nodes.push_back(nodes[j]);
584
}
585
// Determine what to use for the scene name.
586
if (scene_dict.has("name") && !String(scene_dict["name"]).is_empty() && !((String)scene_dict["name"]).begins_with("Scene")) {
587
p_state->scene_name = scene_dict["name"];
588
} else if (p_state->scene_name.is_empty()) {
589
p_state->scene_name = p_state->filename;
590
}
591
if (_naming_version == 0) {
592
p_state->scene_name = _gen_unique_name(p_state, p_state->scene_name);
593
}
594
}
595
596
return OK;
597
}
598
599
Error GLTFDocument::_parse_nodes(Ref<GLTFState> p_state) {
600
ERR_FAIL_COND_V(!p_state->json.has("nodes"), ERR_FILE_CORRUPT);
601
const Array &nodes = p_state->json["nodes"];
602
for (int i = 0; i < nodes.size(); i++) {
603
Ref<GLTFNode> node;
604
node.instantiate();
605
const Dictionary &n = nodes[i];
606
607
if (n.has("name")) {
608
node->set_original_name(n["name"]);
609
node->set_name(n["name"]);
610
}
611
if (n.has("camera")) {
612
node->camera = n["camera"];
613
}
614
if (n.has("mesh")) {
615
node->mesh = n["mesh"];
616
}
617
if (n.has("skin")) {
618
node->skin = n["skin"];
619
}
620
if (n.has("matrix")) {
621
node->transform = _arr_to_xform(n["matrix"]);
622
} else {
623
if (n.has("translation")) {
624
node->set_position(_arr_to_vec3(n["translation"]));
625
}
626
if (n.has("rotation")) {
627
node->set_rotation(_arr_to_quaternion(n["rotation"]));
628
}
629
if (n.has("scale")) {
630
node->set_scale(_arr_to_vec3(n["scale"]));
631
}
632
}
633
node->set_additional_data("GODOT_rest_transform", node->transform);
634
635
if (n.has("extensions")) {
636
Dictionary extensions = n["extensions"];
637
if (extensions.has("KHR_lights_punctual")) {
638
Dictionary lights_punctual = extensions["KHR_lights_punctual"];
639
if (lights_punctual.has("light")) {
640
GLTFLightIndex light = lights_punctual["light"];
641
node->light = light;
642
}
643
}
644
if (extensions.has("KHR_node_visibility")) {
645
Dictionary khr_node_visibility = extensions["KHR_node_visibility"];
646
if (khr_node_visibility.has("visible")) {
647
node->visible = khr_node_visibility["visible"];
648
}
649
}
650
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
651
ERR_CONTINUE(ext.is_null());
652
Error err = ext->parse_node_extensions(p_state, node, extensions);
653
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.");
654
}
655
}
656
657
if (n.has("extras")) {
658
_attach_extras_to_meta(n["extras"], node);
659
}
660
661
if (n.has("children")) {
662
const Array &children = n["children"];
663
for (int j = 0; j < children.size(); j++) {
664
node->children.push_back(children[j]);
665
}
666
}
667
668
p_state->nodes.push_back(node);
669
}
670
671
// build the hierarchy
672
for (GLTFNodeIndex node_i = 0; node_i < p_state->nodes.size(); node_i++) {
673
for (int j = 0; j < p_state->nodes[node_i]->children.size(); j++) {
674
GLTFNodeIndex child_i = p_state->nodes[node_i]->children[j];
675
676
ERR_FAIL_INDEX_V(child_i, p_state->nodes.size(), ERR_FILE_CORRUPT);
677
ERR_CONTINUE(p_state->nodes[child_i]->parent != -1); //node already has a parent, wtf.
678
679
p_state->nodes.write[child_i]->parent = node_i;
680
}
681
}
682
683
_compute_node_heights(p_state);
684
685
return OK;
686
}
687
688
void GLTFDocument::_compute_node_heights(Ref<GLTFState> p_state) {
689
if (_naming_version < 2) {
690
p_state->root_nodes.clear();
691
}
692
for (GLTFNodeIndex node_i = 0; node_i < p_state->nodes.size(); ++node_i) {
693
Ref<GLTFNode> node = p_state->nodes[node_i];
694
node->height = 0;
695
696
GLTFNodeIndex current_i = node_i;
697
while (current_i >= 0) {
698
const GLTFNodeIndex parent_i = p_state->nodes[current_i]->parent;
699
if (parent_i >= 0) {
700
++node->height;
701
}
702
current_i = parent_i;
703
}
704
705
if (_naming_version < 2) {
706
// This is incorrect, but required for compatibility with previous Godot versions.
707
if (node->height == 0) {
708
p_state->root_nodes.push_back(node_i);
709
}
710
}
711
}
712
}
713
714
static Vector<uint8_t> _parse_base64_uri(const String &p_uri) {
715
int start = p_uri.find_char(',');
716
ERR_FAIL_COND_V(start == -1, Vector<uint8_t>());
717
718
CharString substr = p_uri.substr(start + 1).ascii();
719
720
int strlen = substr.length();
721
722
Vector<uint8_t> buf;
723
buf.resize(strlen / 4 * 3 + 1 + 1);
724
725
size_t len = 0;
726
ERR_FAIL_COND_V(CryptoCore::b64_decode(buf.ptrw(), buf.size(), &len, (unsigned char *)substr.get_data(), strlen) != OK, Vector<uint8_t>());
727
728
buf.resize(len);
729
730
return buf;
731
}
732
733
Error GLTFDocument::_encode_buffer_glb(Ref<GLTFState> p_state, const String &p_path) {
734
print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size()));
735
736
if (p_state->buffers.is_empty()) {
737
return OK;
738
}
739
Array buffers;
740
if (!p_state->buffers.is_empty()) {
741
Vector<uint8_t> buffer_data = p_state->buffers[0];
742
Dictionary gltf_buffer;
743
744
gltf_buffer["byteLength"] = buffer_data.size();
745
buffers.push_back(gltf_buffer);
746
}
747
748
for (GLTFBufferIndex i = 1; i < p_state->buffers.size(); i++) {
749
Vector<uint8_t> buffer_data = p_state->buffers[i];
750
Dictionary gltf_buffer;
751
String filename = p_path.get_basename().get_file() + itos(i) + ".bin";
752
String path = p_path.get_base_dir() + "/" + filename;
753
Error err;
754
Ref<FileAccess> file = FileAccess::open(path, FileAccess::WRITE, &err);
755
if (file.is_null()) {
756
return err;
757
}
758
if (buffer_data.is_empty()) {
759
return OK;
760
}
761
file->create(FileAccess::ACCESS_RESOURCES);
762
file->store_buffer(buffer_data.ptr(), buffer_data.size());
763
gltf_buffer["uri"] = filename;
764
gltf_buffer["byteLength"] = buffer_data.size();
765
buffers.push_back(gltf_buffer);
766
}
767
p_state->json["buffers"] = buffers;
768
769
return OK;
770
}
771
772
Error GLTFDocument::_encode_buffer_bins(Ref<GLTFState> p_state, const String &p_path) {
773
print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size()));
774
775
if (p_state->buffers.is_empty()) {
776
return OK;
777
}
778
Array buffers;
779
780
for (GLTFBufferIndex i = 0; i < p_state->buffers.size(); i++) {
781
Vector<uint8_t> buffer_data = p_state->buffers[i];
782
Dictionary gltf_buffer;
783
String filename = p_path.get_basename().get_file() + itos(i) + ".bin";
784
String path = p_path.get_base_dir() + "/" + filename;
785
Error err;
786
Ref<FileAccess> file = FileAccess::open(path, FileAccess::WRITE, &err);
787
if (file.is_null()) {
788
return err;
789
}
790
if (buffer_data.is_empty()) {
791
return OK;
792
}
793
file->create(FileAccess::ACCESS_RESOURCES);
794
file->store_buffer(buffer_data.ptr(), buffer_data.size());
795
gltf_buffer["uri"] = filename;
796
gltf_buffer["byteLength"] = buffer_data.size();
797
buffers.push_back(gltf_buffer);
798
}
799
p_state->json["buffers"] = buffers;
800
801
return OK;
802
}
803
804
Error GLTFDocument::_parse_buffers(Ref<GLTFState> p_state, const String &p_base_path) {
805
if (!p_state->json.has("buffers")) {
806
return OK;
807
}
808
809
const Array &buffers = p_state->json["buffers"];
810
for (GLTFBufferIndex i = 0; i < buffers.size(); i++) {
811
const Dictionary &buffer = buffers[i];
812
Vector<uint8_t> buffer_data;
813
if (buffer.has("uri")) {
814
String uri = buffer["uri"];
815
816
if (uri.begins_with("data:")) { // Embedded data using base64.
817
// Validate data MIME types and throw an error if it's one we don't know/support.
818
if (!uri.begins_with("data:application/octet-stream;base64") &&
819
!uri.begins_with("data:application/gltf-buffer;base64")) {
820
ERR_PRINT("glTF: Got buffer with an unknown URI data type: " + uri);
821
}
822
buffer_data = _parse_base64_uri(uri);
823
} else { // Relative path to an external image file.
824
ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER);
825
uri = uri.uri_file_decode();
826
uri = p_base_path.path_join(uri).replace_char('\\', '/'); // Fix for Windows.
827
ERR_FAIL_COND_V_MSG(!FileAccess::exists(uri), ERR_FILE_NOT_FOUND, "glTF: Binary file not found: " + uri);
828
buffer_data = FileAccess::get_file_as_bytes(uri);
829
ERR_FAIL_COND_V_MSG(buffer_data.is_empty(), ERR_PARSE_ERROR, "glTF: Couldn't load binary file as an array: " + uri);
830
}
831
832
ERR_FAIL_COND_V(!buffer.has("byteLength"), ERR_PARSE_ERROR);
833
int64_t byteLength = buffer["byteLength"];
834
ERR_FAIL_COND_V(byteLength < buffer_data.size(), ERR_PARSE_ERROR);
835
} else if (i == 0 && p_state->glb_data.size()) {
836
buffer_data = p_state->glb_data;
837
} else {
838
ERR_PRINT("glTF: Buffer " + itos(i) + " has no data and cannot be loaded.");
839
}
840
p_state->buffers.push_back(buffer_data);
841
}
842
843
print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size()));
844
845
return OK;
846
}
847
848
Error GLTFDocument::_encode_buffer_views(Ref<GLTFState> p_state) {
849
Array buffers;
850
for (GLTFBufferViewIndex i = 0; i < p_state->buffer_views.size(); i++) {
851
Dictionary d;
852
853
Ref<GLTFBufferView> buffer_view = p_state->buffer_views[i];
854
855
d["buffer"] = buffer_view->buffer;
856
d["byteLength"] = buffer_view->byte_length;
857
858
if (buffer_view->byte_offset > 0) {
859
d["byteOffset"] = buffer_view->byte_offset;
860
}
861
862
if (buffer_view->byte_stride != -1) {
863
d["byteStride"] = buffer_view->byte_stride;
864
}
865
866
if (buffer_view->indices) {
867
d["target"] = GLTFDocument::ELEMENT_ARRAY_BUFFER;
868
} else if (buffer_view->vertex_attributes) {
869
d["target"] = GLTFDocument::ARRAY_BUFFER;
870
}
871
872
ERR_FAIL_COND_V(!d.has("buffer"), ERR_INVALID_DATA);
873
ERR_FAIL_COND_V(!d.has("byteLength"), ERR_INVALID_DATA);
874
buffers.push_back(d);
875
}
876
print_verbose("glTF: Total buffer views: " + itos(p_state->buffer_views.size()));
877
if (!buffers.size()) {
878
return OK;
879
}
880
p_state->json["bufferViews"] = buffers;
881
return OK;
882
}
883
884
Error GLTFDocument::_parse_buffer_views(Ref<GLTFState> p_state) {
885
if (!p_state->json.has("bufferViews")) {
886
return OK;
887
}
888
const Array &buffers = p_state->json["bufferViews"];
889
for (GLTFBufferViewIndex i = 0; i < buffers.size(); i++) {
890
const Dictionary &d = buffers[i];
891
892
Ref<GLTFBufferView> buffer_view;
893
buffer_view.instantiate();
894
895
ERR_FAIL_COND_V(!d.has("buffer"), ERR_PARSE_ERROR);
896
buffer_view->buffer = d["buffer"];
897
ERR_FAIL_COND_V(!d.has("byteLength"), ERR_PARSE_ERROR);
898
buffer_view->byte_length = d["byteLength"];
899
900
if (d.has("byteOffset")) {
901
buffer_view->byte_offset = d["byteOffset"];
902
}
903
904
if (d.has("byteStride")) {
905
buffer_view->byte_stride = d["byteStride"];
906
if (buffer_view->byte_stride < 4 || buffer_view->byte_stride > 252 || buffer_view->byte_stride % 4 != 0) {
907
ERR_PRINT("glTF import: Invalid byte stride " + itos(buffer_view->byte_stride) + " for buffer view at index " + itos(i) + " while importing file '" + p_state->filename + "'. If defined, byte stride must be a multiple of 4 and between 4 and 252.");
908
}
909
}
910
911
if (d.has("target")) {
912
const int target = d["target"];
913
buffer_view->indices = target == GLTFDocument::ELEMENT_ARRAY_BUFFER;
914
buffer_view->vertex_attributes = target == GLTFDocument::ARRAY_BUFFER;
915
}
916
917
p_state->buffer_views.push_back(buffer_view);
918
}
919
920
print_verbose("glTF: Total buffer views: " + itos(p_state->buffer_views.size()));
921
922
return OK;
923
}
924
925
Error GLTFDocument::_encode_accessors(Ref<GLTFState> p_state) {
926
Array accessors;
927
for (GLTFAccessorIndex i = 0; i < p_state->accessors.size(); i++) {
928
Dictionary d;
929
930
Ref<GLTFAccessor> accessor = p_state->accessors[i];
931
d["componentType"] = accessor->component_type;
932
d["count"] = accessor->count;
933
d["type"] = _get_accessor_type_name(accessor->accessor_type);
934
d["normalized"] = accessor->normalized;
935
d["max"] = accessor->max;
936
d["min"] = accessor->min;
937
if (accessor->buffer_view != -1) {
938
// bufferView may be omitted to zero-initialize the buffer. When this happens, byteOffset MUST also be omitted.
939
if (accessor->byte_offset > 0) {
940
d["byteOffset"] = accessor->byte_offset;
941
}
942
d["bufferView"] = accessor->buffer_view;
943
}
944
945
if (accessor->sparse_count > 0) {
946
Dictionary s;
947
s["count"] = accessor->sparse_count;
948
949
Dictionary si;
950
si["bufferView"] = accessor->sparse_indices_buffer_view;
951
si["componentType"] = accessor->sparse_indices_component_type;
952
if (accessor->sparse_indices_byte_offset > 0) {
953
si["byteOffset"] = accessor->sparse_indices_byte_offset;
954
}
955
ERR_FAIL_COND_V(!si.has("bufferView") || !si.has("componentType"), ERR_PARSE_ERROR);
956
s["indices"] = si;
957
958
Dictionary sv;
959
sv["bufferView"] = accessor->sparse_values_buffer_view;
960
if (accessor->sparse_values_byte_offset > 0) {
961
sv["byteOffset"] = accessor->sparse_values_byte_offset;
962
}
963
ERR_FAIL_COND_V(!sv.has("bufferView"), ERR_PARSE_ERROR);
964
s["values"] = sv;
965
966
ERR_FAIL_COND_V(!s.has("count") || !s.has("indices") || !s.has("values"), ERR_PARSE_ERROR);
967
d["sparse"] = s;
968
}
969
970
accessors.push_back(d);
971
}
972
973
if (!accessors.size()) {
974
return OK;
975
}
976
p_state->json["accessors"] = accessors;
977
ERR_FAIL_COND_V(!p_state->json.has("accessors"), ERR_FILE_CORRUPT);
978
print_verbose("glTF: Total accessors: " + itos(p_state->accessors.size()));
979
980
return OK;
981
}
982
983
String GLTFDocument::_get_accessor_type_name(const GLTFAccessor::GLTFAccessorType p_accessor_type) {
984
if (p_accessor_type == GLTFAccessor::TYPE_SCALAR) {
985
return "SCALAR";
986
}
987
if (p_accessor_type == GLTFAccessor::TYPE_VEC2) {
988
return "VEC2";
989
}
990
if (p_accessor_type == GLTFAccessor::TYPE_VEC3) {
991
return "VEC3";
992
}
993
if (p_accessor_type == GLTFAccessor::TYPE_VEC4) {
994
return "VEC4";
995
}
996
997
if (p_accessor_type == GLTFAccessor::TYPE_MAT2) {
998
return "MAT2";
999
}
1000
if (p_accessor_type == GLTFAccessor::TYPE_MAT3) {
1001
return "MAT3";
1002
}
1003
if (p_accessor_type == GLTFAccessor::TYPE_MAT4) {
1004
return "MAT4";
1005
}
1006
ERR_FAIL_V("SCALAR");
1007
}
1008
1009
GLTFAccessor::GLTFAccessorType GLTFDocument::_get_accessor_type_from_str(const String &p_string) {
1010
if (p_string == "SCALAR") {
1011
return GLTFAccessor::TYPE_SCALAR;
1012
}
1013
1014
if (p_string == "VEC2") {
1015
return GLTFAccessor::TYPE_VEC2;
1016
}
1017
if (p_string == "VEC3") {
1018
return GLTFAccessor::TYPE_VEC3;
1019
}
1020
if (p_string == "VEC4") {
1021
return GLTFAccessor::TYPE_VEC4;
1022
}
1023
1024
if (p_string == "MAT2") {
1025
return GLTFAccessor::TYPE_MAT2;
1026
}
1027
if (p_string == "MAT3") {
1028
return GLTFAccessor::TYPE_MAT3;
1029
}
1030
if (p_string == "MAT4") {
1031
return GLTFAccessor::TYPE_MAT4;
1032
}
1033
1034
ERR_FAIL_V(GLTFAccessor::TYPE_SCALAR);
1035
}
1036
1037
Error GLTFDocument::_parse_accessors(Ref<GLTFState> p_state) {
1038
if (!p_state->json.has("accessors")) {
1039
return OK;
1040
}
1041
const Array &accessors = p_state->json["accessors"];
1042
for (GLTFAccessorIndex i = 0; i < accessors.size(); i++) {
1043
const Dictionary &d = accessors[i];
1044
1045
Ref<GLTFAccessor> accessor;
1046
accessor.instantiate();
1047
1048
ERR_FAIL_COND_V(!d.has("componentType"), ERR_PARSE_ERROR);
1049
accessor->component_type = (GLTFAccessor::GLTFComponentType)(int32_t)d["componentType"];
1050
ERR_FAIL_COND_V(!d.has("count"), ERR_PARSE_ERROR);
1051
accessor->count = d["count"];
1052
if (accessor->count <= 0) {
1053
ERR_PRINT("glTF import: Invalid accessor count " + itos(accessor->count) + " for accessor at index " + itos(i) + " while importing file '" + p_state->filename + "'. Accessor count must be greater than 0.");
1054
}
1055
ERR_FAIL_COND_V(!d.has("type"), ERR_PARSE_ERROR);
1056
accessor->accessor_type = _get_accessor_type_from_str(d["type"]);
1057
1058
if (d.has("bufferView")) {
1059
accessor->buffer_view = d["bufferView"]; //optional because it may be sparse...
1060
}
1061
1062
if (d.has("byteOffset")) {
1063
accessor->byte_offset = d["byteOffset"];
1064
}
1065
1066
if (d.has("normalized")) {
1067
accessor->normalized = d["normalized"];
1068
}
1069
1070
if (d.has("max")) {
1071
accessor->max = d["max"];
1072
}
1073
1074
if (d.has("min")) {
1075
accessor->min = d["min"];
1076
}
1077
1078
if (d.has("sparse")) {
1079
const Dictionary &s = d["sparse"];
1080
1081
ERR_FAIL_COND_V(!s.has("count"), ERR_PARSE_ERROR);
1082
accessor->sparse_count = s["count"];
1083
ERR_FAIL_COND_V(!s.has("indices"), ERR_PARSE_ERROR);
1084
const Dictionary &si = s["indices"];
1085
1086
ERR_FAIL_COND_V(!si.has("bufferView"), ERR_PARSE_ERROR);
1087
accessor->sparse_indices_buffer_view = si["bufferView"];
1088
ERR_FAIL_COND_V(!si.has("componentType"), ERR_PARSE_ERROR);
1089
accessor->sparse_indices_component_type = (GLTFAccessor::GLTFComponentType)(int32_t)si["componentType"];
1090
1091
if (si.has("byteOffset")) {
1092
accessor->sparse_indices_byte_offset = si["byteOffset"];
1093
}
1094
1095
ERR_FAIL_COND_V(!s.has("values"), ERR_PARSE_ERROR);
1096
const Dictionary &sv = s["values"];
1097
1098
ERR_FAIL_COND_V(!sv.has("bufferView"), ERR_PARSE_ERROR);
1099
accessor->sparse_values_buffer_view = sv["bufferView"];
1100
if (sv.has("byteOffset")) {
1101
accessor->sparse_values_byte_offset = sv["byteOffset"];
1102
}
1103
}
1104
1105
p_state->accessors.push_back(accessor);
1106
}
1107
1108
print_verbose("glTF: Total accessors: " + itos(p_state->accessors.size()));
1109
1110
return OK;
1111
}
1112
1113
double GLTFDocument::_filter_number(double p_float) {
1114
if (!Math::is_finite(p_float)) {
1115
// 3.6.2.2. "Values of NaN, +Infinity, and -Infinity MUST NOT be present."
1116
return 0.0f;
1117
}
1118
return (double)(float)p_float;
1119
}
1120
1121
String GLTFDocument::_get_component_type_name(const GLTFAccessor::GLTFComponentType p_component) {
1122
switch (p_component) {
1123
case GLTFAccessor::COMPONENT_TYPE_NONE:
1124
return "None";
1125
case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE:
1126
return "Byte";
1127
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE:
1128
return "UByte";
1129
case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT:
1130
return "Short";
1131
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT:
1132
return "UShort";
1133
case GLTFAccessor::COMPONENT_TYPE_SIGNED_INT:
1134
return "Int";
1135
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT:
1136
return "UInt";
1137
case GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT:
1138
return "Float";
1139
case GLTFAccessor::COMPONENT_TYPE_DOUBLE_FLOAT:
1140
return "Double";
1141
case GLTFAccessor::COMPONENT_TYPE_HALF_FLOAT:
1142
return "Half";
1143
case GLTFAccessor::COMPONENT_TYPE_SIGNED_LONG:
1144
return "Long";
1145
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_LONG:
1146
return "ULong";
1147
}
1148
1149
return "<Error>";
1150
}
1151
1152
Error GLTFDocument::_encode_accessor_into_buffer_view(Ref<GLTFState> p_state, const double *p_src, const int64_t p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const GLTFAccessor::GLTFComponentType p_component_type, const bool p_normalized, const int64_t p_byte_offset, const bool p_for_vertex, GLTFBufferViewIndex &r_buffer_view, const bool p_for_vertex_indices) {
1153
const int component_count = COMPONENT_COUNT_FOR_ACCESSOR_TYPE[p_accessor_type];
1154
const int component_size = _get_component_type_size(p_component_type);
1155
ERR_FAIL_COND_V(component_size == 0, FAILED);
1156
// The byte offset of an accessor MUST be a multiple of the accessor's component size.
1157
// See 3.6.2.4: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#data-alignment
1158
int64_t offset = p_byte_offset;
1159
if (p_byte_offset % component_size != 0) {
1160
offset += component_size - (p_byte_offset % component_size);
1161
}
1162
1163
int64_t skip_every = 0;
1164
int64_t skip_bytes = 0;
1165
// Accessors of matrix type have data stored in column-major order. The start of each column MUST be aligned to 4-byte boundaries.
1166
// See 3.6.2.4: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#data-alignment
1167
switch (p_component_type) {
1168
case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE:
1169
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE: {
1170
if (p_accessor_type == GLTFAccessor::TYPE_MAT2) {
1171
skip_every = 2;
1172
skip_bytes = 2;
1173
}
1174
if (p_accessor_type == GLTFAccessor::TYPE_MAT3) {
1175
skip_every = 3;
1176
skip_bytes = 1;
1177
}
1178
} break;
1179
case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT:
1180
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: {
1181
if (p_accessor_type == GLTFAccessor::TYPE_MAT3) {
1182
skip_every = 6;
1183
skip_bytes = 2;
1184
}
1185
} break;
1186
default: {
1187
}
1188
}
1189
1190
Ref<GLTFBufferView> bv;
1191
bv.instantiate();
1192
const GLTFBufferIndex buffer0 = 0;
1193
bv->buffer = buffer0;
1194
bv->byte_offset = offset;
1195
Vector<uint8_t> &gltf_buffer = p_state->buffers.write[buffer0];
1196
1197
int64_t stride = component_count * component_size;
1198
if (p_for_vertex && stride % 4) {
1199
stride += 4 - (stride % 4); //according to spec must be multiple of 4
1200
}
1201
//use to debug
1202
print_verbose("glTF: encoding accessor type " + _get_accessor_type_name(p_accessor_type) + " component type: " + _get_component_type_name(p_component_type) + " stride: " + itos(stride) + " amount " + itos(p_count));
1203
1204
print_verbose("glTF: encoding accessor offset " + itos(offset) + " view offset: " + itos(bv->byte_offset) + " total buffer len: " + itos(gltf_buffer.size()) + " view len " + itos(bv->byte_length));
1205
1206
const int64_t buffer_end = (stride * (p_count - 1)) + component_size;
1207
// TODO define bv->byte_stride
1208
bv->byte_offset = gltf_buffer.size();
1209
if (p_for_vertex_indices) {
1210
bv->indices = true;
1211
} else if (p_for_vertex) {
1212
bv->vertex_attributes = true;
1213
bv->byte_stride = stride;
1214
}
1215
1216
switch (p_component_type) {
1217
case GLTFAccessor::COMPONENT_TYPE_NONE: {
1218
ERR_FAIL_V_MSG(ERR_INVALID_DATA, "glTF: Failed to encode buffer view, component type not set.");
1219
}
1220
case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: {
1221
Vector<int8_t> encoded_data;
1222
encoded_data.resize(p_count * component_count);
1223
int64_t dst_i = 0;
1224
for (int64_t i = 0; i < p_count; i++) {
1225
for (int64_t j = 0; j < component_count; j++) {
1226
if (skip_every && j > 0 && (j % skip_every) == 0) {
1227
dst_i += skip_bytes;
1228
}
1229
double d = *p_src;
1230
if (p_normalized) {
1231
encoded_data.write[dst_i] = d * 128.0;
1232
} else {
1233
encoded_data.write[dst_i] = d;
1234
}
1235
p_src++;
1236
dst_i++;
1237
}
1238
}
1239
const int64_t old_size = gltf_buffer.size();
1240
const size_t buffer_size = encoded_data.size() * sizeof(int8_t);
1241
gltf_buffer.resize(old_size + buffer_size);
1242
memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size);
1243
bv->byte_length = buffer_size;
1244
} break;
1245
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE: {
1246
Vector<uint8_t> encoded_data;
1247
encoded_data.resize(p_count * component_count);
1248
int64_t dst_i = 0;
1249
for (int64_t i = 0; i < p_count; i++) {
1250
for (int64_t j = 0; j < component_count; j++) {
1251
if (skip_every && j > 0 && (j % skip_every) == 0) {
1252
dst_i += skip_bytes;
1253
}
1254
double d = *p_src;
1255
if (p_normalized) {
1256
encoded_data.write[dst_i] = d * 255.0;
1257
} else {
1258
encoded_data.write[dst_i] = d;
1259
}
1260
p_src++;
1261
dst_i++;
1262
}
1263
}
1264
gltf_buffer.append_array(encoded_data);
1265
const size_t buffer_size = encoded_data.size() * sizeof(uint8_t);
1266
bv->byte_length = buffer_size;
1267
} break;
1268
case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT: {
1269
Vector<int16_t> encoded_data;
1270
encoded_data.resize(p_count * component_count);
1271
int64_t dst_i = 0;
1272
for (int64_t i = 0; i < p_count; i++) {
1273
for (int64_t j = 0; j < component_count; j++) {
1274
if (skip_every && j > 0 && (j % skip_every) == 0) {
1275
dst_i += skip_bytes;
1276
}
1277
double d = *p_src;
1278
if (p_normalized) {
1279
encoded_data.write[dst_i] = d * 32768.0;
1280
} else {
1281
encoded_data.write[dst_i] = d;
1282
}
1283
p_src++;
1284
dst_i++;
1285
}
1286
}
1287
const int64_t old_size = gltf_buffer.size();
1288
const size_t buffer_size = encoded_data.size() * sizeof(int16_t);
1289
gltf_buffer.resize(old_size + buffer_size);
1290
memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size);
1291
bv->byte_length = buffer_size;
1292
} break;
1293
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: {
1294
Vector<uint16_t> encoded_data;
1295
encoded_data.resize(p_count * component_count);
1296
int64_t dst_i = 0;
1297
for (int64_t i = 0; i < p_count; i++) {
1298
for (int64_t j = 0; j < component_count; j++) {
1299
if (skip_every && j > 0 && (j % skip_every) == 0) {
1300
dst_i += skip_bytes;
1301
}
1302
double d = *p_src;
1303
if (p_normalized) {
1304
encoded_data.write[dst_i] = d * 65535.0;
1305
} else {
1306
encoded_data.write[dst_i] = d;
1307
}
1308
p_src++;
1309
dst_i++;
1310
}
1311
}
1312
const int64_t old_size = gltf_buffer.size();
1313
const size_t buffer_size = encoded_data.size() * sizeof(uint16_t);
1314
gltf_buffer.resize(old_size + buffer_size);
1315
memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size);
1316
bv->byte_length = buffer_size;
1317
} break;
1318
case GLTFAccessor::COMPONENT_TYPE_SIGNED_INT: {
1319
Vector<int32_t> encoded_data;
1320
encoded_data.resize(p_count * component_count);
1321
int64_t dst_i = 0;
1322
for (int64_t i = 0; i < p_count; i++) {
1323
for (int64_t j = 0; j < component_count; j++) {
1324
if (skip_every && j > 0 && (j % skip_every) == 0) {
1325
dst_i += skip_bytes;
1326
}
1327
double d = *p_src;
1328
encoded_data.write[dst_i] = d;
1329
p_src++;
1330
dst_i++;
1331
}
1332
}
1333
const int64_t old_size = gltf_buffer.size();
1334
const size_t buffer_size = encoded_data.size() * sizeof(int32_t);
1335
gltf_buffer.resize(old_size + buffer_size);
1336
memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size);
1337
bv->byte_length = buffer_size;
1338
} break;
1339
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT: {
1340
Vector<uint32_t> encoded_data;
1341
encoded_data.resize(p_count * component_count);
1342
int64_t dst_i = 0;
1343
for (int64_t i = 0; i < p_count; i++) {
1344
for (int64_t j = 0; j < component_count; j++) {
1345
if (skip_every && j > 0 && (j % skip_every) == 0) {
1346
dst_i += skip_bytes;
1347
}
1348
double d = *p_src;
1349
encoded_data.write[dst_i] = d;
1350
p_src++;
1351
dst_i++;
1352
}
1353
}
1354
const int64_t old_size = gltf_buffer.size();
1355
const size_t buffer_size = encoded_data.size() * sizeof(uint32_t);
1356
gltf_buffer.resize(old_size + buffer_size);
1357
memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size);
1358
bv->byte_length = buffer_size;
1359
} break;
1360
case GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT: {
1361
Vector<float> encoded_data;
1362
encoded_data.resize(p_count * component_count);
1363
int64_t dst_i = 0;
1364
for (int64_t i = 0; i < p_count; i++) {
1365
for (int64_t j = 0; j < component_count; j++) {
1366
if (skip_every && j > 0 && (j % skip_every) == 0) {
1367
dst_i += skip_bytes;
1368
}
1369
double d = *p_src;
1370
encoded_data.write[dst_i] = d;
1371
p_src++;
1372
dst_i++;
1373
}
1374
}
1375
const int64_t old_size = gltf_buffer.size();
1376
const size_t buffer_size = encoded_data.size() * sizeof(float);
1377
gltf_buffer.resize(old_size + buffer_size);
1378
memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size);
1379
bv->byte_length = buffer_size;
1380
} break;
1381
case GLTFAccessor::COMPONENT_TYPE_DOUBLE_FLOAT: {
1382
Vector<double> encoded_data;
1383
encoded_data.resize(p_count * component_count);
1384
int64_t dst_i = 0;
1385
for (int64_t i = 0; i < p_count; i++) {
1386
for (int64_t j = 0; j < component_count; j++) {
1387
if (skip_every && j > 0 && (j % skip_every) == 0) {
1388
dst_i += skip_bytes;
1389
}
1390
double d = *p_src;
1391
encoded_data.write[dst_i] = d;
1392
p_src++;
1393
dst_i++;
1394
}
1395
}
1396
const int64_t old_size = gltf_buffer.size();
1397
const size_t buffer_size = encoded_data.size() * sizeof(double);
1398
gltf_buffer.resize(old_size + buffer_size);
1399
memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size);
1400
bv->byte_length = buffer_size;
1401
} break;
1402
case GLTFAccessor::COMPONENT_TYPE_HALF_FLOAT: {
1403
ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "glTF: Half float not supported yet.");
1404
} break;
1405
case GLTFAccessor::COMPONENT_TYPE_SIGNED_LONG: {
1406
Vector<int64_t> encoded_data;
1407
encoded_data.resize(p_count * component_count);
1408
int64_t dst_i = 0;
1409
for (int64_t i = 0; i < p_count; i++) {
1410
for (int64_t j = 0; j < component_count; j++) {
1411
if (skip_every && j > 0 && (j % skip_every) == 0) {
1412
dst_i += skip_bytes;
1413
}
1414
// FIXME: This can result in precision loss because int64_t can store some values that double can't.
1415
double d = *p_src;
1416
encoded_data.write[dst_i] = d;
1417
p_src++;
1418
dst_i++;
1419
}
1420
}
1421
const int64_t old_size = gltf_buffer.size();
1422
const size_t buffer_size = encoded_data.size() * sizeof(int64_t);
1423
gltf_buffer.resize(old_size + buffer_size);
1424
memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size);
1425
bv->byte_length = buffer_size;
1426
} break;
1427
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_LONG: {
1428
Vector<uint64_t> encoded_data;
1429
encoded_data.resize(p_count * component_count);
1430
int64_t dst_i = 0;
1431
for (int64_t i = 0; i < p_count; i++) {
1432
for (int64_t j = 0; j < component_count; j++) {
1433
if (skip_every && j > 0 && (j % skip_every) == 0) {
1434
dst_i += skip_bytes;
1435
}
1436
// FIXME: This can result in precision loss because int64_t can store some values that double can't.
1437
double d = *p_src;
1438
encoded_data.write[dst_i] = d;
1439
p_src++;
1440
dst_i++;
1441
}
1442
}
1443
const int64_t old_size = gltf_buffer.size();
1444
const size_t buffer_size = encoded_data.size() * sizeof(uint64_t);
1445
gltf_buffer.resize(old_size + buffer_size);
1446
memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size);
1447
bv->byte_length = buffer_size;
1448
} break;
1449
}
1450
ERR_FAIL_COND_V(buffer_end > bv->byte_length, ERR_INVALID_DATA);
1451
1452
ERR_FAIL_COND_V((int)(offset + buffer_end) > gltf_buffer.size(), ERR_INVALID_DATA);
1453
int64_t pad_bytes = (4 - gltf_buffer.size()) & 3;
1454
for (int64_t i = 0; i < pad_bytes; i++) {
1455
gltf_buffer.push_back(0);
1456
}
1457
1458
r_buffer_view = p_state->buffer_views.size();
1459
p_state->buffer_views.push_back(bv);
1460
return OK;
1461
}
1462
1463
Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, const GLTFBufferViewIndex p_buffer_view, const int64_t p_skip_every, const int64_t p_skip_bytes, const int64_t p_element_size, const int64_t p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const int64_t p_component_count, const GLTFAccessor::GLTFComponentType p_component_type, const int64_t p_component_size, const bool p_normalized, const int64_t p_byte_offset, const bool p_for_vertex) {
1464
const Ref<GLTFBufferView> bv = p_state->buffer_views[p_buffer_view];
1465
1466
int64_t stride = p_element_size;
1467
if (bv->byte_stride > 0) {
1468
stride = bv->byte_stride;
1469
}
1470
if (p_for_vertex && stride % 4) {
1471
stride += 4 - (stride % 4); //according to spec must be multiple of 4
1472
}
1473
1474
ERR_FAIL_INDEX_V(bv->buffer, p_state->buffers.size(), ERR_PARSE_ERROR);
1475
if (bv->byte_offset % p_component_size != 0) {
1476
WARN_PRINT("glTF: Buffer view byte offset is not a multiple of accessor component size. This file is invalid per the glTF specification and will not load correctly in some glTF viewers, but Godot will try to load it anyway.");
1477
}
1478
if (p_byte_offset % p_component_size != 0) {
1479
WARN_PRINT("glTF: Accessor byte offset is not a multiple of accessor component size. This file is invalid per the glTF specification and will not load correctly in some glTF viewers, but Godot will try to load it anyway.");
1480
}
1481
1482
const uint32_t offset = bv->byte_offset + p_byte_offset;
1483
Vector<uint8_t> buffer = p_state->buffers[bv->buffer]; //copy on write, so no performance hit
1484
const uint8_t *bufptr = buffer.ptr();
1485
1486
//use to debug
1487
print_verbose("glTF: accessor type " + _get_accessor_type_name(p_accessor_type) + " component type: " + _get_component_type_name(p_component_type) + " stride: " + itos(stride) + " amount " + itos(p_count));
1488
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));
1489
1490
const int64_t buffer_end = (stride * (p_count - 1)) + p_element_size;
1491
ERR_FAIL_COND_V(buffer_end > bv->byte_length, ERR_PARSE_ERROR);
1492
1493
ERR_FAIL_COND_V((int)(offset + buffer_end) > buffer.size(), ERR_PARSE_ERROR);
1494
1495
//fill everything as doubles
1496
1497
for (int64_t i = 0; i < p_count; i++) {
1498
const uint8_t *src = &bufptr[offset + i * stride];
1499
1500
for (int64_t j = 0; j < p_component_count; j++) {
1501
if (p_skip_every && j > 0 && (j % p_skip_every) == 0) {
1502
src += p_skip_bytes;
1503
}
1504
1505
double d = 0;
1506
// 3.11. Implementations MUST use following equations to decode real floating-point value f from a normalized integer c and vise-versa.
1507
// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#animations
1508
switch (p_component_type) {
1509
case GLTFAccessor::COMPONENT_TYPE_NONE: {
1510
ERR_FAIL_V_MSG(ERR_INVALID_DATA, "glTF: Failed to decode buffer view, component type not set.");
1511
} break;
1512
case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: {
1513
int8_t b = int8_t(*src);
1514
if (p_normalized) {
1515
d = MAX(double(b) / 127.0, -1.0);
1516
} else {
1517
d = double(b);
1518
}
1519
} break;
1520
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE: {
1521
uint8_t b = *src;
1522
if (p_normalized) {
1523
d = (double(b) / 255.0);
1524
} else {
1525
d = double(b);
1526
}
1527
} break;
1528
case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT: {
1529
int16_t s = *(int16_t *)src;
1530
if (p_normalized) {
1531
d = MAX(double(s) / 32767.0, -1.0);
1532
} else {
1533
d = double(s);
1534
}
1535
} break;
1536
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: {
1537
uint16_t s = *(uint16_t *)src;
1538
if (p_normalized) {
1539
d = (double(s) / 65535.0);
1540
} else {
1541
d = double(s);
1542
}
1543
} break;
1544
case GLTFAccessor::COMPONENT_TYPE_SIGNED_INT: {
1545
d = *(int32_t *)src;
1546
} break;
1547
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT: {
1548
d = *(uint32_t *)src;
1549
} break;
1550
case GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT: {
1551
d = *(float *)src;
1552
} break;
1553
case GLTFAccessor::COMPONENT_TYPE_DOUBLE_FLOAT: {
1554
d = *(double *)src;
1555
} break;
1556
case GLTFAccessor::COMPONENT_TYPE_HALF_FLOAT: {
1557
ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "glTF: Half float not supported yet.");
1558
} break;
1559
case GLTFAccessor::COMPONENT_TYPE_SIGNED_LONG: {
1560
d = *(int64_t *)src;
1561
} break;
1562
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_LONG: {
1563
d = *(uint64_t *)src;
1564
} break;
1565
}
1566
1567
*p_dst++ = d;
1568
src += p_component_size;
1569
}
1570
}
1571
1572
return OK;
1573
}
1574
1575
int GLTFDocument::_get_component_type_size(const GLTFAccessor::GLTFComponentType p_component_type) {
1576
switch (p_component_type) {
1577
case GLTFAccessor::COMPONENT_TYPE_NONE:
1578
ERR_FAIL_V(0);
1579
case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE:
1580
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE:
1581
return 1;
1582
case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT:
1583
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT:
1584
case GLTFAccessor::COMPONENT_TYPE_HALF_FLOAT:
1585
return 2;
1586
case GLTFAccessor::COMPONENT_TYPE_SIGNED_INT:
1587
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT:
1588
case GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT:
1589
return 4;
1590
case GLTFAccessor::COMPONENT_TYPE_DOUBLE_FLOAT:
1591
case GLTFAccessor::COMPONENT_TYPE_SIGNED_LONG:
1592
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_LONG:
1593
return 8;
1594
}
1595
ERR_FAIL_V(0);
1596
}
1597
1598
Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
1599
//spec, for reference:
1600
//https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
1601
1602
ERR_FAIL_INDEX_V(p_accessor, p_state->accessors.size(), Vector<double>());
1603
1604
const Ref<GLTFAccessor> a = p_state->accessors[p_accessor];
1605
1606
const int component_count = COMPONENT_COUNT_FOR_ACCESSOR_TYPE[a->accessor_type];
1607
const int component_size = _get_component_type_size(a->component_type);
1608
ERR_FAIL_COND_V(component_size == 0, Vector<double>());
1609
int element_size = component_count * component_size;
1610
1611
int64_t skip_every = 0;
1612
int64_t skip_bytes = 0;
1613
//special case of alignments, as described in spec
1614
switch (a->component_type) {
1615
case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE:
1616
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE: {
1617
if (a->accessor_type == GLTFAccessor::TYPE_MAT2) {
1618
skip_every = 2;
1619
skip_bytes = 2;
1620
element_size = 8; //override for this case
1621
}
1622
if (a->accessor_type == GLTFAccessor::TYPE_MAT3) {
1623
skip_every = 3;
1624
skip_bytes = 1;
1625
element_size = 12; //override for this case
1626
}
1627
} break;
1628
case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT:
1629
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: {
1630
if (a->accessor_type == GLTFAccessor::TYPE_MAT3) {
1631
skip_every = 6;
1632
skip_bytes = 2;
1633
element_size = 16; //override for this case
1634
}
1635
} break;
1636
default: {
1637
}
1638
}
1639
1640
Vector<double> dst_buffer;
1641
dst_buffer.resize(component_count * a->count);
1642
double *dst = dst_buffer.ptrw();
1643
1644
if (a->buffer_view >= 0) {
1645
ERR_FAIL_INDEX_V(a->buffer_view, p_state->buffer_views.size(), Vector<double>());
1646
1647
const Error err = _decode_buffer_view(p_state, dst, a->buffer_view, skip_every, skip_bytes, element_size, a->count, a->accessor_type, component_count, a->component_type, component_size, a->normalized, a->byte_offset, p_for_vertex);
1648
if (err != OK) {
1649
return Vector<double>();
1650
}
1651
} else {
1652
//fill with zeros, as bufferview is not defined.
1653
for (int64_t i = 0; i < (a->count * component_count); i++) {
1654
dst_buffer.write[i] = 0;
1655
}
1656
}
1657
1658
if (a->sparse_count > 0) {
1659
// I could not find any file using this, so this code is so far untested
1660
Vector<double> indices;
1661
indices.resize(a->sparse_count);
1662
const int indices_component_size = _get_component_type_size(a->sparse_indices_component_type);
1663
1664
Error err = _decode_buffer_view(p_state, indices.ptrw(), a->sparse_indices_buffer_view, 0, 0, indices_component_size, a->sparse_count, GLTFAccessor::TYPE_SCALAR, 1, a->sparse_indices_component_type, indices_component_size, false, a->sparse_indices_byte_offset, false);
1665
if (err != OK) {
1666
return Vector<double>();
1667
}
1668
1669
Vector<double> data;
1670
data.resize(component_count * a->sparse_count);
1671
err = _decode_buffer_view(p_state, data.ptrw(), a->sparse_values_buffer_view, skip_every, skip_bytes, element_size, a->sparse_count, a->accessor_type, component_count, a->component_type, component_size, a->normalized, a->sparse_values_byte_offset, p_for_vertex);
1672
if (err != OK) {
1673
return Vector<double>();
1674
}
1675
1676
for (int i = 0; i < indices.size(); i++) {
1677
const int64_t write_offset = int(indices[i]) * component_count;
1678
1679
for (int j = 0; j < component_count; j++) {
1680
dst[write_offset + j] = data[i * component_count + j];
1681
}
1682
}
1683
}
1684
1685
return dst_buffer;
1686
}
1687
1688
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref<GLTFState> p_state, const Vector<int32_t> p_attribs, const bool p_for_vertex, const bool p_for_vertex_indices) {
1689
if (p_attribs.is_empty()) {
1690
return -1;
1691
}
1692
const int element_count = 1;
1693
const int ret_size = p_attribs.size();
1694
Vector<double> attribs;
1695
attribs.resize(ret_size);
1696
Vector<double> type_max;
1697
type_max.resize(element_count);
1698
Vector<double> type_min;
1699
type_min.resize(element_count);
1700
int max_index = 0;
1701
for (int64_t i = 0; i < p_attribs.size(); i++) {
1702
attribs.write[i] = p_attribs[i];
1703
if (p_attribs[i] > max_index) {
1704
max_index = p_attribs[i];
1705
}
1706
if (i == 0) {
1707
for (int32_t type_i = 0; type_i < element_count; type_i++) {
1708
type_max.write[type_i] = attribs[(i * element_count) + type_i];
1709
type_min.write[type_i] = attribs[(i * element_count) + type_i];
1710
}
1711
}
1712
for (int32_t type_i = 0; type_i < element_count; type_i++) {
1713
type_max.write[type_i] = MAX(attribs[(i * element_count) + type_i], type_max[type_i]);
1714
type_min.write[type_i] = MIN(attribs[(i * element_count) + type_i], type_min[type_i]);
1715
}
1716
}
1717
ERR_FAIL_COND_V(attribs.is_empty(), -1);
1718
1719
Ref<GLTFAccessor> accessor;
1720
accessor.instantiate();
1721
GLTFBufferIndex buffer_view_i;
1722
if (p_state->buffers.is_empty()) {
1723
p_state->buffers.push_back(Vector<uint8_t>());
1724
}
1725
int64_t size = p_state->buffers[0].size();
1726
const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_SCALAR;
1727
GLTFAccessor::GLTFComponentType component_type;
1728
if (max_index > 65534 || p_for_vertex) {
1729
component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT;
1730
} else {
1731
component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT;
1732
}
1733
1734
accessor->max = type_max;
1735
accessor->min = type_min;
1736
accessor->normalized = false;
1737
accessor->count = ret_size;
1738
accessor->accessor_type = accessor_type;
1739
accessor->component_type = component_type;
1740
accessor->byte_offset = 0;
1741
Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i, p_for_vertex_indices);
1742
if (err != OK) {
1743
return -1;
1744
}
1745
accessor->buffer_view = buffer_view_i;
1746
p_state->accessors.push_back(accessor);
1747
return p_state->accessors.size() - 1;
1748
}
1749
1750
Vector<int> GLTFDocument::_decode_accessor_as_ints(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex, const Vector<int> &p_packed_vertex_ids) {
1751
const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
1752
Vector<int> ret;
1753
1754
if (attribs.is_empty()) {
1755
return ret;
1756
}
1757
1758
const double *attribs_ptr = attribs.ptr();
1759
int64_t ret_size = attribs.size();
1760
if (!p_packed_vertex_ids.is_empty()) {
1761
ERR_FAIL_COND_V(p_packed_vertex_ids[p_packed_vertex_ids.size() - 1] >= ret_size, ret);
1762
ret_size = p_packed_vertex_ids.size();
1763
}
1764
ret.resize(ret_size);
1765
for (int64_t i = 0; i < ret_size; i++) {
1766
int64_t src_i = i;
1767
if (!p_packed_vertex_ids.is_empty()) {
1768
src_i = p_packed_vertex_ids[i];
1769
}
1770
ret.write[i] = int(attribs_ptr[src_i]);
1771
}
1772
return ret;
1773
}
1774
1775
Vector<float> GLTFDocument::_decode_accessor_as_floats(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex, const Vector<int> &p_packed_vertex_ids) {
1776
const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
1777
Vector<float> ret;
1778
1779
if (attribs.is_empty()) {
1780
return ret;
1781
}
1782
1783
const double *attribs_ptr = attribs.ptr();
1784
int64_t ret_size = attribs.size();
1785
if (!p_packed_vertex_ids.is_empty()) {
1786
ERR_FAIL_COND_V(p_packed_vertex_ids[p_packed_vertex_ids.size() - 1] >= ret_size, ret);
1787
ret_size = p_packed_vertex_ids.size();
1788
}
1789
ret.resize(ret_size);
1790
for (int64_t i = 0; i < ret_size; i++) {
1791
int64_t src_i = i;
1792
if (!p_packed_vertex_ids.is_empty()) {
1793
src_i = p_packed_vertex_ids[i];
1794
}
1795
ret.write[i] = float(attribs_ptr[src_i]);
1796
}
1797
return ret;
1798
}
1799
1800
void GLTFDocument::_round_min_max_components(Vector<double> &r_type_min, Vector<double> &r_type_max) {
1801
// 3.6.2.5: For floating-point components, JSON-stored minimum and maximum values represent single precision
1802
// floats and SHOULD be rounded to single precision before usage to avoid any potential boundary mismatches.
1803
for (int32_t type_i = 0; type_i < r_type_min.size(); type_i++) {
1804
r_type_min.write[type_i] = (double)(float)r_type_min[type_i];
1805
r_type_max.write[type_i] = (double)(float)r_type_max[type_i];
1806
}
1807
}
1808
1809
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref<GLTFState> p_state, const Vector<Vector2> p_attribs, const bool p_for_vertex) {
1810
if (p_attribs.is_empty()) {
1811
return -1;
1812
}
1813
const int element_count = 2;
1814
1815
const int64_t ret_size = p_attribs.size() * element_count;
1816
Vector<double> attribs;
1817
attribs.resize(ret_size);
1818
Vector<double> type_max;
1819
type_max.resize(element_count);
1820
Vector<double> type_min;
1821
type_min.resize(element_count);
1822
1823
for (int64_t i = 0; i < p_attribs.size(); i++) {
1824
Vector2 attrib = p_attribs[i];
1825
attribs.write[(i * element_count) + 0] = _filter_number(attrib.x);
1826
attribs.write[(i * element_count) + 1] = _filter_number(attrib.y);
1827
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
1828
}
1829
_round_min_max_components(type_min, type_max);
1830
1831
ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
1832
1833
Ref<GLTFAccessor> accessor;
1834
accessor.instantiate();
1835
GLTFBufferIndex buffer_view_i;
1836
if (p_state->buffers.is_empty()) {
1837
p_state->buffers.push_back(Vector<uint8_t>());
1838
}
1839
int64_t size = p_state->buffers[0].size();
1840
const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC2;
1841
const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT;
1842
1843
accessor->max = type_max;
1844
accessor->min = type_min;
1845
accessor->normalized = false;
1846
accessor->count = p_attribs.size();
1847
accessor->accessor_type = accessor_type;
1848
accessor->component_type = component_type;
1849
accessor->byte_offset = 0;
1850
Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
1851
if (err != OK) {
1852
return -1;
1853
}
1854
accessor->buffer_view = buffer_view_i;
1855
p_state->accessors.push_back(accessor);
1856
return p_state->accessors.size() - 1;
1857
}
1858
1859
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref<GLTFState> p_state, const Vector<Color> p_attribs, const bool p_for_vertex) {
1860
if (p_attribs.is_empty()) {
1861
return -1;
1862
}
1863
1864
const int64_t ret_size = p_attribs.size() * 4;
1865
Vector<double> attribs;
1866
attribs.resize(ret_size);
1867
1868
const int element_count = 4;
1869
Vector<double> type_max;
1870
type_max.resize(element_count);
1871
Vector<double> type_min;
1872
type_min.resize(element_count);
1873
for (int64_t i = 0; i < p_attribs.size(); i++) {
1874
Color attrib = p_attribs[i];
1875
attribs.write[(i * element_count) + 0] = _filter_number(attrib.r);
1876
attribs.write[(i * element_count) + 1] = _filter_number(attrib.g);
1877
attribs.write[(i * element_count) + 2] = _filter_number(attrib.b);
1878
attribs.write[(i * element_count) + 3] = _filter_number(attrib.a);
1879
1880
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
1881
}
1882
_round_min_max_components(type_min, type_max);
1883
1884
ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
1885
1886
Ref<GLTFAccessor> accessor;
1887
accessor.instantiate();
1888
GLTFBufferIndex buffer_view_i;
1889
if (p_state->buffers.is_empty()) {
1890
p_state->buffers.push_back(Vector<uint8_t>());
1891
}
1892
int64_t size = p_state->buffers[0].size();
1893
const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC4;
1894
const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT;
1895
1896
accessor->max = type_max;
1897
accessor->min = type_min;
1898
accessor->normalized = false;
1899
accessor->count = p_attribs.size();
1900
accessor->accessor_type = accessor_type;
1901
accessor->component_type = component_type;
1902
accessor->byte_offset = 0;
1903
Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
1904
if (err != OK) {
1905
return -1;
1906
}
1907
accessor->buffer_view = buffer_view_i;
1908
p_state->accessors.push_back(accessor);
1909
return p_state->accessors.size() - 1;
1910
}
1911
1912
void GLTFDocument::_calc_accessor_min_max(int p_i, const int64_t p_element_count, Vector<double> &p_type_max, Vector<double> p_attribs, Vector<double> &p_type_min) {
1913
if (p_i == 0) {
1914
for (int32_t type_i = 0; type_i < p_element_count; type_i++) {
1915
p_type_max.write[type_i] = p_attribs[(p_i * p_element_count) + type_i];
1916
p_type_min.write[type_i] = p_attribs[(p_i * p_element_count) + type_i];
1917
}
1918
}
1919
for (int32_t type_i = 0; type_i < p_element_count; type_i++) {
1920
p_type_max.write[type_i] = MAX(p_attribs[(p_i * p_element_count) + type_i], p_type_max[type_i]);
1921
p_type_min.write[type_i] = MIN(p_attribs[(p_i * p_element_count) + type_i], p_type_min[type_i]);
1922
}
1923
}
1924
1925
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref<GLTFState> p_state, const Vector<Color> p_attribs, const bool p_for_vertex) {
1926
if (p_attribs.is_empty()) {
1927
return -1;
1928
}
1929
1930
const int64_t ret_size = p_attribs.size() * 4;
1931
Vector<double> attribs;
1932
attribs.resize(ret_size);
1933
1934
const int element_count = 4;
1935
1936
Vector<double> type_max;
1937
type_max.resize(element_count);
1938
Vector<double> type_min;
1939
type_min.resize(element_count);
1940
for (int64_t i = 0; i < p_attribs.size(); i++) {
1941
Color attrib = p_attribs[i];
1942
attribs.write[(i * element_count) + 0] = _filter_number(attrib.r);
1943
attribs.write[(i * element_count) + 1] = _filter_number(attrib.g);
1944
attribs.write[(i * element_count) + 2] = _filter_number(attrib.b);
1945
attribs.write[(i * element_count) + 3] = _filter_number(attrib.a);
1946
1947
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
1948
}
1949
_round_min_max_components(type_min, type_max);
1950
1951
ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
1952
1953
Ref<GLTFAccessor> accessor;
1954
accessor.instantiate();
1955
GLTFBufferIndex buffer_view_i;
1956
if (p_state->buffers.is_empty()) {
1957
p_state->buffers.push_back(Vector<uint8_t>());
1958
}
1959
int64_t size = p_state->buffers[0].size();
1960
const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC4;
1961
const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT;
1962
1963
accessor->max = type_max;
1964
accessor->min = type_min;
1965
accessor->normalized = false;
1966
accessor->count = p_attribs.size();
1967
accessor->accessor_type = accessor_type;
1968
accessor->component_type = component_type;
1969
accessor->byte_offset = 0;
1970
Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
1971
if (err != OK) {
1972
return -1;
1973
}
1974
accessor->buffer_view = buffer_view_i;
1975
p_state->accessors.push_back(accessor);
1976
return p_state->accessors.size() - 1;
1977
}
1978
1979
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref<GLTFState> p_state, const Vector<Color> p_attribs, const bool p_for_vertex) {
1980
if (p_attribs.is_empty()) {
1981
return -1;
1982
}
1983
1984
const int element_count = 4;
1985
const int64_t ret_size = p_attribs.size() * element_count;
1986
Vector<double> attribs;
1987
attribs.resize(ret_size);
1988
1989
Vector<double> type_max;
1990
type_max.resize(element_count);
1991
Vector<double> type_min;
1992
type_min.resize(element_count);
1993
for (int64_t i = 0; i < p_attribs.size(); i++) {
1994
Color attrib = p_attribs[i];
1995
attribs.write[(i * element_count) + 0] = _filter_number(attrib.r);
1996
attribs.write[(i * element_count) + 1] = _filter_number(attrib.g);
1997
attribs.write[(i * element_count) + 2] = _filter_number(attrib.b);
1998
attribs.write[(i * element_count) + 3] = _filter_number(attrib.a);
1999
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
2000
}
2001
_round_min_max_components(type_min, type_max);
2002
ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
2003
2004
Ref<GLTFAccessor> accessor;
2005
accessor.instantiate();
2006
GLTFBufferIndex buffer_view_i;
2007
if (p_state->buffers.is_empty()) {
2008
p_state->buffers.push_back(Vector<uint8_t>());
2009
}
2010
int64_t size = p_state->buffers[0].size();
2011
const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC4;
2012
const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT;
2013
2014
accessor->max = type_max;
2015
accessor->min = type_min;
2016
accessor->normalized = false;
2017
accessor->count = p_attribs.size();
2018
accessor->accessor_type = accessor_type;
2019
accessor->component_type = component_type;
2020
accessor->byte_offset = 0;
2021
Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
2022
if (err != OK) {
2023
return -1;
2024
}
2025
accessor->buffer_view = buffer_view_i;
2026
p_state->accessors.push_back(accessor);
2027
return p_state->accessors.size() - 1;
2028
}
2029
2030
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref<GLTFState> p_state, const Vector<Quaternion> p_attribs, const bool p_for_vertex) {
2031
if (p_attribs.is_empty()) {
2032
return -1;
2033
}
2034
const int element_count = 4;
2035
2036
const int64_t ret_size = p_attribs.size() * element_count;
2037
Vector<double> attribs;
2038
attribs.resize(ret_size);
2039
2040
Vector<double> type_max;
2041
type_max.resize(element_count);
2042
Vector<double> type_min;
2043
type_min.resize(element_count);
2044
for (int64_t i = 0; i < p_attribs.size(); i++) {
2045
Quaternion quaternion = p_attribs[i];
2046
attribs.write[(i * element_count) + 0] = _filter_number(quaternion.x);
2047
attribs.write[(i * element_count) + 1] = _filter_number(quaternion.y);
2048
attribs.write[(i * element_count) + 2] = _filter_number(quaternion.z);
2049
attribs.write[(i * element_count) + 3] = _filter_number(quaternion.w);
2050
2051
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
2052
}
2053
_round_min_max_components(type_min, type_max);
2054
2055
ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
2056
2057
Ref<GLTFAccessor> accessor;
2058
accessor.instantiate();
2059
GLTFBufferIndex buffer_view_i;
2060
if (p_state->buffers.is_empty()) {
2061
p_state->buffers.push_back(Vector<uint8_t>());
2062
}
2063
int64_t size = p_state->buffers[0].size();
2064
const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC4;
2065
const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT;
2066
2067
accessor->max = type_max;
2068
accessor->min = type_min;
2069
accessor->normalized = false;
2070
accessor->count = p_attribs.size();
2071
accessor->accessor_type = accessor_type;
2072
accessor->component_type = component_type;
2073
accessor->byte_offset = 0;
2074
Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
2075
if (err != OK) {
2076
return -1;
2077
}
2078
accessor->buffer_view = buffer_view_i;
2079
p_state->accessors.push_back(accessor);
2080
return p_state->accessors.size() - 1;
2081
}
2082
2083
Vector<Vector2> GLTFDocument::_decode_accessor_as_vec2(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex, const Vector<int> &p_packed_vertex_ids) {
2084
const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
2085
Vector<Vector2> ret;
2086
2087
if (attribs.is_empty()) {
2088
return ret;
2089
}
2090
2091
ERR_FAIL_COND_V(attribs.size() % 2 != 0, ret);
2092
const double *attribs_ptr = attribs.ptr();
2093
int64_t ret_size = attribs.size() / 2;
2094
if (!p_packed_vertex_ids.is_empty()) {
2095
ERR_FAIL_COND_V(p_packed_vertex_ids[p_packed_vertex_ids.size() - 1] >= ret_size, ret);
2096
ret_size = p_packed_vertex_ids.size();
2097
}
2098
ret.resize(ret_size);
2099
for (int64_t i = 0; i < ret_size; i++) {
2100
int64_t src_i = i;
2101
if (!p_packed_vertex_ids.is_empty()) {
2102
src_i = p_packed_vertex_ids[i];
2103
}
2104
ret.write[i] = Vector2(attribs_ptr[src_i * 2 + 0], attribs_ptr[src_i * 2 + 1]);
2105
}
2106
return ret;
2107
}
2108
2109
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref<GLTFState> p_state, const Vector<double> p_attribs, const bool p_for_vertex) {
2110
if (p_attribs.is_empty()) {
2111
return -1;
2112
}
2113
const int element_count = 1;
2114
const int64_t ret_size = p_attribs.size();
2115
Vector<double> attribs;
2116
attribs.resize(ret_size);
2117
2118
Vector<double> type_max;
2119
type_max.resize(element_count);
2120
Vector<double> type_min;
2121
type_min.resize(element_count);
2122
2123
for (int64_t i = 0; i < p_attribs.size(); i++) {
2124
attribs.write[i] = _filter_number(p_attribs[i]);
2125
2126
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
2127
}
2128
_round_min_max_components(type_min, type_max);
2129
2130
ERR_FAIL_COND_V(attribs.is_empty(), -1);
2131
2132
Ref<GLTFAccessor> accessor;
2133
accessor.instantiate();
2134
GLTFBufferIndex buffer_view_i;
2135
if (p_state->buffers.is_empty()) {
2136
p_state->buffers.push_back(Vector<uint8_t>());
2137
}
2138
int64_t size = p_state->buffers[0].size();
2139
const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_SCALAR;
2140
const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT;
2141
2142
accessor->max = type_max;
2143
accessor->min = type_min;
2144
accessor->normalized = false;
2145
accessor->count = ret_size;
2146
accessor->accessor_type = accessor_type;
2147
accessor->component_type = component_type;
2148
accessor->byte_offset = 0;
2149
Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
2150
if (err != OK) {
2151
return -1;
2152
}
2153
accessor->buffer_view = buffer_view_i;
2154
p_state->accessors.push_back(accessor);
2155
return p_state->accessors.size() - 1;
2156
}
2157
2158
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref<GLTFState> p_state, const Vector<Vector3> p_attribs, const bool p_for_vertex) {
2159
if (p_attribs.is_empty()) {
2160
return -1;
2161
}
2162
const int element_count = 3;
2163
const int64_t ret_size = p_attribs.size() * element_count;
2164
Vector<double> attribs;
2165
attribs.resize(ret_size);
2166
2167
Vector<double> type_max;
2168
type_max.resize(element_count);
2169
Vector<double> type_min;
2170
type_min.resize(element_count);
2171
for (int64_t i = 0; i < p_attribs.size(); i++) {
2172
Vector3 attrib = p_attribs[i];
2173
attribs.write[(i * element_count) + 0] = _filter_number(attrib.x);
2174
attribs.write[(i * element_count) + 1] = _filter_number(attrib.y);
2175
attribs.write[(i * element_count) + 2] = _filter_number(attrib.z);
2176
2177
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
2178
}
2179
_round_min_max_components(type_min, type_max);
2180
ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
2181
2182
Ref<GLTFAccessor> accessor;
2183
accessor.instantiate();
2184
GLTFBufferIndex buffer_view_i;
2185
if (p_state->buffers.is_empty()) {
2186
p_state->buffers.push_back(Vector<uint8_t>());
2187
}
2188
int64_t size = p_state->buffers[0].size();
2189
const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC3;
2190
const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT;
2191
2192
accessor->max = type_max;
2193
accessor->min = type_min;
2194
accessor->normalized = false;
2195
accessor->count = p_attribs.size();
2196
accessor->accessor_type = accessor_type;
2197
accessor->component_type = component_type;
2198
accessor->byte_offset = 0;
2199
Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
2200
if (err != OK) {
2201
return -1;
2202
}
2203
accessor->buffer_view = buffer_view_i;
2204
p_state->accessors.push_back(accessor);
2205
return p_state->accessors.size() - 1;
2206
}
2207
2208
GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref<GLTFState> p_state, const Vector<Vector3> p_attribs, const Vector<Vector3> p_reference_attribs, const float p_reference_multiplier, const bool p_for_vertex, const GLTFAccessorIndex p_reference_accessor) {
2209
if (p_attribs.is_empty()) {
2210
return -1;
2211
}
2212
2213
const int element_count = 3;
2214
Vector<double> attribs;
2215
Vector<double> type_max;
2216
Vector<double> type_min;
2217
attribs.resize(p_attribs.size() * element_count);
2218
type_max.resize(element_count);
2219
type_min.resize(element_count);
2220
2221
Vector<double> changed_indices;
2222
Vector<double> changed_values;
2223
int max_changed_index = 0;
2224
2225
for (int64_t i = 0; i < p_attribs.size(); i++) {
2226
Vector3 attrib = p_attribs[i];
2227
bool is_different = false;
2228
if (i < p_reference_attribs.size()) {
2229
is_different = !(attrib * p_reference_multiplier).is_equal_approx(p_reference_attribs[i]);
2230
if (!is_different) {
2231
attrib = p_reference_attribs[i];
2232
}
2233
} else {
2234
is_different = !(attrib * p_reference_multiplier).is_zero_approx();
2235
if (!is_different) {
2236
attrib = Vector3();
2237
}
2238
}
2239
attribs.write[(i * element_count) + 0] = _filter_number(attrib.x);
2240
attribs.write[(i * element_count) + 1] = _filter_number(attrib.y);
2241
attribs.write[(i * element_count) + 2] = _filter_number(attrib.z);
2242
if (is_different) {
2243
changed_indices.push_back(i);
2244
if (i > max_changed_index) {
2245
max_changed_index = i;
2246
}
2247
changed_values.push_back(_filter_number(attrib.x));
2248
changed_values.push_back(_filter_number(attrib.y));
2249
changed_values.push_back(_filter_number(attrib.z));
2250
}
2251
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
2252
}
2253
_round_min_max_components(type_min, type_max);
2254
2255
if (attribs.size() % element_count != 0) {
2256
return -1;
2257
}
2258
2259
Ref<GLTFAccessor> sparse_accessor;
2260
sparse_accessor.instantiate();
2261
if (p_state->buffers.is_empty()) {
2262
p_state->buffers.push_back(Vector<uint8_t>());
2263
}
2264
int64_t size = p_state->buffers[0].size();
2265
const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC3;
2266
const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT;
2267
2268
sparse_accessor->normalized = false;
2269
sparse_accessor->count = p_attribs.size();
2270
sparse_accessor->accessor_type = accessor_type;
2271
sparse_accessor->component_type = component_type;
2272
if (p_reference_accessor < p_state->accessors.size() && p_reference_accessor >= 0 && p_state->accessors[p_reference_accessor].is_valid()) {
2273
sparse_accessor->byte_offset = p_state->accessors[p_reference_accessor]->byte_offset;
2274
sparse_accessor->buffer_view = p_state->accessors[p_reference_accessor]->buffer_view;
2275
}
2276
sparse_accessor->max = type_max;
2277
sparse_accessor->min = type_min;
2278
int64_t sparse_accessor_index_stride = max_changed_index > 65534 ? 4 : 2;
2279
2280
int64_t sparse_accessor_storage_size = changed_indices.size() * (sparse_accessor_index_stride + element_count * sizeof(float));
2281
int64_t conventional_storage_size = p_attribs.size() * element_count * sizeof(float);
2282
2283
if (changed_indices.size() > 0 && sparse_accessor_storage_size < conventional_storage_size) {
2284
// It must be worthwhile to use a sparse accessor.
2285
2286
GLTFBufferIndex buffer_view_i_indices = -1;
2287
GLTFBufferIndex buffer_view_i_values = -1;
2288
if (sparse_accessor_index_stride == 4) {
2289
sparse_accessor->sparse_indices_component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT;
2290
} else {
2291
sparse_accessor->sparse_indices_component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT;
2292
}
2293
if (_encode_accessor_into_buffer_view(p_state, changed_indices.ptr(), changed_indices.size(), GLTFAccessor::TYPE_SCALAR, sparse_accessor->sparse_indices_component_type, sparse_accessor->normalized, sparse_accessor->sparse_indices_byte_offset, false, buffer_view_i_indices) != OK) {
2294
return -1;
2295
}
2296
// We use changed_indices.size() here, because we must pass the number of vec3 values rather than the number of components.
2297
if (_encode_accessor_into_buffer_view(p_state, changed_values.ptr(), changed_indices.size(), sparse_accessor->accessor_type, sparse_accessor->component_type, sparse_accessor->normalized, sparse_accessor->sparse_values_byte_offset, false, buffer_view_i_values) != OK) {
2298
return -1;
2299
}
2300
sparse_accessor->sparse_indices_buffer_view = buffer_view_i_indices;
2301
sparse_accessor->sparse_values_buffer_view = buffer_view_i_values;
2302
sparse_accessor->sparse_count = changed_indices.size();
2303
} else if (changed_indices.size() > 0) {
2304
GLTFBufferIndex buffer_view_i;
2305
sparse_accessor->byte_offset = 0;
2306
Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, sparse_accessor->normalized, size, p_for_vertex, buffer_view_i);
2307
if (err != OK) {
2308
return -1;
2309
}
2310
sparse_accessor->buffer_view = buffer_view_i;
2311
}
2312
p_state->accessors.push_back(sparse_accessor);
2313
2314
return p_state->accessors.size() - 1;
2315
}
2316
2317
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref<GLTFState> p_state, const Vector<Transform3D> p_attribs, const bool p_for_vertex) {
2318
if (p_attribs.is_empty()) {
2319
return -1;
2320
}
2321
const int64_t element_count = 16;
2322
const int64_t ret_size = p_attribs.size() * element_count;
2323
Vector<double> attribs;
2324
attribs.resize(ret_size);
2325
2326
Vector<double> type_max;
2327
type_max.resize(element_count);
2328
Vector<double> type_min;
2329
type_min.resize(element_count);
2330
for (int64_t i = 0; i < p_attribs.size(); i++) {
2331
Transform3D attrib = p_attribs[i];
2332
Basis basis = attrib.get_basis();
2333
Vector3 axis_0 = basis.get_column(Vector3::AXIS_X);
2334
2335
attribs.write[i * element_count + 0] = _filter_number(axis_0.x);
2336
attribs.write[i * element_count + 1] = _filter_number(axis_0.y);
2337
attribs.write[i * element_count + 2] = _filter_number(axis_0.z);
2338
attribs.write[i * element_count + 3] = 0.0;
2339
2340
Vector3 axis_1 = basis.get_column(Vector3::AXIS_Y);
2341
attribs.write[i * element_count + 4] = _filter_number(axis_1.x);
2342
attribs.write[i * element_count + 5] = _filter_number(axis_1.y);
2343
attribs.write[i * element_count + 6] = _filter_number(axis_1.z);
2344
attribs.write[i * element_count + 7] = 0.0;
2345
2346
Vector3 axis_2 = basis.get_column(Vector3::AXIS_Z);
2347
attribs.write[i * element_count + 8] = _filter_number(axis_2.x);
2348
attribs.write[i * element_count + 9] = _filter_number(axis_2.y);
2349
attribs.write[i * element_count + 10] = _filter_number(axis_2.z);
2350
attribs.write[i * element_count + 11] = 0.0;
2351
2352
Vector3 origin = attrib.get_origin();
2353
attribs.write[i * element_count + 12] = _filter_number(origin.x);
2354
attribs.write[i * element_count + 13] = _filter_number(origin.y);
2355
attribs.write[i * element_count + 14] = _filter_number(origin.z);
2356
attribs.write[i * element_count + 15] = 1.0;
2357
2358
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
2359
}
2360
_round_min_max_components(type_min, type_max);
2361
ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
2362
2363
Ref<GLTFAccessor> accessor;
2364
accessor.instantiate();
2365
GLTFBufferIndex buffer_view_i;
2366
if (p_state->buffers.is_empty()) {
2367
p_state->buffers.push_back(Vector<uint8_t>());
2368
}
2369
int64_t size = p_state->buffers[0].size();
2370
const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_MAT4;
2371
const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT;
2372
2373
accessor->max = type_max;
2374
accessor->min = type_min;
2375
accessor->normalized = false;
2376
accessor->count = p_attribs.size();
2377
accessor->accessor_type = accessor_type;
2378
accessor->component_type = component_type;
2379
accessor->byte_offset = 0;
2380
Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i);
2381
if (err != OK) {
2382
return -1;
2383
}
2384
accessor->buffer_view = buffer_view_i;
2385
p_state->accessors.push_back(accessor);
2386
return p_state->accessors.size() - 1;
2387
}
2388
2389
Vector<Vector3> GLTFDocument::_decode_accessor_as_vec3(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex, const Vector<int> &p_packed_vertex_ids) {
2390
const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
2391
Vector<Vector3> ret;
2392
2393
if (attribs.is_empty()) {
2394
return ret;
2395
}
2396
2397
ERR_FAIL_COND_V(attribs.size() % 3 != 0, ret);
2398
const double *attribs_ptr = attribs.ptr();
2399
int64_t ret_size = attribs.size() / 3;
2400
if (!p_packed_vertex_ids.is_empty()) {
2401
ERR_FAIL_COND_V(p_packed_vertex_ids[p_packed_vertex_ids.size() - 1] >= ret_size, ret);
2402
ret_size = p_packed_vertex_ids.size();
2403
}
2404
ret.resize(ret_size);
2405
for (int64_t i = 0; i < ret_size; i++) {
2406
int64_t src_i = i;
2407
if (!p_packed_vertex_ids.is_empty()) {
2408
src_i = p_packed_vertex_ids[i];
2409
}
2410
ret.write[i] = Vector3(attribs_ptr[src_i * 3 + 0], attribs_ptr[src_i * 3 + 1], attribs_ptr[src_i * 3 + 2]);
2411
}
2412
return ret;
2413
}
2414
2415
Vector<Color> GLTFDocument::_decode_accessor_as_color(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex, const Vector<int> &p_packed_vertex_ids) {
2416
const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
2417
Vector<Color> ret;
2418
2419
if (attribs.is_empty()) {
2420
return ret;
2421
}
2422
2423
const GLTFAccessor::GLTFAccessorType accessor_type = p_state->accessors[p_accessor]->accessor_type;
2424
ERR_FAIL_COND_V(!(accessor_type == GLTFAccessor::TYPE_VEC3 || accessor_type == GLTFAccessor::TYPE_VEC4), ret);
2425
int vec_len = 3;
2426
if (accessor_type == GLTFAccessor::TYPE_VEC4) {
2427
vec_len = 4;
2428
}
2429
2430
ERR_FAIL_COND_V(attribs.size() % vec_len != 0, ret);
2431
const double *attribs_ptr = attribs.ptr();
2432
int64_t ret_size = attribs.size() / vec_len;
2433
if (!p_packed_vertex_ids.is_empty()) {
2434
ERR_FAIL_COND_V(p_packed_vertex_ids[p_packed_vertex_ids.size() - 1] >= ret_size, ret);
2435
ret_size = p_packed_vertex_ids.size();
2436
}
2437
ret.resize(ret_size);
2438
for (int64_t i = 0; i < ret_size; i++) {
2439
int64_t src_i = i;
2440
if (!p_packed_vertex_ids.is_empty()) {
2441
src_i = p_packed_vertex_ids[i];
2442
}
2443
ret.write[i] = Color(attribs_ptr[src_i * vec_len + 0], attribs_ptr[src_i * vec_len + 1], attribs_ptr[src_i * vec_len + 2], vec_len == 4 ? attribs_ptr[src_i * 4 + 3] : 1.0);
2444
}
2445
return ret;
2446
}
2447
Vector<Quaternion> GLTFDocument::_decode_accessor_as_quaternion(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
2448
const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
2449
Vector<Quaternion> ret;
2450
2451
if (attribs.is_empty()) {
2452
return ret;
2453
}
2454
2455
ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
2456
const double *attribs_ptr = attribs.ptr();
2457
const int64_t ret_size = attribs.size() / 4;
2458
ret.resize(ret_size);
2459
{
2460
for (int64_t i = 0; i < ret_size; i++) {
2461
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();
2462
}
2463
}
2464
return ret;
2465
}
2466
Vector<Transform2D> GLTFDocument::_decode_accessor_as_xform2d(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
2467
const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
2468
Vector<Transform2D> ret;
2469
2470
if (attribs.is_empty()) {
2471
return ret;
2472
}
2473
2474
ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
2475
ret.resize(attribs.size() / 4);
2476
for (int64_t i = 0; i < ret.size(); i++) {
2477
ret.write[i][0] = Vector2(attribs[i * 4 + 0], attribs[i * 4 + 1]);
2478
ret.write[i][1] = Vector2(attribs[i * 4 + 2], attribs[i * 4 + 3]);
2479
}
2480
return ret;
2481
}
2482
2483
Vector<Basis> GLTFDocument::_decode_accessor_as_basis(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
2484
const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
2485
Vector<Basis> ret;
2486
2487
if (attribs.is_empty()) {
2488
return ret;
2489
}
2490
2491
ERR_FAIL_COND_V(attribs.size() % 9 != 0, ret);
2492
ret.resize(attribs.size() / 9);
2493
for (int64_t i = 0; i < ret.size(); i++) {
2494
ret.write[i].set_column(0, Vector3(attribs[i * 9 + 0], attribs[i * 9 + 1], attribs[i * 9 + 2]));
2495
ret.write[i].set_column(1, Vector3(attribs[i * 9 + 3], attribs[i * 9 + 4], attribs[i * 9 + 5]));
2496
ret.write[i].set_column(2, Vector3(attribs[i * 9 + 6], attribs[i * 9 + 7], attribs[i * 9 + 8]));
2497
}
2498
return ret;
2499
}
2500
2501
Vector<Transform3D> GLTFDocument::_decode_accessor_as_xform(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
2502
const Vector<double> attribs = _decode_accessor(p_state, p_accessor, p_for_vertex);
2503
Vector<Transform3D> ret;
2504
2505
if (attribs.is_empty()) {
2506
return ret;
2507
}
2508
2509
ERR_FAIL_COND_V(attribs.size() % 16 != 0, ret);
2510
ret.resize(attribs.size() / 16);
2511
for (int64_t i = 0; i < ret.size(); i++) {
2512
ret.write[i].basis.set_column(0, Vector3(attribs[i * 16 + 0], attribs[i * 16 + 1], attribs[i * 16 + 2]));
2513
ret.write[i].basis.set_column(1, Vector3(attribs[i * 16 + 4], attribs[i * 16 + 5], attribs[i * 16 + 6]));
2514
ret.write[i].basis.set_column(2, Vector3(attribs[i * 16 + 8], attribs[i * 16 + 9], attribs[i * 16 + 10]));
2515
ret.write[i].set_origin(Vector3(attribs[i * 16 + 12], attribs[i * 16 + 13], attribs[i * 16 + 14]));
2516
}
2517
return ret;
2518
}
2519
2520
Vector<Variant> GLTFDocument::_decode_accessor_as_variant(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, Variant::Type p_variant_type, GLTFAccessor::GLTFAccessorType p_accessor_type) {
2521
const Vector<double> attribs = _decode_accessor(p_state, p_accessor, false);
2522
Vector<Variant> ret;
2523
ERR_FAIL_COND_V_MSG(attribs.is_empty(), ret, "glTF: The accessor was empty.");
2524
const int component_count = COMPONENT_COUNT_FOR_ACCESSOR_TYPE[p_accessor_type];
2525
ERR_FAIL_COND_V_MSG(attribs.size() % component_count != 0, ret, "glTF: The accessor size was not a multiple of the component count.");
2526
const int64_t ret_size = attribs.size() / component_count;
2527
ret.resize(ret_size);
2528
for (int64_t i = 0; i < ret_size; i++) {
2529
switch (p_variant_type) {
2530
case Variant::BOOL: {
2531
ret.write[i] = attribs[i * component_count] != 0.0;
2532
} break;
2533
case Variant::INT: {
2534
ret.write[i] = (int64_t)attribs[i * component_count];
2535
} break;
2536
case Variant::FLOAT: {
2537
ret.write[i] = attribs[i * component_count];
2538
} break;
2539
case Variant::VECTOR2:
2540
case Variant::RECT2:
2541
case Variant::VECTOR3:
2542
case Variant::VECTOR4:
2543
case Variant::PLANE:
2544
case Variant::QUATERNION: {
2545
// General-purpose code for importing glTF accessor data with any component count into structs up to 4 `real_t`s in size.
2546
Variant v;
2547
switch (component_count) {
2548
case 1: {
2549
v = Vector4(attribs[i * component_count], 0.0f, 0.0f, 0.0f);
2550
} break;
2551
case 2: {
2552
v = Vector4(attribs[i * component_count], attribs[i * component_count + 1], 0.0f, 0.0f);
2553
} break;
2554
case 3: {
2555
v = Vector4(attribs[i * component_count], attribs[i * component_count + 1], attribs[i * component_count + 2], 0.0f);
2556
} break;
2557
default: {
2558
v = Vector4(attribs[i * component_count], attribs[i * component_count + 1], attribs[i * component_count + 2], attribs[i * component_count + 3]);
2559
} break;
2560
}
2561
// Evil hack that relies on the structure of Variant, but it's the
2562
// only way to accomplish this without a ton of code duplication.
2563
*(Variant::Type *)&v = p_variant_type;
2564
ret.write[i] = v;
2565
} break;
2566
case Variant::VECTOR2I:
2567
case Variant::RECT2I:
2568
case Variant::VECTOR3I:
2569
case Variant::VECTOR4I: {
2570
// General-purpose code for importing glTF accessor data with any component count into structs up to 4 `int32_t`s in size.
2571
Variant v;
2572
switch (component_count) {
2573
case 1: {
2574
v = Vector4i((int32_t)attribs[i * component_count], 0, 0, 0);
2575
} break;
2576
case 2: {
2577
v = Vector4i((int32_t)attribs[i * component_count], (int32_t)attribs[i * component_count + 1], 0, 0);
2578
} break;
2579
case 3: {
2580
v = Vector4i((int32_t)attribs[i * component_count], (int32_t)attribs[i * component_count + 1], (int32_t)attribs[i * component_count + 2], 0);
2581
} break;
2582
default: {
2583
v = Vector4i((int32_t)attribs[i * component_count], (int32_t)attribs[i * component_count + 1], (int32_t)attribs[i * component_count + 2], (int32_t)attribs[i * component_count + 3]);
2584
} break;
2585
}
2586
// Evil hack that relies on the structure of Variant, but it's the
2587
// only way to accomplish this without a ton of code duplication.
2588
*(Variant::Type *)&v = p_variant_type;
2589
ret.write[i] = v;
2590
} break;
2591
// No more generalized hacks, each of the below types needs a lot of repetitive code.
2592
case Variant::COLOR: {
2593
Variant v;
2594
switch (component_count) {
2595
case 1: {
2596
v = Color(attribs[i * component_count], 0.0f, 0.0f, 1.0f);
2597
} break;
2598
case 2: {
2599
v = Color(attribs[i * component_count], attribs[i * component_count + 1], 0.0f, 1.0f);
2600
} break;
2601
case 3: {
2602
v = Color(attribs[i * component_count], attribs[i * component_count + 1], attribs[i * component_count + 2], 1.0f);
2603
} break;
2604
default: {
2605
v = Color(attribs[i * component_count], attribs[i * component_count + 1], attribs[i * component_count + 2], attribs[i * component_count + 3]);
2606
} break;
2607
}
2608
ret.write[i] = v;
2609
} break;
2610
case Variant::TRANSFORM2D: {
2611
Transform2D t;
2612
switch (component_count) {
2613
case 4: {
2614
t.columns[0] = Vector2(attribs[i * component_count + 0], attribs[i * component_count + 1]);
2615
t.columns[1] = Vector2(attribs[i * component_count + 2], attribs[i * component_count + 3]);
2616
} break;
2617
case 9: {
2618
t.columns[0] = Vector2(attribs[i * component_count + 0], attribs[i * component_count + 1]);
2619
t.columns[1] = Vector2(attribs[i * component_count + 3], attribs[i * component_count + 4]);
2620
t.columns[2] = Vector2(attribs[i * component_count + 6], attribs[i * component_count + 7]);
2621
} break;
2622
case 16: {
2623
t.columns[0] = Vector2(attribs[i * component_count + 0], attribs[i * component_count + 1]);
2624
t.columns[1] = Vector2(attribs[i * component_count + 4], attribs[i * component_count + 5]);
2625
t.columns[2] = Vector2(attribs[i * component_count + 12], attribs[i * component_count + 13]);
2626
} break;
2627
}
2628
ret.write[i] = t;
2629
} break;
2630
case Variant::BASIS: {
2631
Basis b;
2632
switch (component_count) {
2633
case 4: {
2634
b.rows[0] = Vector3(attribs[i * component_count + 0], attribs[i * component_count + 2], 0.0f);
2635
b.rows[1] = Vector3(attribs[i * component_count + 1], attribs[i * component_count + 3], 0.0f);
2636
} break;
2637
case 9: {
2638
b.rows[0] = Vector3(attribs[i * component_count + 0], attribs[i * component_count + 3], attribs[i * component_count + 6]);
2639
b.rows[1] = Vector3(attribs[i * component_count + 1], attribs[i * component_count + 4], attribs[i * component_count + 7]);
2640
b.rows[2] = Vector3(attribs[i * component_count + 2], attribs[i * component_count + 5], attribs[i * component_count + 8]);
2641
} break;
2642
case 16: {
2643
b.rows[0] = Vector3(attribs[i * component_count + 0], attribs[i * component_count + 4], attribs[i * component_count + 8]);
2644
b.rows[1] = Vector3(attribs[i * component_count + 1], attribs[i * component_count + 5], attribs[i * component_count + 9]);
2645
b.rows[2] = Vector3(attribs[i * component_count + 2], attribs[i * component_count + 6], attribs[i * component_count + 10]);
2646
} break;
2647
}
2648
ret.write[i] = b;
2649
} break;
2650
case Variant::TRANSFORM3D: {
2651
Transform3D t;
2652
switch (component_count) {
2653
case 4: {
2654
t.basis.rows[0] = Vector3(attribs[i * component_count + 0], attribs[i * component_count + 2], 0.0f);
2655
t.basis.rows[1] = Vector3(attribs[i * component_count + 1], attribs[i * component_count + 3], 0.0f);
2656
} break;
2657
case 9: {
2658
t.basis.rows[0] = Vector3(attribs[i * component_count + 0], attribs[i * component_count + 3], attribs[i * component_count + 6]);
2659
t.basis.rows[1] = Vector3(attribs[i * component_count + 1], attribs[i * component_count + 4], attribs[i * component_count + 7]);
2660
t.basis.rows[2] = Vector3(attribs[i * component_count + 2], attribs[i * component_count + 5], attribs[i * component_count + 8]);
2661
} break;
2662
case 16: {
2663
t.basis.rows[0] = Vector3(attribs[i * component_count + 0], attribs[i * component_count + 4], attribs[i * component_count + 8]);
2664
t.basis.rows[1] = Vector3(attribs[i * component_count + 1], attribs[i * component_count + 5], attribs[i * component_count + 9]);
2665
t.basis.rows[2] = Vector3(attribs[i * component_count + 2], attribs[i * component_count + 6], attribs[i * component_count + 10]);
2666
t.origin = Vector3(attribs[i * component_count + 12], attribs[i * component_count + 13], attribs[i * component_count + 14]);
2667
} break;
2668
}
2669
ret.write[i] = t;
2670
} break;
2671
case Variant::PROJECTION: {
2672
Projection p;
2673
switch (component_count) {
2674
case 4: {
2675
p.columns[0] = Vector4(attribs[i * component_count + 0], attribs[i * component_count + 1], 0.0f, 0.0f);
2676
p.columns[1] = Vector4(attribs[i * component_count + 4], attribs[i * component_count + 5], 0.0f, 0.0f);
2677
} break;
2678
case 9: {
2679
p.columns[0] = Vector4(attribs[i * component_count + 0], attribs[i * component_count + 1], attribs[i * component_count + 2], 0.0f);
2680
p.columns[1] = Vector4(attribs[i * component_count + 4], attribs[i * component_count + 5], attribs[i * component_count + 6], 0.0f);
2681
p.columns[2] = Vector4(attribs[i * component_count + 8], attribs[i * component_count + 9], attribs[i * component_count + 10], 0.0f);
2682
} break;
2683
case 16: {
2684
p.columns[0] = Vector4(attribs[i * component_count + 0], attribs[i * component_count + 1], attribs[i * component_count + 2], attribs[i * component_count + 3]);
2685
p.columns[1] = Vector4(attribs[i * component_count + 4], attribs[i * component_count + 5], attribs[i * component_count + 6], attribs[i * component_count + 7]);
2686
p.columns[2] = Vector4(attribs[i * component_count + 8], attribs[i * component_count + 9], attribs[i * component_count + 10], attribs[i * component_count + 11]);
2687
p.columns[3] = Vector4(attribs[i * component_count + 12], attribs[i * component_count + 13], attribs[i * component_count + 14], attribs[i * component_count + 15]);
2688
} break;
2689
}
2690
ret.write[i] = p;
2691
} break;
2692
default: {
2693
ERR_FAIL_V_MSG(ret, "glTF: Cannot decode accessor as Variant of type " + Variant::get_type_name(p_variant_type) + ".");
2694
}
2695
}
2696
}
2697
return ret;
2698
}
2699
2700
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_variant(Ref<GLTFState> p_state, Vector<Variant> p_attribs, Variant::Type p_variant_type, GLTFAccessor::GLTFAccessorType p_accessor_type, GLTFAccessor::GLTFComponentType p_component_type) {
2701
const int accessor_component_count = COMPONENT_COUNT_FOR_ACCESSOR_TYPE[p_accessor_type];
2702
Vector<double> encoded_attribs;
2703
for (const Variant &v : p_attribs) {
2704
switch (p_variant_type) {
2705
case Variant::NIL:
2706
case Variant::BOOL:
2707
case Variant::INT:
2708
case Variant::FLOAT: {
2709
// For scalar values, just append them. Variant can convert all of these to double. Some padding may also be needed.
2710
encoded_attribs.append(v);
2711
if (unlikely(accessor_component_count > 1)) {
2712
for (int i = 1; i < accessor_component_count; i++) {
2713
encoded_attribs.append(0.0);
2714
}
2715
}
2716
} break;
2717
case Variant::VECTOR2:
2718
case Variant::VECTOR2I:
2719
case Variant::VECTOR3:
2720
case Variant::VECTOR3I:
2721
case Variant::VECTOR4:
2722
case Variant::VECTOR4I: {
2723
// Variant can handle converting Vector2/2i/3/3i/4/4i to Vector4 for us.
2724
Vector4 vec = v;
2725
if (likely(accessor_component_count < 5)) {
2726
for (int i = 0; i < accessor_component_count; i++) {
2727
encoded_attribs.append(vec[i]);
2728
}
2729
}
2730
} break;
2731
case Variant::PLANE: {
2732
Plane p = v;
2733
if (likely(accessor_component_count == 4)) {
2734
encoded_attribs.append(p.normal.x);
2735
encoded_attribs.append(p.normal.y);
2736
encoded_attribs.append(p.normal.z);
2737
encoded_attribs.append(p.d);
2738
}
2739
} break;
2740
case Variant::QUATERNION: {
2741
Quaternion q = v;
2742
if (likely(accessor_component_count < 5)) {
2743
for (int i = 0; i < accessor_component_count; i++) {
2744
encoded_attribs.append(q[i]);
2745
}
2746
}
2747
} break;
2748
case Variant::COLOR: {
2749
Color c = v;
2750
if (likely(accessor_component_count < 5)) {
2751
for (int i = 0; i < accessor_component_count; i++) {
2752
encoded_attribs.append(c[i]);
2753
}
2754
}
2755
} break;
2756
case Variant::RECT2:
2757
case Variant::RECT2I: {
2758
// Variant can handle converting Rect2i to Rect2 for us.
2759
Rect2 r = v;
2760
if (likely(accessor_component_count == 4)) {
2761
encoded_attribs.append(r.position.x);
2762
encoded_attribs.append(r.position.y);
2763
encoded_attribs.append(r.size.x);
2764
encoded_attribs.append(r.size.y);
2765
}
2766
} break;
2767
case Variant::TRANSFORM2D:
2768
case Variant::BASIS:
2769
case Variant::TRANSFORM3D:
2770
case Variant::PROJECTION: {
2771
// Variant can handle converting Transform2D/Transform3D/Basis to Projection for us.
2772
Projection p = v;
2773
if (accessor_component_count == 16) {
2774
for (int i = 0; i < 4; i++) {
2775
encoded_attribs.append(p.columns[i][0]);
2776
encoded_attribs.append(p.columns[i][1]);
2777
encoded_attribs.append(p.columns[i][2]);
2778
encoded_attribs.append(p.columns[i][3]);
2779
}
2780
} else if (accessor_component_count == 9) {
2781
for (int i = 0; i < 3; i++) {
2782
encoded_attribs.append(p.columns[i][0]);
2783
encoded_attribs.append(p.columns[i][1]);
2784
encoded_attribs.append(p.columns[i][2]);
2785
}
2786
} else if (accessor_component_count == 4) {
2787
encoded_attribs.append(p.columns[0][0]);
2788
encoded_attribs.append(p.columns[0][1]);
2789
encoded_attribs.append(p.columns[1][0]);
2790
encoded_attribs.append(p.columns[1][1]);
2791
}
2792
} break;
2793
default: {
2794
ERR_FAIL_V_MSG(-1, "glTF: Cannot encode accessor from Variant of type " + Variant::get_type_name(p_variant_type) + ".");
2795
}
2796
}
2797
}
2798
// Determine the min and max values for the accessor.
2799
Vector<double> type_max;
2800
type_max.resize(accessor_component_count);
2801
Vector<double> type_min;
2802
type_min.resize(accessor_component_count);
2803
for (int64_t i = 0; i < encoded_attribs.size(); i++) {
2804
if (Math::is_zero_approx(encoded_attribs[i])) {
2805
encoded_attribs.write[i] = 0.0;
2806
} else {
2807
encoded_attribs.write[i] = _filter_number(encoded_attribs[i]);
2808
}
2809
}
2810
for (int i = 0; i < p_attribs.size(); i++) {
2811
_calc_accessor_min_max(i, accessor_component_count, type_max, encoded_attribs, type_min);
2812
}
2813
_round_min_max_components(type_min, type_max);
2814
// Encode the data in a buffer view.
2815
GLTFBufferIndex buffer_view_index = 0;
2816
if (p_state->buffers.is_empty()) {
2817
p_state->buffers.push_back(Vector<uint8_t>());
2818
}
2819
const int64_t buffer_size = p_state->buffers[buffer_view_index].size();
2820
Error err = _encode_accessor_into_buffer_view(p_state, encoded_attribs.ptr(), p_attribs.size(), p_accessor_type, p_component_type, false, buffer_size, false, buffer_view_index);
2821
if (err != OK) {
2822
return -1;
2823
}
2824
// Create the accessor and fill it with the data.
2825
Ref<GLTFAccessor> accessor;
2826
accessor.instantiate();
2827
accessor->max = type_max;
2828
accessor->min = type_min;
2829
accessor->count = p_attribs.size();
2830
accessor->accessor_type = p_accessor_type;
2831
accessor->component_type = p_component_type;
2832
accessor->byte_offset = 0;
2833
accessor->buffer_view = buffer_view_index;
2834
const GLTFAccessorIndex new_accessor_index = p_state->accessors.size();
2835
p_state->accessors.push_back(accessor);
2836
return new_accessor_index;
2837
}
2838
2839
Error GLTFDocument::_serialize_meshes(Ref<GLTFState> p_state) {
2840
Array meshes;
2841
for (GLTFMeshIndex gltf_mesh_i = 0; gltf_mesh_i < p_state->meshes.size(); gltf_mesh_i++) {
2842
print_verbose("glTF: Serializing mesh: " + itos(gltf_mesh_i));
2843
Ref<ImporterMesh> import_mesh = p_state->meshes.write[gltf_mesh_i]->get_mesh();
2844
if (import_mesh.is_null()) {
2845
continue;
2846
}
2847
Array instance_materials = p_state->meshes.write[gltf_mesh_i]->get_instance_materials();
2848
Array primitives;
2849
Dictionary gltf_mesh;
2850
Array target_names;
2851
Array weights;
2852
for (int morph_i = 0; morph_i < import_mesh->get_blend_shape_count(); morph_i++) {
2853
target_names.push_back(import_mesh->get_blend_shape_name(morph_i));
2854
}
2855
for (int surface_i = 0; surface_i < import_mesh->get_surface_count(); surface_i++) {
2856
Array targets;
2857
Dictionary primitive;
2858
Mesh::PrimitiveType primitive_type = import_mesh->get_surface_primitive_type(surface_i);
2859
switch (primitive_type) {
2860
case Mesh::PRIMITIVE_POINTS: {
2861
primitive["mode"] = 0;
2862
break;
2863
}
2864
case Mesh::PRIMITIVE_LINES: {
2865
primitive["mode"] = 1;
2866
break;
2867
}
2868
// case Mesh::PRIMITIVE_LINE_LOOP: {
2869
// primitive["mode"] = 2;
2870
// break;
2871
// }
2872
case Mesh::PRIMITIVE_LINE_STRIP: {
2873
primitive["mode"] = 3;
2874
break;
2875
}
2876
case Mesh::PRIMITIVE_TRIANGLES: {
2877
primitive["mode"] = 4;
2878
break;
2879
}
2880
case Mesh::PRIMITIVE_TRIANGLE_STRIP: {
2881
primitive["mode"] = 5;
2882
break;
2883
}
2884
// case Mesh::PRIMITIVE_TRIANGLE_FAN: {
2885
// primitive["mode"] = 6;
2886
// break;
2887
// }
2888
default: {
2889
ERR_FAIL_V(FAILED);
2890
}
2891
}
2892
2893
Array array = import_mesh->get_surface_arrays(surface_i);
2894
uint64_t format = import_mesh->get_surface_format(surface_i);
2895
int32_t vertex_num = 0;
2896
Dictionary attributes;
2897
{
2898
Vector<Vector3> a = array[Mesh::ARRAY_VERTEX];
2899
ERR_FAIL_COND_V(a.is_empty(), ERR_INVALID_DATA);
2900
attributes["POSITION"] = _encode_accessor_as_vec3(p_state, a, true);
2901
vertex_num = a.size();
2902
}
2903
{
2904
Vector<real_t> a = array[Mesh::ARRAY_TANGENT];
2905
if (a.size()) {
2906
const int64_t ret_size = a.size() / 4;
2907
Vector<Color> attribs;
2908
attribs.resize(ret_size);
2909
for (int64_t i = 0; i < ret_size; i++) {
2910
Color out;
2911
out.r = a[(i * 4) + 0];
2912
out.g = a[(i * 4) + 1];
2913
out.b = a[(i * 4) + 2];
2914
out.a = a[(i * 4) + 3];
2915
attribs.write[i] = out;
2916
}
2917
attributes["TANGENT"] = _encode_accessor_as_color(p_state, attribs, true);
2918
}
2919
}
2920
{
2921
Vector<Vector3> a = array[Mesh::ARRAY_NORMAL];
2922
if (a.size()) {
2923
const int64_t ret_size = a.size();
2924
Vector<Vector3> attribs;
2925
attribs.resize(ret_size);
2926
for (int64_t i = 0; i < ret_size; i++) {
2927
attribs.write[i] = Vector3(a[i]).normalized();
2928
}
2929
attributes["NORMAL"] = _encode_accessor_as_vec3(p_state, attribs, true);
2930
}
2931
}
2932
{
2933
Vector<Vector2> a = array[Mesh::ARRAY_TEX_UV];
2934
if (a.size()) {
2935
attributes["TEXCOORD_0"] = _encode_accessor_as_vec2(p_state, a, true);
2936
}
2937
}
2938
{
2939
Vector<Vector2> a = array[Mesh::ARRAY_TEX_UV2];
2940
if (a.size()) {
2941
attributes["TEXCOORD_1"] = _encode_accessor_as_vec2(p_state, a, true);
2942
}
2943
}
2944
for (int custom_i = 0; custom_i < 3; custom_i++) {
2945
Vector<float> a = array[Mesh::ARRAY_CUSTOM0 + custom_i];
2946
if (a.size()) {
2947
int num_channels = 4;
2948
int custom_shift = Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT + custom_i * Mesh::ARRAY_FORMAT_CUSTOM_BITS;
2949
switch ((format >> custom_shift) & Mesh::ARRAY_FORMAT_CUSTOM_MASK) {
2950
case Mesh::ARRAY_CUSTOM_R_FLOAT:
2951
num_channels = 1;
2952
break;
2953
case Mesh::ARRAY_CUSTOM_RG_FLOAT:
2954
num_channels = 2;
2955
break;
2956
case Mesh::ARRAY_CUSTOM_RGB_FLOAT:
2957
num_channels = 3;
2958
break;
2959
case Mesh::ARRAY_CUSTOM_RGBA_FLOAT:
2960
num_channels = 4;
2961
break;
2962
}
2963
int texcoord_i = 2 + 2 * custom_i;
2964
String gltf_texcoord_key;
2965
for (int prev_texcoord_i = 0; prev_texcoord_i < texcoord_i; prev_texcoord_i++) {
2966
gltf_texcoord_key = vformat("TEXCOORD_%d", prev_texcoord_i);
2967
if (!attributes.has(gltf_texcoord_key)) {
2968
Vector<Vector2> empty;
2969
empty.resize(vertex_num);
2970
attributes[gltf_texcoord_key] = _encode_accessor_as_vec2(p_state, empty, true);
2971
}
2972
}
2973
2974
LocalVector<Vector2> first_channel;
2975
first_channel.resize(vertex_num);
2976
LocalVector<Vector2> second_channel;
2977
second_channel.resize(vertex_num);
2978
for (int32_t vert_i = 0; vert_i < vertex_num; vert_i++) {
2979
float u = a[vert_i * num_channels + 0];
2980
float v = (num_channels == 1 ? 0.0f : a[vert_i * num_channels + 1]);
2981
first_channel[vert_i] = Vector2(u, v);
2982
u = 0;
2983
v = 0;
2984
if (num_channels >= 3) {
2985
u = a[vert_i * num_channels + 2];
2986
v = (num_channels == 3 ? 0.0f : a[vert_i * num_channels + 3]);
2987
second_channel[vert_i] = Vector2(u, v);
2988
}
2989
}
2990
gltf_texcoord_key = vformat("TEXCOORD_%d", texcoord_i);
2991
attributes[gltf_texcoord_key] = _encode_accessor_as_vec2(p_state, Vector<Vector2>(first_channel), true);
2992
gltf_texcoord_key = vformat("TEXCOORD_%d", texcoord_i + 1);
2993
attributes[gltf_texcoord_key] = _encode_accessor_as_vec2(p_state, Vector<Vector2>(second_channel), true);
2994
}
2995
}
2996
{
2997
Vector<Color> a = array[Mesh::ARRAY_COLOR];
2998
if (a.size()) {
2999
attributes["COLOR_0"] = _encode_accessor_as_color(p_state, a, true);
3000
}
3001
}
3002
HashMap<int, int> joint_i_to_bone_i;
3003
for (GLTFNodeIndex node_i = 0; node_i < p_state->nodes.size(); node_i++) {
3004
GLTFSkinIndex skin_i = -1;
3005
if (p_state->nodes[node_i]->mesh == gltf_mesh_i) {
3006
skin_i = p_state->nodes[node_i]->skin;
3007
}
3008
if (skin_i != -1) {
3009
joint_i_to_bone_i = p_state->skins[skin_i]->joint_i_to_bone_i;
3010
break;
3011
}
3012
}
3013
{
3014
const Array &a = array[Mesh::ARRAY_BONES];
3015
const Vector<Vector3> &vertex_array = array[Mesh::ARRAY_VERTEX];
3016
if ((a.size() / JOINT_GROUP_SIZE) == vertex_array.size()) {
3017
const int ret_size = a.size() / JOINT_GROUP_SIZE;
3018
Vector<Color> attribs;
3019
attribs.resize(ret_size);
3020
{
3021
for (int array_i = 0; array_i < attribs.size(); array_i++) {
3022
int32_t joint_0 = a[(array_i * JOINT_GROUP_SIZE) + 0];
3023
int32_t joint_1 = a[(array_i * JOINT_GROUP_SIZE) + 1];
3024
int32_t joint_2 = a[(array_i * JOINT_GROUP_SIZE) + 2];
3025
int32_t joint_3 = a[(array_i * JOINT_GROUP_SIZE) + 3];
3026
attribs.write[array_i] = Color(joint_0, joint_1, joint_2, joint_3);
3027
}
3028
}
3029
attributes["JOINTS_0"] = _encode_accessor_as_joints(p_state, attribs, true);
3030
} else if ((a.size() / (JOINT_GROUP_SIZE * 2)) >= vertex_array.size()) {
3031
Vector<Color> joints_0;
3032
joints_0.resize(vertex_num);
3033
Vector<Color> joints_1;
3034
joints_1.resize(vertex_num);
3035
int32_t weights_8_count = JOINT_GROUP_SIZE * 2;
3036
for (int32_t vertex_i = 0; vertex_i < vertex_num; vertex_i++) {
3037
Color joint_0;
3038
joint_0.r = a[vertex_i * weights_8_count + 0];
3039
joint_0.g = a[vertex_i * weights_8_count + 1];
3040
joint_0.b = a[vertex_i * weights_8_count + 2];
3041
joint_0.a = a[vertex_i * weights_8_count + 3];
3042
joints_0.write[vertex_i] = joint_0;
3043
Color joint_1;
3044
joint_1.r = a[vertex_i * weights_8_count + 4];
3045
joint_1.g = a[vertex_i * weights_8_count + 5];
3046
joint_1.b = a[vertex_i * weights_8_count + 6];
3047
joint_1.a = a[vertex_i * weights_8_count + 7];
3048
joints_1.write[vertex_i] = joint_1;
3049
}
3050
attributes["JOINTS_0"] = _encode_accessor_as_joints(p_state, joints_0, true);
3051
attributes["JOINTS_1"] = _encode_accessor_as_joints(p_state, joints_1, true);
3052
}
3053
}
3054
{
3055
const PackedRealArray &a = array[Mesh::ARRAY_WEIGHTS];
3056
const Vector<Vector3> &vertex_array = array[Mesh::ARRAY_VERTEX];
3057
if ((a.size() / JOINT_GROUP_SIZE) == vertex_array.size()) {
3058
int32_t vertex_count = vertex_array.size();
3059
Vector<Color> attribs;
3060
attribs.resize(vertex_count);
3061
for (int i = 0; i < vertex_count; i++) {
3062
Color weight_0(a[(i * JOINT_GROUP_SIZE) + 0], a[(i * JOINT_GROUP_SIZE) + 1], a[(i * JOINT_GROUP_SIZE) + 2], a[(i * JOINT_GROUP_SIZE) + 3]);
3063
float divisor = weight_0.r + weight_0.g + weight_0.b + weight_0.a;
3064
if (Math::is_zero_approx(divisor) || !Math::is_finite(divisor)) {
3065
divisor = 1.0;
3066
weight_0 = Color(1, 0, 0, 0);
3067
}
3068
attribs.write[i] = weight_0 / divisor;
3069
}
3070
attributes["WEIGHTS_0"] = _encode_accessor_as_weights(p_state, attribs, true);
3071
} else if ((a.size() / (JOINT_GROUP_SIZE * 2)) >= vertex_array.size()) {
3072
Vector<Color> weights_0;
3073
weights_0.resize(vertex_num);
3074
Vector<Color> weights_1;
3075
weights_1.resize(vertex_num);
3076
int32_t weights_8_count = JOINT_GROUP_SIZE * 2;
3077
for (int32_t vertex_i = 0; vertex_i < vertex_num; vertex_i++) {
3078
Color weight_0;
3079
weight_0.r = a[vertex_i * weights_8_count + 0];
3080
weight_0.g = a[vertex_i * weights_8_count + 1];
3081
weight_0.b = a[vertex_i * weights_8_count + 2];
3082
weight_0.a = a[vertex_i * weights_8_count + 3];
3083
Color weight_1;
3084
weight_1.r = a[vertex_i * weights_8_count + 4];
3085
weight_1.g = a[vertex_i * weights_8_count + 5];
3086
weight_1.b = a[vertex_i * weights_8_count + 6];
3087
weight_1.a = a[vertex_i * weights_8_count + 7];
3088
float divisor = weight_0.r + weight_0.g + weight_0.b + weight_0.a + weight_1.r + weight_1.g + weight_1.b + weight_1.a;
3089
if (Math::is_zero_approx(divisor) || !Math::is_finite(divisor)) {
3090
divisor = 1.0f;
3091
weight_0 = Color(1, 0, 0, 0);
3092
weight_1 = Color(0, 0, 0, 0);
3093
}
3094
weights_0.write[vertex_i] = weight_0 / divisor;
3095
weights_1.write[vertex_i] = weight_1 / divisor;
3096
}
3097
attributes["WEIGHTS_0"] = _encode_accessor_as_weights(p_state, weights_0, true);
3098
attributes["WEIGHTS_1"] = _encode_accessor_as_weights(p_state, weights_1, true);
3099
}
3100
}
3101
{
3102
Vector<int32_t> mesh_indices = array[Mesh::ARRAY_INDEX];
3103
if (mesh_indices.size()) {
3104
if (primitive_type == Mesh::PRIMITIVE_TRIANGLES) {
3105
// Swap around indices, convert ccw to cw for front face.
3106
const int is = mesh_indices.size();
3107
for (int k = 0; k < is; k += 3) {
3108
SWAP(mesh_indices.write[k + 0], mesh_indices.write[k + 2]);
3109
}
3110
}
3111
primitive["indices"] = _encode_accessor_as_ints(p_state, mesh_indices, false, true);
3112
} else {
3113
if (primitive_type == Mesh::PRIMITIVE_TRIANGLES) {
3114
// Generate indices because they need to be swapped for CW/CCW.
3115
const Vector<Vector3> &vertices = array[Mesh::ARRAY_VERTEX];
3116
Ref<SurfaceTool> st;
3117
st.instantiate();
3118
st->create_from_triangle_arrays(array);
3119
st->index();
3120
Vector<int32_t> generated_indices = st->commit_to_arrays()[Mesh::ARRAY_INDEX];
3121
const int vs = vertices.size();
3122
generated_indices.resize(vs);
3123
{
3124
for (int k = 0; k < vs; k += 3) {
3125
generated_indices.write[k] = k;
3126
generated_indices.write[k + 1] = k + 2;
3127
generated_indices.write[k + 2] = k + 1;
3128
}
3129
}
3130
primitive["indices"] = _encode_accessor_as_ints(p_state, generated_indices, false, true);
3131
}
3132
}
3133
}
3134
3135
primitive["attributes"] = attributes;
3136
3137
// Blend shapes
3138
print_verbose("glTF: Mesh has targets");
3139
if (import_mesh->get_blend_shape_count()) {
3140
ArrayMesh::BlendShapeMode shape_mode = import_mesh->get_blend_shape_mode();
3141
const float normal_tangent_sparse_rounding = 0.001;
3142
for (int morph_i = 0; morph_i < import_mesh->get_blend_shape_count(); morph_i++) {
3143
Array array_morph = import_mesh->get_surface_blend_shape_arrays(surface_i, morph_i);
3144
Dictionary t;
3145
Vector<Vector3> varr = array_morph[Mesh::ARRAY_VERTEX];
3146
Vector<Vector3> src_varr = array[Mesh::ARRAY_VERTEX];
3147
Array mesh_arrays = import_mesh->get_surface_arrays(surface_i);
3148
if (varr.size() && varr.size() == src_varr.size()) {
3149
if (shape_mode == ArrayMesh::BlendShapeMode::BLEND_SHAPE_MODE_NORMALIZED) {
3150
const int max_idx = src_varr.size();
3151
for (int blend_i = 0; blend_i < max_idx; blend_i++) {
3152
varr.write[blend_i] = varr[blend_i] - src_varr[blend_i];
3153
}
3154
}
3155
GLTFAccessorIndex position_accessor = attributes["POSITION"];
3156
if (position_accessor != -1) {
3157
int new_accessor = _encode_sparse_accessor_as_vec3(p_state, varr, Vector<Vector3>(), 1.0, true, -1);
3158
if (new_accessor != -1) {
3159
t["POSITION"] = new_accessor;
3160
}
3161
}
3162
}
3163
3164
Vector<Vector3> narr = array_morph[Mesh::ARRAY_NORMAL];
3165
Vector<Vector3> src_narr = array[Mesh::ARRAY_NORMAL];
3166
if (narr.size() && narr.size() == src_narr.size()) {
3167
if (shape_mode == ArrayMesh::BlendShapeMode::BLEND_SHAPE_MODE_NORMALIZED) {
3168
const int max_idx = src_narr.size();
3169
for (int blend_i = 0; blend_i < max_idx; blend_i++) {
3170
narr.write[blend_i] = narr[blend_i] - src_narr[blend_i];
3171
}
3172
}
3173
GLTFAccessorIndex normal_accessor = attributes["NORMAL"];
3174
if (normal_accessor != -1) {
3175
int new_accessor = _encode_sparse_accessor_as_vec3(p_state, narr, Vector<Vector3>(), normal_tangent_sparse_rounding, true, -1);
3176
if (new_accessor != -1) {
3177
t["NORMAL"] = new_accessor;
3178
}
3179
}
3180
}
3181
Vector<real_t> tarr = array_morph[Mesh::ARRAY_TANGENT];
3182
Vector<real_t> src_tarr = array[Mesh::ARRAY_TANGENT];
3183
if (tarr.size() && tarr.size() == src_tarr.size()) {
3184
const int ret_size = tarr.size() / 4;
3185
Vector<Vector3> attribs;
3186
attribs.resize(ret_size);
3187
for (int i = 0; i < ret_size; i++) {
3188
Vector3 vec3;
3189
vec3.x = tarr[(i * 4) + 0] - src_tarr[(i * 4) + 0];
3190
vec3.y = tarr[(i * 4) + 1] - src_tarr[(i * 4) + 1];
3191
vec3.z = tarr[(i * 4) + 2] - src_tarr[(i * 4) + 2];
3192
attribs.write[i] = vec3;
3193
}
3194
GLTFAccessorIndex tangent_accessor = attributes["TANGENT"];
3195
if (tangent_accessor != -1) {
3196
int new_accessor = _encode_sparse_accessor_as_vec3(p_state, attribs, Vector<Vector3>(), normal_tangent_sparse_rounding, true, -1);
3197
if (new_accessor != -1) {
3198
t["TANGENT"] = new_accessor;
3199
}
3200
}
3201
}
3202
targets.push_back(t);
3203
}
3204
}
3205
3206
Variant v;
3207
if (surface_i < instance_materials.size()) {
3208
v = instance_materials.get(surface_i);
3209
}
3210
Ref<Material> mat = v;
3211
if (mat.is_null()) {
3212
mat = import_mesh->get_surface_material(surface_i);
3213
}
3214
if (mat.is_valid()) {
3215
HashMap<Ref<Material>, GLTFMaterialIndex>::Iterator material_cache_i = p_state->material_cache.find(mat);
3216
if (material_cache_i && material_cache_i->value != -1) {
3217
primitive["material"] = material_cache_i->value;
3218
} else {
3219
GLTFMaterialIndex mat_i = p_state->materials.size();
3220
p_state->materials.push_back(mat);
3221
primitive["material"] = mat_i;
3222
p_state->material_cache.insert(mat, mat_i);
3223
}
3224
}
3225
3226
if (targets.size()) {
3227
primitive["targets"] = targets;
3228
}
3229
3230
primitives.push_back(primitive);
3231
}
3232
3233
if (!target_names.is_empty()) {
3234
Dictionary e;
3235
e["targetNames"] = target_names;
3236
gltf_mesh["extras"] = e;
3237
}
3238
_attach_meta_to_extras(import_mesh, gltf_mesh);
3239
3240
weights.resize(target_names.size());
3241
for (int name_i = 0; name_i < target_names.size(); name_i++) {
3242
real_t weight = 0.0;
3243
if (name_i < p_state->meshes.write[gltf_mesh_i]->get_blend_weights().size()) {
3244
weight = p_state->meshes.write[gltf_mesh_i]->get_blend_weights()[name_i];
3245
}
3246
weights[name_i] = weight;
3247
}
3248
if (weights.size()) {
3249
gltf_mesh["weights"] = weights;
3250
}
3251
3252
ERR_FAIL_COND_V(target_names.size() != weights.size(), FAILED);
3253
3254
gltf_mesh["primitives"] = primitives;
3255
3256
meshes.push_back(gltf_mesh);
3257
}
3258
3259
if (!meshes.size()) {
3260
return OK;
3261
}
3262
p_state->json["meshes"] = meshes;
3263
print_verbose("glTF: Total meshes: " + itos(meshes.size()));
3264
3265
return OK;
3266
}
3267
3268
Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) {
3269
if (!p_state->json.has("meshes")) {
3270
return OK;
3271
}
3272
3273
Array meshes = p_state->json["meshes"];
3274
for (GLTFMeshIndex i = 0; i < meshes.size(); i++) {
3275
print_verbose("glTF: Parsing mesh: " + itos(i));
3276
Dictionary mesh_dict = meshes[i];
3277
3278
Ref<GLTFMesh> mesh;
3279
mesh.instantiate();
3280
bool has_vertex_color = false;
3281
3282
ERR_FAIL_COND_V(!mesh_dict.has("primitives"), ERR_PARSE_ERROR);
3283
3284
Array primitives = mesh_dict["primitives"];
3285
const Dictionary &extras = mesh_dict.has("extras") ? (Dictionary)mesh_dict["extras"] : Dictionary();
3286
_attach_extras_to_meta(extras, mesh);
3287
Ref<ImporterMesh> import_mesh;
3288
import_mesh.instantiate();
3289
String mesh_name = "mesh";
3290
if (mesh_dict.has("name") && !String(mesh_dict["name"]).is_empty()) {
3291
mesh_name = mesh_dict["name"];
3292
mesh->set_original_name(mesh_name);
3293
}
3294
import_mesh->set_name(_gen_unique_name(p_state, vformat("%s_%s", p_state->scene_name, mesh_name)));
3295
mesh->set_name(import_mesh->get_name());
3296
TypedArray<Material> instance_materials;
3297
3298
for (int j = 0; j < primitives.size(); j++) {
3299
uint64_t flags = RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES;
3300
Dictionary mesh_prim = primitives[j];
3301
3302
Array array;
3303
array.resize(Mesh::ARRAY_MAX);
3304
3305
ERR_FAIL_COND_V(!mesh_prim.has("attributes"), ERR_PARSE_ERROR);
3306
3307
Dictionary a = mesh_prim["attributes"];
3308
3309
Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_TRIANGLES;
3310
if (mesh_prim.has("mode")) {
3311
const int mode = mesh_prim["mode"];
3312
ERR_FAIL_INDEX_V(mode, 7, ERR_FILE_CORRUPT);
3313
// Convert mesh.primitive.mode to Godot Mesh enum. See:
3314
// https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#_mesh_primitive_mode
3315
static const Mesh::PrimitiveType primitives2[7] = {
3316
Mesh::PRIMITIVE_POINTS, // 0 POINTS
3317
Mesh::PRIMITIVE_LINES, // 1 LINES
3318
Mesh::PRIMITIVE_LINES, // 2 LINE_LOOP; loop not supported, should be converted
3319
Mesh::PRIMITIVE_LINE_STRIP, // 3 LINE_STRIP
3320
Mesh::PRIMITIVE_TRIANGLES, // 4 TRIANGLES
3321
Mesh::PRIMITIVE_TRIANGLE_STRIP, // 5 TRIANGLE_STRIP
3322
Mesh::PRIMITIVE_TRIANGLES, // 6 TRIANGLE_FAN fan not supported, should be converted
3323
// TODO: Line loop and triangle fan are not supported and need to be converted to lines and triangles.
3324
};
3325
3326
primitive = primitives2[mode];
3327
}
3328
3329
int32_t orig_vertex_num = 0;
3330
ERR_FAIL_COND_V(!a.has("POSITION"), ERR_PARSE_ERROR);
3331
if (a.has("POSITION")) {
3332
PackedVector3Array vertices = _decode_accessor_as_vec3(p_state, a["POSITION"], true);
3333
array[Mesh::ARRAY_VERTEX] = vertices;
3334
orig_vertex_num = vertices.size();
3335
}
3336
int32_t vertex_num = orig_vertex_num;
3337
3338
Vector<int> indices;
3339
Vector<int> indices_mapping;
3340
Vector<int> indices_rev_mapping;
3341
Vector<int> indices_vec4_mapping;
3342
if (mesh_prim.has("indices")) {
3343
indices = _decode_accessor_as_ints(p_state, mesh_prim["indices"], false);
3344
const int index_count = indices.size();
3345
3346
if (primitive == Mesh::PRIMITIVE_TRIANGLES) {
3347
ERR_FAIL_COND_V_MSG(index_count % 3 != 0, ERR_PARSE_ERROR, "glTF import: Mesh " + itos(i) + " surface " + itos(j) + " in file " + p_state->filename + " is invalid. Indexed triangle meshes MUST have an index array with a size that is a multiple of 3, but got " + itos(index_count) + " indices.");
3348
// Swap around indices, convert ccw to cw for front face.
3349
3350
int *w = indices.ptrw();
3351
for (int k = 0; k < index_count; k += 3) {
3352
SWAP(w[k + 1], w[k + 2]);
3353
}
3354
}
3355
3356
const int *indices_w = indices.ptrw();
3357
Vector<bool> used_indices;
3358
used_indices.resize_initialized(orig_vertex_num);
3359
bool *used_w = used_indices.ptrw();
3360
for (int idx_i = 0; idx_i < index_count; idx_i++) {
3361
ERR_FAIL_INDEX_V(indices_w[idx_i], orig_vertex_num, ERR_INVALID_DATA);
3362
used_w[indices_w[idx_i]] = true;
3363
}
3364
indices_rev_mapping.resize_initialized(orig_vertex_num);
3365
int *rev_w = indices_rev_mapping.ptrw();
3366
vertex_num = 0;
3367
for (int vert_i = 0; vert_i < orig_vertex_num; vert_i++) {
3368
if (used_w[vert_i]) {
3369
rev_w[vert_i] = indices_mapping.size();
3370
indices_mapping.push_back(vert_i);
3371
indices_vec4_mapping.push_back(vert_i * 4 + 0);
3372
indices_vec4_mapping.push_back(vert_i * 4 + 1);
3373
indices_vec4_mapping.push_back(vert_i * 4 + 2);
3374
indices_vec4_mapping.push_back(vert_i * 4 + 3);
3375
vertex_num++;
3376
}
3377
}
3378
}
3379
ERR_FAIL_COND_V(vertex_num <= 0, ERR_INVALID_DECLARATION);
3380
3381
if (a.has("POSITION")) {
3382
PackedVector3Array vertices = _decode_accessor_as_vec3(p_state, a["POSITION"], true, indices_mapping);
3383
array[Mesh::ARRAY_VERTEX] = vertices;
3384
}
3385
if (a.has("NORMAL")) {
3386
array[Mesh::ARRAY_NORMAL] = _decode_accessor_as_vec3(p_state, a["NORMAL"], true, indices_mapping);
3387
}
3388
if (a.has("TANGENT")) {
3389
array[Mesh::ARRAY_TANGENT] = _decode_accessor_as_floats(p_state, a["TANGENT"], true, indices_vec4_mapping);
3390
}
3391
if (a.has("TEXCOORD_0")) {
3392
array[Mesh::ARRAY_TEX_UV] = _decode_accessor_as_vec2(p_state, a["TEXCOORD_0"], true, indices_mapping);
3393
}
3394
if (a.has("TEXCOORD_1")) {
3395
array[Mesh::ARRAY_TEX_UV2] = _decode_accessor_as_vec2(p_state, a["TEXCOORD_1"], true, indices_mapping);
3396
}
3397
for (int custom_i = 0; custom_i < 3; custom_i++) {
3398
Vector<float> cur_custom;
3399
Vector<Vector2> texcoord_first;
3400
Vector<Vector2> texcoord_second;
3401
3402
int texcoord_i = 2 + 2 * custom_i;
3403
String gltf_texcoord_key = vformat("TEXCOORD_%d", texcoord_i);
3404
int num_channels = 0;
3405
if (a.has(gltf_texcoord_key)) {
3406
texcoord_first = _decode_accessor_as_vec2(p_state, a[gltf_texcoord_key], true, indices_mapping);
3407
num_channels = 2;
3408
}
3409
gltf_texcoord_key = vformat("TEXCOORD_%d", texcoord_i + 1);
3410
if (a.has(gltf_texcoord_key)) {
3411
texcoord_second = _decode_accessor_as_vec2(p_state, a[gltf_texcoord_key], true, indices_mapping);
3412
num_channels = 4;
3413
}
3414
if (!num_channels) {
3415
break;
3416
}
3417
if (num_channels == 2 || num_channels == 4) {
3418
cur_custom.resize(vertex_num * num_channels);
3419
for (int32_t uv_i = 0; uv_i < texcoord_first.size() && uv_i < vertex_num; uv_i++) {
3420
cur_custom.write[uv_i * num_channels + 0] = texcoord_first[uv_i].x;
3421
cur_custom.write[uv_i * num_channels + 1] = texcoord_first[uv_i].y;
3422
}
3423
// Vector.resize seems to not zero-initialize. Ensure all unused elements are 0:
3424
for (int32_t uv_i = texcoord_first.size(); uv_i < vertex_num; uv_i++) {
3425
cur_custom.write[uv_i * num_channels + 0] = 0;
3426
cur_custom.write[uv_i * num_channels + 1] = 0;
3427
}
3428
}
3429
if (num_channels == 4) {
3430
for (int32_t uv_i = 0; uv_i < texcoord_second.size() && uv_i < vertex_num; uv_i++) {
3431
// num_channels must be 4
3432
cur_custom.write[uv_i * num_channels + 2] = texcoord_second[uv_i].x;
3433
cur_custom.write[uv_i * num_channels + 3] = texcoord_second[uv_i].y;
3434
}
3435
// Vector.resize seems to not zero-initialize. Ensure all unused elements are 0:
3436
for (int32_t uv_i = texcoord_second.size(); uv_i < vertex_num; uv_i++) {
3437
cur_custom.write[uv_i * num_channels + 2] = 0;
3438
cur_custom.write[uv_i * num_channels + 3] = 0;
3439
}
3440
}
3441
if (cur_custom.size() > 0) {
3442
array[Mesh::ARRAY_CUSTOM0 + custom_i] = cur_custom;
3443
int custom_shift = Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT + custom_i * Mesh::ARRAY_FORMAT_CUSTOM_BITS;
3444
if (num_channels == 2) {
3445
flags |= Mesh::ARRAY_CUSTOM_RG_FLOAT << custom_shift;
3446
} else {
3447
flags |= Mesh::ARRAY_CUSTOM_RGBA_FLOAT << custom_shift;
3448
}
3449
}
3450
}
3451
if (a.has("COLOR_0")) {
3452
array[Mesh::ARRAY_COLOR] = _decode_accessor_as_color(p_state, a["COLOR_0"], true, indices_mapping);
3453
has_vertex_color = true;
3454
}
3455
if (a.has("JOINTS_0") && !a.has("JOINTS_1")) {
3456
PackedInt32Array joints_0 = _decode_accessor_as_ints(p_state, a["JOINTS_0"], true, indices_vec4_mapping);
3457
ERR_FAIL_COND_V(joints_0.size() != 4 * vertex_num, ERR_INVALID_DATA);
3458
array[Mesh::ARRAY_BONES] = joints_0;
3459
} else if (a.has("JOINTS_0") && a.has("JOINTS_1")) {
3460
PackedInt32Array joints_0 = _decode_accessor_as_ints(p_state, a["JOINTS_0"], true, indices_vec4_mapping);
3461
PackedInt32Array joints_1 = _decode_accessor_as_ints(p_state, a["JOINTS_1"], true, indices_vec4_mapping);
3462
ERR_FAIL_COND_V(joints_0.size() != joints_1.size(), ERR_INVALID_DATA);
3463
ERR_FAIL_COND_V(joints_0.size() != 4 * vertex_num, ERR_INVALID_DATA);
3464
int32_t weight_8_count = JOINT_GROUP_SIZE * 2;
3465
Vector<int> joints;
3466
joints.resize(vertex_num * weight_8_count);
3467
for (int32_t vertex_i = 0; vertex_i < vertex_num; vertex_i++) {
3468
joints.write[vertex_i * weight_8_count + 0] = joints_0[vertex_i * JOINT_GROUP_SIZE + 0];
3469
joints.write[vertex_i * weight_8_count + 1] = joints_0[vertex_i * JOINT_GROUP_SIZE + 1];
3470
joints.write[vertex_i * weight_8_count + 2] = joints_0[vertex_i * JOINT_GROUP_SIZE + 2];
3471
joints.write[vertex_i * weight_8_count + 3] = joints_0[vertex_i * JOINT_GROUP_SIZE + 3];
3472
joints.write[vertex_i * weight_8_count + 4] = joints_1[vertex_i * JOINT_GROUP_SIZE + 0];
3473
joints.write[vertex_i * weight_8_count + 5] = joints_1[vertex_i * JOINT_GROUP_SIZE + 1];
3474
joints.write[vertex_i * weight_8_count + 6] = joints_1[vertex_i * JOINT_GROUP_SIZE + 2];
3475
joints.write[vertex_i * weight_8_count + 7] = joints_1[vertex_i * JOINT_GROUP_SIZE + 3];
3476
}
3477
array[Mesh::ARRAY_BONES] = joints;
3478
}
3479
// glTF stores weights as a VEC4 array or multiple VEC4 arrays, but Godot's
3480
// ArrayMesh uses a flat array of either 4 or 8 floats per vertex.
3481
// Therefore, decode up to two glTF VEC4 arrays as float arrays.
3482
if (a.has("WEIGHTS_0") && !a.has("WEIGHTS_1")) {
3483
Vector<float> weights = _decode_accessor_as_floats(p_state, a["WEIGHTS_0"], true, indices_vec4_mapping);
3484
ERR_FAIL_COND_V(weights.size() != 4 * vertex_num, ERR_INVALID_DATA);
3485
{ // glTF does not seem to normalize the weights for some reason.
3486
int wc = weights.size();
3487
float *w = weights.ptrw();
3488
3489
for (int k = 0; k < wc; k += 4) {
3490
float total = 0.0;
3491
total += w[k + 0];
3492
total += w[k + 1];
3493
total += w[k + 2];
3494
total += w[k + 3];
3495
if (total > 0.0) {
3496
w[k + 0] /= total;
3497
w[k + 1] /= total;
3498
w[k + 2] /= total;
3499
w[k + 3] /= total;
3500
}
3501
}
3502
}
3503
array[Mesh::ARRAY_WEIGHTS] = weights;
3504
} else if (a.has("WEIGHTS_0") && a.has("WEIGHTS_1")) {
3505
Vector<float> weights_0 = _decode_accessor_as_floats(p_state, a["WEIGHTS_0"], true, indices_vec4_mapping);
3506
Vector<float> weights_1 = _decode_accessor_as_floats(p_state, a["WEIGHTS_1"], true, indices_vec4_mapping);
3507
Vector<float> weights;
3508
ERR_FAIL_COND_V(weights_0.size() != weights_1.size(), ERR_INVALID_DATA);
3509
ERR_FAIL_COND_V(weights_0.size() != 4 * vertex_num, ERR_INVALID_DATA);
3510
int32_t weight_8_count = JOINT_GROUP_SIZE * 2;
3511
weights.resize(vertex_num * weight_8_count);
3512
for (int32_t vertex_i = 0; vertex_i < vertex_num; vertex_i++) {
3513
weights.write[vertex_i * weight_8_count + 0] = weights_0[vertex_i * JOINT_GROUP_SIZE + 0];
3514
weights.write[vertex_i * weight_8_count + 1] = weights_0[vertex_i * JOINT_GROUP_SIZE + 1];
3515
weights.write[vertex_i * weight_8_count + 2] = weights_0[vertex_i * JOINT_GROUP_SIZE + 2];
3516
weights.write[vertex_i * weight_8_count + 3] = weights_0[vertex_i * JOINT_GROUP_SIZE + 3];
3517
weights.write[vertex_i * weight_8_count + 4] = weights_1[vertex_i * JOINT_GROUP_SIZE + 0];
3518
weights.write[vertex_i * weight_8_count + 5] = weights_1[vertex_i * JOINT_GROUP_SIZE + 1];
3519
weights.write[vertex_i * weight_8_count + 6] = weights_1[vertex_i * JOINT_GROUP_SIZE + 2];
3520
weights.write[vertex_i * weight_8_count + 7] = weights_1[vertex_i * JOINT_GROUP_SIZE + 3];
3521
}
3522
{ // glTF does not seem to normalize the weights for some reason.
3523
int wc = weights.size();
3524
float *w = weights.ptrw();
3525
3526
for (int k = 0; k < wc; k += weight_8_count) {
3527
float total = 0.0;
3528
total += w[k + 0];
3529
total += w[k + 1];
3530
total += w[k + 2];
3531
total += w[k + 3];
3532
total += w[k + 4];
3533
total += w[k + 5];
3534
total += w[k + 6];
3535
total += w[k + 7];
3536
if (total > 0.0) {
3537
w[k + 0] /= total;
3538
w[k + 1] /= total;
3539
w[k + 2] /= total;
3540
w[k + 3] /= total;
3541
w[k + 4] /= total;
3542
w[k + 5] /= total;
3543
w[k + 6] /= total;
3544
w[k + 7] /= total;
3545
}
3546
}
3547
}
3548
array[Mesh::ARRAY_WEIGHTS] = weights;
3549
flags |= Mesh::ARRAY_FLAG_USE_8_BONE_WEIGHTS;
3550
}
3551
3552
if (!indices.is_empty()) {
3553
int *w = indices.ptrw();
3554
const int is = indices.size();
3555
for (int ind_i = 0; ind_i < is; ind_i++) {
3556
w[ind_i] = indices_rev_mapping[indices[ind_i]];
3557
}
3558
array[Mesh::ARRAY_INDEX] = indices;
3559
3560
} else if (primitive == Mesh::PRIMITIVE_TRIANGLES) {
3561
// Generate indices because they need to be swapped for CW/CCW.
3562
const Vector<Vector3> &vertices = array[Mesh::ARRAY_VERTEX];
3563
ERR_FAIL_COND_V(vertices.is_empty(), ERR_PARSE_ERROR);
3564
const int vertex_count = vertices.size();
3565
ERR_FAIL_COND_V_MSG(vertex_count % 3 != 0, ERR_PARSE_ERROR, "glTF import: Mesh " + itos(i) + " surface " + itos(j) + " in file " + p_state->filename + " is invalid. Non-indexed triangle meshes MUST have a vertex array with a size that is a multiple of 3, but got " + itos(vertex_count) + " vertices.");
3566
indices.resize(vertex_count);
3567
{
3568
int *w = indices.ptrw();
3569
for (int k = 0; k < vertex_count; k += 3) {
3570
w[k] = k;
3571
w[k + 1] = k + 2;
3572
w[k + 2] = k + 1;
3573
}
3574
}
3575
array[Mesh::ARRAY_INDEX] = indices;
3576
}
3577
3578
bool generate_tangents = p_state->force_generate_tangents && (primitive == Mesh::PRIMITIVE_TRIANGLES && !a.has("TANGENT") && a.has("NORMAL"));
3579
3580
if (generate_tangents && !a.has("TEXCOORD_0")) {
3581
// If we don't have UVs we provide a dummy tangent array.
3582
Vector<float> tangents;
3583
tangents.resize(vertex_num * 4);
3584
float *tangentsw = tangents.ptrw();
3585
3586
Vector<Vector3> normals = array[Mesh::ARRAY_NORMAL];
3587
for (int k = 0; k < vertex_num; k++) {
3588
Vector3 tan = Vector3(normals[k].z, -normals[k].x, normals[k].y).cross(normals[k].normalized()).normalized();
3589
tangentsw[k * 4 + 0] = tan.x;
3590
tangentsw[k * 4 + 1] = tan.y;
3591
tangentsw[k * 4 + 2] = tan.z;
3592
tangentsw[k * 4 + 3] = 1.0;
3593
}
3594
array[Mesh::ARRAY_TANGENT] = tangents;
3595
}
3596
3597
// Disable compression if all z equals 0 (the mesh is 2D).
3598
const Vector<Vector3> &vertices = array[Mesh::ARRAY_VERTEX];
3599
bool is_mesh_2d = true;
3600
for (int k = 0; k < vertices.size(); k++) {
3601
if (!Math::is_zero_approx(vertices[k].z)) {
3602
is_mesh_2d = false;
3603
break;
3604
}
3605
}
3606
3607
if (p_state->force_disable_compression || is_mesh_2d || !a.has("POSITION") || !a.has("NORMAL") || mesh_prim.has("targets") || (a.has("JOINTS_0") || a.has("JOINTS_1"))) {
3608
flags &= ~RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES;
3609
}
3610
3611
Ref<SurfaceTool> mesh_surface_tool;
3612
mesh_surface_tool.instantiate();
3613
mesh_surface_tool->create_from_triangle_arrays(array);
3614
if (a.has("JOINTS_0") && a.has("JOINTS_1")) {
3615
mesh_surface_tool->set_skin_weight_count(SurfaceTool::SKIN_8_WEIGHTS);
3616
}
3617
mesh_surface_tool->index();
3618
if (generate_tangents && a.has("TEXCOORD_0")) {
3619
//must generate mikktspace tangents.. ergh..
3620
mesh_surface_tool->generate_tangents();
3621
}
3622
array = mesh_surface_tool->commit_to_arrays();
3623
3624
if ((flags & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && a.has("NORMAL") && (a.has("TANGENT") || generate_tangents)) {
3625
// Compression is enabled, so let's validate that the normals and tangents are correct.
3626
Vector<Vector3> normals = array[Mesh::ARRAY_NORMAL];
3627
Vector<float> tangents = array[Mesh::ARRAY_TANGENT];
3628
if (unlikely(tangents.size() < normals.size() * 4)) {
3629
ERR_PRINT("glTF import: Mesh " + itos(i) + " has invalid tangents.");
3630
flags &= ~RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES;
3631
} else {
3632
for (int vert = 0; vert < normals.size(); vert++) {
3633
Vector3 tan = Vector3(tangents[vert * 4 + 0], tangents[vert * 4 + 1], tangents[vert * 4 + 2]);
3634
if (std::abs(tan.dot(normals[vert])) > 0.0001) {
3635
// Tangent is not perpendicular to the normal, so we can't use compression.
3636
flags &= ~RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES;
3637
}
3638
}
3639
}
3640
}
3641
3642
Array morphs;
3643
// Blend shapes
3644
if (mesh_prim.has("targets")) {
3645
print_verbose("glTF: Mesh has targets");
3646
const Array &targets = mesh_prim["targets"];
3647
3648
import_mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED);
3649
3650
if (j == 0) {
3651
const Array &target_names = extras.has("targetNames") ? (Array)extras["targetNames"] : Array();
3652
for (int k = 0; k < targets.size(); k++) {
3653
String bs_name;
3654
if (k < target_names.size() && ((String)target_names[k]).size() != 0) {
3655
bs_name = (String)target_names[k];
3656
} else {
3657
bs_name = String("morph_") + itos(k);
3658
}
3659
import_mesh->add_blend_shape(bs_name);
3660
}
3661
}
3662
3663
for (int k = 0; k < targets.size(); k++) {
3664
const Dictionary &t = targets[k];
3665
3666
Array array_copy;
3667
array_copy.resize(Mesh::ARRAY_MAX);
3668
3669
for (int l = 0; l < Mesh::ARRAY_MAX; l++) {
3670
array_copy[l] = array[l];
3671
}
3672
3673
if (t.has("POSITION")) {
3674
Vector<Vector3> varr = _decode_accessor_as_vec3(p_state, t["POSITION"], true, indices_mapping);
3675
const Vector<Vector3> src_varr = array[Mesh::ARRAY_VERTEX];
3676
const int size = src_varr.size();
3677
ERR_FAIL_COND_V(size == 0, ERR_PARSE_ERROR);
3678
{
3679
const int max_idx = varr.size();
3680
varr.resize(size);
3681
3682
Vector3 *w_varr = varr.ptrw();
3683
const Vector3 *r_varr = varr.ptr();
3684
const Vector3 *r_src_varr = src_varr.ptr();
3685
for (int l = 0; l < size; l++) {
3686
if (l < max_idx) {
3687
w_varr[l] = r_varr[l] + r_src_varr[l];
3688
} else {
3689
w_varr[l] = r_src_varr[l];
3690
}
3691
}
3692
}
3693
array_copy[Mesh::ARRAY_VERTEX] = varr;
3694
}
3695
if (t.has("NORMAL")) {
3696
Vector<Vector3> narr = _decode_accessor_as_vec3(p_state, t["NORMAL"], true, indices_mapping);
3697
const Vector<Vector3> src_narr = array[Mesh::ARRAY_NORMAL];
3698
int size = src_narr.size();
3699
ERR_FAIL_COND_V(size == 0, ERR_PARSE_ERROR);
3700
{
3701
int max_idx = narr.size();
3702
narr.resize(size);
3703
3704
Vector3 *w_narr = narr.ptrw();
3705
const Vector3 *r_narr = narr.ptr();
3706
const Vector3 *r_src_narr = src_narr.ptr();
3707
for (int l = 0; l < size; l++) {
3708
if (l < max_idx) {
3709
w_narr[l] = r_narr[l] + r_src_narr[l];
3710
} else {
3711
w_narr[l] = r_src_narr[l];
3712
}
3713
}
3714
}
3715
array_copy[Mesh::ARRAY_NORMAL] = narr;
3716
}
3717
if (t.has("TANGENT")) {
3718
const Vector<Vector3> tangents_v3 = _decode_accessor_as_vec3(p_state, t["TANGENT"], true, indices_mapping);
3719
const Vector<float> src_tangents = array[Mesh::ARRAY_TANGENT];
3720
ERR_FAIL_COND_V(src_tangents.is_empty(), ERR_PARSE_ERROR);
3721
3722
Vector<float> tangents_v4;
3723
3724
{
3725
int max_idx = tangents_v3.size();
3726
3727
int size4 = src_tangents.size();
3728
tangents_v4.resize(size4);
3729
float *w4 = tangents_v4.ptrw();
3730
3731
const Vector3 *r3 = tangents_v3.ptr();
3732
const float *r4 = src_tangents.ptr();
3733
3734
for (int l = 0; l < size4 / 4; l++) {
3735
if (l < max_idx) {
3736
w4[l * 4 + 0] = r3[l].x + r4[l * 4 + 0];
3737
w4[l * 4 + 1] = r3[l].y + r4[l * 4 + 1];
3738
w4[l * 4 + 2] = r3[l].z + r4[l * 4 + 2];
3739
} else {
3740
w4[l * 4 + 0] = r4[l * 4 + 0];
3741
w4[l * 4 + 1] = r4[l * 4 + 1];
3742
w4[l * 4 + 2] = r4[l * 4 + 2];
3743
}
3744
w4[l * 4 + 3] = r4[l * 4 + 3]; //copy flip value
3745
}
3746
}
3747
3748
array_copy[Mesh::ARRAY_TANGENT] = tangents_v4;
3749
}
3750
3751
Ref<SurfaceTool> blend_surface_tool;
3752
blend_surface_tool.instantiate();
3753
blend_surface_tool->create_from_triangle_arrays(array_copy);
3754
if (a.has("JOINTS_0") && a.has("JOINTS_1")) {
3755
blend_surface_tool->set_skin_weight_count(SurfaceTool::SKIN_8_WEIGHTS);
3756
}
3757
blend_surface_tool->index();
3758
if (generate_tangents) {
3759
blend_surface_tool->generate_tangents();
3760
}
3761
array_copy = blend_surface_tool->commit_to_arrays();
3762
3763
// Enforce blend shape mask array format
3764
for (int l = 0; l < Mesh::ARRAY_MAX; l++) {
3765
if (!(Mesh::ARRAY_FORMAT_BLEND_SHAPE_MASK & (1ULL << l))) {
3766
array_copy[l] = Variant();
3767
}
3768
}
3769
3770
morphs.push_back(array_copy);
3771
}
3772
}
3773
3774
Ref<Material> mat;
3775
String mat_name;
3776
if (!p_state->discard_meshes_and_materials) {
3777
if (mesh_prim.has("material")) {
3778
const int material = mesh_prim["material"];
3779
ERR_FAIL_INDEX_V(material, p_state->materials.size(), ERR_FILE_CORRUPT);
3780
Ref<Material> mat3d = p_state->materials[material];
3781
ERR_FAIL_COND_V(mat3d.is_null(), ERR_FILE_CORRUPT);
3782
3783
Ref<BaseMaterial3D> base_material = mat3d;
3784
if (has_vertex_color && base_material.is_valid()) {
3785
base_material->set_flag(BaseMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
3786
}
3787
mat = mat3d;
3788
3789
} else {
3790
Ref<StandardMaterial3D> mat3d;
3791
mat3d.instantiate();
3792
if (has_vertex_color) {
3793
mat3d->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
3794
}
3795
mat = mat3d;
3796
}
3797
ERR_FAIL_COND_V(mat.is_null(), ERR_FILE_CORRUPT);
3798
instance_materials.append(mat);
3799
mat_name = mat->get_name();
3800
}
3801
import_mesh->add_surface(primitive, array, morphs,
3802
Dictionary(), mat, mat_name, flags);
3803
}
3804
3805
Vector<float> blend_weights;
3806
blend_weights.resize(import_mesh->get_blend_shape_count());
3807
for (int32_t weight_i = 0; weight_i < blend_weights.size(); weight_i++) {
3808
blend_weights.write[weight_i] = 0.0f;
3809
}
3810
3811
if (mesh_dict.has("weights")) {
3812
const Array &weights = mesh_dict["weights"];
3813
for (int j = 0; j < weights.size(); j++) {
3814
if (j >= blend_weights.size()) {
3815
break;
3816
}
3817
blend_weights.write[j] = weights[j];
3818
}
3819
}
3820
mesh->set_blend_weights(blend_weights);
3821
mesh->set_instance_materials(instance_materials);
3822
mesh->set_mesh(import_mesh);
3823
3824
p_state->meshes.push_back(mesh);
3825
}
3826
3827
print_verbose("glTF: Total meshes: " + itos(p_state->meshes.size()));
3828
3829
return OK;
3830
}
3831
3832
void GLTFDocument::set_naming_version(int p_version) {
3833
_naming_version = p_version;
3834
}
3835
3836
int GLTFDocument::get_naming_version() const {
3837
return _naming_version;
3838
}
3839
3840
void GLTFDocument::set_image_format(const String &p_image_format) {
3841
_image_format = p_image_format;
3842
}
3843
3844
String GLTFDocument::get_image_format() const {
3845
return _image_format;
3846
}
3847
3848
void GLTFDocument::set_lossy_quality(float p_lossy_quality) {
3849
_lossy_quality = p_lossy_quality;
3850
}
3851
3852
float GLTFDocument::get_lossy_quality() const {
3853
return _lossy_quality;
3854
}
3855
3856
void GLTFDocument::set_fallback_image_format(const String &p_fallback_image_format) {
3857
_fallback_image_format = p_fallback_image_format;
3858
}
3859
3860
String GLTFDocument::get_fallback_image_format() const {
3861
return _fallback_image_format;
3862
}
3863
3864
void GLTFDocument::set_fallback_image_quality(float p_fallback_image_quality) {
3865
_fallback_image_quality = p_fallback_image_quality;
3866
}
3867
3868
float GLTFDocument::get_fallback_image_quality() const {
3869
return _fallback_image_quality;
3870
}
3871
3872
Error GLTFDocument::_serialize_images(Ref<GLTFState> p_state) {
3873
Array images;
3874
// Check if any extension wants to be the image saver.
3875
_image_save_extension = Ref<GLTFDocumentExtension>();
3876
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
3877
ERR_CONTINUE(ext.is_null());
3878
Vector<String> image_formats = ext->get_saveable_image_formats();
3879
if (image_formats.has(_image_format)) {
3880
_image_save_extension = ext;
3881
break;
3882
}
3883
}
3884
// Serialize every image in the state's images array.
3885
for (int i = 0; i < p_state->images.size(); i++) {
3886
Dictionary image_dict;
3887
if (p_state->images[i].is_null()) {
3888
ERR_PRINT("glTF export: Image Texture2D is null.");
3889
} else {
3890
Ref<Image> image = p_state->images[i]->get_image();
3891
if (image.is_null()) {
3892
ERR_PRINT("glTF export: Image's image is null.");
3893
} else {
3894
String image_name = p_state->images[i]->get_name();
3895
if (image_name.is_empty()) {
3896
image_name = itos(i).pad_zeros(3);
3897
}
3898
image_name = _gen_unique_name(p_state, image_name);
3899
image->set_name(image_name);
3900
image_dict = _serialize_image(p_state, image, _image_format, _lossy_quality, _image_save_extension);
3901
}
3902
}
3903
images.push_back(image_dict);
3904
}
3905
3906
print_verbose("Total images: " + itos(p_state->images.size()));
3907
3908
if (!images.size()) {
3909
return OK;
3910
}
3911
p_state->json["images"] = images;
3912
3913
return OK;
3914
}
3915
3916
Dictionary GLTFDocument::_serialize_image(Ref<GLTFState> p_state, Ref<Image> p_image, const String &p_image_format, float p_lossy_quality, Ref<GLTFDocumentExtension> p_image_save_extension) {
3917
Dictionary image_dict;
3918
if (p_image->is_compressed()) {
3919
p_image->decompress();
3920
ERR_FAIL_COND_V_MSG(p_image->is_compressed(), image_dict, "glTF: Image was compressed, but could not be decompressed.");
3921
}
3922
3923
if (p_state->filename.to_lower().ends_with("gltf")) {
3924
String relative_texture_dir = "textures";
3925
String full_texture_dir = p_state->base_path.path_join(relative_texture_dir);
3926
Ref<DirAccess> da = DirAccess::open(p_state->base_path);
3927
ERR_FAIL_COND_V(da.is_null(), image_dict);
3928
3929
if (!da->dir_exists(full_texture_dir)) {
3930
da->make_dir(full_texture_dir);
3931
}
3932
String image_file_name = p_image->get_name();
3933
if (p_image_save_extension.is_valid()) {
3934
image_file_name = image_file_name + p_image_save_extension->get_image_file_extension();
3935
Error err = p_image_save_extension->save_image_at_path(p_state, p_image, full_texture_dir.path_join(image_file_name), p_image_format, p_lossy_quality);
3936
ERR_FAIL_COND_V_MSG(err != OK, image_dict, "glTF: Failed to save image in '" + p_image_format + "' format as a separate file, error " + itos(err) + ".");
3937
} else if (p_image_format == "PNG") {
3938
image_file_name = image_file_name + ".png";
3939
p_image->save_png(full_texture_dir.path_join(image_file_name));
3940
} else if (p_image_format == "JPEG") {
3941
image_file_name = image_file_name + ".jpg";
3942
p_image->save_jpg(full_texture_dir.path_join(image_file_name), p_lossy_quality);
3943
} else {
3944
ERR_FAIL_V_MSG(image_dict, "glTF: Unknown image format '" + p_image_format + "'.");
3945
}
3946
image_dict["uri"] = relative_texture_dir.path_join(image_file_name).uri_encode();
3947
} else {
3948
GLTFBufferViewIndex bvi;
3949
3950
Ref<GLTFBufferView> bv;
3951
bv.instantiate();
3952
3953
const GLTFBufferIndex bi = 0;
3954
bv->buffer = bi;
3955
ERR_FAIL_INDEX_V(bi, p_state->buffers.size(), image_dict);
3956
bv->byte_offset = p_state->buffers[bi].size();
3957
3958
Vector<uint8_t> buffer;
3959
Ref<ImageTexture> img_tex = p_image;
3960
if (img_tex.is_valid()) {
3961
p_image = img_tex->get_image();
3962
}
3963
// Save in various image formats. Note that if the format is "None",
3964
// the state's images will be empty, so this code will not be reached.
3965
if (_image_save_extension.is_valid()) {
3966
buffer = _image_save_extension->serialize_image_to_bytes(p_state, p_image, image_dict, p_image_format, p_lossy_quality);
3967
} else if (p_image_format == "PNG") {
3968
buffer = p_image->save_png_to_buffer();
3969
image_dict["mimeType"] = "image/png";
3970
} else if (p_image_format == "JPEG") {
3971
buffer = p_image->save_jpg_to_buffer(p_lossy_quality);
3972
image_dict["mimeType"] = "image/jpeg";
3973
} else {
3974
ERR_FAIL_V_MSG(image_dict, "glTF: Unknown image format '" + p_image_format + "'.");
3975
}
3976
ERR_FAIL_COND_V_MSG(buffer.is_empty(), image_dict, "glTF: Failed to save image in '" + p_image_format + "' format.");
3977
3978
bv->byte_length = buffer.size();
3979
p_state->buffers.write[bi].resize(p_state->buffers[bi].size() + bv->byte_length);
3980
memcpy(&p_state->buffers.write[bi].write[bv->byte_offset], buffer.ptr(), buffer.size());
3981
ERR_FAIL_COND_V(bv->byte_offset + bv->byte_length > p_state->buffers[bi].size(), image_dict);
3982
3983
p_state->buffer_views.push_back(bv);
3984
bvi = p_state->buffer_views.size() - 1;
3985
image_dict["bufferView"] = bvi;
3986
}
3987
return image_dict;
3988
}
3989
3990
Ref<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) {
3991
Ref<Image> r_image;
3992
r_image.instantiate();
3993
// Check if any GLTFDocumentExtensions want to import this data as an image.
3994
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
3995
ERR_CONTINUE(ext.is_null());
3996
Error err = ext->parse_image_data(p_state, p_bytes, p_mime_type, r_image);
3997
ERR_CONTINUE_MSG(err != OK, "glTF: Encountered error " + itos(err) + " when parsing image " + itos(p_index) + " in file " + p_state->filename + ". Continuing.");
3998
if (!r_image->is_empty()) {
3999
r_file_extension = ext->get_image_file_extension();
4000
return r_image;
4001
}
4002
}
4003
// If no extension wanted to import this data as an image, try to load a PNG or JPEG.
4004
// First we honor the mime types if they were defined.
4005
if (p_mime_type == "image/png") { // Load buffer as PNG.
4006
r_image->load_png_from_buffer(p_bytes);
4007
r_file_extension = ".png";
4008
} else if (p_mime_type == "image/jpeg") { // Loader buffer as JPEG.
4009
r_image->load_jpg_from_buffer(p_bytes);
4010
r_file_extension = ".jpg";
4011
}
4012
// If we didn't pass the above tests, we attempt loading as PNG and then JPEG directly.
4013
// This covers URIs with base64-encoded data with application/* type but
4014
// no optional mimeType property, or bufferViews with a bogus mimeType
4015
// (e.g. `image/jpeg` but the data is actually PNG).
4016
// That's not *exactly* what the spec mandates but this lets us be
4017
// lenient with bogus glb files which do exist in production.
4018
if (r_image->is_empty()) { // Try PNG first.
4019
r_image->load_png_from_buffer(p_bytes);
4020
}
4021
if (r_image->is_empty()) { // And then JPEG.
4022
r_image->load_jpg_from_buffer(p_bytes);
4023
}
4024
// If it still can't be loaded, give up and insert an empty image as placeholder.
4025
if (r_image->is_empty()) {
4026
ERR_PRINT(vformat("glTF: Couldn't load image index '%d' with its given mimetype: %s.", p_index, p_mime_type));
4027
}
4028
return r_image;
4029
}
4030
4031
void GLTFDocument::_parse_image_save_image(Ref<GLTFState> p_state, const Vector<uint8_t> &p_bytes, const String &p_resource_uri, const String &p_file_extension, int p_index, Ref<Image> p_image) {
4032
GLTFState::GLTFHandleBinary handling = GLTFState::GLTFHandleBinary(p_state->handle_binary_image);
4033
if (p_image->is_empty() || handling == GLTFState::GLTFHandleBinary::HANDLE_BINARY_DISCARD_TEXTURES) {
4034
p_state->images.push_back(Ref<Texture2D>());
4035
p_state->source_images.push_back(Ref<Image>());
4036
return;
4037
}
4038
#ifdef TOOLS_ENABLED
4039
if (Engine::get_singleton()->is_editor_hint() && handling == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EXTRACT_TEXTURES) {
4040
if (p_state->extract_path.is_empty()) {
4041
WARN_PRINT("glTF: Couldn't extract image because the base and extract paths are empty. It will be loaded directly instead, uncompressed.");
4042
} else if (p_state->extract_path.begins_with("res://.godot/imported")) {
4043
WARN_PRINT(vformat("glTF: Extract path is in the imported directory. Image index '%d' will be loaded directly, uncompressed.", p_index));
4044
} else {
4045
if (p_image->get_name().is_empty()) {
4046
WARN_PRINT(vformat("glTF: Image index '%d' did not have a name. It will be automatically given a name based on its index.", p_index));
4047
p_image->set_name(itos(p_index));
4048
}
4049
bool must_write = true; // If the resource does not exist on the disk within res:// directory write it.
4050
bool must_import = true; // Trigger import.
4051
Vector<uint8_t> img_data = p_image->get_data();
4052
Dictionary generator_parameters;
4053
String file_path;
4054
// If resource_uri is within res:// folder but outside of .godot/imported folder, use it.
4055
if (!p_resource_uri.is_empty() && !p_resource_uri.begins_with("res://.godot/imported") && !p_resource_uri.begins_with("res://..")) {
4056
file_path = p_resource_uri;
4057
must_import = true;
4058
must_write = !FileAccess::exists(file_path);
4059
} else {
4060
// Texture data has to be written to the res:// folder and imported.
4061
file_path = p_state->get_extract_path().path_join(p_state->get_extract_prefix() + "_" + p_image->get_name());
4062
file_path += p_file_extension.is_empty() ? ".png" : p_file_extension;
4063
if (FileAccess::exists(file_path + ".import")) {
4064
Ref<ConfigFile> config;
4065
config.instantiate();
4066
config->load(file_path + ".import");
4067
if (config->has_section_key("remap", "generator_parameters")) {
4068
generator_parameters = (Dictionary)config->get_value("remap", "generator_parameters");
4069
}
4070
if (!generator_parameters.has("md5")) {
4071
must_write = false; // Didn't come from a gltf document; don't overwrite.
4072
must_import = false; // And don't import.
4073
}
4074
}
4075
}
4076
4077
if (must_write) {
4078
String existing_md5 = generator_parameters["md5"];
4079
unsigned char md5_hash[16];
4080
CryptoCore::md5(img_data.ptr(), img_data.size(), md5_hash);
4081
String new_md5 = String::hex_encode_buffer(md5_hash, 16);
4082
generator_parameters["md5"] = new_md5;
4083
if (new_md5 == existing_md5) {
4084
must_write = false;
4085
must_import = false;
4086
}
4087
}
4088
if (must_write) {
4089
Error err = OK;
4090
if (p_file_extension.is_empty()) {
4091
// If a file extension was not specified, save the image data to a PNG file.
4092
err = p_image->save_png(file_path);
4093
ERR_FAIL_COND(err != OK);
4094
} else {
4095
// If a file extension was specified, save the original bytes to a file with that extension.
4096
Ref<FileAccess> file = FileAccess::open(file_path, FileAccess::WRITE, &err);
4097
ERR_FAIL_COND(err != OK);
4098
file->store_buffer(p_bytes);
4099
file->close();
4100
}
4101
}
4102
if (must_import) {
4103
// ResourceLoader::import will crash if not is_editor_hint(), so this case is protected above and will fall through to uncompressed.
4104
HashMap<StringName, Variant> custom_options;
4105
custom_options[SNAME("mipmaps/generate")] = true;
4106
// Will only use project settings defaults if custom_importer is empty.
4107
4108
EditorFileSystem::get_singleton()->update_file(file_path);
4109
EditorFileSystem::get_singleton()->reimport_append(file_path, custom_options, String(), generator_parameters);
4110
}
4111
Ref<Texture2D> saved_image = ResourceLoader::load(file_path, "Texture2D");
4112
if (saved_image.is_valid()) {
4113
p_state->images.push_back(saved_image);
4114
p_state->source_images.push_back(saved_image->get_image());
4115
return;
4116
} else {
4117
WARN_PRINT(vformat("glTF: Image index '%d' with the name '%s' resolved to %s couldn't be imported. It will be loaded directly instead, uncompressed.", p_index, p_image->get_name(), file_path));
4118
}
4119
}
4120
}
4121
#endif // TOOLS_ENABLED
4122
if (handling == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EMBED_AS_BASISU) {
4123
Ref<PortableCompressedTexture2D> tex;
4124
tex.instantiate();
4125
tex->set_name(p_image->get_name());
4126
tex->set_keep_compressed_buffer(true);
4127
tex->create_from_image(p_image, PortableCompressedTexture2D::COMPRESSION_MODE_BASIS_UNIVERSAL);
4128
p_state->images.push_back(tex);
4129
p_state->source_images.push_back(p_image);
4130
return;
4131
}
4132
// This handles the case of HANDLE_BINARY_EMBED_AS_UNCOMPRESSED, and it also serves
4133
// as a fallback for HANDLE_BINARY_EXTRACT_TEXTURES when this is not the editor.
4134
Ref<ImageTexture> tex;
4135
tex.instantiate();
4136
tex->set_name(p_image->get_name());
4137
tex->set_image(p_image);
4138
p_state->images.push_back(tex);
4139
p_state->source_images.push_back(p_image);
4140
}
4141
4142
Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_path) {
4143
ERR_FAIL_COND_V(p_state.is_null(), ERR_INVALID_PARAMETER);
4144
if (!p_state->json.has("images")) {
4145
return OK;
4146
}
4147
4148
// Ref: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#images
4149
4150
const Array &images = p_state->json["images"];
4151
HashSet<String> used_names;
4152
for (int i = 0; i < images.size(); i++) {
4153
const Dictionary &dict = images[i];
4154
4155
// glTF 2.0 supports PNG and JPEG types, which can be specified as (from spec):
4156
// "- a URI to an external file in one of the supported images formats, or
4157
// - a URI with embedded base64-encoded data, or
4158
// - a reference to a bufferView; in that case mimeType must be defined."
4159
// Since mimeType is optional for external files and base64 data, we'll have to
4160
// fall back on letting Godot parse the data to figure out if it's PNG or JPEG.
4161
4162
// We'll assume that we use either URI or bufferView, so let's warn the user
4163
// if their image somehow uses both. And fail if it has neither.
4164
ERR_CONTINUE_MSG(!dict.has("uri") && !dict.has("bufferView"), "Invalid image definition in glTF file, it should specify an 'uri' or 'bufferView'.");
4165
if (dict.has("uri") && dict.has("bufferView")) {
4166
WARN_PRINT("Invalid image definition in glTF file using both 'uri' and 'bufferView'. 'uri' will take precedence.");
4167
}
4168
4169
String mime_type;
4170
if (dict.has("mimeType")) { // Should be "image/png", "image/jpeg", or something handled by an extension.
4171
mime_type = dict["mimeType"];
4172
}
4173
4174
String image_name;
4175
if (dict.has("name")) {
4176
image_name = dict["name"];
4177
image_name = image_name.get_file().get_basename().validate_filename();
4178
}
4179
if (image_name.is_empty()) {
4180
image_name = itos(i);
4181
}
4182
while (used_names.has(image_name)) {
4183
image_name += "_" + itos(i);
4184
}
4185
4186
String resource_uri;
4187
4188
used_names.insert(image_name);
4189
// Load the image data. If we get a byte array, store here for later.
4190
Vector<uint8_t> data;
4191
if (dict.has("uri")) {
4192
// Handles the first two bullet points from the spec (embedded data, or external file).
4193
String uri = dict["uri"];
4194
if (uri.begins_with("data:")) { // Embedded data using base64.
4195
data = _parse_base64_uri(uri);
4196
// mimeType is optional, but if we have it defined in the URI, let's use it.
4197
if (mime_type.is_empty() && uri.contains_char(';')) {
4198
// Trim "data:" prefix which is 5 characters long, and end at ";base64".
4199
mime_type = uri.substr(5, uri.find(";base64") - 5);
4200
}
4201
} else { // Relative path to an external image file.
4202
ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER);
4203
uri = uri.uri_file_decode();
4204
uri = p_base_path.path_join(uri).replace_char('\\', '/'); // Fix for Windows.
4205
resource_uri = uri.simplify_path();
4206
// ResourceLoader will rely on the file extension to use the relevant loader.
4207
// The spec says that if mimeType is defined, it should take precedence (e.g.
4208
// there could be a `.png` image which is actually JPEG), but there's no easy
4209
// API for that in Godot, so we'd have to load as a buffer (i.e. embedded in
4210
// the material), so we only do that only as fallback.
4211
if (ResourceLoader::exists(resource_uri)) {
4212
Ref<Texture2D> texture = ResourceLoader::load(resource_uri, "Texture2D");
4213
if (texture.is_valid()) {
4214
p_state->images.push_back(texture);
4215
p_state->source_images.push_back(texture->get_image());
4216
continue;
4217
}
4218
}
4219
// mimeType is optional, but if we have it in the file extension, let's use it.
4220
// If the mimeType does not match with the file extension, either it should be
4221
// specified in the file, or the GLTFDocumentExtension should handle it.
4222
if (mime_type.is_empty()) {
4223
mime_type = "image/" + resource_uri.get_extension();
4224
}
4225
// Fallback to loading as byte array. This enables us to support the
4226
// spec's requirement that we honor mimetype regardless of file URI.
4227
data = FileAccess::get_file_as_bytes(resource_uri);
4228
if (data.is_empty()) {
4229
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, resource_uri));
4230
p_state->images.push_back(Ref<Texture2D>()); // Placeholder to keep count.
4231
p_state->source_images.push_back(Ref<Image>());
4232
continue;
4233
}
4234
}
4235
} else if (dict.has("bufferView")) {
4236
// Handles the third bullet point from the spec (bufferView).
4237
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));
4238
const GLTFBufferViewIndex bvi = dict["bufferView"];
4239
ERR_FAIL_INDEX_V(bvi, p_state->buffer_views.size(), ERR_PARAMETER_RANGE_ERROR);
4240
Ref<GLTFBufferView> bv = p_state->buffer_views[bvi];
4241
const GLTFBufferIndex bi = bv->buffer;
4242
ERR_FAIL_INDEX_V(bi, p_state->buffers.size(), ERR_PARAMETER_RANGE_ERROR);
4243
ERR_FAIL_COND_V(bv->byte_offset + bv->byte_length > p_state->buffers[bi].size(), ERR_FILE_CORRUPT);
4244
const PackedByteArray &buffer = p_state->buffers[bi];
4245
data = buffer.slice(bv->byte_offset, bv->byte_offset + bv->byte_length);
4246
}
4247
// Done loading the image data bytes. Check that we actually got data to parse.
4248
// Note: There are paths above that return early, so this point might not be reached.
4249
if (data.is_empty()) {
4250
WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded, no data found. Skipping it.", i));
4251
p_state->images.push_back(Ref<Texture2D>()); // Placeholder to keep count.
4252
p_state->source_images.push_back(Ref<Image>());
4253
continue;
4254
}
4255
// Parse the image data from bytes into an Image resource and save if needed.
4256
String file_extension;
4257
Ref<Image> img = _parse_image_bytes_into_image(p_state, data, mime_type, i, file_extension);
4258
img->set_name(image_name);
4259
_parse_image_save_image(p_state, data, resource_uri, file_extension, i, img);
4260
}
4261
4262
print_verbose("glTF: Total images: " + itos(p_state->images.size()));
4263
4264
return OK;
4265
}
4266
4267
Error GLTFDocument::_serialize_textures(Ref<GLTFState> p_state) {
4268
if (!p_state->textures.size()) {
4269
return OK;
4270
}
4271
4272
Array textures;
4273
for (int32_t i = 0; i < p_state->textures.size(); i++) {
4274
Dictionary texture_dict;
4275
Ref<GLTFTexture> gltf_texture = p_state->textures[i];
4276
if (_image_save_extension.is_valid()) {
4277
Error err = _image_save_extension->serialize_texture_json(p_state, texture_dict, gltf_texture, _image_format);
4278
ERR_FAIL_COND_V(err != OK, err);
4279
// If a fallback image format was specified, serialize another image for it.
4280
// Note: This must only be done after serializing other images to keep the indices of those consistent.
4281
if (_fallback_image_format != "None" && p_state->json.has("images")) {
4282
Array json_images = p_state->json["images"];
4283
texture_dict["source"] = json_images.size();
4284
Ref<Image> image = p_state->source_images[gltf_texture->get_src_image()];
4285
String fallback_name = _gen_unique_name(p_state, image->get_name() + "_fallback");
4286
image = image->duplicate();
4287
image->set_name(fallback_name);
4288
ERR_CONTINUE(image.is_null());
4289
if (_fallback_image_format == "PNG") {
4290
image->resize(image->get_width() * _fallback_image_quality, image->get_height() * _fallback_image_quality);
4291
}
4292
json_images.push_back(_serialize_image(p_state, image, _fallback_image_format, _fallback_image_quality, nullptr));
4293
}
4294
} else {
4295
ERR_CONTINUE(gltf_texture->get_src_image() == -1);
4296
texture_dict["source"] = gltf_texture->get_src_image();
4297
}
4298
GLTFTextureSamplerIndex sampler_index = gltf_texture->get_sampler();
4299
if (sampler_index != -1) {
4300
texture_dict["sampler"] = sampler_index;
4301
}
4302
textures.push_back(texture_dict);
4303
}
4304
p_state->json["textures"] = textures;
4305
4306
return OK;
4307
}
4308
4309
Error GLTFDocument::_parse_textures(Ref<GLTFState> p_state) {
4310
if (!p_state->json.has("textures")) {
4311
return OK;
4312
}
4313
4314
const Array &textures = p_state->json["textures"];
4315
for (GLTFTextureIndex i = 0; i < textures.size(); i++) {
4316
const Dictionary &texture_dict = textures[i];
4317
Ref<GLTFTexture> gltf_texture;
4318
gltf_texture.instantiate();
4319
// Check if any GLTFDocumentExtensions want to handle this texture JSON.
4320
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
4321
ERR_CONTINUE(ext.is_null());
4322
Error err = ext->parse_texture_json(p_state, texture_dict, gltf_texture);
4323
ERR_CONTINUE_MSG(err != OK, "glTF: Encountered error " + itos(err) + " when parsing texture JSON " + String(Variant(texture_dict)) + " in file " + p_state->filename + ". Continuing.");
4324
if (gltf_texture->get_src_image() != -1) {
4325
break;
4326
}
4327
}
4328
if (gltf_texture->get_src_image() == -1) {
4329
// No extensions handled it, so use the base glTF source.
4330
// This may be the fallback, or the only option anyway.
4331
ERR_FAIL_COND_V(!texture_dict.has("source"), ERR_PARSE_ERROR);
4332
gltf_texture->set_src_image(texture_dict["source"]);
4333
}
4334
if (gltf_texture->get_sampler() == -1 && texture_dict.has("sampler")) {
4335
gltf_texture->set_sampler(texture_dict["sampler"]);
4336
}
4337
p_state->textures.push_back(gltf_texture);
4338
}
4339
4340
return OK;
4341
}
4342
4343
GLTFTextureIndex GLTFDocument::_set_texture(Ref<GLTFState> p_state, Ref<Texture2D> p_texture, StandardMaterial3D::TextureFilter p_filter_mode, bool p_repeats) {
4344
ERR_FAIL_COND_V(p_texture.is_null(), -1);
4345
Ref<GLTFTexture> gltf_texture;
4346
gltf_texture.instantiate();
4347
ERR_FAIL_COND_V(p_texture->get_image().is_null(), -1);
4348
GLTFImageIndex gltf_src_image_i = p_state->images.find(p_texture);
4349
if (gltf_src_image_i == -1) {
4350
gltf_src_image_i = p_state->images.size();
4351
p_state->images.push_back(p_texture);
4352
p_state->source_images.push_back(p_texture->get_image());
4353
}
4354
gltf_texture->set_src_image(gltf_src_image_i);
4355
gltf_texture->set_sampler(_set_sampler_for_mode(p_state, p_filter_mode, p_repeats));
4356
GLTFTextureIndex gltf_texture_i = p_state->textures.size();
4357
p_state->textures.push_back(gltf_texture);
4358
return gltf_texture_i;
4359
}
4360
4361
Ref<Texture2D> GLTFDocument::_get_texture(Ref<GLTFState> p_state, const GLTFTextureIndex p_texture, int p_texture_types) {
4362
ERR_FAIL_COND_V_MSG(p_state->textures.is_empty(), Ref<Texture2D>(), "glTF import: Tried to read texture at index " + itos(p_texture) + ", but this glTF file does not contain any textures.");
4363
ERR_FAIL_INDEX_V(p_texture, p_state->textures.size(), Ref<Texture2D>());
4364
const GLTFImageIndex image = p_state->textures[p_texture]->get_src_image();
4365
ERR_FAIL_INDEX_V(image, p_state->images.size(), Ref<Texture2D>());
4366
if (GLTFState::GLTFHandleBinary(p_state->handle_binary_image) == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EMBED_AS_BASISU) {
4367
ERR_FAIL_INDEX_V(image, p_state->source_images.size(), Ref<Texture2D>());
4368
Ref<PortableCompressedTexture2D> portable_texture;
4369
portable_texture.instantiate();
4370
portable_texture->set_keep_compressed_buffer(true);
4371
Ref<Image> new_img = p_state->source_images[image]->duplicate();
4372
ERR_FAIL_COND_V(new_img.is_null(), Ref<Texture2D>());
4373
new_img->generate_mipmaps();
4374
if (p_texture_types) {
4375
portable_texture->create_from_image(new_img, PortableCompressedTexture2D::COMPRESSION_MODE_BASIS_UNIVERSAL, true);
4376
} else {
4377
portable_texture->create_from_image(new_img, PortableCompressedTexture2D::COMPRESSION_MODE_BASIS_UNIVERSAL, false);
4378
}
4379
p_state->images.write[image] = portable_texture;
4380
p_state->source_images.write[image] = new_img;
4381
}
4382
return p_state->images[image];
4383
}
4384
4385
GLTFTextureSamplerIndex GLTFDocument::_set_sampler_for_mode(Ref<GLTFState> p_state, StandardMaterial3D::TextureFilter p_filter_mode, bool p_repeats) {
4386
for (int i = 0; i < p_state->texture_samplers.size(); ++i) {
4387
if (p_state->texture_samplers[i]->get_filter_mode() == p_filter_mode) {
4388
return i;
4389
}
4390
}
4391
4392
GLTFTextureSamplerIndex gltf_sampler_i = p_state->texture_samplers.size();
4393
Ref<GLTFTextureSampler> gltf_sampler;
4394
gltf_sampler.instantiate();
4395
gltf_sampler->set_filter_mode(p_filter_mode);
4396
gltf_sampler->set_wrap_mode(p_repeats);
4397
p_state->texture_samplers.push_back(gltf_sampler);
4398
return gltf_sampler_i;
4399
}
4400
4401
Ref<GLTFTextureSampler> GLTFDocument::_get_sampler_for_texture(Ref<GLTFState> p_state, const GLTFTextureIndex p_texture) {
4402
ERR_FAIL_COND_V_MSG(p_state->textures.is_empty(), Ref<GLTFTextureSampler>(), "glTF import: Tried to read sampler for texture at index " + itos(p_texture) + ", but this glTF file does not contain any textures.");
4403
ERR_FAIL_INDEX_V(p_texture, p_state->textures.size(), Ref<GLTFTextureSampler>());
4404
const GLTFTextureSamplerIndex sampler = p_state->textures[p_texture]->get_sampler();
4405
4406
if (sampler == -1) {
4407
return p_state->default_texture_sampler;
4408
} else {
4409
ERR_FAIL_INDEX_V(sampler, p_state->texture_samplers.size(), Ref<GLTFTextureSampler>());
4410
4411
return p_state->texture_samplers[sampler];
4412
}
4413
}
4414
4415
Error GLTFDocument::_serialize_texture_samplers(Ref<GLTFState> p_state) {
4416
if (!p_state->texture_samplers.size()) {
4417
return OK;
4418
}
4419
4420
Array samplers;
4421
for (int32_t i = 0; i < p_state->texture_samplers.size(); ++i) {
4422
Dictionary d;
4423
Ref<GLTFTextureSampler> s = p_state->texture_samplers[i];
4424
d["magFilter"] = s->get_mag_filter();
4425
d["minFilter"] = s->get_min_filter();
4426
d["wrapS"] = s->get_wrap_s();
4427
d["wrapT"] = s->get_wrap_t();
4428
samplers.push_back(d);
4429
}
4430
p_state->json["samplers"] = samplers;
4431
4432
return OK;
4433
}
4434
4435
Error GLTFDocument::_parse_texture_samplers(Ref<GLTFState> p_state) {
4436
p_state->default_texture_sampler.instantiate();
4437
p_state->default_texture_sampler->set_min_filter(GLTFTextureSampler::FilterMode::LINEAR_MIPMAP_LINEAR);
4438
p_state->default_texture_sampler->set_mag_filter(GLTFTextureSampler::FilterMode::LINEAR);
4439
p_state->default_texture_sampler->set_wrap_s(GLTFTextureSampler::WrapMode::REPEAT);
4440
p_state->default_texture_sampler->set_wrap_t(GLTFTextureSampler::WrapMode::REPEAT);
4441
4442
if (!p_state->json.has("samplers")) {
4443
return OK;
4444
}
4445
4446
const Array &samplers = p_state->json["samplers"];
4447
for (int i = 0; i < samplers.size(); ++i) {
4448
const Dictionary &d = samplers[i];
4449
4450
Ref<GLTFTextureSampler> sampler;
4451
sampler.instantiate();
4452
4453
if (d.has("minFilter")) {
4454
sampler->set_min_filter(d["minFilter"]);
4455
} else {
4456
sampler->set_min_filter(GLTFTextureSampler::FilterMode::LINEAR_MIPMAP_LINEAR);
4457
}
4458
if (d.has("magFilter")) {
4459
sampler->set_mag_filter(d["magFilter"]);
4460
} else {
4461
sampler->set_mag_filter(GLTFTextureSampler::FilterMode::LINEAR);
4462
}
4463
4464
if (d.has("wrapS")) {
4465
sampler->set_wrap_s(d["wrapS"]);
4466
} else {
4467
sampler->set_wrap_s(GLTFTextureSampler::WrapMode::DEFAULT);
4468
}
4469
4470
if (d.has("wrapT")) {
4471
sampler->set_wrap_t(d["wrapT"]);
4472
} else {
4473
sampler->set_wrap_t(GLTFTextureSampler::WrapMode::DEFAULT);
4474
}
4475
4476
p_state->texture_samplers.push_back(sampler);
4477
}
4478
4479
return OK;
4480
}
4481
4482
Error GLTFDocument::_serialize_materials(Ref<GLTFState> p_state) {
4483
Array materials;
4484
for (int32_t i = 0; i < p_state->materials.size(); i++) {
4485
Dictionary d;
4486
Ref<Material> material = p_state->materials[i];
4487
if (material.is_null()) {
4488
materials.push_back(d);
4489
continue;
4490
}
4491
if (!material->get_name().is_empty()) {
4492
d["name"] = _gen_unique_name(p_state, material->get_name());
4493
}
4494
4495
Ref<BaseMaterial3D> base_material = material;
4496
if (base_material.is_null()) {
4497
materials.push_back(d);
4498
continue;
4499
}
4500
4501
Dictionary mr;
4502
{
4503
const Color c = base_material->get_albedo().srgb_to_linear();
4504
Array arr = { c.r, c.g, c.b, c.a };
4505
mr["baseColorFactor"] = arr;
4506
}
4507
if (_image_format != "None") {
4508
Dictionary bct;
4509
Ref<Texture2D> albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO);
4510
GLTFTextureIndex gltf_texture_index = -1;
4511
4512
if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) {
4513
albedo_texture->set_name(material->get_name() + "_albedo");
4514
gltf_texture_index = _set_texture(p_state, albedo_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
4515
}
4516
if (gltf_texture_index != -1) {
4517
bct["index"] = gltf_texture_index;
4518
Dictionary extensions = _serialize_texture_transform_uv1(material);
4519
if (!extensions.is_empty()) {
4520
bct["extensions"] = extensions;
4521
p_state->use_khr_texture_transform = true;
4522
}
4523
mr["baseColorTexture"] = bct;
4524
}
4525
}
4526
4527
mr["metallicFactor"] = base_material->get_metallic();
4528
mr["roughnessFactor"] = base_material->get_roughness();
4529
if (_image_format != "None") {
4530
bool has_roughness = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS)->get_image().is_valid();
4531
bool has_ao = base_material->get_feature(BaseMaterial3D::FEATURE_AMBIENT_OCCLUSION) && base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION).is_valid();
4532
bool has_metalness = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC)->get_image().is_valid();
4533
if (has_ao || has_roughness || has_metalness) {
4534
Dictionary mrt;
4535
Ref<Texture2D> roughness_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS);
4536
BaseMaterial3D::TextureChannel roughness_channel = base_material->get_roughness_texture_channel();
4537
Ref<Texture2D> metallic_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC);
4538
BaseMaterial3D::TextureChannel metalness_channel = base_material->get_metallic_texture_channel();
4539
Ref<Texture2D> ao_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION);
4540
BaseMaterial3D::TextureChannel ao_channel = base_material->get_ao_texture_channel();
4541
Ref<ImageTexture> orm_texture;
4542
orm_texture.instantiate();
4543
Ref<Image> orm_image;
4544
orm_image.instantiate();
4545
int32_t height = 0;
4546
int32_t width = 0;
4547
Ref<Image> ao_image;
4548
if (has_ao) {
4549
height = ao_texture->get_height();
4550
width = ao_texture->get_width();
4551
ao_image = ao_texture->get_image();
4552
Ref<ImageTexture> img_tex = ao_image;
4553
if (img_tex.is_valid()) {
4554
ao_image = img_tex->get_image();
4555
}
4556
if (ao_image->is_compressed()) {
4557
ao_image->decompress();
4558
}
4559
}
4560
Ref<Image> roughness_image;
4561
if (has_roughness) {
4562
height = roughness_texture->get_height();
4563
width = roughness_texture->get_width();
4564
roughness_image = roughness_texture->get_image();
4565
Ref<ImageTexture> img_tex = roughness_image;
4566
if (img_tex.is_valid()) {
4567
roughness_image = img_tex->get_image();
4568
}
4569
if (roughness_image->is_compressed()) {
4570
roughness_image->decompress();
4571
}
4572
}
4573
Ref<Image> metallness_image;
4574
if (has_metalness) {
4575
height = metallic_texture->get_height();
4576
width = metallic_texture->get_width();
4577
metallness_image = metallic_texture->get_image();
4578
Ref<ImageTexture> img_tex = metallness_image;
4579
if (img_tex.is_valid()) {
4580
metallness_image = img_tex->get_image();
4581
}
4582
if (metallness_image->is_compressed()) {
4583
metallness_image->decompress();
4584
}
4585
}
4586
Ref<Texture2D> albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO);
4587
if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) {
4588
height = albedo_texture->get_height();
4589
width = albedo_texture->get_width();
4590
}
4591
orm_image->initialize_data(width, height, false, Image::FORMAT_RGBA8);
4592
if (ao_image.is_valid() && ao_image->get_size() != Vector2(width, height)) {
4593
ao_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
4594
}
4595
if (roughness_image.is_valid() && roughness_image->get_size() != Vector2(width, height)) {
4596
roughness_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
4597
}
4598
if (metallness_image.is_valid() && metallness_image->get_size() != Vector2(width, height)) {
4599
metallness_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
4600
}
4601
for (int32_t h = 0; h < height; h++) {
4602
for (int32_t w = 0; w < width; w++) {
4603
Color c = Color(1.0f, 1.0f, 1.0f);
4604
if (has_ao) {
4605
if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == ao_channel) {
4606
c.r = ao_image->get_pixel(w, h).r;
4607
} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == ao_channel) {
4608
c.r = ao_image->get_pixel(w, h).g;
4609
} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == ao_channel) {
4610
c.r = ao_image->get_pixel(w, h).b;
4611
} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == ao_channel) {
4612
c.r = ao_image->get_pixel(w, h).a;
4613
}
4614
}
4615
if (has_roughness) {
4616
if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == roughness_channel) {
4617
c.g = roughness_image->get_pixel(w, h).r;
4618
} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == roughness_channel) {
4619
c.g = roughness_image->get_pixel(w, h).g;
4620
} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == roughness_channel) {
4621
c.g = roughness_image->get_pixel(w, h).b;
4622
} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == roughness_channel) {
4623
c.g = roughness_image->get_pixel(w, h).a;
4624
}
4625
}
4626
if (has_metalness) {
4627
if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == metalness_channel) {
4628
c.b = metallness_image->get_pixel(w, h).r;
4629
} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == metalness_channel) {
4630
c.b = metallness_image->get_pixel(w, h).g;
4631
} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == metalness_channel) {
4632
c.b = metallness_image->get_pixel(w, h).b;
4633
} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == metalness_channel) {
4634
c.b = metallness_image->get_pixel(w, h).a;
4635
}
4636
}
4637
orm_image->set_pixel(w, h, c);
4638
}
4639
}
4640
orm_image->generate_mipmaps();
4641
orm_texture->set_image(orm_image);
4642
GLTFTextureIndex orm_texture_index = -1;
4643
if (has_ao || has_roughness || has_metalness) {
4644
orm_texture->set_name(material->get_name() + "_orm");
4645
orm_texture_index = _set_texture(p_state, orm_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
4646
}
4647
if (has_ao) {
4648
Dictionary occt;
4649
occt["index"] = orm_texture_index;
4650
d["occlusionTexture"] = occt;
4651
}
4652
if (has_roughness || has_metalness) {
4653
mrt["index"] = orm_texture_index;
4654
Dictionary extensions = _serialize_texture_transform_uv1(material);
4655
if (!extensions.is_empty()) {
4656
mrt["extensions"] = extensions;
4657
p_state->use_khr_texture_transform = true;
4658
}
4659
mr["metallicRoughnessTexture"] = mrt;
4660
}
4661
}
4662
}
4663
4664
d["pbrMetallicRoughness"] = mr;
4665
if (base_material->get_feature(BaseMaterial3D::FEATURE_NORMAL_MAPPING) && _image_format != "None") {
4666
Dictionary nt;
4667
Ref<ImageTexture> tex;
4668
tex.instantiate();
4669
{
4670
Ref<Texture2D> normal_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_NORMAL);
4671
if (normal_texture.is_valid()) {
4672
// Code for uncompressing RG normal maps
4673
Ref<Image> img = normal_texture->get_image();
4674
if (img.is_valid()) {
4675
Ref<ImageTexture> img_tex = img;
4676
if (img_tex.is_valid()) {
4677
img = img_tex->get_image();
4678
}
4679
img->decompress();
4680
img->convert(Image::FORMAT_RGBA8);
4681
for (int32_t y = 0; y < img->get_height(); y++) {
4682
for (int32_t x = 0; x < img->get_width(); x++) {
4683
Color c = img->get_pixel(x, y);
4684
Vector2 red_green = Vector2(c.r, c.g);
4685
red_green = red_green * Vector2(2.0f, 2.0f) - Vector2(1.0f, 1.0f);
4686
float blue = 1.0f - red_green.dot(red_green);
4687
blue = MAX(0.0f, blue);
4688
c.b = Math::sqrt(blue);
4689
img->set_pixel(x, y, c);
4690
}
4691
}
4692
tex->set_image(img);
4693
}
4694
}
4695
}
4696
GLTFTextureIndex gltf_texture_index = -1;
4697
if (tex.is_valid() && tex->get_image().is_valid()) {
4698
tex->set_name(material->get_name() + "_normal");
4699
gltf_texture_index = _set_texture(p_state, tex, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
4700
}
4701
nt["scale"] = base_material->get_normal_scale();
4702
if (gltf_texture_index != -1) {
4703
nt["index"] = gltf_texture_index;
4704
d["normalTexture"] = nt;
4705
}
4706
}
4707
4708
if (base_material->get_feature(BaseMaterial3D::FEATURE_EMISSION)) {
4709
const Color c = base_material->get_emission().linear_to_srgb();
4710
Array arr = { c.r, c.g, c.b };
4711
d["emissiveFactor"] = arr;
4712
}
4713
4714
if (base_material->get_feature(BaseMaterial3D::FEATURE_EMISSION) && _image_format != "None") {
4715
Dictionary et;
4716
Ref<Texture2D> emission_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_EMISSION);
4717
GLTFTextureIndex gltf_texture_index = -1;
4718
if (emission_texture.is_valid() && emission_texture->get_image().is_valid()) {
4719
emission_texture->set_name(material->get_name() + "_emission");
4720
gltf_texture_index = _set_texture(p_state, emission_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
4721
}
4722
4723
if (gltf_texture_index != -1) {
4724
et["index"] = gltf_texture_index;
4725
d["emissiveTexture"] = et;
4726
}
4727
}
4728
4729
const bool ds = base_material->get_cull_mode() == BaseMaterial3D::CULL_DISABLED;
4730
if (ds) {
4731
d["doubleSided"] = ds;
4732
}
4733
4734
if (base_material->get_transparency() == BaseMaterial3D::TRANSPARENCY_ALPHA_SCISSOR) {
4735
d["alphaMode"] = "MASK";
4736
d["alphaCutoff"] = base_material->get_alpha_scissor_threshold();
4737
} else if (base_material->get_transparency() != BaseMaterial3D::TRANSPARENCY_DISABLED) {
4738
d["alphaMode"] = "BLEND";
4739
}
4740
4741
Dictionary extensions;
4742
if (base_material->get_shading_mode() == BaseMaterial3D::SHADING_MODE_UNSHADED) {
4743
Dictionary mat_unlit;
4744
extensions["KHR_materials_unlit"] = mat_unlit;
4745
p_state->add_used_extension("KHR_materials_unlit");
4746
}
4747
if (base_material->get_feature(BaseMaterial3D::FEATURE_EMISSION) && !Math::is_equal_approx(base_material->get_emission_energy_multiplier(), 1.0f)) {
4748
Dictionary mat_emissive_strength;
4749
mat_emissive_strength["emissiveStrength"] = base_material->get_emission_energy_multiplier();
4750
extensions["KHR_materials_emissive_strength"] = mat_emissive_strength;
4751
p_state->add_used_extension("KHR_materials_emissive_strength");
4752
}
4753
d["extensions"] = extensions;
4754
4755
_attach_meta_to_extras(material, d);
4756
materials.push_back(d);
4757
}
4758
if (!materials.size()) {
4759
return OK;
4760
}
4761
p_state->json["materials"] = materials;
4762
print_verbose("Total materials: " + itos(p_state->materials.size()));
4763
4764
return OK;
4765
}
4766
4767
Error GLTFDocument::_parse_materials(Ref<GLTFState> p_state) {
4768
if (!p_state->json.has("materials")) {
4769
return OK;
4770
}
4771
4772
const Array &materials = p_state->json["materials"];
4773
for (GLTFMaterialIndex i = 0; i < materials.size(); i++) {
4774
const Dictionary &material_dict = materials[i];
4775
4776
Ref<StandardMaterial3D> material;
4777
material.instantiate();
4778
if (material_dict.has("name") && !String(material_dict["name"]).is_empty()) {
4779
material->set_name(material_dict["name"]);
4780
} else {
4781
material->set_name(vformat("material_%s", itos(i)));
4782
}
4783
Dictionary material_extensions;
4784
if (material_dict.has("extensions")) {
4785
material_extensions = material_dict["extensions"];
4786
}
4787
4788
if (material_extensions.has("KHR_materials_unlit")) {
4789
material->set_shading_mode(BaseMaterial3D::SHADING_MODE_UNSHADED);
4790
}
4791
4792
if (material_extensions.has("KHR_materials_emissive_strength")) {
4793
Dictionary emissive_strength = material_extensions["KHR_materials_emissive_strength"];
4794
if (emissive_strength.has("emissiveStrength")) {
4795
material->set_emission_energy_multiplier(emissive_strength["emissiveStrength"]);
4796
}
4797
}
4798
4799
if (material_extensions.has("KHR_materials_pbrSpecularGlossiness")) {
4800
WARN_PRINT("Material uses a specular and glossiness workflow. Textures will be converted to roughness and metallic workflow, which may not be 100% accurate.");
4801
Dictionary sgm = material_extensions["KHR_materials_pbrSpecularGlossiness"];
4802
4803
Ref<GLTFSpecGloss> spec_gloss;
4804
spec_gloss.instantiate();
4805
if (sgm.has("diffuseTexture")) {
4806
const Dictionary &diffuse_texture_dict = sgm["diffuseTexture"];
4807
if (diffuse_texture_dict.has("index")) {
4808
Ref<GLTFTextureSampler> diffuse_sampler = _get_sampler_for_texture(p_state, diffuse_texture_dict["index"]);
4809
if (diffuse_sampler.is_valid()) {
4810
material->set_texture_filter(diffuse_sampler->get_filter_mode());
4811
material->set_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT, diffuse_sampler->get_wrap_mode());
4812
}
4813
Ref<Texture2D> diffuse_texture = _get_texture(p_state, diffuse_texture_dict["index"], TEXTURE_TYPE_GENERIC);
4814
if (diffuse_texture.is_valid()) {
4815
spec_gloss->diffuse_img = diffuse_texture->get_image();
4816
material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, diffuse_texture);
4817
}
4818
}
4819
}
4820
if (sgm.has("diffuseFactor")) {
4821
const Array &arr = sgm["diffuseFactor"];
4822
ERR_FAIL_COND_V(arr.size() != 4, ERR_PARSE_ERROR);
4823
const Color c = Color(arr[0], arr[1], arr[2], arr[3]).linear_to_srgb();
4824
spec_gloss->diffuse_factor = c;
4825
material->set_albedo(spec_gloss->diffuse_factor);
4826
}
4827
4828
if (sgm.has("specularFactor")) {
4829
const Array &arr = sgm["specularFactor"];
4830
ERR_FAIL_COND_V(arr.size() != 3, ERR_PARSE_ERROR);
4831
spec_gloss->specular_factor = Color(arr[0], arr[1], arr[2]);
4832
}
4833
4834
if (sgm.has("glossinessFactor")) {
4835
spec_gloss->gloss_factor = sgm["glossinessFactor"];
4836
material->set_roughness(1.0f - CLAMP(spec_gloss->gloss_factor, 0.0f, 1.0f));
4837
}
4838
if (sgm.has("specularGlossinessTexture")) {
4839
const Dictionary &spec_gloss_texture = sgm["specularGlossinessTexture"];
4840
if (spec_gloss_texture.has("index")) {
4841
const Ref<Texture2D> orig_texture = _get_texture(p_state, spec_gloss_texture["index"], TEXTURE_TYPE_GENERIC);
4842
if (orig_texture.is_valid()) {
4843
spec_gloss->spec_gloss_img = orig_texture->get_image();
4844
}
4845
}
4846
}
4847
spec_gloss_to_rough_metal(spec_gloss, material);
4848
4849
} else if (material_dict.has("pbrMetallicRoughness")) {
4850
const Dictionary &mr = material_dict["pbrMetallicRoughness"];
4851
if (mr.has("baseColorFactor")) {
4852
const Array &arr = mr["baseColorFactor"];
4853
ERR_FAIL_COND_V(arr.size() != 4, ERR_PARSE_ERROR);
4854
const Color c = Color(arr[0], arr[1], arr[2], arr[3]).linear_to_srgb();
4855
material->set_albedo(c);
4856
}
4857
4858
if (mr.has("baseColorTexture")) {
4859
const Dictionary &bct = mr["baseColorTexture"];
4860
if (bct.has("index")) {
4861
const GLTFTextureIndex base_color_texture_index = bct["index"];
4862
material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, _get_texture(p_state, base_color_texture_index, TEXTURE_TYPE_GENERIC));
4863
const Ref<GLTFTextureSampler> bct_sampler = _get_sampler_for_texture(p_state, base_color_texture_index);
4864
if (bct_sampler.is_valid()) {
4865
material->set_texture_filter(bct_sampler->get_filter_mode());
4866
material->set_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT, bct_sampler->get_wrap_mode());
4867
}
4868
}
4869
if (!mr.has("baseColorFactor")) {
4870
material->set_albedo(Color(1, 1, 1));
4871
}
4872
_set_texture_transform_uv1(bct, material);
4873
}
4874
4875
if (mr.has("metallicFactor")) {
4876
material->set_metallic(mr["metallicFactor"]);
4877
} else {
4878
material->set_metallic(1.0);
4879
}
4880
4881
if (mr.has("roughnessFactor")) {
4882
material->set_roughness(mr["roughnessFactor"]);
4883
} else {
4884
material->set_roughness(1.0);
4885
}
4886
4887
if (mr.has("metallicRoughnessTexture")) {
4888
const Dictionary &bct = mr["metallicRoughnessTexture"];
4889
if (bct.has("index")) {
4890
const Ref<Texture2D> t = _get_texture(p_state, bct["index"], TEXTURE_TYPE_GENERIC);
4891
material->set_texture(BaseMaterial3D::TEXTURE_METALLIC, t);
4892
material->set_metallic_texture_channel(BaseMaterial3D::TEXTURE_CHANNEL_BLUE);
4893
material->set_texture(BaseMaterial3D::TEXTURE_ROUGHNESS, t);
4894
material->set_roughness_texture_channel(BaseMaterial3D::TEXTURE_CHANNEL_GREEN);
4895
if (!mr.has("metallicFactor")) {
4896
material->set_metallic(1);
4897
}
4898
if (!mr.has("roughnessFactor")) {
4899
material->set_roughness(1);
4900
}
4901
}
4902
}
4903
}
4904
4905
if (material_dict.has("normalTexture")) {
4906
const Dictionary &bct = material_dict["normalTexture"];
4907
if (bct.has("index")) {
4908
material->set_texture(BaseMaterial3D::TEXTURE_NORMAL, _get_texture(p_state, bct["index"], TEXTURE_TYPE_NORMAL));
4909
material->set_feature(BaseMaterial3D::FEATURE_NORMAL_MAPPING, true);
4910
}
4911
if (bct.has("scale")) {
4912
material->set_normal_scale(bct["scale"]);
4913
}
4914
}
4915
if (material_dict.has("occlusionTexture")) {
4916
const Dictionary &bct = material_dict["occlusionTexture"];
4917
if (bct.has("index")) {
4918
material->set_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION, _get_texture(p_state, bct["index"], TEXTURE_TYPE_GENERIC));
4919
material->set_ao_texture_channel(BaseMaterial3D::TEXTURE_CHANNEL_RED);
4920
material->set_feature(BaseMaterial3D::FEATURE_AMBIENT_OCCLUSION, true);
4921
}
4922
}
4923
4924
if (material_dict.has("emissiveFactor")) {
4925
const Array &arr = material_dict["emissiveFactor"];
4926
ERR_FAIL_COND_V(arr.size() != 3, ERR_PARSE_ERROR);
4927
const Color c = Color(arr[0], arr[1], arr[2]).linear_to_srgb();
4928
material->set_feature(BaseMaterial3D::FEATURE_EMISSION, true);
4929
4930
material->set_emission(c);
4931
}
4932
4933
if (material_dict.has("emissiveTexture")) {
4934
const Dictionary &bct = material_dict["emissiveTexture"];
4935
if (bct.has("index")) {
4936
material->set_texture(BaseMaterial3D::TEXTURE_EMISSION, _get_texture(p_state, bct["index"], TEXTURE_TYPE_GENERIC));
4937
material->set_feature(BaseMaterial3D::FEATURE_EMISSION, true);
4938
material->set_emission(Color(0, 0, 0));
4939
}
4940
}
4941
4942
if (material_dict.has("doubleSided")) {
4943
const bool ds = material_dict["doubleSided"];
4944
if (ds) {
4945
material->set_cull_mode(BaseMaterial3D::CULL_DISABLED);
4946
}
4947
}
4948
if (material_dict.has("alphaMode")) {
4949
const String &am = material_dict["alphaMode"];
4950
if (am == "BLEND") {
4951
material->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS);
4952
} else if (am == "MASK") {
4953
material->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA_SCISSOR);
4954
}
4955
}
4956
if (material_dict.has("alphaCutoff")) {
4957
material->set_alpha_scissor_threshold(material_dict["alphaCutoff"]);
4958
} else {
4959
material->set_alpha_scissor_threshold(0.5f);
4960
}
4961
4962
if (material_dict.has("extras")) {
4963
_attach_extras_to_meta(material_dict["extras"], material);
4964
}
4965
p_state->materials.push_back(material);
4966
}
4967
4968
print_verbose("Total materials: " + itos(p_state->materials.size()));
4969
4970
return OK;
4971
}
4972
4973
void GLTFDocument::_set_texture_transform_uv1(const Dictionary &p_dict, Ref<BaseMaterial3D> p_material) {
4974
if (p_dict.has("extensions")) {
4975
const Dictionary &extensions = p_dict["extensions"];
4976
if (extensions.has("KHR_texture_transform")) {
4977
if (p_material.is_valid()) {
4978
const Dictionary &texture_transform = extensions["KHR_texture_transform"];
4979
const Array &offset_arr = texture_transform["offset"];
4980
if (offset_arr.size() == 2) {
4981
const Vector3 offset_vector3 = Vector3(offset_arr[0], offset_arr[1], 0.0f);
4982
p_material->set_uv1_offset(offset_vector3);
4983
}
4984
4985
const Array &scale_arr = texture_transform["scale"];
4986
if (scale_arr.size() == 2) {
4987
const Vector3 scale_vector3 = Vector3(scale_arr[0], scale_arr[1], 1.0f);
4988
p_material->set_uv1_scale(scale_vector3);
4989
}
4990
}
4991
}
4992
}
4993
}
4994
4995
void GLTFDocument::spec_gloss_to_rough_metal(Ref<GLTFSpecGloss> r_spec_gloss, Ref<BaseMaterial3D> p_material) {
4996
if (r_spec_gloss.is_null()) {
4997
return;
4998
}
4999
if (r_spec_gloss->spec_gloss_img.is_null()) {
5000
return;
5001
}
5002
if (r_spec_gloss->diffuse_img.is_null()) {
5003
return;
5004
}
5005
if (p_material.is_null()) {
5006
return;
5007
}
5008
bool has_roughness = false;
5009
bool has_metal = false;
5010
p_material->set_roughness(1.0f);
5011
p_material->set_metallic(1.0f);
5012
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);
5013
r_spec_gloss->spec_gloss_img->decompress();
5014
if (r_spec_gloss->diffuse_img.is_valid()) {
5015
r_spec_gloss->diffuse_img->decompress();
5016
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);
5017
r_spec_gloss->spec_gloss_img->resize(r_spec_gloss->diffuse_img->get_width(), r_spec_gloss->diffuse_img->get_height(), Image::INTERPOLATE_LANCZOS);
5018
}
5019
for (int32_t y = 0; y < r_spec_gloss->spec_gloss_img->get_height(); y++) {
5020
for (int32_t x = 0; x < r_spec_gloss->spec_gloss_img->get_width(); x++) {
5021
const Color specular_pixel = r_spec_gloss->spec_gloss_img->get_pixel(x, y).srgb_to_linear();
5022
Color specular = Color(specular_pixel.r, specular_pixel.g, specular_pixel.b);
5023
specular *= r_spec_gloss->specular_factor;
5024
Color diffuse = Color(1.0f, 1.0f, 1.0f);
5025
diffuse *= r_spec_gloss->diffuse_img->get_pixel(x, y).srgb_to_linear();
5026
float metallic = 0.0f;
5027
Color base_color;
5028
spec_gloss_to_metal_base_color(specular, diffuse, base_color, metallic);
5029
Color mr = Color(1.0f, 1.0f, 1.0f);
5030
mr.g = specular_pixel.a;
5031
mr.b = metallic;
5032
if (!Math::is_equal_approx(mr.g, 1.0f)) {
5033
has_roughness = true;
5034
}
5035
if (!Math::is_zero_approx(mr.b)) {
5036
has_metal = true;
5037
}
5038
mr.g *= r_spec_gloss->gloss_factor;
5039
mr.g = 1.0f - mr.g;
5040
rm_img->set_pixel(x, y, mr);
5041
if (r_spec_gloss->diffuse_img.is_valid()) {
5042
r_spec_gloss->diffuse_img->set_pixel(x, y, base_color.linear_to_srgb());
5043
}
5044
}
5045
}
5046
rm_img->generate_mipmaps();
5047
r_spec_gloss->diffuse_img->generate_mipmaps();
5048
p_material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, ImageTexture::create_from_image(r_spec_gloss->diffuse_img));
5049
Ref<ImageTexture> rm_image_texture = ImageTexture::create_from_image(rm_img);
5050
if (has_roughness) {
5051
p_material->set_texture(BaseMaterial3D::TEXTURE_ROUGHNESS, rm_image_texture);
5052
p_material->set_roughness_texture_channel(BaseMaterial3D::TEXTURE_CHANNEL_GREEN);
5053
}
5054
5055
if (has_metal) {
5056
p_material->set_texture(BaseMaterial3D::TEXTURE_METALLIC, rm_image_texture);
5057
p_material->set_metallic_texture_channel(BaseMaterial3D::TEXTURE_CHANNEL_BLUE);
5058
}
5059
}
5060
5061
void GLTFDocument::spec_gloss_to_metal_base_color(const Color &p_specular_factor, const Color &p_diffuse, Color &r_base_color, float &r_metallic) {
5062
const Color DIELECTRIC_SPECULAR = Color(0.04f, 0.04f, 0.04f);
5063
Color specular = Color(p_specular_factor.r, p_specular_factor.g, p_specular_factor.b);
5064
const float one_minus_specular_strength = 1.0f - get_max_component(specular);
5065
const float dielectric_specular_red = DIELECTRIC_SPECULAR.r;
5066
float brightness_diffuse = get_perceived_brightness(p_diffuse);
5067
const float brightness_specular = get_perceived_brightness(specular);
5068
r_metallic = solve_metallic(dielectric_specular_red, brightness_diffuse, brightness_specular, one_minus_specular_strength);
5069
const float one_minus_metallic = 1.0f - r_metallic;
5070
const Color base_color_from_diffuse = p_diffuse * (one_minus_specular_strength / (1.0f - dielectric_specular_red) / MAX(one_minus_metallic, CMP_EPSILON));
5071
const Color base_color_from_specular = (specular - (DIELECTRIC_SPECULAR * (one_minus_metallic))) * (1.0f / MAX(r_metallic, CMP_EPSILON));
5072
r_base_color.r = Math::lerp(base_color_from_diffuse.r, base_color_from_specular.r, r_metallic * r_metallic);
5073
r_base_color.g = Math::lerp(base_color_from_diffuse.g, base_color_from_specular.g, r_metallic * r_metallic);
5074
r_base_color.b = Math::lerp(base_color_from_diffuse.b, base_color_from_specular.b, r_metallic * r_metallic);
5075
r_base_color.a = p_diffuse.a;
5076
r_base_color = r_base_color.clamp();
5077
}
5078
Error GLTFDocument::_parse_skins(Ref<GLTFState> p_state) {
5079
if (!p_state->json.has("skins")) {
5080
return OK;
5081
}
5082
5083
const Array &skins = p_state->json["skins"];
5084
5085
// Create the base skins, and mark nodes that are joints
5086
for (int i = 0; i < skins.size(); i++) {
5087
const Dictionary &d = skins[i];
5088
5089
Ref<GLTFSkin> skin;
5090
skin.instantiate();
5091
5092
ERR_FAIL_COND_V(!d.has("joints"), ERR_PARSE_ERROR);
5093
5094
const Array &joints = d["joints"];
5095
5096
if (d.has("inverseBindMatrices")) {
5097
skin->inverse_binds = _decode_accessor_as_xform(p_state, d["inverseBindMatrices"], false);
5098
ERR_FAIL_COND_V(skin->inverse_binds.size() != joints.size(), ERR_PARSE_ERROR);
5099
}
5100
5101
for (int j = 0; j < joints.size(); j++) {
5102
const GLTFNodeIndex node = joints[j];
5103
ERR_FAIL_INDEX_V(node, p_state->nodes.size(), ERR_PARSE_ERROR);
5104
5105
skin->joints.push_back(node);
5106
skin->joints_original.push_back(node);
5107
5108
p_state->nodes.write[node]->joint = true;
5109
}
5110
5111
if (d.has("name") && !String(d["name"]).is_empty()) {
5112
skin->set_name(d["name"]);
5113
} else {
5114
skin->set_name(vformat("skin_%s", itos(i)));
5115
}
5116
5117
if (d.has("skeleton")) {
5118
skin->skin_root = d["skeleton"];
5119
}
5120
5121
p_state->skins.push_back(skin);
5122
}
5123
5124
for (GLTFSkinIndex i = 0; i < p_state->skins.size(); ++i) {
5125
Ref<GLTFSkin> skin = p_state->skins.write[i];
5126
5127
// Expand the skin to capture all the extra non-joints that lie in between the actual joints,
5128
// and expand the hierarchy to ensure multi-rooted trees lie on the same height level
5129
ERR_FAIL_COND_V(SkinTool::_expand_skin(p_state->nodes, skin), ERR_PARSE_ERROR);
5130
ERR_FAIL_COND_V(SkinTool::_verify_skin(p_state->nodes, skin), ERR_PARSE_ERROR);
5131
}
5132
5133
print_verbose("glTF: Total skins: " + itos(p_state->skins.size()));
5134
5135
return OK;
5136
}
5137
Error GLTFDocument::_serialize_skins(Ref<GLTFState> p_state) {
5138
_remove_duplicate_skins(p_state);
5139
Array json_skins;
5140
for (int skin_i = 0; skin_i < p_state->skins.size(); skin_i++) {
5141
Ref<GLTFSkin> gltf_skin = p_state->skins[skin_i];
5142
Dictionary json_skin;
5143
json_skin["inverseBindMatrices"] = _encode_accessor_as_xform(p_state, gltf_skin->inverse_binds, false);
5144
json_skin["joints"] = gltf_skin->get_joints();
5145
json_skin["name"] = gltf_skin->get_name();
5146
json_skins.push_back(json_skin);
5147
}
5148
if (!p_state->skins.size()) {
5149
return OK;
5150
}
5151
5152
p_state->json["skins"] = json_skins;
5153
return OK;
5154
}
5155
5156
Error GLTFDocument::_create_skins(Ref<GLTFState> p_state) {
5157
for (GLTFSkinIndex skin_i = 0; skin_i < p_state->skins.size(); ++skin_i) {
5158
Ref<GLTFSkin> gltf_skin = p_state->skins.write[skin_i];
5159
5160
Ref<Skin> skin;
5161
skin.instantiate();
5162
5163
// Some skins don't have IBM's! What absolute monsters!
5164
const bool has_ibms = !gltf_skin->inverse_binds.is_empty();
5165
5166
for (int joint_i = 0; joint_i < gltf_skin->joints_original.size(); ++joint_i) {
5167
GLTFNodeIndex node = gltf_skin->joints_original[joint_i];
5168
String bone_name = p_state->nodes[node]->get_name();
5169
5170
Transform3D xform;
5171
if (has_ibms) {
5172
xform = gltf_skin->inverse_binds[joint_i];
5173
}
5174
5175
if (p_state->use_named_skin_binds) {
5176
skin->add_named_bind(bone_name, xform);
5177
} else {
5178
int32_t bone_i = gltf_skin->joint_i_to_bone_i[joint_i];
5179
skin->add_bind(bone_i, xform);
5180
}
5181
}
5182
5183
gltf_skin->godot_skin = skin;
5184
}
5185
5186
// Purge the duplicates!
5187
_remove_duplicate_skins(p_state);
5188
5189
// Create unique names now, after removing duplicates
5190
for (GLTFSkinIndex skin_i = 0; skin_i < p_state->skins.size(); ++skin_i) {
5191
Ref<Skin> skin = p_state->skins.write[skin_i]->godot_skin;
5192
if (skin->get_name().is_empty()) {
5193
// Make a unique name, no gltf node represents this skin
5194
skin->set_name(_gen_unique_name(p_state, "Skin"));
5195
}
5196
}
5197
5198
return OK;
5199
}
5200
5201
bool GLTFDocument::_skins_are_same(const Ref<Skin> p_skin_a, const Ref<Skin> p_skin_b) {
5202
if (p_skin_a->get_bind_count() != p_skin_b->get_bind_count()) {
5203
return false;
5204
}
5205
5206
for (int i = 0; i < p_skin_a->get_bind_count(); ++i) {
5207
if (p_skin_a->get_bind_bone(i) != p_skin_b->get_bind_bone(i)) {
5208
return false;
5209
}
5210
if (p_skin_a->get_bind_name(i) != p_skin_b->get_bind_name(i)) {
5211
return false;
5212
}
5213
5214
Transform3D a_xform = p_skin_a->get_bind_pose(i);
5215
Transform3D b_xform = p_skin_b->get_bind_pose(i);
5216
5217
if (a_xform != b_xform) {
5218
return false;
5219
}
5220
}
5221
5222
return true;
5223
}
5224
5225
void GLTFDocument::_remove_duplicate_skins(Ref<GLTFState> p_state) {
5226
for (int i = 0; i < p_state->skins.size(); ++i) {
5227
for (int j = i + 1; j < p_state->skins.size(); ++j) {
5228
const Ref<Skin> skin_i = p_state->skins[i]->godot_skin;
5229
const Ref<Skin> skin_j = p_state->skins[j]->godot_skin;
5230
5231
if (_skins_are_same(skin_i, skin_j)) {
5232
// replace it and delete the old
5233
p_state->skins.write[j]->godot_skin = skin_i;
5234
}
5235
}
5236
}
5237
}
5238
5239
Error GLTFDocument::_serialize_lights(Ref<GLTFState> p_state) {
5240
if (p_state->lights.is_empty()) {
5241
return OK;
5242
}
5243
Array lights;
5244
for (GLTFLightIndex i = 0; i < p_state->lights.size(); i++) {
5245
lights.push_back(p_state->lights[i]->to_dictionary());
5246
}
5247
5248
Dictionary extensions;
5249
if (p_state->json.has("extensions")) {
5250
extensions = p_state->json["extensions"];
5251
} else {
5252
p_state->json["extensions"] = extensions;
5253
}
5254
Dictionary lights_punctual;
5255
extensions["KHR_lights_punctual"] = lights_punctual;
5256
lights_punctual["lights"] = lights;
5257
5258
print_verbose("glTF: Total lights: " + itos(p_state->lights.size()));
5259
5260
return OK;
5261
}
5262
5263
Error GLTFDocument::_serialize_cameras(Ref<GLTFState> p_state) {
5264
Array cameras;
5265
cameras.resize(p_state->cameras.size());
5266
for (GLTFCameraIndex i = 0; i < p_state->cameras.size(); i++) {
5267
cameras[i] = p_state->cameras[i]->to_dictionary();
5268
}
5269
5270
if (!p_state->cameras.size()) {
5271
return OK;
5272
}
5273
5274
p_state->json["cameras"] = cameras;
5275
5276
print_verbose("glTF: Total cameras: " + itos(p_state->cameras.size()));
5277
5278
return OK;
5279
}
5280
5281
Error GLTFDocument::_parse_lights(Ref<GLTFState> p_state) {
5282
if (!p_state->json.has("extensions")) {
5283
return OK;
5284
}
5285
Dictionary extensions = p_state->json["extensions"];
5286
if (!extensions.has("KHR_lights_punctual")) {
5287
return OK;
5288
}
5289
Dictionary lights_punctual = extensions["KHR_lights_punctual"];
5290
if (!lights_punctual.has("lights")) {
5291
return OK;
5292
}
5293
5294
const Array &lights = lights_punctual["lights"];
5295
5296
for (GLTFLightIndex light_i = 0; light_i < lights.size(); light_i++) {
5297
Ref<GLTFLight> light = GLTFLight::from_dictionary(lights[light_i]);
5298
if (light.is_null()) {
5299
return Error::ERR_PARSE_ERROR;
5300
}
5301
p_state->lights.push_back(light);
5302
}
5303
5304
print_verbose("glTF: Total lights: " + itos(p_state->lights.size()));
5305
5306
return OK;
5307
}
5308
5309
Error GLTFDocument::_parse_cameras(Ref<GLTFState> p_state) {
5310
if (!p_state->json.has("cameras")) {
5311
return OK;
5312
}
5313
5314
const Array cameras = p_state->json["cameras"];
5315
5316
for (GLTFCameraIndex i = 0; i < cameras.size(); i++) {
5317
p_state->cameras.push_back(GLTFCamera::from_dictionary(cameras[i]));
5318
}
5319
5320
print_verbose("glTF: Total cameras: " + itos(p_state->cameras.size()));
5321
5322
return OK;
5323
}
5324
5325
String GLTFDocument::interpolation_to_string(const GLTFAnimation::Interpolation p_interp) {
5326
String interp = "LINEAR";
5327
if (p_interp == GLTFAnimation::INTERP_STEP) {
5328
interp = "STEP";
5329
} else if (p_interp == GLTFAnimation::INTERP_LINEAR) {
5330
interp = "LINEAR";
5331
} else if (p_interp == GLTFAnimation::INTERP_CATMULLROMSPLINE) {
5332
interp = "CATMULLROMSPLINE";
5333
} else if (p_interp == GLTFAnimation::INTERP_CUBIC_SPLINE) {
5334
interp = "CUBICSPLINE";
5335
}
5336
5337
return interp;
5338
}
5339
5340
Error GLTFDocument::_serialize_animations(Ref<GLTFState> p_state) {
5341
if (!p_state->animation_players.size()) {
5342
return OK;
5343
}
5344
for (int32_t player_i = 0; player_i < p_state->animation_players.size(); player_i++) {
5345
AnimationPlayer *animation_player = p_state->animation_players[player_i];
5346
List<StringName> animations;
5347
animation_player->get_animation_list(&animations);
5348
for (const StringName &animation_name : animations) {
5349
_convert_animation(p_state, animation_player, animation_name);
5350
}
5351
}
5352
Array animations;
5353
for (GLTFAnimationIndex animation_i = 0; animation_i < p_state->animations.size(); animation_i++) {
5354
Dictionary d;
5355
Ref<GLTFAnimation> gltf_animation = p_state->animations[animation_i];
5356
if (gltf_animation->is_empty_of_tracks()) {
5357
continue;
5358
}
5359
5360
if (!gltf_animation->get_name().is_empty()) {
5361
d["name"] = gltf_animation->get_name();
5362
}
5363
Array channels;
5364
Array samplers;
5365
// Serialize glTF node tracks with the vanilla glTF animation system.
5366
for (KeyValue<int, GLTFAnimation::NodeTrack> &track_i : gltf_animation->get_node_tracks()) {
5367
GLTFAnimation::NodeTrack track = track_i.value;
5368
if (track.position_track.times.size()) {
5369
Dictionary t;
5370
t["sampler"] = samplers.size();
5371
Dictionary s;
5372
5373
s["interpolation"] = interpolation_to_string(track.position_track.interpolation);
5374
Vector<double> times = track.position_track.times;
5375
s["input"] = _encode_accessor_as_floats(p_state, times, false);
5376
Vector<Vector3> values = track.position_track.values;
5377
s["output"] = _encode_accessor_as_vec3(p_state, values, false);
5378
5379
samplers.push_back(s);
5380
5381
Dictionary target;
5382
target["path"] = "translation";
5383
target["node"] = track_i.key;
5384
5385
t["target"] = target;
5386
channels.push_back(t);
5387
}
5388
if (track.rotation_track.times.size()) {
5389
Dictionary t;
5390
t["sampler"] = samplers.size();
5391
Dictionary s;
5392
5393
s["interpolation"] = interpolation_to_string(track.rotation_track.interpolation);
5394
Vector<double> times = track.rotation_track.times;
5395
s["input"] = _encode_accessor_as_floats(p_state, times, false);
5396
Vector<Quaternion> values = track.rotation_track.values;
5397
s["output"] = _encode_accessor_as_quaternions(p_state, values, false);
5398
5399
samplers.push_back(s);
5400
5401
Dictionary target;
5402
target["path"] = "rotation";
5403
target["node"] = track_i.key;
5404
5405
t["target"] = target;
5406
channels.push_back(t);
5407
}
5408
if (track.scale_track.times.size()) {
5409
Dictionary t;
5410
t["sampler"] = samplers.size();
5411
Dictionary s;
5412
5413
s["interpolation"] = interpolation_to_string(track.scale_track.interpolation);
5414
Vector<double> times = track.scale_track.times;
5415
s["input"] = _encode_accessor_as_floats(p_state, times, false);
5416
Vector<Vector3> values = track.scale_track.values;
5417
s["output"] = _encode_accessor_as_vec3(p_state, values, false);
5418
5419
samplers.push_back(s);
5420
5421
Dictionary target;
5422
target["path"] = "scale";
5423
target["node"] = track_i.key;
5424
5425
t["target"] = target;
5426
channels.push_back(t);
5427
}
5428
if (track.weight_tracks.size()) {
5429
double length = 0.0f;
5430
5431
for (int32_t track_idx = 0; track_idx < track.weight_tracks.size(); track_idx++) {
5432
int32_t last_time_index = track.weight_tracks[track_idx].times.size() - 1;
5433
length = MAX(length, track.weight_tracks[track_idx].times[last_time_index]);
5434
}
5435
5436
Dictionary t;
5437
t["sampler"] = samplers.size();
5438
Dictionary s;
5439
Vector<double> times;
5440
const double increment = 1.0 / p_state->get_bake_fps();
5441
{
5442
double time = 0.0;
5443
bool last = false;
5444
while (true) {
5445
times.push_back(time);
5446
if (last) {
5447
break;
5448
}
5449
time += increment;
5450
if (time >= length) {
5451
last = true;
5452
time = length;
5453
}
5454
}
5455
}
5456
5457
for (int32_t track_idx = 0; track_idx < track.weight_tracks.size(); track_idx++) {
5458
double time = 0.0;
5459
bool last = false;
5460
Vector<real_t> weight_track;
5461
while (true) {
5462
float weight = _interpolate_track<real_t>(track.weight_tracks[track_idx].times,
5463
track.weight_tracks[track_idx].values,
5464
time,
5465
track.weight_tracks[track_idx].interpolation);
5466
weight_track.push_back(weight);
5467
if (last) {
5468
break;
5469
}
5470
time += increment;
5471
if (time >= length) {
5472
last = true;
5473
time = length;
5474
}
5475
}
5476
track.weight_tracks.write[track_idx].times = times;
5477
track.weight_tracks.write[track_idx].values = weight_track;
5478
}
5479
5480
Vector<double> all_track_times = times;
5481
Vector<double> all_track_values;
5482
int32_t values_size = track.weight_tracks[0].values.size();
5483
int32_t weight_tracks_size = track.weight_tracks.size();
5484
all_track_values.resize(weight_tracks_size * values_size);
5485
for (int k = 0; k < track.weight_tracks.size(); k++) {
5486
Vector<real_t> wdata = track.weight_tracks[k].values;
5487
for (int l = 0; l < wdata.size(); l++) {
5488
int32_t index = l * weight_tracks_size + k;
5489
ERR_BREAK(index >= all_track_values.size());
5490
all_track_values.write[index] = wdata.write[l];
5491
}
5492
}
5493
5494
s["interpolation"] = interpolation_to_string(track.weight_tracks[track.weight_tracks.size() - 1].interpolation);
5495
s["input"] = _encode_accessor_as_floats(p_state, all_track_times, false);
5496
s["output"] = _encode_accessor_as_floats(p_state, all_track_values, false);
5497
5498
samplers.push_back(s);
5499
5500
Dictionary target;
5501
target["path"] = "weights";
5502
target["node"] = track_i.key;
5503
5504
t["target"] = target;
5505
channels.push_back(t);
5506
}
5507
}
5508
if (!gltf_animation->get_pointer_tracks().is_empty()) {
5509
// Serialize glTF pointer tracks with the KHR_animation_pointer extension.
5510
if (!p_state->extensions_used.has("KHR_animation_pointer")) {
5511
p_state->extensions_used.push_back("KHR_animation_pointer");
5512
}
5513
for (KeyValue<String, GLTFAnimation::Channel<Variant>> &pointer_track_iter : gltf_animation->get_pointer_tracks()) {
5514
const String &json_pointer = pointer_track_iter.key;
5515
const GLTFAnimation::Channel<Variant> &pointer_track = pointer_track_iter.value;
5516
const Ref<GLTFObjectModelProperty> &obj_model_prop = p_state->object_model_properties[json_pointer];
5517
Dictionary channel;
5518
channel["sampler"] = samplers.size();
5519
Dictionary channel_target;
5520
channel_target["path"] = "pointer";
5521
Dictionary channel_target_ext;
5522
Dictionary channel_target_ext_khr_anim_ptr;
5523
channel_target_ext_khr_anim_ptr["pointer"] = json_pointer;
5524
channel_target_ext["KHR_animation_pointer"] = channel_target_ext_khr_anim_ptr;
5525
channel_target["extensions"] = channel_target_ext;
5526
channel["target"] = channel_target;
5527
channels.push_back(channel);
5528
Dictionary sampler;
5529
sampler["input"] = _encode_accessor_as_floats(p_state, pointer_track.times, false);
5530
sampler["interpolation"] = interpolation_to_string(pointer_track.interpolation);
5531
sampler["output"] = _encode_accessor_as_variant(p_state, pointer_track.values, obj_model_prop->get_variant_type(), obj_model_prop->get_accessor_type());
5532
samplers.push_back(sampler);
5533
}
5534
}
5535
if (channels.size() && samplers.size()) {
5536
d["channels"] = channels;
5537
d["samplers"] = samplers;
5538
animations.push_back(d);
5539
}
5540
}
5541
5542
if (!animations.size()) {
5543
return OK;
5544
}
5545
p_state->json["animations"] = animations;
5546
5547
print_verbose("glTF: Total animations '" + itos(p_state->animations.size()) + "'.");
5548
5549
return OK;
5550
}
5551
5552
Error GLTFDocument::_parse_animations(Ref<GLTFState> p_state) {
5553
if (!p_state->json.has("animations")) {
5554
return OK;
5555
}
5556
5557
const Array &animations = p_state->json["animations"];
5558
5559
for (GLTFAnimationIndex anim_index = 0; anim_index < animations.size(); anim_index++) {
5560
const Dictionary &anim_dict = animations[anim_index];
5561
5562
Ref<GLTFAnimation> animation;
5563
animation.instantiate();
5564
5565
if (!anim_dict.has("channels") || !anim_dict.has("samplers")) {
5566
continue;
5567
}
5568
5569
Array channels = anim_dict["channels"];
5570
Array samplers = anim_dict["samplers"];
5571
5572
if (anim_dict.has("name")) {
5573
const String anim_name = anim_dict["name"];
5574
const String anim_name_lower = anim_name.to_lower();
5575
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")) {
5576
animation->set_loop(true);
5577
}
5578
animation->set_original_name(anim_name);
5579
animation->set_name(_gen_unique_animation_name(p_state, anim_name));
5580
}
5581
5582
for (int channel_index = 0; channel_index < channels.size(); channel_index++) {
5583
const Dictionary &anim_channel = channels[channel_index];
5584
ERR_FAIL_COND_V_MSG(!anim_channel.has("sampler"), ERR_PARSE_ERROR, "glTF: Animation channel missing required 'sampler' property.");
5585
ERR_FAIL_COND_V_MSG(!anim_channel.has("target"), ERR_PARSE_ERROR, "glTF: Animation channel missing required 'target' property.");
5586
// Parse sampler.
5587
const int sampler_index = anim_channel["sampler"];
5588
ERR_FAIL_INDEX_V(sampler_index, samplers.size(), ERR_PARSE_ERROR);
5589
const Dictionary &sampler_dict = samplers[sampler_index];
5590
ERR_FAIL_COND_V(!sampler_dict.has("input"), ERR_PARSE_ERROR);
5591
ERR_FAIL_COND_V(!sampler_dict.has("output"), ERR_PARSE_ERROR);
5592
const int input_time_accessor_index = sampler_dict["input"];
5593
const int output_value_accessor_index = sampler_dict["output"];
5594
GLTFAnimation::Interpolation interp = GLTFAnimation::INTERP_LINEAR;
5595
int output_count = 1;
5596
if (sampler_dict.has("interpolation")) {
5597
const String &in = sampler_dict["interpolation"];
5598
if (in == "STEP") {
5599
interp = GLTFAnimation::INTERP_STEP;
5600
} else if (in == "LINEAR") {
5601
interp = GLTFAnimation::INTERP_LINEAR;
5602
} else if (in == "CATMULLROMSPLINE") {
5603
interp = GLTFAnimation::INTERP_CATMULLROMSPLINE;
5604
output_count = 3;
5605
} else if (in == "CUBICSPLINE") {
5606
interp = GLTFAnimation::INTERP_CUBIC_SPLINE;
5607
output_count = 3;
5608
}
5609
}
5610
const Vector<double> times = _decode_accessor(p_state, input_time_accessor_index, false);
5611
// Parse target.
5612
const Dictionary &anim_target = anim_channel["target"];
5613
ERR_FAIL_COND_V_MSG(!anim_target.has("path"), ERR_PARSE_ERROR, "glTF: Animation channel target missing required 'path' property.");
5614
String path = anim_target["path"];
5615
if (path == "pointer") {
5616
ERR_FAIL_COND_V(!anim_target.has("extensions"), ERR_PARSE_ERROR);
5617
Dictionary target_extensions = anim_target["extensions"];
5618
ERR_FAIL_COND_V(!target_extensions.has("KHR_animation_pointer"), ERR_PARSE_ERROR);
5619
Dictionary khr_anim_ptr = target_extensions["KHR_animation_pointer"];
5620
ERR_FAIL_COND_V(!khr_anim_ptr.has("pointer"), ERR_PARSE_ERROR);
5621
String anim_json_ptr = khr_anim_ptr["pointer"];
5622
_parse_animation_pointer(p_state, anim_json_ptr, animation, interp, times, output_value_accessor_index);
5623
} else {
5624
// If it's not a pointer, it's a regular animation channel from vanilla glTF (pos/rot/scale/weights).
5625
if (!anim_target.has("node")) {
5626
WARN_PRINT("glTF: Animation channel target missing 'node' property. Ignoring this channel.");
5627
continue;
5628
}
5629
5630
GLTFNodeIndex node = anim_target["node"];
5631
5632
ERR_FAIL_INDEX_V(node, p_state->nodes.size(), ERR_PARSE_ERROR);
5633
5634
GLTFAnimation::NodeTrack *track = nullptr;
5635
5636
if (!animation->get_node_tracks().has(node)) {
5637
animation->get_node_tracks()[node] = GLTFAnimation::NodeTrack();
5638
}
5639
5640
track = &animation->get_node_tracks()[node];
5641
5642
if (path == "translation") {
5643
const Vector<Vector3> positions = _decode_accessor_as_vec3(p_state, output_value_accessor_index, false);
5644
track->position_track.interpolation = interp;
5645
track->position_track.times = times;
5646
track->position_track.values = positions;
5647
} else if (path == "rotation") {
5648
const Vector<Quaternion> rotations = _decode_accessor_as_quaternion(p_state, output_value_accessor_index, false);
5649
track->rotation_track.interpolation = interp;
5650
track->rotation_track.times = times;
5651
track->rotation_track.values = rotations;
5652
} else if (path == "scale") {
5653
const Vector<Vector3> scales = _decode_accessor_as_vec3(p_state, output_value_accessor_index, false);
5654
track->scale_track.interpolation = interp;
5655
track->scale_track.times = times;
5656
track->scale_track.values = scales;
5657
} else if (path == "weights") {
5658
const Vector<float> weights = _decode_accessor_as_floats(p_state, output_value_accessor_index, false);
5659
5660
ERR_FAIL_INDEX_V(p_state->nodes[node]->mesh, p_state->meshes.size(), ERR_PARSE_ERROR);
5661
Ref<GLTFMesh> mesh = p_state->meshes[p_state->nodes[node]->mesh];
5662
const int wc = mesh->get_blend_weights().size();
5663
ERR_CONTINUE_MSG(wc == 0, "glTF: Animation tried to animate weights, but mesh has no weights.");
5664
5665
track->weight_tracks.resize(wc);
5666
5667
const int expected_value_count = times.size() * output_count * wc;
5668
ERR_CONTINUE_MSG(weights.size() != expected_value_count, "Invalid weight data, expected " + itos(expected_value_count) + " weight values, got " + itos(weights.size()) + " instead.");
5669
5670
const int wlen = weights.size() / wc;
5671
for (int k = 0; k < wc; k++) { //separate tracks, having them together is not such a good idea
5672
GLTFAnimation::Channel<real_t> cf;
5673
cf.interpolation = interp;
5674
cf.times = Variant(times);
5675
Vector<real_t> wdata;
5676
wdata.resize(wlen);
5677
for (int l = 0; l < wlen; l++) {
5678
wdata.write[l] = weights[l * wc + k];
5679
}
5680
5681
cf.values = wdata;
5682
track->weight_tracks.write[k] = cf;
5683
}
5684
} else {
5685
WARN_PRINT("Invalid path '" + path + "'.");
5686
}
5687
}
5688
}
5689
5690
p_state->animations.push_back(animation);
5691
}
5692
5693
print_verbose("glTF: Total animations '" + itos(p_state->animations.size()) + "'.");
5694
5695
return OK;
5696
}
5697
5698
void GLTFDocument::_parse_animation_pointer(Ref<GLTFState> p_state, const String &p_animation_json_pointer, const Ref<GLTFAnimation> p_gltf_animation, const GLTFAnimation::Interpolation p_interp, const Vector<double> &p_times, const int p_output_value_accessor_index) {
5699
// Special case: Convert TRS animation pointers to node track pos/rot/scale.
5700
// This is required to handle skeleton bones, and improves performance for regular nodes.
5701
// Mark this as unlikely because TRS animation pointers are not recommended,
5702
// since vanilla glTF animations can already animate TRS properties directly.
5703
// But having this code exist is required to be spec-compliant and handle all test files.
5704
// Note that TRS still needs to be handled in the general case as well, for KHR_interactivity.
5705
const PackedStringArray split = p_animation_json_pointer.split("/", false, 3);
5706
if (unlikely(split.size() == 3 && split[0] == "nodes" && (split[2] == "translation" || split[2] == "rotation" || split[2] == "scale" || split[2] == "matrix" || split[2] == "weights"))) {
5707
const GLTFNodeIndex node_index = split[1].to_int();
5708
HashMap<int, GLTFAnimation::NodeTrack> &node_tracks = p_gltf_animation->get_node_tracks();
5709
if (!node_tracks.has(node_index)) {
5710
node_tracks[node_index] = GLTFAnimation::NodeTrack();
5711
}
5712
GLTFAnimation::NodeTrack *track = &node_tracks[node_index];
5713
if (split[2] == "translation") {
5714
const Vector<Vector3> positions = _decode_accessor_as_vec3(p_state, p_output_value_accessor_index, false);
5715
track->position_track.interpolation = p_interp;
5716
track->position_track.times = p_times;
5717
track->position_track.values = positions;
5718
} else if (split[2] == "rotation") {
5719
const Vector<Quaternion> rotations = _decode_accessor_as_quaternion(p_state, p_output_value_accessor_index, false);
5720
track->rotation_track.interpolation = p_interp;
5721
track->rotation_track.times = p_times;
5722
track->rotation_track.values = rotations;
5723
} else if (split[2] == "scale") {
5724
const Vector<Vector3> scales = _decode_accessor_as_vec3(p_state, p_output_value_accessor_index, false);
5725
track->scale_track.interpolation = p_interp;
5726
track->scale_track.times = p_times;
5727
track->scale_track.values = scales;
5728
} else if (split[2] == "matrix") {
5729
const Vector<Transform3D> transforms = _decode_accessor_as_xform(p_state, p_output_value_accessor_index, false);
5730
track->position_track.interpolation = p_interp;
5731
track->position_track.times = p_times;
5732
track->position_track.values.resize(transforms.size());
5733
track->rotation_track.interpolation = p_interp;
5734
track->rotation_track.times = p_times;
5735
track->rotation_track.values.resize(transforms.size());
5736
track->scale_track.interpolation = p_interp;
5737
track->scale_track.times = p_times;
5738
track->scale_track.values.resize(transforms.size());
5739
for (int i = 0; i < transforms.size(); i++) {
5740
track->position_track.values.write[i] = transforms[i].get_origin();
5741
track->rotation_track.values.write[i] = transforms[i].basis.get_rotation_quaternion();
5742
track->scale_track.values.write[i] = transforms[i].basis.get_scale();
5743
}
5744
} else { // if (split[2] == "weights")
5745
const Vector<float> accessor_weights = _decode_accessor_as_floats(p_state, p_output_value_accessor_index, false);
5746
const GLTFMeshIndex mesh_index = p_state->nodes[node_index]->mesh;
5747
ERR_FAIL_INDEX(mesh_index, p_state->meshes.size());
5748
const Ref<GLTFMesh> gltf_mesh = p_state->meshes[mesh_index];
5749
const Vector<float> &blend_weights = gltf_mesh->get_blend_weights();
5750
const int blend_weight_count = gltf_mesh->get_blend_weights().size();
5751
const int anim_weights_size = accessor_weights.size();
5752
// For example, if a mesh has 2 blend weights, and the accessor provides 10 values, then there are 5 frames of animation, each with 2 blend weights.
5753
ERR_FAIL_COND_MSG(blend_weight_count == 0 || ((anim_weights_size % blend_weight_count) != 0), "glTF: Cannot apply " + itos(accessor_weights.size()) + " weights to a mesh with " + itos(blend_weights.size()) + " blend weights.");
5754
const int frame_count = anim_weights_size / blend_weight_count;
5755
track->weight_tracks.resize(blend_weight_count);
5756
for (int blend_weight_index = 0; blend_weight_index < blend_weight_count; blend_weight_index++) {
5757
GLTFAnimation::Channel<real_t> weight_track;
5758
weight_track.interpolation = p_interp;
5759
weight_track.times = p_times;
5760
weight_track.values.resize(frame_count);
5761
for (int frame_index = 0; frame_index < frame_count; frame_index++) {
5762
// For example, if a mesh has 2 blend weights, and the accessor provides 10 values,
5763
// then the first frame has indices [0, 1], the second frame has [2, 3], and so on.
5764
// Here we process all frames of one blend weight, so we want [0, 2, 4, 6, 8] or [1, 3, 5, 7, 9].
5765
// For the fist one we calculate 0 * 2 + 0, 1 * 2 + 0, 2 * 2 + 0, etc, then for the second 0 * 2 + 1, 1 * 2 + 1, 2 * 2 + 1, etc.
5766
weight_track.values.write[frame_index] = accessor_weights[frame_index * blend_weight_count + blend_weight_index];
5767
}
5768
track->weight_tracks.write[blend_weight_index] = weight_track;
5769
}
5770
}
5771
// The special case was handled, return to skip the general case.
5772
return;
5773
}
5774
// General case: Convert animation pointers to Variant value pointer tracks.
5775
Ref<GLTFObjectModelProperty> obj_model_prop = import_object_model_property(p_state, p_animation_json_pointer);
5776
if (obj_model_prop.is_null() || !obj_model_prop->has_node_paths()) {
5777
// Exit quietly, `import_object_model_property` already prints a warning if the property is not found.
5778
return;
5779
}
5780
HashMap<String, GLTFAnimation::Channel<Variant>> &anim_ptr_map = p_gltf_animation->get_pointer_tracks();
5781
GLTFAnimation::Channel<Variant> channel;
5782
channel.interpolation = p_interp;
5783
channel.times = p_times;
5784
channel.values = _decode_accessor_as_variant(p_state, p_output_value_accessor_index, obj_model_prop->get_variant_type(), obj_model_prop->get_accessor_type());
5785
anim_ptr_map[p_animation_json_pointer] = channel;
5786
}
5787
5788
void GLTFDocument::_assign_node_names(Ref<GLTFState> p_state) {
5789
for (int i = 0; i < p_state->nodes.size(); i++) {
5790
Ref<GLTFNode> gltf_node = p_state->nodes[i];
5791
// Any joints get unique names generated when the skeleton is made, unique to the skeleton
5792
if (gltf_node->skeleton >= 0) {
5793
continue;
5794
}
5795
String gltf_node_name = gltf_node->get_name();
5796
if (gltf_node_name.is_empty()) {
5797
if (_naming_version == 0) {
5798
if (gltf_node->mesh >= 0) {
5799
gltf_node_name = _gen_unique_name(p_state, "Mesh");
5800
} else if (gltf_node->camera >= 0) {
5801
gltf_node_name = _gen_unique_name(p_state, "Camera3D");
5802
} else {
5803
gltf_node_name = _gen_unique_name(p_state, "Node");
5804
}
5805
} else {
5806
if (gltf_node->mesh >= 0) {
5807
gltf_node_name = "Mesh";
5808
} else if (gltf_node->camera >= 0) {
5809
gltf_node_name = "Camera";
5810
} else {
5811
gltf_node_name = "Node";
5812
}
5813
}
5814
}
5815
gltf_node->set_name(_gen_unique_name(p_state, gltf_node_name));
5816
}
5817
}
5818
5819
BoneAttachment3D *GLTFDocument::_generate_bone_attachment(Skeleton3D *p_godot_skeleton, const Ref<GLTFNode> &p_bone_node) {
5820
BoneAttachment3D *bone_attachment = memnew(BoneAttachment3D);
5821
print_verbose("glTF: Creating bone attachment for: " + p_bone_node->get_name());
5822
bone_attachment->set_name(p_bone_node->get_name());
5823
p_godot_skeleton->add_child(bone_attachment, true);
5824
bone_attachment->set_bone_name(p_bone_node->get_name());
5825
return bone_attachment;
5826
}
5827
5828
BoneAttachment3D *GLTFDocument::_generate_bone_attachment_compat_4pt4(Ref<GLTFState> p_state, Skeleton3D *p_skeleton, const GLTFNodeIndex p_node_index, const GLTFNodeIndex p_bone_index) {
5829
Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
5830
Ref<GLTFNode> bone_node = p_state->nodes[p_bone_index];
5831
BoneAttachment3D *bone_attachment = memnew(BoneAttachment3D);
5832
print_verbose("glTF: Creating bone attachment for: " + gltf_node->get_name());
5833
5834
ERR_FAIL_COND_V(!bone_node->joint, nullptr);
5835
5836
bone_attachment->set_bone_name(bone_node->get_name());
5837
5838
return bone_attachment;
5839
}
5840
5841
GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref<GLTFState> p_state, MeshInstance3D *p_mesh_instance) {
5842
ERR_FAIL_NULL_V(p_mesh_instance, -1);
5843
ERR_FAIL_COND_V_MSG(p_mesh_instance->get_mesh().is_null(), -1, "glTF: Tried to export a MeshInstance3D node named " + p_mesh_instance->get_name() + ", but it has no mesh. This node will be exported without a mesh.");
5844
Ref<Mesh> mesh_resource = p_mesh_instance->get_mesh();
5845
ERR_FAIL_COND_V_MSG(mesh_resource->get_surface_count() == 0, -1, "glTF: Tried to export a MeshInstance3D node named " + p_mesh_instance->get_name() + ", but its mesh has no surfaces. This node will be exported without a mesh.");
5846
TypedArray<Material> instance_materials;
5847
for (int32_t surface_i = 0; surface_i < mesh_resource->get_surface_count(); surface_i++) {
5848
Ref<Material> mat = p_mesh_instance->get_active_material(surface_i);
5849
instance_materials.append(mat);
5850
}
5851
Ref<ImporterMesh> current_mesh = _mesh_to_importer_mesh(mesh_resource);
5852
Vector<float> blend_weights;
5853
int32_t blend_count = mesh_resource->get_blend_shape_count();
5854
blend_weights.resize(blend_count);
5855
for (int32_t blend_i = 0; blend_i < blend_count; blend_i++) {
5856
blend_weights.write[blend_i] = 0.0f;
5857
}
5858
5859
Ref<GLTFMesh> gltf_mesh;
5860
gltf_mesh.instantiate();
5861
gltf_mesh->set_instance_materials(instance_materials);
5862
gltf_mesh->set_mesh(current_mesh);
5863
gltf_mesh->set_blend_weights(blend_weights);
5864
GLTFMeshIndex mesh_i = p_state->meshes.size();
5865
p_state->meshes.push_back(gltf_mesh);
5866
return mesh_i;
5867
}
5868
5869
ImporterMeshInstance3D *GLTFDocument::_generate_mesh_instance(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index) {
5870
Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
5871
5872
ERR_FAIL_INDEX_V(gltf_node->mesh, p_state->meshes.size(), nullptr);
5873
5874
ImporterMeshInstance3D *mi = memnew(ImporterMeshInstance3D);
5875
print_verbose("glTF: Creating mesh for: " + gltf_node->get_name());
5876
5877
p_state->scene_mesh_instances.insert(p_node_index, mi);
5878
Ref<GLTFMesh> mesh = p_state->meshes.write[gltf_node->mesh];
5879
if (mesh.is_null()) {
5880
return mi;
5881
}
5882
Ref<ImporterMesh> import_mesh = mesh->get_mesh();
5883
if (import_mesh.is_null()) {
5884
return mi;
5885
}
5886
mi->set_mesh(import_mesh);
5887
import_mesh->merge_meta_from(*mesh);
5888
return mi;
5889
}
5890
5891
Light3D *GLTFDocument::_generate_light(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index) {
5892
Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
5893
5894
ERR_FAIL_INDEX_V(gltf_node->light, p_state->lights.size(), nullptr);
5895
5896
print_verbose("glTF: Creating light for: " + gltf_node->get_name());
5897
5898
Ref<GLTFLight> l = p_state->lights[gltf_node->light];
5899
return l->to_node();
5900
}
5901
5902
Camera3D *GLTFDocument::_generate_camera(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index) {
5903
Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
5904
5905
ERR_FAIL_INDEX_V(gltf_node->camera, p_state->cameras.size(), nullptr);
5906
5907
print_verbose("glTF: Creating camera for: " + gltf_node->get_name());
5908
5909
Ref<GLTFCamera> c = p_state->cameras[gltf_node->camera];
5910
return c->to_node();
5911
}
5912
5913
GLTFCameraIndex GLTFDocument::_convert_camera(Ref<GLTFState> p_state, Camera3D *p_camera) {
5914
print_verbose("glTF: Converting camera: " + p_camera->get_name());
5915
5916
Ref<GLTFCamera> c = GLTFCamera::from_node(p_camera);
5917
GLTFCameraIndex camera_index = p_state->cameras.size();
5918
p_state->cameras.push_back(c);
5919
return camera_index;
5920
}
5921
5922
GLTFLightIndex GLTFDocument::_convert_light(Ref<GLTFState> p_state, Light3D *p_light) {
5923
print_verbose("glTF: Converting light: " + p_light->get_name());
5924
5925
Ref<GLTFLight> l = GLTFLight::from_node(p_light);
5926
5927
GLTFLightIndex light_index = p_state->lights.size();
5928
p_state->lights.push_back(l);
5929
return light_index;
5930
}
5931
5932
void GLTFDocument::_convert_spatial(Ref<GLTFState> p_state, Node3D *p_spatial, Ref<GLTFNode> p_node) {
5933
p_node->transform = p_spatial->get_transform();
5934
}
5935
5936
Node3D *GLTFDocument::_generate_spatial(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index) {
5937
Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
5938
5939
Node3D *spatial = memnew(Node3D);
5940
print_verbose("glTF: Converting spatial: " + gltf_node->get_name());
5941
5942
return spatial;
5943
}
5944
5945
void GLTFDocument::_convert_scene_node(Ref<GLTFState> p_state, Node *p_current, const GLTFNodeIndex p_gltf_parent, const GLTFNodeIndex p_gltf_root) {
5946
#ifdef TOOLS_ENABLED
5947
if (Engine::get_singleton()->is_editor_hint() && p_gltf_root != -1 && p_current->get_owner() == nullptr) {
5948
WARN_VERBOSE("glTF export warning: Node '" + p_current->get_name() + "' has no owner. This is likely a temporary node generated by a @tool script. This would not be saved when saving the Godot scene, therefore it will not be exported to glTF.");
5949
return;
5950
}
5951
#endif // TOOLS_ENABLED
5952
Ref<GLTFNode> gltf_node;
5953
gltf_node.instantiate();
5954
if (p_current->has_method("is_visible")) {
5955
bool visible = p_current->call("is_visible");
5956
if (!visible && _visibility_mode == VISIBILITY_MODE_EXCLUDE) {
5957
return;
5958
}
5959
gltf_node->visible = visible;
5960
}
5961
gltf_node->set_original_name(p_current->get_name());
5962
gltf_node->set_name(_gen_unique_name(p_state, p_current->get_name()));
5963
gltf_node->merge_meta_from(p_current);
5964
if (Object::cast_to<Node3D>(p_current)) {
5965
Node3D *spatial = Object::cast_to<Node3D>(p_current);
5966
_convert_spatial(p_state, spatial, gltf_node);
5967
}
5968
if (Object::cast_to<MeshInstance3D>(p_current)) {
5969
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_current);
5970
_convert_mesh_instance_to_gltf(mi, p_state, gltf_node);
5971
} else if (Object::cast_to<BoneAttachment3D>(p_current)) {
5972
BoneAttachment3D *bone = Object::cast_to<BoneAttachment3D>(p_current);
5973
_convert_bone_attachment_to_gltf(bone, p_state, p_gltf_parent, p_gltf_root, gltf_node);
5974
return;
5975
} else if (Object::cast_to<Skeleton3D>(p_current)) {
5976
Skeleton3D *skel = Object::cast_to<Skeleton3D>(p_current);
5977
_convert_skeleton_to_gltf(skel, p_state, p_gltf_parent, p_gltf_root, gltf_node);
5978
// We ignore the Godot Engine node that is the skeleton.
5979
return;
5980
} else if (Object::cast_to<MultiMeshInstance3D>(p_current)) {
5981
MultiMeshInstance3D *multi = Object::cast_to<MultiMeshInstance3D>(p_current);
5982
_convert_multi_mesh_instance_to_gltf(multi, p_gltf_parent, p_gltf_root, gltf_node, p_state);
5983
#ifdef MODULE_CSG_ENABLED
5984
} else if (Object::cast_to<CSGShape3D>(p_current)) {
5985
CSGShape3D *shape = Object::cast_to<CSGShape3D>(p_current);
5986
if (shape->get_parent() && shape->is_root_shape()) {
5987
_convert_csg_shape_to_gltf(shape, p_gltf_parent, gltf_node, p_state);
5988
}
5989
#endif // MODULE_CSG_ENABLED
5990
#ifdef MODULE_GRIDMAP_ENABLED
5991
} else if (Object::cast_to<GridMap>(p_current)) {
5992
GridMap *gridmap = Object::cast_to<GridMap>(p_current);
5993
_convert_grid_map_to_gltf(gridmap, p_gltf_parent, p_gltf_root, gltf_node, p_state);
5994
#endif // MODULE_GRIDMAP_ENABLED
5995
} else if (Object::cast_to<Camera3D>(p_current)) {
5996
Camera3D *camera = Object::cast_to<Camera3D>(p_current);
5997
_convert_camera_to_gltf(camera, p_state, gltf_node);
5998
} else if (Object::cast_to<Light3D>(p_current)) {
5999
Light3D *light = Object::cast_to<Light3D>(p_current);
6000
_convert_light_to_gltf(light, p_state, gltf_node);
6001
} else if (Object::cast_to<AnimationPlayer>(p_current)) {
6002
AnimationPlayer *animation_player = Object::cast_to<AnimationPlayer>(p_current);
6003
p_state->animation_players.push_back(animation_player);
6004
if (animation_player->get_child_count() == 0) {
6005
gltf_node->set_parent(-2); // Don't export AnimationPlayer nodes as glTF nodes (unless they have children).
6006
}
6007
}
6008
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
6009
ERR_CONTINUE(ext.is_null());
6010
ext->convert_scene_node(p_state, gltf_node, p_current);
6011
}
6012
GLTFNodeIndex current_node_i;
6013
if (gltf_node->get_parent() == -1) {
6014
current_node_i = p_state->append_gltf_node(gltf_node, p_current, p_gltf_parent);
6015
} else if (gltf_node->get_parent() < -1) {
6016
return;
6017
} else {
6018
current_node_i = p_state->nodes.size() - 1;
6019
while (gltf_node != p_state->nodes[current_node_i]) {
6020
current_node_i--;
6021
}
6022
}
6023
const GLTFNodeIndex gltf_root = (p_gltf_root == -1) ? current_node_i : p_gltf_root;
6024
for (int node_i = 0; node_i < p_current->get_child_count(); node_i++) {
6025
_convert_scene_node(p_state, p_current->get_child(node_i), current_node_i, gltf_root);
6026
}
6027
}
6028
6029
void GLTFDocument::_convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> p_gltf_node, Ref<GLTFState> p_state) {
6030
#ifndef MODULE_CSG_ENABLED
6031
ERR_FAIL_MSG("csg module is disabled.");
6032
#else
6033
CSGShape3D *csg = p_current;
6034
csg->update_shape();
6035
Array meshes = csg->get_meshes();
6036
if (meshes.size() != 2) {
6037
return;
6038
}
6039
6040
Ref<ImporterMesh> mesh;
6041
mesh.instantiate();
6042
{
6043
Ref<ArrayMesh> csg_mesh = csg->get_meshes()[1];
6044
for (int32_t surface_i = 0; surface_i < csg_mesh->get_surface_count(); surface_i++) {
6045
Array array = csg_mesh->surface_get_arrays(surface_i);
6046
6047
Ref<Material> mat;
6048
6049
Ref<Material> mat_override = csg->get_material_override();
6050
if (mat_override.is_valid()) {
6051
mat = mat_override;
6052
}
6053
6054
Ref<Material> mat_surface_override = csg_mesh->surface_get_material(surface_i);
6055
if (mat_surface_override.is_valid() && mat.is_null()) {
6056
mat = mat_surface_override;
6057
}
6058
6059
String mat_name;
6060
if (mat.is_valid()) {
6061
mat_name = mat->get_name();
6062
} else {
6063
// Assign default material when no material is assigned.
6064
mat.instantiate();
6065
}
6066
6067
mesh->add_surface(csg_mesh->surface_get_primitive_type(surface_i),
6068
array, csg_mesh->surface_get_blend_shape_arrays(surface_i), csg_mesh->surface_get_lods(surface_i), mat,
6069
mat_name, csg_mesh->surface_get_format(surface_i));
6070
}
6071
}
6072
6073
Ref<GLTFMesh> gltf_mesh;
6074
gltf_mesh.instantiate();
6075
gltf_mesh->set_mesh(mesh);
6076
gltf_mesh->set_original_name(csg->get_name());
6077
GLTFMeshIndex mesh_i = p_state->meshes.size();
6078
p_state->meshes.push_back(gltf_mesh);
6079
p_gltf_node->mesh = mesh_i;
6080
p_gltf_node->transform = csg->get_transform();
6081
p_gltf_node->set_original_name(csg->get_name());
6082
p_gltf_node->set_name(_gen_unique_name(p_state, csg->get_name()));
6083
#endif // MODULE_CSG_ENABLED
6084
}
6085
6086
void GLTFDocument::_convert_camera_to_gltf(Camera3D *camera, Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node) {
6087
ERR_FAIL_NULL(camera);
6088
GLTFCameraIndex camera_index = _convert_camera(p_state, camera);
6089
if (camera_index != -1) {
6090
p_gltf_node->camera = camera_index;
6091
}
6092
}
6093
6094
void GLTFDocument::_convert_light_to_gltf(Light3D *light, Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node) {
6095
ERR_FAIL_NULL(light);
6096
GLTFLightIndex light_index = _convert_light(p_state, light);
6097
if (light_index != -1) {
6098
p_gltf_node->light = light_index;
6099
}
6100
}
6101
6102
void 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) {
6103
#ifndef MODULE_GRIDMAP_ENABLED
6104
ERR_FAIL_MSG("gridmap module is disabled.");
6105
#else
6106
Array cells = p_grid_map->get_used_cells();
6107
for (int32_t k = 0; k < cells.size(); k++) {
6108
GLTFNode *new_gltf_node = memnew(GLTFNode);
6109
p_gltf_node->children.push_back(p_state->nodes.size());
6110
p_state->nodes.push_back(new_gltf_node);
6111
Vector3 cell_location = cells[k];
6112
int32_t cell = p_grid_map->get_cell_item(
6113
Vector3(cell_location.x, cell_location.y, cell_location.z));
6114
Transform3D cell_xform;
6115
cell_xform.basis = p_grid_map->get_basis_with_orthogonal_index(
6116
p_grid_map->get_cell_item_orientation(
6117
Vector3(cell_location.x, cell_location.y, cell_location.z)));
6118
cell_xform.basis.scale(Vector3(p_grid_map->get_cell_scale(),
6119
p_grid_map->get_cell_scale(),
6120
p_grid_map->get_cell_scale()));
6121
cell_xform.set_origin(p_grid_map->map_to_local(
6122
Vector3(cell_location.x, cell_location.y, cell_location.z)));
6123
Ref<GLTFMesh> gltf_mesh;
6124
gltf_mesh.instantiate();
6125
gltf_mesh->set_mesh(_mesh_to_importer_mesh(p_grid_map->get_mesh_library()->get_item_mesh(cell)));
6126
gltf_mesh->set_original_name(p_grid_map->get_mesh_library()->get_item_name(cell));
6127
new_gltf_node->mesh = p_state->meshes.size();
6128
p_state->meshes.push_back(gltf_mesh);
6129
new_gltf_node->transform = cell_xform * p_grid_map->get_transform();
6130
new_gltf_node->set_original_name(p_grid_map->get_mesh_library()->get_item_name(cell));
6131
new_gltf_node->set_name(_gen_unique_name(p_state, p_grid_map->get_mesh_library()->get_item_name(cell)));
6132
}
6133
#endif // MODULE_GRIDMAP_ENABLED
6134
}
6135
6136
void GLTFDocument::_convert_multi_mesh_instance_to_gltf(
6137
MultiMeshInstance3D *p_multi_mesh_instance,
6138
GLTFNodeIndex p_parent_node_index,
6139
GLTFNodeIndex p_root_node_index,
6140
Ref<GLTFNode> p_gltf_node, Ref<GLTFState> p_state) {
6141
ERR_FAIL_NULL(p_multi_mesh_instance);
6142
Ref<MultiMesh> multi_mesh = p_multi_mesh_instance->get_multimesh();
6143
if (multi_mesh.is_null()) {
6144
return;
6145
}
6146
Ref<GLTFMesh> gltf_mesh;
6147
gltf_mesh.instantiate();
6148
Ref<Mesh> mesh = multi_mesh->get_mesh();
6149
if (mesh.is_null()) {
6150
return;
6151
}
6152
gltf_mesh->set_original_name(multi_mesh->get_name());
6153
gltf_mesh->set_name(multi_mesh->get_name());
6154
Ref<ImporterMesh> importer_mesh;
6155
importer_mesh.instantiate();
6156
Ref<ArrayMesh> array_mesh = multi_mesh->get_mesh();
6157
if (array_mesh.is_valid()) {
6158
importer_mesh->set_blend_shape_mode(array_mesh->get_blend_shape_mode());
6159
for (int32_t blend_i = 0; blend_i < array_mesh->get_blend_shape_count(); blend_i++) {
6160
importer_mesh->add_blend_shape(array_mesh->get_blend_shape_name(blend_i));
6161
}
6162
}
6163
for (int32_t surface_i = 0; surface_i < mesh->get_surface_count(); surface_i++) {
6164
Ref<Material> mat = mesh->surface_get_material(surface_i);
6165
String material_name;
6166
if (mat.is_valid()) {
6167
material_name = mat->get_name();
6168
}
6169
Array blend_arrays;
6170
if (array_mesh.is_valid()) {
6171
blend_arrays = array_mesh->surface_get_blend_shape_arrays(surface_i);
6172
}
6173
importer_mesh->add_surface(mesh->surface_get_primitive_type(surface_i), mesh->surface_get_arrays(surface_i),
6174
blend_arrays, mesh->surface_get_lods(surface_i), mat, material_name, mesh->surface_get_format(surface_i));
6175
}
6176
gltf_mesh->set_mesh(importer_mesh);
6177
GLTFMeshIndex mesh_index = p_state->meshes.size();
6178
p_state->meshes.push_back(gltf_mesh);
6179
for (int32_t instance_i = 0; instance_i < multi_mesh->get_instance_count();
6180
instance_i++) {
6181
Transform3D transform;
6182
if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_2D) {
6183
Transform2D xform_2d = multi_mesh->get_instance_transform_2d(instance_i);
6184
transform.origin =
6185
Vector3(xform_2d.get_origin().x, 0, xform_2d.get_origin().y);
6186
real_t rotation = xform_2d.get_rotation();
6187
Quaternion quaternion(Vector3(0, 1, 0), rotation);
6188
Size2 scale = xform_2d.get_scale();
6189
transform.basis.set_quaternion_scale(quaternion,
6190
Vector3(scale.x, 0, scale.y));
6191
transform = p_multi_mesh_instance->get_transform() * transform;
6192
} else if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_3D) {
6193
transform = p_multi_mesh_instance->get_transform() *
6194
multi_mesh->get_instance_transform(instance_i);
6195
}
6196
Ref<GLTFNode> new_gltf_node;
6197
new_gltf_node.instantiate();
6198
new_gltf_node->mesh = mesh_index;
6199
new_gltf_node->transform = transform;
6200
new_gltf_node->set_original_name(p_multi_mesh_instance->get_name());
6201
new_gltf_node->set_name(_gen_unique_name(p_state, p_multi_mesh_instance->get_name()));
6202
p_gltf_node->children.push_back(p_state->nodes.size());
6203
p_state->nodes.push_back(new_gltf_node);
6204
}
6205
}
6206
6207
void 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) {
6208
Skeleton3D *skeleton = p_skeleton3d;
6209
Ref<GLTFSkeleton> gltf_skeleton;
6210
gltf_skeleton.instantiate();
6211
// GLTFSkeleton is only used to hold internal p_state data. It will not be written to the document.
6212
//
6213
gltf_skeleton->godot_skeleton = skeleton;
6214
GLTFSkeletonIndex skeleton_i = p_state->skeletons.size();
6215
p_state->skeleton3d_to_gltf_skeleton[skeleton->get_instance_id()] = skeleton_i;
6216
p_state->skeletons.push_back(gltf_skeleton);
6217
6218
BoneId bone_count = skeleton->get_bone_count();
6219
for (BoneId bone_i = 0; bone_i < bone_count; bone_i++) {
6220
Ref<GLTFNode> joint_node;
6221
joint_node.instantiate();
6222
// Note that we cannot use _gen_unique_bone_name here, because glTF spec requires all node
6223
// names to be unique regardless of whether or not they are used as joints.
6224
joint_node->set_original_name(skeleton->get_bone_name(bone_i));
6225
joint_node->set_name(_gen_unique_name(p_state, skeleton->get_bone_name(bone_i)));
6226
joint_node->transform = skeleton->get_bone_pose(bone_i);
6227
joint_node->joint = true;
6228
6229
if (p_skeleton3d->has_bone_meta(bone_i, "extras")) {
6230
joint_node->set_meta("extras", p_skeleton3d->get_bone_meta(bone_i, "extras"));
6231
}
6232
GLTFNodeIndex current_node_i = p_state->nodes.size();
6233
p_state->scene_nodes.insert(current_node_i, skeleton);
6234
p_state->nodes.push_back(joint_node);
6235
6236
gltf_skeleton->joints.push_back(current_node_i);
6237
if (skeleton->get_bone_parent(bone_i) == -1) {
6238
gltf_skeleton->roots.push_back(current_node_i);
6239
}
6240
gltf_skeleton->godot_bone_node.insert(bone_i, current_node_i);
6241
}
6242
for (BoneId bone_i = 0; bone_i < bone_count; bone_i++) {
6243
GLTFNodeIndex current_node_i = gltf_skeleton->godot_bone_node[bone_i];
6244
BoneId parent_bone_id = skeleton->get_bone_parent(bone_i);
6245
if (parent_bone_id == -1) {
6246
if (p_parent_node_index != -1) {
6247
p_state->nodes.write[current_node_i]->parent = p_parent_node_index;
6248
p_state->nodes.write[p_parent_node_index]->children.push_back(current_node_i);
6249
}
6250
} else {
6251
GLTFNodeIndex parent_node_i = gltf_skeleton->godot_bone_node[parent_bone_id];
6252
p_state->nodes.write[current_node_i]->parent = parent_node_i;
6253
p_state->nodes.write[parent_node_i]->children.push_back(current_node_i);
6254
}
6255
}
6256
// Remove placeholder skeleton3d node by not creating the gltf node
6257
// Skins are per mesh
6258
for (int node_i = 0; node_i < skeleton->get_child_count(); node_i++) {
6259
_convert_scene_node(p_state, skeleton->get_child(node_i), p_parent_node_index, p_root_node_index);
6260
}
6261
}
6262
6263
void 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) {
6264
Skeleton3D *skeleton;
6265
// Note that relative transforms to external skeletons and pose overrides are not supported.
6266
if (p_bone_attachment->get_use_external_skeleton()) {
6267
skeleton = Object::cast_to<Skeleton3D>(p_bone_attachment->get_node_or_null(p_bone_attachment->get_external_skeleton()));
6268
} else {
6269
skeleton = Object::cast_to<Skeleton3D>(p_bone_attachment->get_parent());
6270
}
6271
GLTFSkeletonIndex skel_gltf_i = -1;
6272
if (skeleton != nullptr && p_state->skeleton3d_to_gltf_skeleton.has(skeleton->get_instance_id())) {
6273
skel_gltf_i = p_state->skeleton3d_to_gltf_skeleton[skeleton->get_instance_id()];
6274
}
6275
int bone_idx = -1;
6276
if (skeleton != nullptr) {
6277
bone_idx = p_bone_attachment->get_bone_idx();
6278
if (bone_idx == -1) {
6279
bone_idx = skeleton->find_bone(p_bone_attachment->get_bone_name());
6280
}
6281
}
6282
GLTFNodeIndex par_node_index = p_parent_node_index;
6283
if (skeleton != nullptr && bone_idx != -1 && skel_gltf_i != -1) {
6284
Ref<GLTFSkeleton> gltf_skeleton = p_state->skeletons.write[skel_gltf_i];
6285
gltf_skeleton->bone_attachments.push_back(p_bone_attachment);
6286
par_node_index = gltf_skeleton->joints[bone_idx];
6287
}
6288
6289
for (int node_i = 0; node_i < p_bone_attachment->get_child_count(); node_i++) {
6290
_convert_scene_node(p_state, p_bone_attachment->get_child(node_i), par_node_index, p_root_node_index);
6291
}
6292
}
6293
6294
void GLTFDocument::_convert_mesh_instance_to_gltf(MeshInstance3D *p_scene_parent, Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node) {
6295
GLTFMeshIndex gltf_mesh_index = _convert_mesh_to_gltf(p_state, p_scene_parent);
6296
if (gltf_mesh_index != -1) {
6297
p_gltf_node->mesh = gltf_mesh_index;
6298
}
6299
}
6300
6301
void _set_node_tree_owner(Node *p_current_node, Node *&p_scene_root) {
6302
// Note: p_scene_parent and p_scene_root must either both be null or both be valid.
6303
if (p_scene_root == nullptr) {
6304
// If the root node argument is null, this is the root node.
6305
p_scene_root = p_current_node;
6306
// If multiple nodes were generated under the root node, ensure they have the owner set.
6307
if (unlikely(p_current_node->get_child_count() > 0)) {
6308
Array args;
6309
args.append(p_scene_root);
6310
for (int i = 0; i < p_current_node->get_child_count(); i++) {
6311
Node *child = p_current_node->get_child(i);
6312
child->propagate_call(StringName("set_owner"), args);
6313
}
6314
}
6315
} else {
6316
// Add the node we generated and set the owner to the scene root.
6317
Array args;
6318
args.append(p_scene_root);
6319
p_current_node->propagate_call(StringName("set_owner"), args);
6320
}
6321
}
6322
6323
bool GLTFDocument::_does_skinned_mesh_require_placeholder_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node) {
6324
if (p_gltf_node->skin < 0) {
6325
return false; // Not a skinned mesh.
6326
}
6327
// Check for child nodes that aren't joints/bones.
6328
for (int i = 0; i < p_gltf_node->children.size(); ++i) {
6329
Ref<GLTFNode> child = p_state->nodes[p_gltf_node->children[i]];
6330
if (!child->joint) {
6331
return true;
6332
}
6333
// Edge case: If a child's skeleton is not yet in the tree, then we must add it as a child of this node.
6334
// While the Skeleton3D node isn't a glTF node, it's still a case where we need a placeholder.
6335
// This is required to handle this issue: https://github.com/godotengine/godot/issues/67773
6336
const GLTFSkeletonIndex skel_index = child->skeleton;
6337
ERR_FAIL_INDEX_V(skel_index, p_state->skeletons.size(), false);
6338
if (p_state->skeletons[skel_index]->godot_skeleton->get_parent() == nullptr) {
6339
return true;
6340
}
6341
}
6342
return false;
6343
}
6344
6345
void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root) {
6346
Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
6347
Node3D *current_node = nullptr;
6348
// Check if any GLTFDocumentExtension classes want to generate a node for us.
6349
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
6350
ERR_CONTINUE(ext.is_null());
6351
current_node = ext->generate_scene_node(p_state, gltf_node, p_scene_parent);
6352
if (current_node) {
6353
break;
6354
}
6355
}
6356
// If none of our GLTFDocumentExtension classes generated us a node, try using built-in glTF types.
6357
if (!current_node) {
6358
if (gltf_node->mesh >= 0) {
6359
current_node = _generate_mesh_instance(p_state, p_node_index);
6360
// glTF specifies that skinned meshes should ignore their node transforms,
6361
// only being controlled by the skeleton, so Godot will reparent a skinned
6362
// mesh to its skeleton. However, we still need to ensure any child nodes
6363
// keep their place in the tree, so if there are any child nodes, the skinned
6364
// mesh must not be the base node, so generate an empty spatial base.
6365
if (_does_skinned_mesh_require_placeholder_node(p_state, gltf_node)) {
6366
Node3D *placeholder;
6367
// We need a placeholder, but maybe the Skeleton3D *is* the placeholder?
6368
const GLTFSkeletonIndex skel_index = gltf_node->skeleton;
6369
if (skel_index >= 0 && skel_index < p_state->skeletons.size() && p_state->skeletons[skel_index]->godot_skeleton->get_parent() == nullptr) {
6370
placeholder = p_state->skeletons[skel_index]->godot_skeleton;
6371
} else {
6372
placeholder = _generate_spatial(p_state, p_node_index);
6373
}
6374
current_node->set_name(gltf_node->get_name());
6375
placeholder->add_child(current_node, true);
6376
current_node = placeholder;
6377
}
6378
} else if (gltf_node->camera >= 0) {
6379
current_node = _generate_camera(p_state, p_node_index);
6380
} else if (gltf_node->light >= 0) {
6381
current_node = _generate_light(p_state, p_node_index);
6382
}
6383
}
6384
// The only case where current_node is a Skeleton3D is when it is the placeholder for a skinned mesh.
6385
// In that case, we don't set the name or possibly generate a bone attachment. But usually, we do.
6386
// It is also possible that user code generates a Skeleton3D node, and this code also works for that case.
6387
if (likely(!Object::cast_to<Skeleton3D>(current_node))) {
6388
if (current_node) {
6389
// Set the name of the Godot node to the name of the glTF node.
6390
String gltf_node_name = gltf_node->get_name();
6391
if (!gltf_node_name.is_empty()) {
6392
current_node->set_name(gltf_node_name);
6393
}
6394
}
6395
// Skeleton stuff: If this node is in a skeleton, we need to attach it to a bone attachment pointing to its bone.
6396
if (gltf_node->skeleton >= 0) {
6397
_generate_skeleton_bone_node(p_state, p_node_index, current_node, p_scene_parent, p_scene_root);
6398
return;
6399
}
6400
}
6401
// Skeleton stuff: If the parent node is in a skeleton, we need to attach this node to a bone attachment pointing to the parent's bone.
6402
if (Object::cast_to<Skeleton3D>(p_scene_parent)) {
6403
Skeleton3D *parent_skeleton = Object::cast_to<Skeleton3D>(p_scene_parent);
6404
_attach_node_to_skeleton(p_state, p_node_index, current_node, parent_skeleton, p_scene_root);
6405
return;
6406
}
6407
// Not a skeleton bone, so definitely some kind of node that goes in the Godot scene tree.
6408
if (current_node == nullptr) {
6409
current_node = _generate_spatial(p_state, p_node_index);
6410
// Set the name of the Godot node to the name of the glTF node.
6411
String gltf_node_name = gltf_node->get_name();
6412
if (!gltf_node_name.is_empty()) {
6413
current_node->set_name(gltf_node_name);
6414
}
6415
}
6416
if (p_scene_parent) {
6417
p_scene_parent->add_child(current_node, true);
6418
}
6419
// Set the owner of the nodes to the scene root.
6420
// Note: p_scene_parent and p_scene_root must either both be null or both be valid.
6421
_set_node_tree_owner(current_node, p_scene_root);
6422
current_node->set_transform(gltf_node->transform);
6423
current_node->merge_meta_from(*gltf_node);
6424
p_state->scene_nodes.insert(p_node_index, current_node);
6425
for (int i = 0; i < gltf_node->children.size(); ++i) {
6426
_generate_scene_node(p_state, gltf_node->children[i], current_node, p_scene_root);
6427
}
6428
}
6429
6430
void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node3D *p_current_node, Node *p_scene_parent, Node *p_scene_root) {
6431
Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
6432
// Grab the current skeleton, and ensure it's added to the tree.
6433
Skeleton3D *godot_skeleton = p_state->skeletons[gltf_node->skeleton]->godot_skeleton;
6434
if (godot_skeleton->get_parent() == nullptr) {
6435
if (p_scene_root) {
6436
if (Object::cast_to<Skeleton3D>(p_scene_parent)) {
6437
Skeleton3D *parent_skeleton = Object::cast_to<Skeleton3D>(p_scene_parent);
6438
// Explicitly specifying the bone of the parent glTF node is required to
6439
// handle the edge case where a skeleton is a child of another skeleton.
6440
_attach_node_to_skeleton(p_state, p_node_index, godot_skeleton, parent_skeleton, p_scene_root, gltf_node->parent);
6441
} else {
6442
p_scene_parent->add_child(godot_skeleton, true);
6443
godot_skeleton->set_owner(p_scene_root);
6444
}
6445
} else {
6446
p_scene_root = godot_skeleton;
6447
}
6448
}
6449
_attach_node_to_skeleton(p_state, p_node_index, p_current_node, godot_skeleton, p_scene_root);
6450
}
6451
6452
void GLTFDocument::_attach_node_to_skeleton(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node3D *p_current_node, Skeleton3D *p_godot_skeleton, Node *p_scene_root, GLTFNodeIndex p_bone_node_index) {
6453
ERR_FAIL_NULL(p_godot_skeleton->get_parent());
6454
Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
6455
if (Object::cast_to<ImporterMeshInstance3D>(p_current_node) && gltf_node->skin >= 0) {
6456
// Skinned meshes should be attached directly to the skeleton without a BoneAttachment3D.
6457
ERR_FAIL_COND_MSG(p_current_node->get_child_count() > 0, "Skinned mesh nodes passed to this function should not have children (a placeholder should be inserted by `_generate_scene_node`).");
6458
p_godot_skeleton->add_child(p_current_node, true);
6459
} else if (p_current_node || !gltf_node->joint) {
6460
// If we have a node in need of attaching, we need a BoneAttachment3D.
6461
// This happens when a node in Blender has Relations -> Parent set to a bone.
6462
GLTFNodeIndex attachment_node_index = likely(p_bone_node_index == -1) ? (gltf_node->joint ? p_node_index : gltf_node->parent) : p_bone_node_index;
6463
ERR_FAIL_COND(!p_state->scene_nodes.has(attachment_node_index));
6464
Node *attachment_godot_node = p_state->scene_nodes[attachment_node_index];
6465
// If the parent is a Skeleton3D, we need to make a BoneAttachment3D.
6466
if (Object::cast_to<Skeleton3D>(attachment_godot_node)) {
6467
Ref<GLTFNode> attachment_gltf_node = p_state->nodes[attachment_node_index];
6468
BoneAttachment3D *bone_attachment = _generate_bone_attachment(p_godot_skeleton, attachment_gltf_node);
6469
bone_attachment->set_owner(p_scene_root);
6470
bone_attachment->merge_meta_from(*p_state->nodes[attachment_node_index]);
6471
p_state->scene_nodes.insert(attachment_node_index, bone_attachment);
6472
attachment_godot_node = bone_attachment;
6473
}
6474
// By this point, `attachment_godot_node` is either a BoneAttachment3D or part of a BoneAttachment3D subtree.
6475
// If the node is a plain non-joint, we should generate a Godot node for it.
6476
if (p_current_node == nullptr) {
6477
DEV_ASSERT(!gltf_node->joint);
6478
p_current_node = _generate_spatial(p_state, p_node_index);
6479
}
6480
if (!gltf_node->joint) {
6481
p_current_node->set_transform(gltf_node->transform);
6482
}
6483
p_current_node->set_name(gltf_node->get_name());
6484
attachment_godot_node->add_child(p_current_node, true);
6485
} else {
6486
// If this glTF is a plain joint, this glTF node only becomes a Godot bone.
6487
// We refer to the skeleton itself as this glTF node's corresponding Godot node.
6488
// This may be overridden later if the joint has a non-joint as a child in need of an attachment.
6489
p_current_node = p_godot_skeleton;
6490
}
6491
_set_node_tree_owner(p_current_node, p_scene_root);
6492
p_current_node->merge_meta_from(*gltf_node);
6493
p_state->scene_nodes.insert(p_node_index, p_current_node);
6494
for (int i = 0; i < gltf_node->children.size(); ++i) {
6495
_generate_scene_node(p_state, gltf_node->children[i], p_current_node, p_scene_root);
6496
}
6497
}
6498
6499
// Deprecated code used when naming_version is 0 or 1 (Godot 4.0 to 4.4).
6500
void GLTFDocument::_generate_scene_node_compat_4pt4(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root) {
6501
Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
6502
6503
if (gltf_node->skeleton >= 0) {
6504
_generate_skeleton_bone_node_compat_4pt4(p_state, p_node_index, p_scene_parent, p_scene_root);
6505
return;
6506
}
6507
6508
Node3D *current_node = nullptr;
6509
6510
// Is our parent a skeleton
6511
Skeleton3D *active_skeleton = Object::cast_to<Skeleton3D>(p_scene_parent);
6512
6513
const bool non_bone_parented_to_skeleton = active_skeleton;
6514
6515
// skinned meshes must not be placed in a bone attachment.
6516
if (non_bone_parented_to_skeleton && gltf_node->skin < 0) {
6517
// Bone Attachment - Parent Case
6518
BoneAttachment3D *bone_attachment = _generate_bone_attachment_compat_4pt4(p_state, active_skeleton, p_node_index, gltf_node->parent);
6519
6520
p_scene_parent->add_child(bone_attachment, true);
6521
6522
// Find the correct bone_idx so we can properly serialize it.
6523
bone_attachment->set_bone_idx(active_skeleton->find_bone(gltf_node->get_name()));
6524
6525
bone_attachment->set_owner(p_scene_root);
6526
6527
// There is no gltf_node that represent this, so just directly create a unique name
6528
bone_attachment->set_name(gltf_node->get_name());
6529
6530
// We change the scene_parent to our bone attachment now. We do not set current_node because we want to make the node
6531
// and attach it to the bone_attachment
6532
p_scene_parent = bone_attachment;
6533
}
6534
// Check if any GLTFDocumentExtension classes want to generate a node for us.
6535
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
6536
ERR_CONTINUE(ext.is_null());
6537
current_node = ext->generate_scene_node(p_state, gltf_node, p_scene_parent);
6538
if (current_node) {
6539
break;
6540
}
6541
}
6542
// If none of our GLTFDocumentExtension classes generated us a node, we generate one.
6543
if (!current_node) {
6544
if (gltf_node->skin >= 0 && gltf_node->mesh >= 0 && !gltf_node->children.is_empty()) {
6545
// glTF specifies that skinned meshes should ignore their node transforms,
6546
// only being controlled by the skeleton, so Godot will reparent a skinned
6547
// mesh to its skeleton. However, we still need to ensure any child nodes
6548
// keep their place in the tree, so if there are any child nodes, the skinned
6549
// mesh must not be the base node, so generate an empty spatial base.
6550
current_node = _generate_spatial(p_state, p_node_index);
6551
Node3D *mesh_inst = _generate_mesh_instance(p_state, p_node_index);
6552
mesh_inst->set_name(gltf_node->get_name());
6553
current_node->add_child(mesh_inst, true);
6554
} else if (gltf_node->mesh >= 0) {
6555
current_node = _generate_mesh_instance(p_state, p_node_index);
6556
} else if (gltf_node->camera >= 0) {
6557
current_node = _generate_camera(p_state, p_node_index);
6558
} else if (gltf_node->light >= 0) {
6559
current_node = _generate_light(p_state, p_node_index);
6560
} else {
6561
current_node = _generate_spatial(p_state, p_node_index);
6562
}
6563
}
6564
String gltf_node_name = gltf_node->get_name();
6565
if (!gltf_node_name.is_empty()) {
6566
current_node->set_name(gltf_node_name);
6567
}
6568
current_node->set_visible(gltf_node->visible);
6569
// Note: p_scene_parent and p_scene_root must either both be null or both be valid.
6570
if (p_scene_root == nullptr) {
6571
// If the root node argument is null, this is the root node.
6572
p_scene_root = current_node;
6573
// If multiple nodes were generated under the root node, ensure they have the owner set.
6574
if (unlikely(current_node->get_child_count() > 0)) {
6575
Array args;
6576
args.append(p_scene_root);
6577
for (int i = 0; i < current_node->get_child_count(); i++) {
6578
Node *child = current_node->get_child(i);
6579
child->propagate_call(StringName("set_owner"), args);
6580
}
6581
}
6582
} else {
6583
// Add the node we generated and set the owner to the scene root.
6584
p_scene_parent->add_child(current_node, true);
6585
Array args;
6586
args.append(p_scene_root);
6587
current_node->propagate_call(StringName("set_owner"), args);
6588
current_node->set_transform(gltf_node->transform);
6589
}
6590
6591
current_node->merge_meta_from(*gltf_node);
6592
6593
p_state->scene_nodes.insert(p_node_index, current_node);
6594
for (int i = 0; i < gltf_node->children.size(); ++i) {
6595
_generate_scene_node_compat_4pt4(p_state, gltf_node->children[i], current_node, p_scene_root);
6596
}
6597
}
6598
6599
// Deprecated code used when naming_version is 0 or 1 (Godot 4.0 to 4.4).
6600
void GLTFDocument::_generate_skeleton_bone_node_compat_4pt4(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root) {
6601
Ref<GLTFNode> gltf_node = p_state->nodes[p_node_index];
6602
6603
Node3D *current_node = nullptr;
6604
6605
Skeleton3D *skeleton = p_state->skeletons[gltf_node->skeleton]->godot_skeleton;
6606
// In this case, this node is already a bone in skeleton.
6607
const bool is_skinned_mesh = (gltf_node->skin >= 0 && gltf_node->mesh >= 0);
6608
const bool requires_extra_node = (gltf_node->mesh >= 0 || gltf_node->camera >= 0 || gltf_node->light >= 0);
6609
6610
Skeleton3D *active_skeleton = Object::cast_to<Skeleton3D>(p_scene_parent);
6611
if (active_skeleton != skeleton) {
6612
if (active_skeleton) {
6613
// Should no longer be possible.
6614
ERR_PRINT(vformat("glTF: Generating scene detected direct parented Skeletons at node %d", p_node_index));
6615
BoneAttachment3D *bone_attachment = _generate_bone_attachment_compat_4pt4(p_state, active_skeleton, p_node_index, gltf_node->parent);
6616
p_scene_parent->add_child(bone_attachment, true);
6617
bone_attachment->set_owner(p_scene_root);
6618
// There is no gltf_node that represent this, so just directly create a unique name
6619
bone_attachment->set_name(_gen_unique_name(p_state, "BoneAttachment3D"));
6620
// We change the scene_parent to our bone attachment now. We do not set current_node because we want to make the node
6621
// and attach it to the bone_attachment
6622
p_scene_parent = bone_attachment;
6623
}
6624
if (skeleton->get_parent() == nullptr) {
6625
if (p_scene_root) {
6626
p_scene_parent->add_child(skeleton, true);
6627
skeleton->set_owner(p_scene_root);
6628
} else {
6629
p_scene_parent = skeleton;
6630
p_scene_root = skeleton;
6631
}
6632
}
6633
}
6634
6635
active_skeleton = skeleton;
6636
current_node = active_skeleton;
6637
if (active_skeleton) {
6638
p_scene_parent = active_skeleton;
6639
}
6640
6641
if (requires_extra_node) {
6642
current_node = nullptr;
6643
// skinned meshes must not be placed in a bone attachment.
6644
if (!is_skinned_mesh) {
6645
// Bone Attachment - Same Node Case
6646
BoneAttachment3D *bone_attachment = _generate_bone_attachment_compat_4pt4(p_state, active_skeleton, p_node_index, p_node_index);
6647
6648
p_scene_parent->add_child(bone_attachment, true);
6649
6650
// Find the correct bone_idx so we can properly serialize it.
6651
bone_attachment->set_bone_idx(active_skeleton->find_bone(gltf_node->get_name()));
6652
6653
bone_attachment->set_owner(p_scene_root);
6654
6655
// There is no gltf_node that represent this, so just directly create a unique name
6656
bone_attachment->set_name(gltf_node->get_name());
6657
6658
// We change the scene_parent to our bone attachment now. We do not set current_node because we want to make the node
6659
// and attach it to the bone_attachment
6660
p_scene_parent = bone_attachment;
6661
}
6662
// Check if any GLTFDocumentExtension classes want to generate a node for us.
6663
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
6664
ERR_CONTINUE(ext.is_null());
6665
current_node = ext->generate_scene_node(p_state, gltf_node, p_scene_parent);
6666
if (current_node) {
6667
break;
6668
}
6669
}
6670
// If none of our GLTFDocumentExtension classes generated us a node, we generate one.
6671
if (!current_node) {
6672
if (gltf_node->mesh >= 0) {
6673
current_node = _generate_mesh_instance(p_state, p_node_index);
6674
} else if (gltf_node->camera >= 0) {
6675
current_node = _generate_camera(p_state, p_node_index);
6676
} else if (gltf_node->light >= 0) {
6677
current_node = _generate_light(p_state, p_node_index);
6678
} else {
6679
current_node = _generate_spatial(p_state, p_node_index);
6680
}
6681
}
6682
// Add the node we generated and set the owner to the scene root.
6683
p_scene_parent->add_child(current_node, true);
6684
if (current_node != p_scene_root) {
6685
Array args;
6686
args.append(p_scene_root);
6687
current_node->propagate_call(StringName("set_owner"), args);
6688
}
6689
// Do not set transform here. Transform is already applied to our bone.
6690
current_node->set_name(gltf_node->get_name());
6691
}
6692
6693
p_state->scene_nodes.insert(p_node_index, current_node);
6694
6695
for (int i = 0; i < gltf_node->children.size(); ++i) {
6696
_generate_scene_node_compat_4pt4(p_state, gltf_node->children[i], active_skeleton, p_scene_root);
6697
}
6698
}
6699
6700
template <typename T>
6701
struct SceneFormatImporterGLTFInterpolate {
6702
T lerp(const T &a, const T &b, float c) const {
6703
return a + (b - a) * c;
6704
}
6705
6706
T catmull_rom(const T &p0, const T &p1, const T &p2, const T &p3, float t) {
6707
const float t2 = t * t;
6708
const float t3 = t2 * t;
6709
6710
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);
6711
}
6712
6713
T hermite(T start, T tan_start, T end, T tan_end, float t) {
6714
/* Formula from the glTF 2.0 specification. */
6715
const real_t t2 = t * t;
6716
const real_t t3 = t2 * t;
6717
6718
const real_t h00 = 2.0 * t3 - 3.0 * t2 + 1.0;
6719
const real_t h10 = t3 - 2.0 * t2 + t;
6720
const real_t h01 = -2.0 * t3 + 3.0 * t2;
6721
const real_t h11 = t3 - t2;
6722
6723
return start * h00 + tan_start * h10 + end * h01 + tan_end * h11;
6724
}
6725
};
6726
6727
// thank you for existing, partial specialization
6728
template <>
6729
struct SceneFormatImporterGLTFInterpolate<Quaternion> {
6730
Quaternion lerp(const Quaternion &a, const Quaternion &b, const float c) const {
6731
ERR_FAIL_COND_V_MSG(!a.is_normalized(), Quaternion(), vformat("The quaternion \"a\" %s must be normalized.", a));
6732
ERR_FAIL_COND_V_MSG(!b.is_normalized(), Quaternion(), vformat("The quaternion \"b\" %s must be normalized.", b));
6733
6734
return a.slerp(b, c).normalized();
6735
}
6736
6737
Quaternion catmull_rom(const Quaternion &p0, const Quaternion &p1, const Quaternion &p2, const Quaternion &p3, const float c) {
6738
ERR_FAIL_COND_V_MSG(!p1.is_normalized(), Quaternion(), vformat("The quaternion \"p1\" (%s) must be normalized.", p1));
6739
ERR_FAIL_COND_V_MSG(!p2.is_normalized(), Quaternion(), vformat("The quaternion \"p2\" (%s) must be normalized.", p2));
6740
6741
return p1.slerp(p2, c).normalized();
6742
}
6743
6744
Quaternion hermite(const Quaternion start, const Quaternion tan_start, const Quaternion end, const Quaternion tan_end, const float t) {
6745
ERR_FAIL_COND_V_MSG(!start.is_normalized(), Quaternion(), vformat("The start quaternion %s must be normalized.", start));
6746
ERR_FAIL_COND_V_MSG(!end.is_normalized(), Quaternion(), vformat("The end quaternion %s must be normalized.", end));
6747
6748
return start.slerp(end, t).normalized();
6749
}
6750
};
6751
6752
template <typename T>
6753
T GLTFDocument::_interpolate_track(const Vector<double> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) {
6754
ERR_FAIL_COND_V(p_values.is_empty(), T());
6755
if (p_times.size() != (p_values.size() / (p_interp == GLTFAnimation::INTERP_CUBIC_SPLINE ? 3 : 1))) {
6756
ERR_PRINT_ONCE("The interpolated values are not corresponding to its times.");
6757
return p_values[0];
6758
}
6759
//could use binary search, worth it?
6760
int idx = -1;
6761
for (int i = 0; i < p_times.size(); i++) {
6762
if (p_times[i] > p_time) {
6763
break;
6764
}
6765
idx++;
6766
}
6767
6768
SceneFormatImporterGLTFInterpolate<T> interp;
6769
6770
switch (p_interp) {
6771
case GLTFAnimation::INTERP_LINEAR: {
6772
if (idx == -1) {
6773
return p_values[0];
6774
} else if (idx >= p_times.size() - 1) {
6775
return p_values[p_times.size() - 1];
6776
}
6777
6778
const float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]);
6779
6780
return interp.lerp(p_values[idx], p_values[idx + 1], c);
6781
} break;
6782
case GLTFAnimation::INTERP_STEP: {
6783
if (idx == -1) {
6784
return p_values[0];
6785
} else if (idx >= p_times.size() - 1) {
6786
return p_values[p_times.size() - 1];
6787
}
6788
6789
return p_values[idx];
6790
} break;
6791
case GLTFAnimation::INTERP_CATMULLROMSPLINE: {
6792
if (idx == -1) {
6793
return p_values[1];
6794
} else if (idx >= p_times.size() - 1) {
6795
return p_values[1 + p_times.size() - 1];
6796
}
6797
6798
const float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]);
6799
6800
return interp.catmull_rom(p_values[idx - 1], p_values[idx], p_values[idx + 1], p_values[idx + 3], c);
6801
} break;
6802
case GLTFAnimation::INTERP_CUBIC_SPLINE: {
6803
if (idx == -1) {
6804
return p_values[1];
6805
} else if (idx >= p_times.size() - 1) {
6806
return p_values[(p_times.size() - 1) * 3 + 1];
6807
}
6808
6809
const float td = (p_times[idx + 1] - p_times[idx]);
6810
const float c = (p_time - p_times[idx]) / td;
6811
6812
const T &from = p_values[idx * 3 + 1];
6813
const T tan_from = td * p_values[idx * 3 + 2];
6814
const T &to = p_values[idx * 3 + 4];
6815
const T tan_to = td * p_values[idx * 3 + 3];
6816
6817
return interp.hermite(from, tan_from, to, tan_to, c);
6818
} break;
6819
}
6820
6821
ERR_FAIL_V(p_values[0]);
6822
}
6823
6824
NodePath GLTFDocument::_find_material_node_path(Ref<GLTFState> p_state, Ref<Material> p_material) {
6825
int mesh_index = 0;
6826
for (Ref<GLTFMesh> gltf_mesh : p_state->meshes) {
6827
TypedArray<Material> materials = gltf_mesh->get_instance_materials();
6828
for (int mat_index = 0; mat_index < materials.size(); mat_index++) {
6829
if (materials[mat_index] == p_material) {
6830
for (Ref<GLTFNode> gltf_node : p_state->nodes) {
6831
if (gltf_node->mesh == mesh_index) {
6832
NodePath node_path = gltf_node->get_scene_node_path(p_state);
6833
// Example: MyNode:mesh:surface_0/material:albedo_color, so we want the mesh:surface_0/material part.
6834
Vector<StringName> subpath;
6835
subpath.append("mesh");
6836
subpath.append("surface_" + itos(mat_index) + "/material");
6837
return NodePath(node_path.get_names(), subpath, false);
6838
}
6839
}
6840
}
6841
}
6842
mesh_index++;
6843
}
6844
return NodePath();
6845
}
6846
6847
Ref<GLTFObjectModelProperty> GLTFDocument::import_object_model_property(Ref<GLTFState> p_state, const String &p_json_pointer) {
6848
if (p_state->object_model_properties.has(p_json_pointer)) {
6849
return p_state->object_model_properties[p_json_pointer];
6850
}
6851
Ref<GLTFObjectModelProperty> ret;
6852
// Split the JSON pointer into its components.
6853
const PackedStringArray split = p_json_pointer.split("/", false);
6854
ERR_FAIL_COND_V_MSG(split.size() < 3, ret, "glTF: Cannot use JSON pointer '" + p_json_pointer + "' because it does not contain enough elements. The only animatable properties are at least 3 levels deep (ex: '/nodes/0/translation' or '/materials/0/emissiveFactor').");
6855
ret.instantiate();
6856
ret->set_json_pointers({ split });
6857
// Partial paths are passed to GLTFDocumentExtension classes if GLTFDocument cannot handle a given JSON pointer.
6858
TypedArray<NodePath> partial_paths;
6859
// Note: This might not be an integer, but in that case, we don't use this value anyway.
6860
const int top_level_index = split[1].to_int();
6861
// For JSON pointers present in the core glTF Object Model, hard-code them in GLTFDocument.
6862
// https://github.com/KhronosGroup/glTF/blob/main/specification/2.0/ObjectModel.adoc
6863
if (split[0] == "nodes") {
6864
ERR_FAIL_INDEX_V_MSG(top_level_index, p_state->nodes.size(), ret, vformat("glTF: Unable to find node %d for JSON pointer '%s'.", top_level_index, p_json_pointer));
6865
Ref<GLTFNode> pointed_gltf_node = p_state->nodes[top_level_index];
6866
NodePath node_path = pointed_gltf_node->get_scene_node_path(p_state);
6867
partial_paths.append(node_path);
6868
// Check if it's something we should be able to handle.
6869
const String &node_prop = split[2];
6870
if (node_prop == "translation") {
6871
ret->append_path_to_property(node_path, "position");
6872
ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3);
6873
} else if (node_prop == "rotation") {
6874
ret->append_path_to_property(node_path, "quaternion");
6875
ret->set_types(Variant::QUATERNION, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4);
6876
} else if (node_prop == "scale") {
6877
ret->append_path_to_property(node_path, "scale");
6878
ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3);
6879
} else if (node_prop == "matrix") {
6880
ret->append_path_to_property(node_path, "transform");
6881
ret->set_types(Variant::TRANSFORM3D, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4X4);
6882
} else if (node_prop == "globalMatrix") {
6883
ret->append_path_to_property(node_path, "global_transform");
6884
ret->set_types(Variant::TRANSFORM3D, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4X4);
6885
} else if (node_prop == "weights") {
6886
if (split.size() > 3) {
6887
const String &weight_index_string = split[3];
6888
ret->append_path_to_property(node_path, "blend_shapes/morph_" + weight_index_string);
6889
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
6890
}
6891
// Else, Godot's MeshInstance3D does not expose the blend shape weights as one property.
6892
// But that's fine, we handle this case in _parse_animation_pointer instead.
6893
}
6894
} else if (split[0] == "cameras") {
6895
const String &camera_prop = split[2];
6896
for (Ref<GLTFNode> gltf_node : p_state->nodes) {
6897
if (gltf_node->camera == top_level_index) {
6898
NodePath node_path = gltf_node->get_scene_node_path(p_state);
6899
partial_paths.append(node_path);
6900
// Check if it's something we should be able to handle.
6901
if (camera_prop == "orthographic" || camera_prop == "perspective") {
6902
ERR_FAIL_COND_V(split.size() < 4, ret);
6903
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
6904
const String &sub_prop = split[3];
6905
if (sub_prop == "xmag" || sub_prop == "ymag") {
6906
ret->append_path_to_property(node_path, "size");
6907
} else if (sub_prop == "yfov") {
6908
ret->append_path_to_property(node_path, "fov");
6909
GLTFCamera::set_fov_conversion_expressions(ret);
6910
} else if (sub_prop == "zfar") {
6911
ret->append_path_to_property(node_path, "far");
6912
} else if (sub_prop == "znear") {
6913
ret->append_path_to_property(node_path, "near");
6914
}
6915
}
6916
}
6917
}
6918
} else if (split[0] == "materials") {
6919
ERR_FAIL_INDEX_V_MSG(top_level_index, p_state->materials.size(), ret, vformat("glTF: Unable to find material %d for JSON pointer '%s'.", top_level_index, p_json_pointer));
6920
Ref<Material> pointed_material = p_state->materials[top_level_index];
6921
NodePath mat_path = _find_material_node_path(p_state, pointed_material);
6922
if (mat_path.is_empty()) {
6923
WARN_PRINT(vformat("glTF: Unable to find a path to the material %d for JSON pointer '%s'. This is likely bad data but it's also possible this is intentional. Continuing anyway.", top_level_index, p_json_pointer));
6924
} else {
6925
partial_paths.append(mat_path);
6926
const String &mat_prop = split[2];
6927
if (mat_prop == "alphaCutoff") {
6928
ret->append_path_to_property(mat_path, "alpha_scissor_threshold");
6929
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
6930
} else if (mat_prop == "emissiveFactor") {
6931
ret->append_path_to_property(mat_path, "emission");
6932
ret->set_types(Variant::COLOR, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3);
6933
} else if (mat_prop == "extensions") {
6934
ERR_FAIL_COND_V(split.size() < 5, ret);
6935
const String &ext_name = split[3];
6936
const String &ext_prop = split[4];
6937
if (ext_name == "KHR_materials_emissive_strength" && ext_prop == "emissiveStrength") {
6938
ret->append_path_to_property(mat_path, "emission_energy_multiplier");
6939
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
6940
}
6941
} else {
6942
ERR_FAIL_COND_V(split.size() < 4, ret);
6943
const String &sub_prop = split[3];
6944
if (mat_prop == "normalTexture") {
6945
if (sub_prop == "scale") {
6946
ret->append_path_to_property(mat_path, "normal_scale");
6947
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
6948
}
6949
} else if (mat_prop == "occlusionTexture") {
6950
if (sub_prop == "strength") {
6951
// This is the closest thing Godot has to an occlusion strength property.
6952
ret->append_path_to_property(mat_path, "ao_light_affect");
6953
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
6954
}
6955
} else if (mat_prop == "pbrMetallicRoughness") {
6956
if (sub_prop == "baseColorFactor") {
6957
ret->append_path_to_property(mat_path, "albedo_color");
6958
ret->set_types(Variant::COLOR, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4);
6959
} else if (sub_prop == "metallicFactor") {
6960
ret->append_path_to_property(mat_path, "metallic");
6961
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
6962
} else if (sub_prop == "roughnessFactor") {
6963
ret->append_path_to_property(mat_path, "roughness");
6964
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
6965
} else if (sub_prop == "baseColorTexture") {
6966
ERR_FAIL_COND_V(split.size() < 6, ret);
6967
const String &tex_ext_dict = split[4];
6968
const String &tex_ext_name = split[5];
6969
const String &tex_ext_prop = split[6];
6970
if (tex_ext_dict == "extensions" && tex_ext_name == "KHR_texture_transform") {
6971
// Godot only supports UVs for the whole material, not per texture.
6972
// We treat the albedo texture as the main texture, and import as UV1.
6973
// Godot does not support texture rotation, only offset and scale.
6974
if (tex_ext_prop == "offset") {
6975
ret->append_path_to_property(mat_path, "uv1_offset");
6976
ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT2);
6977
} else if (tex_ext_prop == "scale") {
6978
ret->append_path_to_property(mat_path, "uv1_scale");
6979
ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT2);
6980
}
6981
}
6982
}
6983
}
6984
}
6985
}
6986
} else if (split[0] == "meshes") {
6987
for (Ref<GLTFNode> gltf_node : p_state->nodes) {
6988
if (gltf_node->mesh == top_level_index) {
6989
NodePath node_path = gltf_node->get_scene_node_path(p_state);
6990
Vector<StringName> subpath;
6991
subpath.append("mesh");
6992
partial_paths.append(NodePath(node_path.get_names(), subpath, false));
6993
break;
6994
}
6995
}
6996
} else if (split[0] == "extensions") {
6997
if (split[1] == "KHR_lights_punctual" && split[2] == "lights" && split.size() > 4) {
6998
const int light_index = split[3].to_int();
6999
ERR_FAIL_INDEX_V_MSG(light_index, p_state->lights.size(), ret, vformat("glTF: Unable to find light %d for JSON pointer '%s'.", light_index, p_json_pointer));
7000
const String &light_prop = split[4];
7001
const Ref<GLTFLight> pointed_light = p_state->lights[light_index];
7002
for (Ref<GLTFNode> gltf_node : p_state->nodes) {
7003
if (gltf_node->light == light_index) {
7004
NodePath node_path = gltf_node->get_scene_node_path(p_state);
7005
partial_paths.append(node_path);
7006
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
7007
// Check if it's something we should be able to handle.
7008
if (light_prop == "color") {
7009
ret->append_path_to_property(node_path, "light_color");
7010
ret->set_types(Variant::COLOR, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3);
7011
} else if (light_prop == "intensity") {
7012
ret->append_path_to_property(node_path, "light_energy");
7013
} else if (light_prop == "range") {
7014
const String &light_type = p_state->lights[light_index]->light_type;
7015
if (light_type == "spot") {
7016
ret->append_path_to_property(node_path, "spot_range");
7017
} else {
7018
ret->append_path_to_property(node_path, "omni_range");
7019
}
7020
} else if (light_prop == "spot") {
7021
ERR_FAIL_COND_V(split.size() < 6, ret);
7022
const String &sub_prop = split[5];
7023
if (sub_prop == "innerConeAngle") {
7024
ret->append_path_to_property(node_path, "spot_angle_attenuation");
7025
GLTFLight::set_cone_inner_attenuation_conversion_expressions(ret);
7026
} else if (sub_prop == "outerConeAngle") {
7027
ret->append_path_to_property(node_path, "spot_angle");
7028
}
7029
}
7030
}
7031
}
7032
}
7033
}
7034
// Additional JSON pointers can be added by GLTFDocumentExtension classes.
7035
// We only need this if no mapping has been found yet from GLTFDocument's internal code.
7036
// When available, we pass the partial paths to the extension to help it generate the full path.
7037
// For example, for `/nodes/3/extensions/MY_ext/prop`, we pass a NodePath that leads to node 3,
7038
// so the GLTFDocumentExtension class only needs to resolve the last `MY_ext/prop` part of the path.
7039
// It should check `split.size() > 4 and split[0] == "nodes" and split[2] == "extensions" and split[3] == "MY_ext"`
7040
// at the start of the function to check if this JSON pointer applies to it, then it can handle `split[4]`.
7041
if (!ret->has_node_paths()) {
7042
for (Ref<GLTFDocumentExtension> ext : all_document_extensions) {
7043
ret = ext->import_object_model_property(p_state, split, partial_paths);
7044
if (ret.is_valid() && ret->has_node_paths()) {
7045
if (!ret->has_json_pointers()) {
7046
ret->set_json_pointers({ split });
7047
}
7048
break;
7049
}
7050
}
7051
if (ret.is_null() || !ret->has_node_paths()) {
7052
if (split.has("KHR_texture_transform")) {
7053
WARN_VERBOSE(vformat("glTF: Texture transforms are only supported per material in Godot. All KHR_texture_transform properties will be ignored except for the albedo texture. Ignoring JSON pointer '%s'.", p_json_pointer));
7054
} else {
7055
WARN_PRINT(vformat("glTF: Animation contained JSON pointer '%s' which could not be resolved. This property will not be animated.", p_json_pointer));
7056
}
7057
}
7058
}
7059
p_state->object_model_properties[p_json_pointer] = ret;
7060
return ret;
7061
}
7062
7063
Ref<GLTFObjectModelProperty> GLTFDocument::export_object_model_property(Ref<GLTFState> p_state, const NodePath &p_node_path, const Node *p_godot_node, GLTFNodeIndex p_gltf_node_index) {
7064
Ref<GLTFObjectModelProperty> ret;
7065
const Object *target_object = p_godot_node;
7066
const Vector<StringName> subpath = p_node_path.get_subnames();
7067
ERR_FAIL_COND_V_MSG(subpath.is_empty(), ret, "glTF: Cannot export empty property. No property was specified in the NodePath: " + String(p_node_path));
7068
int target_prop_depth = 0;
7069
for (StringName subname : subpath) {
7070
Variant target_property = target_object->get(subname);
7071
if (target_property.get_type() == Variant::OBJECT) {
7072
target_object = target_property;
7073
if (target_object) {
7074
target_prop_depth++;
7075
continue;
7076
}
7077
}
7078
break;
7079
}
7080
const String &target_prop = subpath[target_prop_depth];
7081
ret.instantiate();
7082
ret->set_node_paths({ p_node_path });
7083
Vector<PackedStringArray> split_json_pointers;
7084
PackedStringArray split_json_pointer;
7085
if (Object::cast_to<BaseMaterial3D>(target_object)) {
7086
for (int i = 0; i < p_state->materials.size(); i++) {
7087
if (p_state->materials[i].ptr() == target_object) {
7088
split_json_pointer.append("materials");
7089
split_json_pointer.append(itos(i));
7090
if (target_prop == "alpha_scissor_threshold") {
7091
split_json_pointer.append("alphaCutoff");
7092
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
7093
} else if (target_prop == "emission") {
7094
split_json_pointer.append("emissiveFactor");
7095
ret->set_types(Variant::COLOR, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3);
7096
} else if (target_prop == "emission_energy_multiplier") {
7097
split_json_pointer.append("extensions");
7098
split_json_pointer.append("KHR_materials_emissive_strength");
7099
split_json_pointer.append("emissiveStrength");
7100
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
7101
} else if (target_prop == "normal_scale") {
7102
split_json_pointer.append("normalTexture");
7103
split_json_pointer.append("scale");
7104
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
7105
} else if (target_prop == "ao_light_affect") {
7106
split_json_pointer.append("occlusionTexture");
7107
split_json_pointer.append("strength");
7108
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
7109
} else if (target_prop == "albedo_color") {
7110
split_json_pointer.append("pbrMetallicRoughness");
7111
split_json_pointer.append("baseColorFactor");
7112
ret->set_types(Variant::COLOR, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4);
7113
} else if (target_prop == "metallic") {
7114
split_json_pointer.append("pbrMetallicRoughness");
7115
split_json_pointer.append("metallicFactor");
7116
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
7117
} else if (target_prop == "roughness") {
7118
split_json_pointer.append("pbrMetallicRoughness");
7119
split_json_pointer.append("roughnessFactor");
7120
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
7121
} else if (target_prop == "uv1_offset" || target_prop == "uv1_scale") {
7122
split_json_pointer.append("pbrMetallicRoughness");
7123
split_json_pointer.append("baseColorTexture");
7124
split_json_pointer.append("extensions");
7125
split_json_pointer.append("KHR_texture_transform");
7126
if (target_prop == "uv1_offset") {
7127
split_json_pointer.append("offset");
7128
} else {
7129
split_json_pointer.append("scale");
7130
}
7131
ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT2);
7132
} else {
7133
split_json_pointer.clear();
7134
}
7135
break;
7136
}
7137
}
7138
} else {
7139
// Properties directly on Godot nodes.
7140
Ref<GLTFNode> gltf_node = p_state->nodes[p_gltf_node_index];
7141
if (Object::cast_to<Camera3D>(target_object) && gltf_node->camera >= 0) {
7142
split_json_pointer.append("cameras");
7143
split_json_pointer.append(itos(gltf_node->camera));
7144
const Camera3D *camera_node = Object::cast_to<Camera3D>(target_object);
7145
const Camera3D::ProjectionType projection_type = camera_node->get_projection();
7146
if (projection_type == Camera3D::PROJECTION_PERSPECTIVE) {
7147
split_json_pointer.append("perspective");
7148
} else {
7149
split_json_pointer.append("orthographic");
7150
}
7151
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
7152
if (target_prop == "size") {
7153
PackedStringArray xmag = split_json_pointer.duplicate();
7154
xmag.append("xmag");
7155
split_json_pointers.append(xmag);
7156
split_json_pointer.append("ymag");
7157
} else if (target_prop == "fov") {
7158
split_json_pointer.append("yfov");
7159
GLTFCamera::set_fov_conversion_expressions(ret);
7160
} else if (target_prop == "far") {
7161
split_json_pointer.append("zfar");
7162
} else if (target_prop == "near") {
7163
split_json_pointer.append("znear");
7164
} else {
7165
split_json_pointer.clear();
7166
}
7167
} else if (Object::cast_to<Light3D>(target_object) && gltf_node->light >= 0) {
7168
split_json_pointer.append("extensions");
7169
split_json_pointer.append("KHR_lights_punctual");
7170
split_json_pointer.append("lights");
7171
split_json_pointer.append(itos(gltf_node->light));
7172
ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT);
7173
if (target_prop == "light_color") {
7174
split_json_pointer.append("color");
7175
ret->set_types(Variant::COLOR, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3);
7176
} else if (target_prop == "light_energy") {
7177
split_json_pointer.append("intensity");
7178
} else if (target_prop == "spot_range") {
7179
split_json_pointer.append("range");
7180
} else if (target_prop == "omni_range") {
7181
split_json_pointer.append("range");
7182
} else if (target_prop == "spot_angle") {
7183
split_json_pointer.append("spot");
7184
split_json_pointer.append("outerConeAngle");
7185
} else if (target_prop == "spot_angle_attenuation") {
7186
split_json_pointer.append("spot");
7187
split_json_pointer.append("innerConeAngle");
7188
GLTFLight::set_cone_inner_attenuation_conversion_expressions(ret);
7189
} else {
7190
split_json_pointer.clear();
7191
}
7192
} else if (Object::cast_to<MeshInstance3D>(target_object) && target_prop.begins_with("blend_shapes/morph_")) {
7193
const String &weight_index_string = target_prop.trim_prefix("blend_shapes/morph_");
7194
split_json_pointer.append("nodes");
7195
split_json_pointer.append(itos(p_gltf_node_index));
7196
split_json_pointer.append("weights");
7197
split_json_pointer.append(weight_index_string);
7198
}
7199
// Transform properties. Check for all 3D nodes if we haven't resolved the JSON pointer yet.
7200
// Note: Do not put this in an `else`, because otherwise this will not be reached.
7201
if (split_json_pointer.is_empty() && Object::cast_to<Node3D>(target_object)) {
7202
split_json_pointer.append("nodes");
7203
split_json_pointer.append(itos(p_gltf_node_index));
7204
if (target_prop == "position") {
7205
split_json_pointer.append("translation");
7206
ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3);
7207
} else if (target_prop == "quaternion") {
7208
// Note: Only Quaternion rotation can be converted from Godot in this mapping.
7209
// Struct methods like from_euler are not accessible from the Expression class. :(
7210
split_json_pointer.append("rotation");
7211
ret->set_types(Variant::QUATERNION, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4);
7212
} else if (target_prop == "scale") {
7213
split_json_pointer.append("scale");
7214
ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3);
7215
} else if (target_prop == "transform") {
7216
split_json_pointer.append("matrix");
7217
ret->set_types(Variant::TRANSFORM3D, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4X4);
7218
} else if (target_prop == "global_transform") {
7219
split_json_pointer.append("globalMatrix");
7220
ret->set_types(Variant::TRANSFORM3D, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4X4);
7221
} else {
7222
split_json_pointer.clear();
7223
}
7224
}
7225
}
7226
// Additional JSON pointers can be added by GLTFDocumentExtension classes.
7227
// We only need this if no mapping has been found yet from GLTFDocument's internal code.
7228
// We pass as many pieces of information as we can to the extension to give it lots of context.
7229
if (split_json_pointer.is_empty()) {
7230
for (Ref<GLTFDocumentExtension> ext : all_document_extensions) {
7231
ret = ext->export_object_model_property(p_state, p_node_path, p_godot_node, p_gltf_node_index, target_object, target_prop_depth);
7232
if (ret.is_valid() && ret->has_json_pointers()) {
7233
if (!ret->has_node_paths()) {
7234
ret->set_node_paths({ p_node_path });
7235
}
7236
break;
7237
}
7238
}
7239
} else {
7240
// GLTFDocument's internal code found a mapping, so set it and return it.
7241
split_json_pointers.append(split_json_pointer);
7242
ret->set_json_pointers(split_json_pointers);
7243
}
7244
return ret;
7245
}
7246
7247
void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, const GLTFAnimationIndex p_index, const bool p_trimming, const bool p_remove_immutable_tracks) {
7248
ERR_FAIL_COND(p_state.is_null());
7249
Node *scene_root = p_animation_player->get_parent();
7250
ERR_FAIL_NULL(scene_root);
7251
Ref<GLTFAnimation> anim = p_state->animations[p_index];
7252
7253
String anim_name = anim->get_name();
7254
if (anim_name.is_empty()) {
7255
// No node represent these, and they are not in the hierarchy, so just make a unique name
7256
anim_name = _gen_unique_name(p_state, "Animation");
7257
}
7258
7259
Ref<Animation> animation;
7260
animation.instantiate();
7261
animation->set_name(anim_name);
7262
animation->set_step(1.0 / p_state->get_bake_fps());
7263
7264
if (anim->get_loop()) {
7265
animation->set_loop_mode(Animation::LOOP_LINEAR);
7266
}
7267
7268
double anim_start = p_trimming ? Math::INF : 0.0;
7269
double anim_end = 0.0;
7270
7271
for (const KeyValue<int, GLTFAnimation::NodeTrack> &track_i : anim->get_node_tracks()) {
7272
const GLTFAnimation::NodeTrack &track = track_i.value;
7273
//need to find the path: for skeletons, weight tracks will affect the mesh
7274
NodePath node_path;
7275
//for skeletons, transform tracks always affect bones
7276
NodePath transform_node_path;
7277
//for meshes, especially skinned meshes, there are cases where it will be added as a child
7278
NodePath mesh_instance_node_path;
7279
7280
GLTFNodeIndex node_index = track_i.key;
7281
7282
const Ref<GLTFNode> gltf_node = p_state->nodes[track_i.key];
7283
7284
HashMap<GLTFNodeIndex, Node *>::Iterator node_element = p_state->scene_nodes.find(node_index);
7285
ERR_CONTINUE_MSG(!node_element, vformat("Unable to find node %d for animation.", node_index));
7286
node_path = scene_root->get_path_to(node_element->value);
7287
HashMap<GLTFNodeIndex, ImporterMeshInstance3D *>::Iterator mesh_instance_element = p_state->scene_mesh_instances.find(node_index);
7288
if (mesh_instance_element) {
7289
mesh_instance_node_path = scene_root->get_path_to(mesh_instance_element->value);
7290
} else {
7291
mesh_instance_node_path = node_path;
7292
}
7293
7294
if (gltf_node->skeleton >= 0) {
7295
const Skeleton3D *sk = p_state->skeletons[gltf_node->skeleton]->godot_skeleton;
7296
ERR_FAIL_NULL(sk);
7297
7298
const String path = String(p_animation_player->get_parent()->get_path_to(sk));
7299
const String bone = gltf_node->get_name();
7300
transform_node_path = path + ":" + bone;
7301
} else {
7302
transform_node_path = node_path;
7303
}
7304
7305
if (p_trimming) {
7306
for (int i = 0; i < track.rotation_track.times.size(); i++) {
7307
anim_start = MIN(anim_start, track.rotation_track.times[i]);
7308
anim_end = MAX(anim_end, track.rotation_track.times[i]);
7309
}
7310
for (int i = 0; i < track.position_track.times.size(); i++) {
7311
anim_start = MIN(anim_start, track.position_track.times[i]);
7312
anim_end = MAX(anim_end, track.position_track.times[i]);
7313
}
7314
for (int i = 0; i < track.scale_track.times.size(); i++) {
7315
anim_start = MIN(anim_start, track.scale_track.times[i]);
7316
anim_end = MAX(anim_end, track.scale_track.times[i]);
7317
}
7318
for (int i = 0; i < track.weight_tracks.size(); i++) {
7319
for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
7320
anim_start = MIN(anim_start, track.weight_tracks[i].times[j]);
7321
anim_end = MAX(anim_end, track.weight_tracks[i].times[j]);
7322
}
7323
}
7324
} else {
7325
// If you don't use trimming and the first key time is not at 0.0, fake keys will be inserted.
7326
for (int i = 0; i < track.rotation_track.times.size(); i++) {
7327
anim_end = MAX(anim_end, track.rotation_track.times[i]);
7328
}
7329
for (int i = 0; i < track.position_track.times.size(); i++) {
7330
anim_end = MAX(anim_end, track.position_track.times[i]);
7331
}
7332
for (int i = 0; i < track.scale_track.times.size(); i++) {
7333
anim_end = MAX(anim_end, track.scale_track.times[i]);
7334
}
7335
for (int i = 0; i < track.weight_tracks.size(); i++) {
7336
for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
7337
anim_end = MAX(anim_end, track.weight_tracks[i].times[j]);
7338
}
7339
}
7340
}
7341
7342
// Animated TRS properties will not affect a skinned mesh.
7343
const bool transform_affects_skinned_mesh_instance = gltf_node->skeleton < 0 && gltf_node->skin >= 0;
7344
if ((track.rotation_track.values.size() || track.position_track.values.size() || track.scale_track.values.size()) && !transform_affects_skinned_mesh_instance) {
7345
//make transform track
7346
int base_idx = animation->get_track_count();
7347
int position_idx = -1;
7348
int rotation_idx = -1;
7349
int scale_idx = -1;
7350
7351
if (track.position_track.values.size()) {
7352
bool is_default = true; //discard the track if all it contains is default values
7353
if (p_remove_immutable_tracks) {
7354
Vector3 base_pos = gltf_node->get_position();
7355
for (int i = 0; i < track.position_track.times.size(); i++) {
7356
int value_index = track.position_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i;
7357
ERR_FAIL_COND_MSG(value_index >= track.position_track.values.size(), "Animation sampler output accessor with 'CUBICSPLINE' interpolation doesn't have enough elements.");
7358
Vector3 value = track.position_track.values[value_index];
7359
if (!value.is_equal_approx(base_pos)) {
7360
is_default = false;
7361
break;
7362
}
7363
}
7364
}
7365
if (!p_remove_immutable_tracks || !is_default) {
7366
position_idx = base_idx;
7367
animation->add_track(Animation::TYPE_POSITION_3D);
7368
animation->track_set_path(position_idx, transform_node_path);
7369
animation->track_set_imported(position_idx, true); //helps merging later
7370
if (track.position_track.interpolation == GLTFAnimation::INTERP_STEP) {
7371
animation->track_set_interpolation_type(position_idx, Animation::InterpolationType::INTERPOLATION_NEAREST);
7372
}
7373
base_idx++;
7374
}
7375
}
7376
if (track.rotation_track.values.size()) {
7377
bool is_default = true; //discard the track if all it contains is default values
7378
if (p_remove_immutable_tracks) {
7379
Quaternion base_rot = gltf_node->get_rotation();
7380
for (int i = 0; i < track.rotation_track.times.size(); i++) {
7381
int value_index = track.rotation_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i;
7382
ERR_FAIL_COND_MSG(value_index >= track.rotation_track.values.size(), "Animation sampler output accessor with 'CUBICSPLINE' interpolation doesn't have enough elements.");
7383
Quaternion value = track.rotation_track.values[value_index].normalized();
7384
if (!value.is_equal_approx(base_rot)) {
7385
is_default = false;
7386
break;
7387
}
7388
}
7389
}
7390
if (!p_remove_immutable_tracks || !is_default) {
7391
rotation_idx = base_idx;
7392
animation->add_track(Animation::TYPE_ROTATION_3D);
7393
animation->track_set_path(rotation_idx, transform_node_path);
7394
animation->track_set_imported(rotation_idx, true); //helps merging later
7395
if (track.rotation_track.interpolation == GLTFAnimation::INTERP_STEP) {
7396
animation->track_set_interpolation_type(rotation_idx, Animation::InterpolationType::INTERPOLATION_NEAREST);
7397
}
7398
base_idx++;
7399
}
7400
}
7401
if (track.scale_track.values.size()) {
7402
bool is_default = true; //discard the track if all it contains is default values
7403
if (p_remove_immutable_tracks) {
7404
Vector3 base_scale = gltf_node->get_scale();
7405
for (int i = 0; i < track.scale_track.times.size(); i++) {
7406
int value_index = track.scale_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i;
7407
ERR_FAIL_COND_MSG(value_index >= track.scale_track.values.size(), "Animation sampler output accessor with 'CUBICSPLINE' interpolation doesn't have enough elements.");
7408
Vector3 value = track.scale_track.values[value_index];
7409
if (!value.is_equal_approx(base_scale)) {
7410
is_default = false;
7411
break;
7412
}
7413
}
7414
}
7415
if (!p_remove_immutable_tracks || !is_default) {
7416
scale_idx = base_idx;
7417
animation->add_track(Animation::TYPE_SCALE_3D);
7418
animation->track_set_path(scale_idx, transform_node_path);
7419
animation->track_set_imported(scale_idx, true); //helps merging later
7420
if (track.scale_track.interpolation == GLTFAnimation::INTERP_STEP) {
7421
animation->track_set_interpolation_type(scale_idx, Animation::InterpolationType::INTERPOLATION_NEAREST);
7422
}
7423
base_idx++;
7424
}
7425
}
7426
7427
const double increment = 1.0 / p_state->get_bake_fps();
7428
double time = anim_start;
7429
7430
Vector3 base_pos;
7431
Quaternion base_rot;
7432
Vector3 base_scale = Vector3(1, 1, 1);
7433
7434
if (rotation_idx == -1) {
7435
base_rot = gltf_node->get_rotation();
7436
}
7437
7438
if (position_idx == -1) {
7439
base_pos = gltf_node->get_position();
7440
}
7441
7442
if (scale_idx == -1) {
7443
base_scale = gltf_node->get_scale();
7444
}
7445
7446
bool last = false;
7447
while (true) {
7448
Vector3 pos = base_pos;
7449
Quaternion rot = base_rot;
7450
Vector3 scale = base_scale;
7451
7452
if (position_idx >= 0) {
7453
pos = _interpolate_track<Vector3>(track.position_track.times, track.position_track.values, time, track.position_track.interpolation);
7454
animation->position_track_insert_key(position_idx, time - anim_start, pos);
7455
}
7456
7457
if (rotation_idx >= 0) {
7458
rot = _interpolate_track<Quaternion>(track.rotation_track.times, track.rotation_track.values, time, track.rotation_track.interpolation);
7459
animation->rotation_track_insert_key(rotation_idx, time - anim_start, rot);
7460
}
7461
7462
if (scale_idx >= 0) {
7463
scale = _interpolate_track<Vector3>(track.scale_track.times, track.scale_track.values, time, track.scale_track.interpolation);
7464
animation->scale_track_insert_key(scale_idx, time - anim_start, scale);
7465
}
7466
7467
if (last) {
7468
break;
7469
}
7470
time += increment;
7471
if (time >= anim_end) {
7472
last = true;
7473
time = anim_end;
7474
}
7475
}
7476
}
7477
7478
for (int i = 0; i < track.weight_tracks.size(); i++) {
7479
ERR_CONTINUE(gltf_node->mesh < 0 || gltf_node->mesh >= p_state->meshes.size());
7480
Ref<GLTFMesh> mesh = p_state->meshes[gltf_node->mesh];
7481
ERR_CONTINUE(mesh.is_null());
7482
ERR_CONTINUE(mesh->get_mesh().is_null());
7483
ERR_CONTINUE(mesh->get_mesh()->get_mesh().is_null());
7484
7485
const String blend_path = String(mesh_instance_node_path) + ":" + String(mesh->get_mesh()->get_blend_shape_name(i));
7486
7487
const int track_idx = animation->get_track_count();
7488
animation->add_track(Animation::TYPE_BLEND_SHAPE);
7489
animation->track_set_path(track_idx, blend_path);
7490
animation->track_set_imported(track_idx, true); //helps merging later
7491
7492
// Only LINEAR and STEP (NEAREST) can be supported out of the box by Godot's Animation,
7493
// the other modes have to be baked.
7494
GLTFAnimation::Interpolation gltf_interp = track.weight_tracks[i].interpolation;
7495
if (gltf_interp == GLTFAnimation::INTERP_LINEAR || gltf_interp == GLTFAnimation::INTERP_STEP) {
7496
animation->track_set_interpolation_type(track_idx, gltf_interp == GLTFAnimation::INTERP_STEP ? Animation::INTERPOLATION_NEAREST : Animation::INTERPOLATION_LINEAR);
7497
for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
7498
const float t = track.weight_tracks[i].times[j];
7499
const float attribs = track.weight_tracks[i].values[j];
7500
animation->blend_shape_track_insert_key(track_idx, t, attribs);
7501
}
7502
} else {
7503
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
7504
const double increment = 1.0 / p_state->get_bake_fps();
7505
double time = 0.0;
7506
bool last = false;
7507
while (true) {
7508
real_t blend = _interpolate_track<real_t>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, gltf_interp);
7509
animation->blend_shape_track_insert_key(track_idx, time - anim_start, blend);
7510
if (last) {
7511
break;
7512
}
7513
time += increment;
7514
if (time >= anim_end) {
7515
last = true;
7516
time = anim_end;
7517
}
7518
}
7519
}
7520
}
7521
}
7522
7523
for (const KeyValue<String, GLTFAnimation::Channel<Variant>> &track_iter : anim->get_pointer_tracks()) {
7524
// Determine the property to animate.
7525
const String json_pointer = track_iter.key;
7526
const Ref<GLTFObjectModelProperty> prop = import_object_model_property(p_state, json_pointer);
7527
ERR_FAIL_COND(prop.is_null());
7528
// Adjust the animation duration to encompass all keyframes.
7529
const GLTFAnimation::Channel<Variant> &channel = track_iter.value;
7530
ERR_CONTINUE_MSG(channel.times.size() != channel.values.size(), vformat("glTF: Animation pointer '%s' has mismatched keyframe times and values.", json_pointer));
7531
if (p_trimming) {
7532
for (int i = 0; i < channel.times.size(); i++) {
7533
anim_start = MIN(anim_start, channel.times[i]);
7534
anim_end = MAX(anim_end, channel.times[i]);
7535
}
7536
} else {
7537
for (int i = 0; i < channel.times.size(); i++) {
7538
anim_end = MAX(anim_end, channel.times[i]);
7539
}
7540
}
7541
// Begin converting the glTF animation to a Godot animation.
7542
const Ref<Expression> gltf_to_godot_expr = prop->get_gltf_to_godot_expression();
7543
const bool is_gltf_to_godot_expr_valid = gltf_to_godot_expr.is_valid();
7544
for (const NodePath node_path : prop->get_node_paths()) {
7545
// If using an expression, determine the base instance to pass to the expression.
7546
Object *base_instance = nullptr;
7547
if (is_gltf_to_godot_expr_valid) {
7548
Ref<Resource> resource;
7549
Vector<StringName> leftover_subpath;
7550
base_instance = scene_root->get_node_and_resource(node_path, resource, leftover_subpath);
7551
if (resource.is_valid()) {
7552
base_instance = resource.ptr();
7553
}
7554
}
7555
// Add a track and insert all keys and values.
7556
const int track_index = animation->get_track_count();
7557
animation->add_track(Animation::TYPE_VALUE);
7558
animation->track_set_interpolation_type(track_index, GLTFAnimation::gltf_to_godot_interpolation(channel.interpolation));
7559
animation->track_set_path(track_index, node_path);
7560
for (int i = 0; i < channel.times.size(); i++) {
7561
const double time = channel.times[i];
7562
Variant value = channel.values[i];
7563
if (is_gltf_to_godot_expr_valid) {
7564
Array inputs;
7565
inputs.append(value);
7566
value = gltf_to_godot_expr->execute(inputs, base_instance);
7567
}
7568
animation->track_insert_key(track_index, time, value);
7569
}
7570
}
7571
}
7572
7573
animation->set_length(anim_end - anim_start);
7574
7575
Ref<AnimationLibrary> library;
7576
if (!p_animation_player->has_animation_library("")) {
7577
library.instantiate();
7578
p_animation_player->add_animation_library("", library);
7579
} else {
7580
library = p_animation_player->get_animation_library("");
7581
}
7582
library->add_animation(anim_name, animation);
7583
}
7584
7585
void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> p_state) {
7586
for (GLTFNodeIndex mi_node_i = 0; mi_node_i < p_state->nodes.size(); ++mi_node_i) {
7587
Ref<GLTFNode> node = p_state->nodes[mi_node_i];
7588
7589
if (node->mesh < 0) {
7590
continue;
7591
}
7592
HashMap<GLTFNodeIndex, Node *>::Iterator mi_element = p_state->scene_nodes.find(mi_node_i);
7593
if (!mi_element) {
7594
continue;
7595
}
7596
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(mi_element->value);
7597
if (!mi) {
7598
continue;
7599
}
7600
node->transform = mi->get_transform();
7601
7602
Node *skel_node = mi->get_node_or_null(mi->get_skeleton_path());
7603
Skeleton3D *godot_skeleton = Object::cast_to<Skeleton3D>(skel_node);
7604
if (!godot_skeleton || godot_skeleton->get_bone_count() == 0) {
7605
continue;
7606
}
7607
// At this point in the code, we know we have a Skeleton3D with at least one bone.
7608
Ref<Skin> skin = mi->get_skin();
7609
Ref<GLTFSkin> gltf_skin;
7610
gltf_skin.instantiate();
7611
Array json_joints;
7612
if (p_state->skeleton3d_to_gltf_skeleton.has(godot_skeleton->get_instance_id())) {
7613
// This is a skinned mesh. If the mesh has no ARRAY_WEIGHTS or ARRAY_BONES, it will be invisible.
7614
const GLTFSkeletonIndex skeleton_gltf_i = p_state->skeleton3d_to_gltf_skeleton[godot_skeleton->get_instance_id()];
7615
Ref<GLTFSkeleton> gltf_skeleton = p_state->skeletons[skeleton_gltf_i];
7616
int bone_cnt = godot_skeleton->get_bone_count();
7617
ERR_FAIL_COND(bone_cnt != gltf_skeleton->joints.size());
7618
7619
ObjectID gltf_skin_key;
7620
if (skin.is_valid()) {
7621
gltf_skin_key = skin->get_instance_id();
7622
}
7623
ObjectID gltf_skel_key = godot_skeleton->get_instance_id();
7624
GLTFSkinIndex skin_gltf_i = -1;
7625
GLTFNodeIndex root_gltf_i = -1;
7626
if (!gltf_skeleton->roots.is_empty()) {
7627
root_gltf_i = gltf_skeleton->roots[0];
7628
}
7629
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)) {
7630
skin_gltf_i = p_state->skin_and_skeleton3d_to_gltf_skin[gltf_skin_key][gltf_skel_key];
7631
} else {
7632
if (skin.is_null()) {
7633
// Note that gltf_skin_key should remain null, so these can share a reference.
7634
skin = godot_skeleton->create_skin_from_rest_transforms();
7635
}
7636
gltf_skin.instantiate();
7637
gltf_skin->godot_skin = skin;
7638
gltf_skin->set_name(skin->get_name());
7639
gltf_skin->skeleton = skeleton_gltf_i;
7640
gltf_skin->skin_root = root_gltf_i;
7641
//gltf_state->godot_to_gltf_node[skel_node]
7642
HashMap<StringName, int> bone_name_to_idx;
7643
for (int bone_i = 0; bone_i < bone_cnt; bone_i++) {
7644
bone_name_to_idx[godot_skeleton->get_bone_name(bone_i)] = bone_i;
7645
}
7646
for (int bind_i = 0, cnt = skin->get_bind_count(); bind_i < cnt; bind_i++) {
7647
int bone_i = skin->get_bind_bone(bind_i);
7648
Transform3D bind_pose = skin->get_bind_pose(bind_i);
7649
StringName bind_name = skin->get_bind_name(bind_i);
7650
if (bind_name != StringName()) {
7651
bone_i = bone_name_to_idx[bind_name];
7652
}
7653
ERR_CONTINUE(bone_i < 0 || bone_i >= bone_cnt);
7654
if (bind_name == StringName()) {
7655
bind_name = godot_skeleton->get_bone_name(bone_i);
7656
}
7657
GLTFNodeIndex skeleton_bone_i = gltf_skeleton->joints[bone_i];
7658
gltf_skin->joints_original.push_back(skeleton_bone_i);
7659
gltf_skin->joints.push_back(skeleton_bone_i);
7660
gltf_skin->inverse_binds.push_back(bind_pose);
7661
if (godot_skeleton->get_bone_parent(bone_i) == -1) {
7662
gltf_skin->roots.push_back(skeleton_bone_i);
7663
}
7664
gltf_skin->joint_i_to_bone_i[bind_i] = bone_i;
7665
gltf_skin->joint_i_to_name[bind_i] = bind_name;
7666
}
7667
skin_gltf_i = p_state->skins.size();
7668
p_state->skins.push_back(gltf_skin);
7669
p_state->skin_and_skeleton3d_to_gltf_skin[gltf_skin_key][gltf_skel_key] = skin_gltf_i;
7670
}
7671
node->skin = skin_gltf_i;
7672
node->skeleton = skeleton_gltf_i;
7673
}
7674
}
7675
}
7676
7677
float GLTFDocument::solve_metallic(float p_dielectric_specular, float p_diffuse, float p_specular, float p_one_minus_specular_strength) {
7678
if (p_specular <= p_dielectric_specular) {
7679
return 0.0f;
7680
}
7681
7682
const float a = p_dielectric_specular;
7683
const float b = p_diffuse * p_one_minus_specular_strength / (1.0f - p_dielectric_specular) + p_specular - 2.0f * p_dielectric_specular;
7684
const float c = p_dielectric_specular - p_specular;
7685
const float D = b * b - 4.0f * a * c;
7686
return CLAMP((-b + Math::sqrt(D)) / (2.0f * a), 0.0f, 1.0f);
7687
}
7688
7689
float GLTFDocument::get_perceived_brightness(const Color p_color) {
7690
const Color coeff = Color(R_BRIGHTNESS_COEFF, G_BRIGHTNESS_COEFF, B_BRIGHTNESS_COEFF);
7691
const Color value = coeff * (p_color * p_color);
7692
7693
const float r = value.r;
7694
const float g = value.g;
7695
const float b = value.b;
7696
7697
return Math::sqrt(r + g + b);
7698
}
7699
7700
float GLTFDocument::get_max_component(const Color &p_color) {
7701
const float r = p_color.r;
7702
const float g = p_color.g;
7703
const float b = p_color.b;
7704
7705
return MAX(MAX(r, g), b);
7706
}
7707
7708
void GLTFDocument::_process_mesh_instances(Ref<GLTFState> p_state, Node *p_scene_root) {
7709
for (GLTFNodeIndex node_i = 0; node_i < p_state->nodes.size(); ++node_i) {
7710
Ref<GLTFNode> node = p_state->nodes[node_i];
7711
7712
if (node->skin >= 0 && node->mesh >= 0) {
7713
const GLTFSkinIndex skin_i = node->skin;
7714
7715
ImporterMeshInstance3D *mi = nullptr;
7716
HashMap<GLTFNodeIndex, ImporterMeshInstance3D *>::Iterator mi_element = p_state->scene_mesh_instances.find(node_i);
7717
if (mi_element) {
7718
mi = mi_element->value;
7719
} else {
7720
HashMap<GLTFNodeIndex, Node *>::Iterator si_element = p_state->scene_nodes.find(node_i);
7721
ERR_CONTINUE_MSG(!si_element, vformat("Unable to find node %d", node_i));
7722
mi = Object::cast_to<ImporterMeshInstance3D>(si_element->value);
7723
ERR_CONTINUE_MSG(mi == nullptr, vformat("Unable to cast node %d of type %s to ImporterMeshInstance3D", node_i, si_element->value->get_class_name()));
7724
}
7725
ERR_CONTINUE_MSG(mi->get_child_count() > 0, "The glTF importer must generate skinned mesh instances as leaf nodes without any children to allow them to be repositioned in the tree without affecting other nodes.");
7726
7727
const GLTFSkeletonIndex skel_i = p_state->skins.write[node->skin]->skeleton;
7728
Ref<GLTFSkeleton> gltf_skeleton = p_state->skeletons.write[skel_i];
7729
Skeleton3D *skeleton = gltf_skeleton->godot_skeleton;
7730
ERR_CONTINUE_MSG(skeleton == nullptr, vformat("Unable to find Skeleton for node %d skin %d", node_i, skin_i));
7731
7732
mi->get_parent()->remove_child(mi);
7733
mi->set_owner(nullptr);
7734
skeleton->add_child(mi, true);
7735
mi->set_owner(p_scene_root);
7736
7737
mi->set_skin(p_state->skins.write[skin_i]->godot_skin);
7738
mi->set_skeleton_path(mi->get_path_to(skeleton));
7739
mi->set_transform(Transform3D());
7740
}
7741
}
7742
}
7743
7744
GLTFNodeIndex GLTFDocument::_node_and_or_bone_to_gltf_node_index(Ref<GLTFState> p_state, const Vector<StringName> &p_node_subpath, const Node *p_godot_node) {
7745
const Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_godot_node);
7746
if (skeleton && p_node_subpath.size() == 1) {
7747
// Special case: Handle skeleton bone TRS tracks. They use the format `A/B/C/Skeleton3D:bone_name`.
7748
// We have a Skeleton3D, check if it has a bone with the same name as this subpath.
7749
const String &bone_name = p_node_subpath[0];
7750
const int32_t bone_index = skeleton->find_bone(bone_name);
7751
if (bone_index != -1) {
7752
// A bone was found! But we still need to figure out which glTF node it corresponds to.
7753
for (GLTFSkeletonIndex skeleton_i = 0; skeleton_i < p_state->skeletons.size(); skeleton_i++) {
7754
const Ref<GLTFSkeleton> &skeleton_gltf = p_state->skeletons[skeleton_i];
7755
if (skeleton == skeleton_gltf->godot_skeleton) {
7756
GLTFNodeIndex node_i = skeleton_gltf->godot_bone_node[bone_index];
7757
return node_i;
7758
}
7759
}
7760
ERR_FAIL_V_MSG(-1, vformat("glTF: Found a bone %s in a Skeleton3D that wasn't in the GLTFState. Ensure that all nodes referenced by the AnimationPlayer are in the scene you are exporting.", bone_name));
7761
}
7762
}
7763
// General case: Not a skeleton bone, usually this means a normal node, or it could be the Skeleton3D itself.
7764
for (const KeyValue<GLTFNodeIndex, Node *> &scene_node_i : p_state->scene_nodes) {
7765
if (scene_node_i.value == p_godot_node) {
7766
return scene_node_i.key;
7767
}
7768
}
7769
ERR_FAIL_V_MSG(-1, vformat("glTF: A node was animated, but it wasn't found in the GLTFState. Ensure that all nodes referenced by the AnimationPlayer are in the scene you are exporting."));
7770
}
7771
7772
bool GLTFDocument::_convert_animation_node_track(Ref<GLTFState> p_state, GLTFAnimation::NodeTrack &p_gltf_node_track, const Ref<Animation> &p_godot_animation, int32_t p_godot_anim_track_index, Vector<double> &p_times) {
7773
GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::godot_to_gltf_interpolation(p_godot_animation, p_godot_anim_track_index);
7774
const Animation::TrackType track_type = p_godot_animation->track_get_type(p_godot_anim_track_index);
7775
const int32_t key_count = p_godot_animation->track_get_key_count(p_godot_anim_track_index);
7776
const NodePath node_path = p_godot_animation->track_get_path(p_godot_anim_track_index);
7777
const Vector<StringName> subpath = node_path.get_subnames();
7778
double anim_end = p_godot_animation->get_length();
7779
if (track_type == Animation::TYPE_SCALE_3D) {
7780
if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) {
7781
gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
7782
p_gltf_node_track.scale_track.times.clear();
7783
p_gltf_node_track.scale_track.values.clear();
7784
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
7785
const double increment = 1.0 / p_state->get_bake_fps();
7786
double time = 0.0;
7787
bool last = false;
7788
while (true) {
7789
Vector3 scale;
7790
Error err = p_godot_animation->try_scale_track_interpolate(p_godot_anim_track_index, time, &scale);
7791
if (err == OK) {
7792
p_gltf_node_track.scale_track.values.push_back(scale);
7793
p_gltf_node_track.scale_track.times.push_back(time);
7794
} else {
7795
ERR_PRINT(vformat("Error interpolating animation %s scale track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time));
7796
}
7797
if (last) {
7798
break;
7799
}
7800
time += increment;
7801
if (time >= anim_end) {
7802
last = true;
7803
time = anim_end;
7804
}
7805
}
7806
} else {
7807
p_gltf_node_track.scale_track.times = p_times;
7808
p_gltf_node_track.scale_track.interpolation = gltf_interpolation;
7809
p_gltf_node_track.scale_track.values.resize(key_count);
7810
for (int32_t key_i = 0; key_i < key_count; key_i++) {
7811
Vector3 scale;
7812
Error err = p_godot_animation->scale_track_get_key(p_godot_anim_track_index, key_i, &scale);
7813
ERR_CONTINUE(err != OK);
7814
p_gltf_node_track.scale_track.values.write[key_i] = scale;
7815
}
7816
}
7817
} else if (track_type == Animation::TYPE_POSITION_3D) {
7818
if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) {
7819
gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
7820
p_gltf_node_track.position_track.times.clear();
7821
p_gltf_node_track.position_track.values.clear();
7822
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
7823
const double increment = 1.0 / p_state->get_bake_fps();
7824
double time = 0.0;
7825
bool last = false;
7826
while (true) {
7827
Vector3 scale;
7828
Error err = p_godot_animation->try_position_track_interpolate(p_godot_anim_track_index, time, &scale);
7829
if (err == OK) {
7830
p_gltf_node_track.position_track.values.push_back(scale);
7831
p_gltf_node_track.position_track.times.push_back(time);
7832
} else {
7833
ERR_PRINT(vformat("Error interpolating animation %s position track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time));
7834
}
7835
if (last) {
7836
break;
7837
}
7838
time += increment;
7839
if (time >= anim_end) {
7840
last = true;
7841
time = anim_end;
7842
}
7843
}
7844
} else {
7845
p_gltf_node_track.position_track.times = p_times;
7846
p_gltf_node_track.position_track.values.resize(key_count);
7847
p_gltf_node_track.position_track.interpolation = gltf_interpolation;
7848
for (int32_t key_i = 0; key_i < key_count; key_i++) {
7849
Vector3 position;
7850
Error err = p_godot_animation->position_track_get_key(p_godot_anim_track_index, key_i, &position);
7851
ERR_CONTINUE(err != OK);
7852
p_gltf_node_track.position_track.values.write[key_i] = position;
7853
}
7854
}
7855
} else if (track_type == Animation::TYPE_ROTATION_3D) {
7856
if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) {
7857
gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
7858
p_gltf_node_track.rotation_track.times.clear();
7859
p_gltf_node_track.rotation_track.values.clear();
7860
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
7861
const double increment = 1.0 / p_state->get_bake_fps();
7862
double time = 0.0;
7863
bool last = false;
7864
while (true) {
7865
Quaternion rotation;
7866
Error err = p_godot_animation->try_rotation_track_interpolate(p_godot_anim_track_index, time, &rotation);
7867
if (err == OK) {
7868
p_gltf_node_track.rotation_track.values.push_back(rotation);
7869
p_gltf_node_track.rotation_track.times.push_back(time);
7870
} else {
7871
ERR_PRINT(vformat("Error interpolating animation %s value rotation track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time));
7872
}
7873
if (last) {
7874
break;
7875
}
7876
time += increment;
7877
if (time >= anim_end) {
7878
last = true;
7879
time = anim_end;
7880
}
7881
}
7882
} else {
7883
p_gltf_node_track.rotation_track.times = p_times;
7884
p_gltf_node_track.rotation_track.values.resize(key_count);
7885
p_gltf_node_track.rotation_track.interpolation = gltf_interpolation;
7886
for (int32_t key_i = 0; key_i < key_count; key_i++) {
7887
Quaternion rotation;
7888
Error err = p_godot_animation->rotation_track_get_key(p_godot_anim_track_index, key_i, &rotation);
7889
ERR_CONTINUE(err != OK);
7890
p_gltf_node_track.rotation_track.values.write[key_i] = rotation;
7891
}
7892
}
7893
} else if (subpath.size() > 0) {
7894
const StringName &node_prop = subpath[0];
7895
if (track_type == Animation::TYPE_VALUE) {
7896
if (node_prop == "position") {
7897
p_gltf_node_track.position_track.interpolation = gltf_interpolation;
7898
p_gltf_node_track.position_track.times = p_times;
7899
p_gltf_node_track.position_track.values.resize(key_count);
7900
7901
if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) {
7902
gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
7903
p_gltf_node_track.position_track.times.clear();
7904
p_gltf_node_track.position_track.values.clear();
7905
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
7906
const double increment = 1.0 / p_state->get_bake_fps();
7907
double time = 0.0;
7908
bool last = false;
7909
while (true) {
7910
Vector3 position;
7911
Error err = p_godot_animation->try_position_track_interpolate(p_godot_anim_track_index, time, &position);
7912
if (err == OK) {
7913
p_gltf_node_track.position_track.values.push_back(position);
7914
p_gltf_node_track.position_track.times.push_back(time);
7915
} else {
7916
ERR_PRINT(vformat("Error interpolating animation %s value position track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time));
7917
}
7918
if (last) {
7919
break;
7920
}
7921
time += increment;
7922
if (time >= anim_end) {
7923
last = true;
7924
time = anim_end;
7925
}
7926
}
7927
} else {
7928
for (int32_t key_i = 0; key_i < key_count; key_i++) {
7929
Vector3 position = p_godot_animation->track_get_key_value(p_godot_anim_track_index, key_i);
7930
p_gltf_node_track.position_track.values.write[key_i] = position;
7931
}
7932
}
7933
} else if (node_prop == "rotation" || node_prop == "rotation_degrees" || node_prop == "quaternion") {
7934
p_gltf_node_track.rotation_track.interpolation = gltf_interpolation;
7935
p_gltf_node_track.rotation_track.times = p_times;
7936
p_gltf_node_track.rotation_track.values.resize(key_count);
7937
if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) {
7938
gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
7939
p_gltf_node_track.rotation_track.times.clear();
7940
p_gltf_node_track.rotation_track.values.clear();
7941
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
7942
const double increment = 1.0 / p_state->get_bake_fps();
7943
double time = 0.0;
7944
bool last = false;
7945
while (true) {
7946
Quaternion rotation;
7947
Error err = p_godot_animation->try_rotation_track_interpolate(p_godot_anim_track_index, time, &rotation);
7948
if (err == OK) {
7949
p_gltf_node_track.rotation_track.values.push_back(rotation);
7950
p_gltf_node_track.rotation_track.times.push_back(time);
7951
} else {
7952
ERR_PRINT(vformat("Error interpolating animation %s value rotation track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time));
7953
}
7954
if (last) {
7955
break;
7956
}
7957
time += increment;
7958
if (time >= anim_end) {
7959
last = true;
7960
time = anim_end;
7961
}
7962
}
7963
} else {
7964
for (int32_t key_i = 0; key_i < key_count; key_i++) {
7965
Quaternion rotation_quaternion;
7966
if (node_prop == "quaternion") {
7967
rotation_quaternion = p_godot_animation->track_get_key_value(p_godot_anim_track_index, key_i);
7968
} else {
7969
Vector3 rotation_euler = p_godot_animation->track_get_key_value(p_godot_anim_track_index, key_i);
7970
if (node_prop == "rotation_degrees") {
7971
rotation_euler *= Math::TAU / 360.0;
7972
}
7973
rotation_quaternion = Quaternion::from_euler(rotation_euler);
7974
}
7975
p_gltf_node_track.rotation_track.values.write[key_i] = rotation_quaternion;
7976
}
7977
}
7978
} else if (node_prop == "scale") {
7979
p_gltf_node_track.scale_track.interpolation = gltf_interpolation;
7980
p_gltf_node_track.scale_track.times = p_times;
7981
p_gltf_node_track.scale_track.values.resize(key_count);
7982
7983
if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) {
7984
gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
7985
p_gltf_node_track.scale_track.times.clear();
7986
p_gltf_node_track.scale_track.values.clear();
7987
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
7988
const double increment = 1.0 / p_state->get_bake_fps();
7989
double time = 0.0;
7990
bool last = false;
7991
while (true) {
7992
Vector3 scale;
7993
Error err = p_godot_animation->try_scale_track_interpolate(p_godot_anim_track_index, time, &scale);
7994
if (err == OK) {
7995
p_gltf_node_track.scale_track.values.push_back(scale);
7996
p_gltf_node_track.scale_track.times.push_back(time);
7997
} else {
7998
ERR_PRINT(vformat("Error interpolating animation %s scale track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time));
7999
}
8000
if (last) {
8001
break;
8002
}
8003
time += increment;
8004
if (time >= anim_end) {
8005
last = true;
8006
time = anim_end;
8007
}
8008
}
8009
} else {
8010
for (int32_t key_i = 0; key_i < key_count; key_i++) {
8011
Vector3 scale_track = p_godot_animation->track_get_key_value(p_godot_anim_track_index, key_i);
8012
p_gltf_node_track.scale_track.values.write[key_i] = scale_track;
8013
}
8014
}
8015
} else if (node_prop == "transform") {
8016
p_gltf_node_track.position_track.interpolation = gltf_interpolation;
8017
p_gltf_node_track.position_track.times = p_times;
8018
p_gltf_node_track.position_track.values.resize(key_count);
8019
p_gltf_node_track.rotation_track.interpolation = gltf_interpolation;
8020
p_gltf_node_track.rotation_track.times = p_times;
8021
p_gltf_node_track.rotation_track.values.resize(key_count);
8022
p_gltf_node_track.scale_track.interpolation = gltf_interpolation;
8023
p_gltf_node_track.scale_track.times = p_times;
8024
p_gltf_node_track.scale_track.values.resize(key_count);
8025
if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) {
8026
gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
8027
p_gltf_node_track.position_track.times.clear();
8028
p_gltf_node_track.position_track.values.clear();
8029
p_gltf_node_track.rotation_track.times.clear();
8030
p_gltf_node_track.rotation_track.values.clear();
8031
p_gltf_node_track.scale_track.times.clear();
8032
p_gltf_node_track.scale_track.values.clear();
8033
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
8034
const double increment = 1.0 / p_state->get_bake_fps();
8035
double time = 0.0;
8036
bool last = false;
8037
while (true) {
8038
Vector3 position;
8039
Quaternion rotation;
8040
Vector3 scale;
8041
Error err = p_godot_animation->try_position_track_interpolate(p_godot_anim_track_index, time, &position);
8042
if (err == OK) {
8043
err = p_godot_animation->try_rotation_track_interpolate(p_godot_anim_track_index, time, &rotation);
8044
if (err == OK) {
8045
err = p_godot_animation->try_scale_track_interpolate(p_godot_anim_track_index, time, &scale);
8046
}
8047
}
8048
if (err == OK) {
8049
p_gltf_node_track.position_track.values.push_back(position);
8050
p_gltf_node_track.position_track.times.push_back(time);
8051
p_gltf_node_track.rotation_track.values.push_back(rotation);
8052
p_gltf_node_track.rotation_track.times.push_back(time);
8053
p_gltf_node_track.scale_track.values.push_back(scale);
8054
p_gltf_node_track.scale_track.times.push_back(time);
8055
} else {
8056
ERR_PRINT(vformat("Error interpolating animation %s transform track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time));
8057
}
8058
if (last) {
8059
break;
8060
}
8061
time += increment;
8062
if (time >= anim_end) {
8063
last = true;
8064
time = anim_end;
8065
}
8066
}
8067
} else {
8068
for (int32_t key_i = 0; key_i < key_count; key_i++) {
8069
Transform3D transform = p_godot_animation->track_get_key_value(p_godot_anim_track_index, key_i);
8070
p_gltf_node_track.position_track.values.write[key_i] = transform.get_origin();
8071
p_gltf_node_track.rotation_track.values.write[key_i] = transform.basis.get_rotation_quaternion();
8072
p_gltf_node_track.scale_track.values.write[key_i] = transform.basis.get_scale();
8073
}
8074
}
8075
} else {
8076
// This is a Value track animating a property, but not a TRS property, so it can't be converted into a node track.
8077
return false;
8078
}
8079
} else if (track_type == Animation::TYPE_BEZIER) {
8080
const int32_t keys = anim_end * p_state->get_bake_fps();
8081
if (node_prop == "scale") {
8082
if (p_gltf_node_track.scale_track.times.is_empty()) {
8083
p_gltf_node_track.scale_track.interpolation = gltf_interpolation;
8084
Vector<double> new_times;
8085
new_times.resize(keys);
8086
for (int32_t key_i = 0; key_i < keys; key_i++) {
8087
new_times.write[key_i] = key_i / p_state->get_bake_fps();
8088
}
8089
p_gltf_node_track.scale_track.times = new_times;
8090
8091
p_gltf_node_track.scale_track.values.resize(keys);
8092
8093
for (int32_t key_i = 0; key_i < keys; key_i++) {
8094
p_gltf_node_track.scale_track.values.write[key_i] = Vector3(1.0f, 1.0f, 1.0f);
8095
}
8096
8097
for (int32_t key_i = 0; key_i < keys; key_i++) {
8098
Vector3 bezier_track = p_gltf_node_track.scale_track.values[key_i];
8099
if (subpath.size() == 2) {
8100
if (subpath[1] == StringName("x")) {
8101
bezier_track.x = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps());
8102
} else if (subpath[1] == StringName("y")) {
8103
bezier_track.y = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps());
8104
} else if (subpath[1] == StringName("z")) {
8105
bezier_track.z = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps());
8106
}
8107
}
8108
p_gltf_node_track.scale_track.values.write[key_i] = bezier_track;
8109
}
8110
}
8111
} else if (node_prop == "position") {
8112
if (p_gltf_node_track.position_track.times.is_empty()) {
8113
p_gltf_node_track.position_track.interpolation = gltf_interpolation;
8114
Vector<double> new_times;
8115
new_times.resize(keys);
8116
for (int32_t key_i = 0; key_i < keys; key_i++) {
8117
new_times.write[key_i] = key_i / p_state->get_bake_fps();
8118
}
8119
p_gltf_node_track.position_track.times = new_times;
8120
8121
p_gltf_node_track.position_track.values.resize(keys);
8122
}
8123
8124
for (int32_t key_i = 0; key_i < keys; key_i++) {
8125
Vector3 bezier_track = p_gltf_node_track.position_track.values[key_i];
8126
if (subpath.size() == 2) {
8127
if (subpath[1] == StringName("x")) {
8128
bezier_track.x = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps());
8129
} else if (subpath[1] == StringName("y")) {
8130
bezier_track.y = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps());
8131
} else if (subpath[1] == StringName("z")) {
8132
bezier_track.z = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps());
8133
}
8134
}
8135
p_gltf_node_track.position_track.values.write[key_i] = bezier_track;
8136
}
8137
} else if (node_prop == "quaternion") {
8138
if (p_gltf_node_track.rotation_track.times.is_empty()) {
8139
p_gltf_node_track.rotation_track.interpolation = gltf_interpolation;
8140
Vector<double> new_times;
8141
new_times.resize(keys);
8142
for (int32_t key_i = 0; key_i < keys; key_i++) {
8143
new_times.write[key_i] = key_i / p_state->get_bake_fps();
8144
}
8145
p_gltf_node_track.rotation_track.times = new_times;
8146
8147
p_gltf_node_track.rotation_track.values.resize(keys);
8148
}
8149
for (int32_t key_i = 0; key_i < keys; key_i++) {
8150
Quaternion bezier_track = p_gltf_node_track.rotation_track.values[key_i];
8151
if (subpath.size() == 2) {
8152
if (subpath[1] == StringName("x")) {
8153
bezier_track.x = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps());
8154
} else if (subpath[1] == StringName("y")) {
8155
bezier_track.y = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps());
8156
} else if (subpath[1] == StringName("z")) {
8157
bezier_track.z = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps());
8158
} else if (subpath[1] == StringName("w")) {
8159
bezier_track.w = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps());
8160
}
8161
}
8162
p_gltf_node_track.rotation_track.values.write[key_i] = bezier_track;
8163
}
8164
} else {
8165
// This is a Bezier track animating a property, but not a TRS property, so it can't be converted into a node track.
8166
return false;
8167
}
8168
} else {
8169
// This property track isn't a Value track or Bezier track, so it can't be converted into a node track.
8170
return false;
8171
}
8172
} else {
8173
// This isn't a TRS track or a property track, so it can't be converted into a node track.
8174
return false;
8175
}
8176
// If we reached this point, the track was some kind of TRS track and was successfully converted.
8177
// All failure paths should return false before this point to indicate this
8178
// isn't a node track so it can be handled by KHR_animation_pointer instead.
8179
return true;
8180
}
8181
8182
void GLTFDocument::_convert_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, const String &p_animation_track_name) {
8183
Ref<Animation> animation = p_animation_player->get_animation(p_animation_track_name);
8184
Ref<GLTFAnimation> gltf_animation;
8185
gltf_animation.instantiate();
8186
gltf_animation->set_original_name(p_animation_track_name);
8187
gltf_animation->set_name(_gen_unique_name(p_state, p_animation_track_name));
8188
HashMap<int, GLTFAnimation::NodeTrack> &node_tracks = gltf_animation->get_node_tracks();
8189
for (int32_t track_index = 0; track_index < animation->get_track_count(); track_index++) {
8190
if (!animation->track_is_enabled(track_index)) {
8191
continue;
8192
}
8193
// Get the Godot node and the glTF node index for the animation track.
8194
const NodePath track_path = animation->track_get_path(track_index);
8195
const Node *anim_player_parent = p_animation_player->get_parent();
8196
const Node *animated_node = anim_player_parent->get_node_or_null(track_path);
8197
ERR_CONTINUE_MSG(!animated_node, "glTF: Cannot get node for animated track using path: " + String(track_path));
8198
const GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::godot_to_gltf_interpolation(animation, track_index);
8199
// First, check if it's a Blend Shape track.
8200
if (animation->track_get_type(track_index) == Animation::TYPE_BLEND_SHAPE) {
8201
const MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(animated_node);
8202
ERR_CONTINUE_MSG(!mesh_instance, "glTF: Animation had a Blend Shape track, but the node wasn't a MeshInstance3D. Ignoring this track.");
8203
Ref<Mesh> mesh = mesh_instance->get_mesh();
8204
ERR_CONTINUE(mesh.is_null());
8205
int32_t mesh_index = -1;
8206
for (const KeyValue<GLTFNodeIndex, Node *> &mesh_track_i : p_state->scene_nodes) {
8207
if (mesh_track_i.value == animated_node) {
8208
mesh_index = mesh_track_i.key;
8209
}
8210
}
8211
ERR_CONTINUE(mesh_index == -1);
8212
GLTFAnimation::NodeTrack track = node_tracks.has(mesh_index) ? node_tracks[mesh_index] : GLTFAnimation::NodeTrack();
8213
if (!node_tracks.has(mesh_index)) {
8214
for (int32_t shape_i = 0; shape_i < mesh->get_blend_shape_count(); shape_i++) {
8215
String shape_name = mesh->get_blend_shape_name(shape_i);
8216
NodePath shape_path = NodePath(track_path.get_names(), { shape_name }, false);
8217
int32_t shape_track_i = animation->find_track(shape_path, Animation::TYPE_BLEND_SHAPE);
8218
if (shape_track_i == -1) {
8219
GLTFAnimation::Channel<real_t> weight;
8220
weight.interpolation = GLTFAnimation::INTERP_LINEAR;
8221
weight.times.push_back(0.0f);
8222
weight.times.push_back(0.0f);
8223
weight.values.push_back(0.0f);
8224
weight.values.push_back(0.0f);
8225
track.weight_tracks.push_back(weight);
8226
continue;
8227
}
8228
int32_t key_count = animation->track_get_key_count(shape_track_i);
8229
GLTFAnimation::Channel<real_t> weight;
8230
weight.interpolation = gltf_interpolation;
8231
weight.times.resize(key_count);
8232
for (int32_t time_i = 0; time_i < key_count; time_i++) {
8233
weight.times.write[time_i] = animation->track_get_key_time(shape_track_i, time_i);
8234
}
8235
weight.values.resize(key_count);
8236
for (int32_t value_i = 0; value_i < key_count; value_i++) {
8237
weight.values.write[value_i] = animation->track_get_key_value(shape_track_i, value_i);
8238
}
8239
track.weight_tracks.push_back(weight);
8240
}
8241
node_tracks[mesh_index] = track;
8242
}
8243
continue;
8244
}
8245
// If it's not a Blend Shape track, it must either be a TRS track, a property Value track, or something we can't handle.
8246
// For the cases we can handle, we will need to know the glTF node index, glTF interpolation, and the times of the track.
8247
const Vector<StringName> subnames = track_path.get_subnames();
8248
const GLTFNodeIndex node_i = _node_and_or_bone_to_gltf_node_index(p_state, subnames, animated_node);
8249
ERR_CONTINUE_MSG(node_i == -1, "glTF: Cannot get glTF node index for animated track using path: " + String(track_path));
8250
const int anim_key_count = animation->track_get_key_count(track_index);
8251
Vector<double> times;
8252
times.resize(anim_key_count);
8253
for (int32_t key_i = 0; key_i < anim_key_count; key_i++) {
8254
times.write[key_i] = animation->track_get_key_time(track_index, key_i);
8255
}
8256
// Try converting the track to a TRS glTF node track. This will only succeed if the Godot animation is a TRS track.
8257
const HashMap<int, GLTFAnimation::NodeTrack>::Iterator node_track_iter = node_tracks.find(node_i);
8258
GLTFAnimation::NodeTrack track;
8259
if (node_track_iter) {
8260
track = node_track_iter->value;
8261
}
8262
if (_convert_animation_node_track(p_state, track, animation, track_index, times)) {
8263
// If the track was successfully converted, save it and continue to the next track.
8264
node_tracks[node_i] = track;
8265
continue;
8266
}
8267
// If the track wasn't a TRS track or Blend Shape track, it might be a Value track animating a property.
8268
// Then this is something that we need to handle with KHR_animation_pointer.
8269
Ref<GLTFObjectModelProperty> obj_model_prop = export_object_model_property(p_state, track_path, animated_node, node_i);
8270
if (obj_model_prop.is_valid() && obj_model_prop->has_json_pointers()) {
8271
// Insert the property track into the KHR_animation_pointer pointer tracks.
8272
GLTFAnimation::Channel<Variant> channel;
8273
channel.interpolation = gltf_interpolation;
8274
channel.times = times;
8275
channel.values.resize(anim_key_count);
8276
// If using an expression, determine the base instance to pass to the expression.
8277
const Ref<Expression> godot_to_gltf_expr = obj_model_prop->get_godot_to_gltf_expression();
8278
const bool is_godot_to_gltf_expr_valid = godot_to_gltf_expr.is_valid();
8279
Object *base_instance = nullptr;
8280
if (is_godot_to_gltf_expr_valid) {
8281
Ref<Resource> resource;
8282
Vector<StringName> leftover_subpath;
8283
base_instance = anim_player_parent->get_node_and_resource(track_path, resource, leftover_subpath);
8284
if (resource.is_valid()) {
8285
base_instance = resource.ptr();
8286
}
8287
}
8288
// Convert the Godot animation values into glTF animation values (still Variant).
8289
for (int32_t key_i = 0; key_i < anim_key_count; key_i++) {
8290
Variant value = animation->track_get_key_value(track_index, key_i);
8291
if (is_godot_to_gltf_expr_valid) {
8292
Array inputs;
8293
inputs.append(value);
8294
value = godot_to_gltf_expr->execute(inputs, base_instance);
8295
}
8296
channel.values.write[key_i] = value;
8297
}
8298
// Use the JSON pointer to insert the property track into the pointer tracks. There will usually be just one JSON pointer.
8299
HashMap<String, GLTFAnimation::Channel<Variant>> &pointer_tracks = gltf_animation->get_pointer_tracks();
8300
Vector<PackedStringArray> split_json_pointers = obj_model_prop->get_json_pointers();
8301
for (const PackedStringArray &split_json_pointer : split_json_pointers) {
8302
String json_pointer_str = "/" + String("/").join(split_json_pointer);
8303
p_state->object_model_properties[json_pointer_str] = obj_model_prop;
8304
pointer_tracks[json_pointer_str] = channel;
8305
}
8306
}
8307
}
8308
if (!gltf_animation->is_empty_of_tracks()) {
8309
p_state->animations.push_back(gltf_animation);
8310
}
8311
}
8312
8313
Error GLTFDocument::_parse(Ref<GLTFState> p_state, String p_path, Ref<FileAccess> p_file) {
8314
Error err;
8315
if (p_file.is_null()) {
8316
return FAILED;
8317
}
8318
p_file->seek(0);
8319
uint32_t magic = p_file->get_32();
8320
if (magic == 0x46546C67) {
8321
// Binary file.
8322
p_file->seek(0);
8323
err = _parse_glb(p_file, p_state);
8324
if (err != OK) {
8325
return err;
8326
}
8327
} else {
8328
// Text file.
8329
p_file->seek(0);
8330
String text = p_file->get_as_utf8_string();
8331
JSON json;
8332
err = json.parse(text);
8333
ERR_FAIL_COND_V_MSG(err != OK, err, "glTF: Error parsing .gltf JSON data: " + json.get_error_message() + " at line: " + itos(json.get_error_line()));
8334
p_state->json = json.get_data();
8335
}
8336
8337
err = _parse_asset_header(p_state);
8338
ERR_FAIL_COND_V(err != OK, err);
8339
8340
document_extensions.clear();
8341
for (Ref<GLTFDocumentExtension> ext : all_document_extensions) {
8342
ERR_CONTINUE(ext.is_null());
8343
err = ext->import_preflight(p_state, p_state->json["extensionsUsed"]);
8344
if (err == OK) {
8345
document_extensions.push_back(ext);
8346
}
8347
}
8348
8349
err = _parse_gltf_state(p_state, p_path);
8350
ERR_FAIL_COND_V(err != OK, err);
8351
8352
return OK;
8353
}
8354
8355
Dictionary _serialize_texture_transform_uv(Vector2 p_offset, Vector2 p_scale) {
8356
Dictionary texture_transform;
8357
bool is_offset = p_offset != Vector2(0.0, 0.0);
8358
if (is_offset) {
8359
Array offset;
8360
offset.resize(2);
8361
offset[0] = p_offset.x;
8362
offset[1] = p_offset.y;
8363
texture_transform["offset"] = offset;
8364
}
8365
bool is_scaled = p_scale != Vector2(1.0, 1.0);
8366
if (is_scaled) {
8367
Array scale;
8368
scale.resize(2);
8369
scale[0] = p_scale.x;
8370
scale[1] = p_scale.y;
8371
texture_transform["scale"] = scale;
8372
}
8373
Dictionary extension;
8374
// Note: Godot doesn't support texture rotation.
8375
if (is_offset || is_scaled) {
8376
extension["KHR_texture_transform"] = texture_transform;
8377
}
8378
return extension;
8379
}
8380
8381
Dictionary GLTFDocument::_serialize_texture_transform_uv1(Ref<BaseMaterial3D> p_material) {
8382
ERR_FAIL_COND_V(p_material.is_null(), Dictionary());
8383
Vector3 offset = p_material->get_uv1_offset();
8384
Vector3 scale = p_material->get_uv1_scale();
8385
return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y));
8386
}
8387
8388
Dictionary GLTFDocument::_serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material) {
8389
ERR_FAIL_COND_V(p_material.is_null(), Dictionary());
8390
Vector3 offset = p_material->get_uv2_offset();
8391
Vector3 scale = p_material->get_uv2_scale();
8392
return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y));
8393
}
8394
8395
Error GLTFDocument::_serialize_asset_header(Ref<GLTFState> p_state) {
8396
const String version = "2.0";
8397
p_state->major_version = version.get_slicec('.', 0).to_int();
8398
p_state->minor_version = version.get_slicec('.', 1).to_int();
8399
Dictionary asset;
8400
asset["version"] = version;
8401
if (!p_state->copyright.is_empty()) {
8402
asset["copyright"] = p_state->copyright;
8403
}
8404
String hash = String(GODOT_VERSION_HASH);
8405
asset["generator"] = String(GODOT_VERSION_FULL_NAME) + String("@") + (hash.is_empty() ? String("unknown") : hash);
8406
p_state->json["asset"] = asset;
8407
ERR_FAIL_COND_V(!asset.has("version"), Error::FAILED);
8408
ERR_FAIL_COND_V(!p_state->json.has("asset"), Error::FAILED);
8409
return OK;
8410
}
8411
8412
Error GLTFDocument::_serialize_file(Ref<GLTFState> p_state, const String p_path) {
8413
Error err = FAILED;
8414
if (p_path.to_lower().ends_with("glb")) {
8415
err = _encode_buffer_glb(p_state, p_path);
8416
ERR_FAIL_COND_V(err != OK, err);
8417
Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err);
8418
ERR_FAIL_COND_V(file.is_null(), FAILED);
8419
8420
constexpr uint64_t header_size = 12;
8421
constexpr uint64_t chunk_header_size = 8;
8422
constexpr uint32_t magic = 0x46546C67; // The byte sequence "glTF" as little-endian.
8423
constexpr uint32_t text_chunk_type = 0x4E4F534A; // The byte sequence "JSON" as little-endian.
8424
constexpr uint32_t binary_chunk_type = 0x004E4942; // The byte sequence "BIN\0" as little-endian.
8425
8426
String json_string = JSON::stringify(p_state->json, "", true, true);
8427
CharString cs = json_string.utf8();
8428
uint64_t text_data_length = cs.length();
8429
uint64_t text_chunk_length = ((text_data_length + 3) & (~3));
8430
uint64_t total_file_length = header_size + chunk_header_size + text_chunk_length;
8431
uint64_t binary_data_length = 0;
8432
uint64_t binary_chunk_length = 0;
8433
if (p_state->buffers.size() > 0) {
8434
binary_data_length = p_state->buffers[0].size();
8435
binary_chunk_length = ((binary_data_length + 3) & (~3));
8436
const uint64_t file_length_with_buffer = total_file_length + chunk_header_size + binary_chunk_length;
8437
// Check if the file length with the buffer is greater than glTF's maximum of 4 GiB.
8438
// If it is, we can't write the buffer into the file, but can write it separately.
8439
if (unlikely(file_length_with_buffer > (uint64_t)UINT32_MAX)) {
8440
err = _encode_buffer_bins(p_state, p_path);
8441
ERR_FAIL_COND_V(err != OK, err);
8442
// Since the buffer bins were re-encoded, we need to re-convert the JSON to string.
8443
json_string = JSON::stringify(p_state->json, "", true, true);
8444
cs = json_string.utf8();
8445
text_data_length = cs.length();
8446
text_chunk_length = ((text_data_length + 3) & (~3));
8447
total_file_length = header_size + chunk_header_size + text_chunk_length;
8448
binary_data_length = 0;
8449
binary_chunk_length = 0;
8450
} else {
8451
total_file_length = file_length_with_buffer;
8452
}
8453
}
8454
ERR_FAIL_COND_V_MSG(total_file_length > (uint64_t)UINT32_MAX, ERR_CANT_CREATE,
8455
"glTF: File size exceeds glTF Binary's maximum of 4 GiB. Cannot serialize as a GLB file.");
8456
8457
file->create(FileAccess::ACCESS_RESOURCES);
8458
file->store_32(magic);
8459
file->store_32(p_state->major_version); // version
8460
file->store_32(total_file_length);
8461
8462
// Write the JSON text chunk.
8463
file->store_32(text_chunk_length);
8464
file->store_32(text_chunk_type);
8465
file->store_buffer((uint8_t *)&cs[0], text_data_length);
8466
for (uint64_t pad_i = text_data_length; pad_i < text_chunk_length; pad_i++) {
8467
file->store_8(' ');
8468
}
8469
8470
// Write a single binary chunk.
8471
if (binary_chunk_length) {
8472
file->store_32((uint32_t)binary_chunk_length);
8473
file->store_32(binary_chunk_type);
8474
file->store_buffer(p_state->buffers[0].ptr(), binary_data_length);
8475
for (uint32_t pad_i = binary_data_length; pad_i < binary_chunk_length; pad_i++) {
8476
file->store_8(0);
8477
}
8478
}
8479
} else {
8480
err = _encode_buffer_bins(p_state, p_path);
8481
ERR_FAIL_COND_V(err != OK, err);
8482
Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err);
8483
ERR_FAIL_COND_V(file.is_null(), FAILED);
8484
8485
file->create(FileAccess::ACCESS_RESOURCES);
8486
String json = JSON::stringify(p_state->json, "", true, true);
8487
file->store_string(json);
8488
}
8489
return err;
8490
}
8491
8492
void GLTFDocument::_bind_methods() {
8493
BIND_ENUM_CONSTANT(ROOT_NODE_MODE_SINGLE_ROOT);
8494
BIND_ENUM_CONSTANT(ROOT_NODE_MODE_KEEP_ROOT);
8495
BIND_ENUM_CONSTANT(ROOT_NODE_MODE_MULTI_ROOT);
8496
8497
BIND_ENUM_CONSTANT(VISIBILITY_MODE_INCLUDE_REQUIRED);
8498
BIND_ENUM_CONSTANT(VISIBILITY_MODE_INCLUDE_OPTIONAL);
8499
BIND_ENUM_CONSTANT(VISIBILITY_MODE_EXCLUDE);
8500
8501
ClassDB::bind_method(D_METHOD("set_image_format", "image_format"), &GLTFDocument::set_image_format);
8502
ClassDB::bind_method(D_METHOD("get_image_format"), &GLTFDocument::get_image_format);
8503
ClassDB::bind_method(D_METHOD("set_lossy_quality", "lossy_quality"), &GLTFDocument::set_lossy_quality);
8504
ClassDB::bind_method(D_METHOD("get_lossy_quality"), &GLTFDocument::get_lossy_quality);
8505
ClassDB::bind_method(D_METHOD("set_fallback_image_format", "fallback_image_format"), &GLTFDocument::set_fallback_image_format);
8506
ClassDB::bind_method(D_METHOD("get_fallback_image_format"), &GLTFDocument::get_fallback_image_format);
8507
ClassDB::bind_method(D_METHOD("set_fallback_image_quality", "fallback_image_quality"), &GLTFDocument::set_fallback_image_quality);
8508
ClassDB::bind_method(D_METHOD("get_fallback_image_quality"), &GLTFDocument::get_fallback_image_quality);
8509
ClassDB::bind_method(D_METHOD("set_root_node_mode", "root_node_mode"), &GLTFDocument::set_root_node_mode);
8510
ClassDB::bind_method(D_METHOD("get_root_node_mode"), &GLTFDocument::get_root_node_mode);
8511
ClassDB::bind_method(D_METHOD("set_visibility_mode", "visibility_mode"), &GLTFDocument::set_visibility_mode);
8512
ClassDB::bind_method(D_METHOD("get_visibility_mode"), &GLTFDocument::get_visibility_mode);
8513
ClassDB::bind_method(D_METHOD("append_from_file", "path", "state", "flags", "base_path"),
8514
&GLTFDocument::append_from_file, DEFVAL(0), DEFVAL(String()));
8515
ClassDB::bind_method(D_METHOD("append_from_buffer", "bytes", "base_path", "state", "flags"),
8516
&GLTFDocument::append_from_buffer, DEFVAL(0));
8517
ClassDB::bind_method(D_METHOD("append_from_scene", "node", "state", "flags"),
8518
&GLTFDocument::append_from_scene, DEFVAL(0));
8519
ClassDB::bind_method(D_METHOD("generate_scene", "state", "bake_fps", "trimming", "remove_immutable_tracks"),
8520
&GLTFDocument::generate_scene, DEFVAL(30), DEFVAL(false), DEFVAL(true));
8521
ClassDB::bind_method(D_METHOD("generate_buffer", "state"),
8522
&GLTFDocument::generate_buffer);
8523
ClassDB::bind_method(D_METHOD("write_to_filesystem", "state", "path"),
8524
&GLTFDocument::write_to_filesystem);
8525
8526
ADD_PROPERTY(PropertyInfo(Variant::STRING, "image_format"), "set_image_format", "get_image_format");
8527
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lossy_quality"), "set_lossy_quality", "get_lossy_quality");
8528
ADD_PROPERTY(PropertyInfo(Variant::STRING, "fallback_image_format"), "set_fallback_image_format", "get_fallback_image_format");
8529
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fallback_image_quality"), "set_fallback_image_quality", "get_fallback_image_quality");
8530
ADD_PROPERTY(PropertyInfo(Variant::INT, "root_node_mode"), "set_root_node_mode", "get_root_node_mode");
8531
ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_mode"), "set_visibility_mode", "get_visibility_mode");
8532
8533
ClassDB::bind_static_method("GLTFDocument", D_METHOD("import_object_model_property", "state", "json_pointer"), &GLTFDocument::import_object_model_property);
8534
ClassDB::bind_static_method("GLTFDocument", D_METHOD("export_object_model_property", "state", "node_path", "godot_node", "gltf_node_index"), &GLTFDocument::export_object_model_property);
8535
8536
ClassDB::bind_static_method("GLTFDocument", D_METHOD("register_gltf_document_extension", "extension", "first_priority"),
8537
&GLTFDocument::register_gltf_document_extension, DEFVAL(false));
8538
ClassDB::bind_static_method("GLTFDocument", D_METHOD("unregister_gltf_document_extension", "extension"),
8539
&GLTFDocument::unregister_gltf_document_extension);
8540
ClassDB::bind_static_method("GLTFDocument", D_METHOD("get_supported_gltf_extensions"),
8541
&GLTFDocument::get_supported_gltf_extensions);
8542
}
8543
8544
void GLTFDocument::_build_parent_hierarchy(Ref<GLTFState> p_state) {
8545
// build the hierarchy
8546
for (GLTFNodeIndex node_i = 0; node_i < p_state->nodes.size(); node_i++) {
8547
for (int j = 0; j < p_state->nodes[node_i]->children.size(); j++) {
8548
GLTFNodeIndex child_i = p_state->nodes[node_i]->children[j];
8549
ERR_FAIL_INDEX(child_i, p_state->nodes.size());
8550
if (p_state->nodes.write[child_i]->parent != -1) {
8551
continue;
8552
}
8553
p_state->nodes.write[child_i]->parent = node_i;
8554
}
8555
}
8556
}
8557
8558
Vector<Ref<GLTFDocumentExtension>> GLTFDocument::all_document_extensions;
8559
8560
void GLTFDocument::register_gltf_document_extension(Ref<GLTFDocumentExtension> p_extension, bool p_first_priority) {
8561
if (!all_document_extensions.has(p_extension)) {
8562
if (p_first_priority) {
8563
all_document_extensions.insert(0, p_extension);
8564
} else {
8565
all_document_extensions.push_back(p_extension);
8566
}
8567
}
8568
}
8569
8570
void GLTFDocument::unregister_gltf_document_extension(Ref<GLTFDocumentExtension> p_extension) {
8571
all_document_extensions.erase(p_extension);
8572
}
8573
8574
void GLTFDocument::unregister_all_gltf_document_extensions() {
8575
all_document_extensions.clear();
8576
}
8577
8578
Vector<Ref<GLTFDocumentExtension>> GLTFDocument::get_all_gltf_document_extensions() {
8579
return all_document_extensions;
8580
}
8581
8582
Vector<String> GLTFDocument::get_supported_gltf_extensions() {
8583
HashSet<String> set = get_supported_gltf_extensions_hashset();
8584
Vector<String> vec;
8585
for (const String &s : set) {
8586
vec.append(s);
8587
}
8588
vec.sort();
8589
return vec;
8590
}
8591
8592
HashSet<String> GLTFDocument::get_supported_gltf_extensions_hashset() {
8593
HashSet<String> supported_extensions;
8594
// If the extension is supported directly in GLTFDocument, list it here.
8595
// Other built-in extensions are supported by GLTFDocumentExtension classes.
8596
supported_extensions.insert("GODOT_single_root");
8597
supported_extensions.insert("KHR_animation_pointer");
8598
supported_extensions.insert("KHR_lights_punctual");
8599
supported_extensions.insert("KHR_materials_emissive_strength");
8600
supported_extensions.insert("KHR_materials_pbrSpecularGlossiness");
8601
supported_extensions.insert("KHR_materials_unlit");
8602
supported_extensions.insert("KHR_node_visibility");
8603
supported_extensions.insert("KHR_texture_transform");
8604
for (Ref<GLTFDocumentExtension> ext : all_document_extensions) {
8605
ERR_CONTINUE(ext.is_null());
8606
Vector<String> ext_supported_extensions = ext->get_supported_extensions();
8607
for (int i = 0; i < ext_supported_extensions.size(); ++i) {
8608
supported_extensions.insert(ext_supported_extensions[i]);
8609
}
8610
}
8611
return supported_extensions;
8612
}
8613
8614
PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref<GLTFState> p_state, Error *r_err) {
8615
Error err = _encode_buffer_glb(p_state, "");
8616
if (r_err) {
8617
*r_err = err;
8618
}
8619
ERR_FAIL_COND_V(err != OK, PackedByteArray());
8620
String json_string = JSON::stringify(p_state->json, "", true, true);
8621
8622
constexpr uint64_t header_size = 12;
8623
constexpr uint64_t chunk_header_size = 8;
8624
constexpr uint32_t magic = 0x46546C67; // The byte sequence "glTF" as little-endian.
8625
constexpr uint32_t text_chunk_type = 0x4E4F534A; // The byte sequence "JSON" as little-endian.
8626
constexpr uint32_t binary_chunk_type = 0x004E4942; // The byte sequence "BIN\0" as little-endian.
8627
const CharString cs = json_string.utf8();
8628
const uint64_t text_data_length = cs.length();
8629
const uint64_t text_chunk_length = ((text_data_length + 3) & (~3));
8630
8631
uint64_t total_file_length = header_size + chunk_header_size + text_chunk_length;
8632
ERR_FAIL_COND_V(total_file_length > (uint64_t)UINT32_MAX, PackedByteArray());
8633
uint64_t binary_data_length = 0;
8634
if (p_state->buffers.size() > 0) {
8635
binary_data_length = p_state->buffers[0].size();
8636
const uint64_t file_length_with_buffer = total_file_length + chunk_header_size + binary_data_length;
8637
total_file_length = file_length_with_buffer;
8638
}
8639
ERR_FAIL_COND_V_MSG(total_file_length > (uint64_t)UINT32_MAX, PackedByteArray(),
8640
"glTF: File size exceeds glTF Binary's maximum of 4 GiB. Cannot serialize as a single GLB in-memory buffer.");
8641
const uint32_t binary_chunk_length = binary_data_length;
8642
8643
Ref<StreamPeerBuffer> buffer;
8644
buffer.instantiate();
8645
buffer->put_32(magic);
8646
buffer->put_32(p_state->major_version); // version
8647
buffer->put_32((uint32_t)total_file_length); // length
8648
buffer->put_32((uint32_t)text_chunk_length);
8649
buffer->put_32(text_chunk_type);
8650
buffer->put_data((uint8_t *)&cs[0], text_data_length);
8651
for (uint64_t pad_i = text_data_length; pad_i < text_chunk_length; pad_i++) {
8652
buffer->put_8(' ');
8653
}
8654
if (binary_chunk_length) {
8655
buffer->put_32(binary_chunk_length);
8656
buffer->put_32(binary_chunk_type);
8657
buffer->put_data(p_state->buffers[0].ptr(), binary_data_length);
8658
}
8659
return buffer->get_data_array();
8660
}
8661
8662
Node *GLTFDocument::_generate_scene_node_tree(Ref<GLTFState> p_state) {
8663
// Generate the skeletons and skins (if any).
8664
HashMap<ObjectID, SkinSkeletonIndex> skeleton_map;
8665
Error err = SkinTool::_create_skeletons(p_state->unique_names, p_state->skins, p_state->nodes,
8666
skeleton_map, p_state->skeletons, p_state->scene_nodes, _naming_version);
8667
ERR_FAIL_COND_V_MSG(err != OK, nullptr, "glTF: Failed to create skeletons.");
8668
err = _create_skins(p_state);
8669
ERR_FAIL_COND_V_MSG(err != OK, nullptr, "glTF: Failed to create skins.");
8670
// Run pre-generate for each extension, in case an extension needs to do something before generating the scene.
8671
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
8672
ERR_CONTINUE(ext.is_null());
8673
err = ext->import_pre_generate(p_state);
8674
ERR_CONTINUE(err != OK);
8675
}
8676
// Generate the node tree.
8677
Node *single_root;
8678
if (p_state->extensions_used.has("GODOT_single_root")) {
8679
if (_naming_version < 2) {
8680
_generate_scene_node_compat_4pt4(p_state, 0, nullptr, nullptr);
8681
} else {
8682
_generate_scene_node(p_state, 0, nullptr, nullptr);
8683
}
8684
single_root = p_state->scene_nodes[0];
8685
if (single_root && single_root->get_owner() && single_root->get_owner() != single_root) {
8686
single_root = single_root->get_owner();
8687
}
8688
} else {
8689
single_root = memnew(Node3D);
8690
for (int32_t root_i = 0; root_i < p_state->root_nodes.size(); root_i++) {
8691
if (_naming_version < 2) {
8692
_generate_scene_node_compat_4pt4(p_state, p_state->root_nodes[root_i], single_root, single_root);
8693
} else {
8694
_generate_scene_node(p_state, p_state->root_nodes[root_i], single_root, single_root);
8695
}
8696
}
8697
}
8698
// Assign the scene name and single root name to each other
8699
// if one is missing, or do nothing if both are already set.
8700
if (unlikely(p_state->scene_name.is_empty())) {
8701
p_state->scene_name = single_root->get_name();
8702
} else if (single_root->get_name() == StringName()) {
8703
if (_naming_version == 0) {
8704
single_root->set_name(p_state->scene_name);
8705
} else {
8706
single_root->set_name(_gen_unique_name(p_state, p_state->scene_name));
8707
}
8708
}
8709
return single_root;
8710
}
8711
8712
Error GLTFDocument::_parse_asset_header(Ref<GLTFState> p_state) {
8713
if (!p_state->json.has("asset")) {
8714
return ERR_PARSE_ERROR;
8715
}
8716
Dictionary asset = p_state->json["asset"];
8717
if (!asset.has("version")) {
8718
return ERR_PARSE_ERROR;
8719
}
8720
String version = asset["version"];
8721
p_state->major_version = version.get_slicec('.', 0).to_int();
8722
p_state->minor_version = version.get_slicec('.', 1).to_int();
8723
if (asset.has("copyright")) {
8724
p_state->copyright = asset["copyright"];
8725
}
8726
return OK;
8727
}
8728
8729
Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> p_state, const String &p_search_path) {
8730
Error err;
8731
8732
/* PARSE EXTENSIONS */
8733
err = _parse_gltf_extensions(p_state);
8734
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8735
8736
/* PARSE SCENE */
8737
err = _parse_scenes(p_state);
8738
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8739
8740
/* PARSE NODES */
8741
err = _parse_nodes(p_state);
8742
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8743
8744
/* PARSE BUFFERS */
8745
err = _parse_buffers(p_state, p_search_path);
8746
8747
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8748
8749
/* PARSE BUFFER VIEWS */
8750
err = _parse_buffer_views(p_state);
8751
8752
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8753
8754
/* PARSE ACCESSORS */
8755
err = _parse_accessors(p_state);
8756
8757
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8758
8759
if (!p_state->discard_meshes_and_materials) {
8760
/* PARSE IMAGES */
8761
err = _parse_images(p_state, p_search_path);
8762
8763
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8764
8765
/* PARSE TEXTURE SAMPLERS */
8766
err = _parse_texture_samplers(p_state);
8767
8768
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8769
8770
/* PARSE TEXTURES */
8771
err = _parse_textures(p_state);
8772
8773
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8774
8775
/* PARSE TEXTURES */
8776
err = _parse_materials(p_state);
8777
8778
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8779
}
8780
8781
/* PARSE SKINS */
8782
err = _parse_skins(p_state);
8783
8784
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8785
8786
/* DETERMINE SKELETONS */
8787
if (p_state->get_import_as_skeleton_bones()) {
8788
err = SkinTool::_determine_skeletons(p_state->skins, p_state->nodes, p_state->skeletons, p_state->root_nodes, true);
8789
} else {
8790
err = SkinTool::_determine_skeletons(p_state->skins, p_state->nodes, p_state->skeletons, Vector<GLTFNodeIndex>(), _naming_version < 2);
8791
}
8792
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8793
8794
/* ASSIGN SCENE NODE NAMES */
8795
// This must be run AFTER determining skeletons, and BEFORE parsing animations.
8796
_assign_node_names(p_state);
8797
8798
/* PARSE MESHES (we have enough info now) */
8799
err = _parse_meshes(p_state);
8800
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8801
8802
/* PARSE LIGHTS */
8803
err = _parse_lights(p_state);
8804
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8805
8806
/* PARSE CAMERAS */
8807
err = _parse_cameras(p_state);
8808
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8809
8810
/* PARSE ANIMATIONS */
8811
err = _parse_animations(p_state);
8812
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
8813
8814
return OK;
8815
}
8816
8817
PackedByteArray GLTFDocument::generate_buffer(Ref<GLTFState> p_state) {
8818
Ref<GLTFState> state = p_state;
8819
ERR_FAIL_COND_V(state.is_null(), PackedByteArray());
8820
// For buffers, set the state filename to an empty string, but
8821
// don't touch the base path, in case the user set it manually.
8822
state->filename = "";
8823
Error err = _serialize(state);
8824
ERR_FAIL_COND_V(err != OK, PackedByteArray());
8825
PackedByteArray bytes = _serialize_glb_buffer(state, &err);
8826
return bytes;
8827
}
8828
8829
Error GLTFDocument::write_to_filesystem(Ref<GLTFState> p_state, const String &p_path) {
8830
Ref<GLTFState> state = p_state;
8831
ERR_FAIL_COND_V(state.is_null(), ERR_INVALID_PARAMETER);
8832
state->set_base_path(p_path.get_base_dir());
8833
state->filename = p_path.get_file();
8834
Error err = _serialize(state);
8835
if (err != OK) {
8836
return err;
8837
}
8838
err = _serialize_file(state, p_path);
8839
if (err != OK) {
8840
return Error::FAILED;
8841
}
8842
return OK;
8843
}
8844
8845
Node *GLTFDocument::generate_scene(Ref<GLTFState> p_state, float p_bake_fps, bool p_trimming, bool p_remove_immutable_tracks) {
8846
Ref<GLTFState> state = p_state;
8847
ERR_FAIL_COND_V(state.is_null(), nullptr);
8848
ERR_FAIL_INDEX_V(0, state->root_nodes.size(), nullptr);
8849
Error err = OK;
8850
p_state->set_bake_fps(p_bake_fps);
8851
Node *root = _generate_scene_node_tree(state);
8852
ERR_FAIL_NULL_V(root, nullptr);
8853
_process_mesh_instances(state, root);
8854
if (state->get_create_animations() && state->animations.size()) {
8855
AnimationPlayer *ap = memnew(AnimationPlayer);
8856
root->add_child(ap, true);
8857
ap->set_owner(root);
8858
for (int i = 0; i < state->animations.size(); i++) {
8859
_import_animation(state, ap, i, p_trimming, p_remove_immutable_tracks);
8860
}
8861
}
8862
for (KeyValue<GLTFNodeIndex, Node *> E : state->scene_nodes) {
8863
ERR_CONTINUE(!E.value);
8864
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
8865
ERR_CONTINUE(ext.is_null());
8866
Dictionary node_json;
8867
if (state->json.has("nodes")) {
8868
Array nodes = state->json["nodes"];
8869
if (0 <= E.key && E.key < nodes.size()) {
8870
node_json = nodes[E.key];
8871
}
8872
}
8873
Ref<GLTFNode> gltf_node = state->nodes[E.key];
8874
err = ext->import_node(p_state, gltf_node, node_json, E.value);
8875
ERR_CONTINUE(err != OK);
8876
}
8877
}
8878
ImporterMeshInstance3D *root_importer_mesh = Object::cast_to<ImporterMeshInstance3D>(root);
8879
if (unlikely(root_importer_mesh)) {
8880
root = GLTFDocumentExtensionConvertImporterMesh::convert_importer_mesh_instance_3d(root_importer_mesh);
8881
memdelete(root_importer_mesh);
8882
}
8883
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
8884
ERR_CONTINUE(ext.is_null());
8885
err = ext->import_post(p_state, root);
8886
ERR_CONTINUE(err != OK);
8887
}
8888
ERR_FAIL_NULL_V(root, nullptr);
8889
return root;
8890
}
8891
8892
Error GLTFDocument::append_from_scene(Node *p_node, Ref<GLTFState> p_state, uint32_t p_flags) {
8893
ERR_FAIL_NULL_V(p_node, FAILED);
8894
Ref<GLTFState> state = p_state;
8895
ERR_FAIL_COND_V(state.is_null(), FAILED);
8896
state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS;
8897
state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS;
8898
state->force_generate_tangents = p_flags & GLTF_IMPORT_GENERATE_TANGENT_ARRAYS;
8899
state->force_disable_compression = p_flags & GLTF_IMPORT_FORCE_DISABLE_MESH_COMPRESSION;
8900
if (!state->buffers.size()) {
8901
state->buffers.push_back(Vector<uint8_t>());
8902
}
8903
// Perform export preflight for document extensions. Only extensions that
8904
// return OK will be used for the rest of the export steps.
8905
document_extensions.clear();
8906
for (Ref<GLTFDocumentExtension> ext : all_document_extensions) {
8907
ERR_CONTINUE(ext.is_null());
8908
Error err = ext->export_preflight(state, p_node);
8909
if (err == OK) {
8910
document_extensions.push_back(ext);
8911
}
8912
}
8913
// Add the root node(s) and their descendants to the state.
8914
if (_root_node_mode == RootNodeMode::ROOT_NODE_MODE_MULTI_ROOT) {
8915
const int child_count = p_node->get_child_count();
8916
for (int i = 0; i < child_count; i++) {
8917
_convert_scene_node(state, p_node->get_child(i), -1, -1);
8918
}
8919
state->scene_name = p_node->get_name();
8920
} else {
8921
if (_root_node_mode == RootNodeMode::ROOT_NODE_MODE_SINGLE_ROOT) {
8922
state->extensions_used.append("GODOT_single_root");
8923
}
8924
_convert_scene_node(state, p_node, -1, -1);
8925
}
8926
// Run post-convert for each extension, in case an extension needs to do something after converting the scene.
8927
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
8928
ERR_CONTINUE(ext.is_null());
8929
Error err = ext->export_post_convert(p_state, p_node);
8930
ERR_CONTINUE(err != OK);
8931
}
8932
return OK;
8933
}
8934
8935
Error GLTFDocument::append_from_buffer(PackedByteArray p_bytes, String p_base_path, Ref<GLTFState> p_state, uint32_t p_flags) {
8936
Ref<GLTFState> state = p_state;
8937
ERR_FAIL_COND_V(state.is_null(), FAILED);
8938
// TODO Add missing texture and missing .bin file paths to r_missing_deps 2021-09-10 fire
8939
Error err = FAILED;
8940
state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS;
8941
state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS;
8942
state->force_generate_tangents = p_flags & GLTF_IMPORT_GENERATE_TANGENT_ARRAYS;
8943
state->force_disable_compression = p_flags & GLTF_IMPORT_FORCE_DISABLE_MESH_COMPRESSION;
8944
8945
Ref<FileAccessMemory> file_access;
8946
file_access.instantiate();
8947
file_access->open_custom(p_bytes.ptr(), p_bytes.size());
8948
state->set_base_path(p_base_path.get_base_dir());
8949
err = _parse(p_state, state->base_path, file_access);
8950
ERR_FAIL_COND_V(err != OK, err);
8951
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
8952
ERR_CONTINUE(ext.is_null());
8953
err = ext->import_post_parse(state);
8954
ERR_FAIL_COND_V(err != OK, err);
8955
}
8956
return OK;
8957
}
8958
8959
Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> p_state, uint32_t p_flags, String p_base_path) {
8960
Ref<GLTFState> state = p_state;
8961
// TODO Add missing texture and missing .bin file paths to r_missing_deps 2021-09-10 fire
8962
if (state == Ref<GLTFState>()) {
8963
state.instantiate();
8964
}
8965
state->set_filename(p_path.get_file().get_basename());
8966
state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS;
8967
state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS;
8968
state->force_generate_tangents = p_flags & GLTF_IMPORT_GENERATE_TANGENT_ARRAYS;
8969
state->force_disable_compression = p_flags & GLTF_IMPORT_FORCE_DISABLE_MESH_COMPRESSION;
8970
8971
Error err;
8972
Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::READ, &err);
8973
ERR_FAIL_COND_V_MSG(err != OK, err, vformat(R"(Can't open file at path "%s")", p_path));
8974
ERR_FAIL_COND_V(file.is_null(), ERR_FILE_CANT_OPEN);
8975
String base_path = p_base_path;
8976
if (base_path.is_empty()) {
8977
base_path = p_path.get_base_dir();
8978
}
8979
state->set_base_path(base_path);
8980
err = _parse(p_state, base_path, file);
8981
ERR_FAIL_COND_V(err != OK, err);
8982
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
8983
ERR_CONTINUE(ext.is_null());
8984
err = ext->import_post_parse(p_state);
8985
ERR_FAIL_COND_V(err != OK, err);
8986
}
8987
return OK;
8988
}
8989
8990
Error GLTFDocument::_parse_gltf_extensions(Ref<GLTFState> p_state) {
8991
ERR_FAIL_COND_V(p_state.is_null(), ERR_PARSE_ERROR);
8992
if (p_state->json.has("extensionsUsed")) {
8993
Vector<String> ext_array = p_state->json["extensionsUsed"];
8994
p_state->extensions_used = ext_array;
8995
}
8996
if (p_state->json.has("extensionsRequired")) {
8997
Vector<String> ext_array = p_state->json["extensionsRequired"];
8998
p_state->extensions_required = ext_array;
8999
}
9000
HashSet<String> supported_extensions = get_supported_gltf_extensions_hashset();
9001
Error ret = OK;
9002
for (int i = 0; i < p_state->extensions_required.size(); i++) {
9003
if (!supported_extensions.has(p_state->extensions_required[i])) {
9004
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?");
9005
ret = ERR_UNAVAILABLE;
9006
}
9007
}
9008
return ret;
9009
}
9010
9011
void GLTFDocument::set_root_node_mode(GLTFDocument::RootNodeMode p_root_node_mode) {
9012
_root_node_mode = p_root_node_mode;
9013
}
9014
9015
GLTFDocument::RootNodeMode GLTFDocument::get_root_node_mode() const {
9016
return _root_node_mode;
9017
}
9018
9019
void GLTFDocument::set_visibility_mode(VisibilityMode p_visibility_mode) {
9020
_visibility_mode = p_visibility_mode;
9021
}
9022
9023
GLTFDocument::VisibilityMode GLTFDocument::get_visibility_mode() const {
9024
return _visibility_mode;
9025
}
9026
9027
String GLTFDocument::_gen_unique_name_static(HashSet<String> &r_unique_names, const String &p_name) {
9028
const String s_name = p_name.validate_node_name();
9029
9030
String u_name;
9031
int index = 1;
9032
while (true) {
9033
u_name = s_name;
9034
9035
if (index > 1) {
9036
u_name += itos(index);
9037
}
9038
if (!r_unique_names.has(u_name)) {
9039
break;
9040
}
9041
index++;
9042
}
9043
9044
r_unique_names.insert(u_name);
9045
9046
return u_name;
9047
}
9048
9049