Skip to content

Instantly share code, notes, and snippets.

@Miouyouyou
Created December 5, 2020 19:16
Show Gist options
  • Save Miouyouyou/7843e81effb22770b8a1b7411e18fd6f to your computer and use it in GitHub Desktop.
Save Miouyouyou/7843e81effb22770b8a1b7411e18fd6f to your computer and use it in GitHub Desktop.
GLTF Document changes
--- gltf_document.cpp 2020-12-05 20:03:10.357261955 +0100
+++ ../godot/modules/gltf/gltf_document.cpp 2020-12-05 19:55:20.862232677 +0100
@@ -45,11 +45,12 @@
#include "thirdparty/misc/rjm_texbleed.h"
-#include "core/bind/core_bind.h"
+#include "core/core_bind.h"
#include "core/crypto/crypto_core.h"
#include "core/io/json.h"
#include "core/math/disjoint_set.h"
#include "core/os/file_access.h"
+#include "core/variant/typed_array.h"
#include "core/version.h"
#include "core/version_hash.gen.h"
#include "drivers/png/png_driver_common.h"
@@ -58,18 +59,17 @@
#include "modules/gridmap/grid_map.h"
#include "modules/regex/regex.h"
#include "scene/2d/node_2d.h"
-#include "scene/3d/bone_attachment.h"
-#include "scene/3d/camera.h"
-#include "scene/3d/mesh_instance.h"
-#include "scene/3d/multimesh_instance.h"
-#include "scene/3d/skeleton.h"
-#include "scene/3d/spatial.h"
+#include "scene/3d/bone_attachment_3d.h"
+#include "scene/3d/camera_3d.h"
+#include "scene/3d/mesh_instance_3d.h"
+#include "scene/3d/multimesh_instance_3d.h"
+#include "scene/3d/node_3d.h"
+#include "scene/3d/skeleton_3d.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/surface_tool.h"
#include <limits>
Error GLTFDocument::serialize(Ref<GLTFState> state, const String &p_path) {
-
uint64_t begin_time = OS::get_singleton()->get_ticks_usec();
if (!state->buffers.size()) {
@@ -215,7 +215,6 @@
}
Error GLTFDocument::_parse_json(const String &p_path, Ref<GLTFState> state) {
-
Error err;
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err);
if (!f) {
@@ -244,7 +243,7 @@
Error GLTFDocument::_serialize_bone_attachment(Ref<GLTFState> state) {
for (int skeleton_i = 0; skeleton_i < state->skeletons.size(); skeleton_i++) {
for (int attachment_i = 0; attachment_i < state->skeletons[skeleton_i]->bone_attachments.size(); attachment_i++) {
- BoneAttachment *bone_attachment = state->skeletons[skeleton_i]->bone_attachments[attachment_i];
+ BoneAttachment3D *bone_attachment = state->skeletons[skeleton_i]->bone_attachments[attachment_i];
String bone_name = bone_attachment->get_bone_name();
bone_name = _sanitize_bone_name(bone_name);
int32_t bone = state->skeletons[skeleton_i]->godot_skeleton->find_bone(bone_name);
@@ -266,7 +265,6 @@
}
Error GLTFDocument::_parse_glb(const String &p_path, Ref<GLTFState> state) {
-
Error err;
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err);
if (!f) {
@@ -447,7 +445,6 @@
}
String GLTFDocument::_gen_unique_name(Ref<GLTFState> state, const String &p_name) {
-
const String s_name = _sanitize_scene_name(p_name);
String name;
@@ -491,7 +488,6 @@
}
String GLTFDocument::_gen_unique_bone_name(Ref<GLTFState> state, const GLTFSkeletonIndex skel_i, const String &p_name) {
-
String s_name = _sanitize_bone_name(p_name);
if (s_name.empty()) {
s_name = "bone";
@@ -516,7 +512,6 @@
}
Error GLTFDocument::_parse_scenes(Ref<GLTFState> state) {
-
ERR_FAIL_COND_V(!state->json.has("scenes"), ERR_FILE_CORRUPT);
const Array &scenes = state->json["scenes"];
int loaded_scene = 0;
@@ -546,11 +541,9 @@
}
Error GLTFDocument::_parse_nodes(Ref<GLTFState> state) {
-
ERR_FAIL_COND_V(!state->json.has("nodes"), ERR_FILE_CORRUPT);
const Array &nodes = state->json["nodes"];
for (int i = 0; i < nodes.size(); i++) {
-
Ref<GLTFNode> node;
node.instance();
const Dictionary &n = nodes[i];
@@ -570,7 +563,6 @@
if (n.has("matrix")) {
node->xform = _arr_to_xform(n["matrix"]);
} else {
-
if (n.has("translation")) {
node->translation = _arr_to_vec3(n["translation"]);
}
@@ -608,7 +600,6 @@
// build the hierarchy
for (GLTFNodeIndex node_i = 0; node_i < state->nodes.size(); node_i++) {
-
for (int j = 0; j < state->nodes[node_i]->children.size(); j++) {
GLTFNodeIndex child_i = state->nodes[node_i]->children[j];
@@ -625,7 +616,6 @@
}
void GLTFDocument::_compute_node_heights(Ref<GLTFState> state) {
-
state->root_nodes.clear();
for (GLTFNodeIndex node_i = 0; node_i < state->nodes.size(); ++node_i) {
Ref<GLTFNode> node = state->nodes[node_i];
@@ -647,7 +637,6 @@
}
static Vector<uint8_t> _parse_base64_uri(const String &uri) {
-
int start = uri.find(",");
ERR_FAIL_COND_V(start == -1, Vector<uint8_t>());
@@ -666,7 +655,6 @@
return buf;
}
Error GLTFDocument::_encode_buffer_glb(Ref<GLTFState> state, const String &p_path) {
-
print_verbose("glTF: Total buffers: " + itos(state->buffers.size()));
if (!state->buffers.size()) {
@@ -707,7 +695,6 @@
}
Error GLTFDocument::_encode_buffer_bins(Ref<GLTFState> state, const String &p_path) {
-
print_verbose("glTF: Total buffers: " + itos(state->buffers.size()));
if (!state->buffers.size()) {
@@ -741,30 +728,32 @@
}
Error GLTFDocument::_parse_buffers(Ref<GLTFState> state, const String &p_base_path) {
-
- if (!state->json.has("buffers"))
+ if (!state->json.has("buffers")) {
return OK;
+ }
const Array &buffers = state->json["buffers"];
for (GLTFBufferIndex i = 0; i < buffers.size(); i++) {
-
if (i == 0 && state->glb_data.size()) {
state->buffers.push_back(state->glb_data);
+
} else {
const Dictionary &buffer = buffers[i];
if (buffer.has("uri")) {
-
Vector<uint8_t> buffer_data;
String uri = buffer["uri"];
- if (uri.findn("data:application/octet-stream;base64") == 0) {
- //embedded data
+ if (uri.begins_with("data:")) { // Embedded data using base64.
+ // Validate data MIME types and throw an error if it's one we don't know/support.
+ if (!uri.begins_with("data:application/octet-stream;base64") &&
+ !uri.begins_with("data:application/gltf-buffer;base64")) {
+ ERR_PRINT("glTF: Got buffer with an unknown URI data type: " + uri);
+ }
buffer_data = _parse_base64_uri(uri);
- } else {
-
- uri = p_base_path.plus_file(uri).replace("\\", "/"); //fix for windows
+ } else { // Relative path to an external image file.
+ uri = p_base_path.plus_file(uri).replace("\\", "/"); // Fix for Windows.
buffer_data = FileAccess::get_file_as_array(uri);
- ERR_FAIL_COND_V(buffer.size() == 0, ERR_PARSE_ERROR);
+ ERR_FAIL_COND_V_MSG(buffer.size() == 0, ERR_PARSE_ERROR, "glTF: Couldn't load binary file as an array: " + uri);
}
ERR_FAIL_COND_V(!buffer.has("byteLength"), ERR_PARSE_ERROR);
@@ -781,10 +770,8 @@
}
Error GLTFDocument::_encode_buffer_views(Ref<GLTFState> state) {
-
Array buffers;
for (GLTFBufferViewIndex i = 0; i < state->buffer_views.size(); i++) {
-
Dictionary d;
Ref<GLTFBufferView> buffer_view = state->buffer_views[i];
@@ -811,11 +798,9 @@
}
Error GLTFDocument::_parse_buffer_views(Ref<GLTFState> state) {
-
ERR_FAIL_COND_V(!state->json.has("bufferViews"), ERR_FILE_CORRUPT);
const Array &buffers = state->json["bufferViews"];
for (GLTFBufferViewIndex i = 0; i < buffers.size(); i++) {
-
const Dictionary &d = buffers[i];
Ref<GLTFBufferView> buffer_view;
@@ -848,10 +833,8 @@
}
Error GLTFDocument::_encode_accessors(Ref<GLTFState> state) {
-
Array accessors;
for (GLTFAccessorIndex i = 0; i < state->accessors.size(); i++) {
-
Dictionary d;
Ref<GLTFAccessor> accessor = state->accessors[i];
@@ -904,7 +887,6 @@
}
String GLTFDocument::_get_accessor_type_name(const GLTFDocument::GLTFType p_type) {
-
if (p_type == GLTFDocument::TYPE_SCALAR) {
return "SCALAR";
}
@@ -931,7 +913,6 @@
}
GLTFDocument::GLTFType GLTFDocument::_get_type_from_str(const String &p_string) {
-
if (p_string == "SCALAR")
return GLTFDocument::TYPE_SCALAR;
@@ -953,11 +934,9 @@
}
Error GLTFDocument::_parse_accessors(Ref<GLTFState> state) {
-
ERR_FAIL_COND_V(!state->json.has("accessors"), ERR_FILE_CORRUPT);
const Array &accessors = state->json["accessors"];
for (GLTFAccessorIndex i = 0; i < accessors.size(); i++) {
-
const Dictionary &d = accessors[i];
Ref<GLTFAccessor> accessor;
@@ -1024,7 +1003,6 @@
}
String GLTFDocument::_get_component_type_name(const uint32_t p_component) {
-
switch (p_component) {
case GLTFDocument::COMPONENT_TYPE_BYTE:
return "Byte";
@@ -1044,7 +1022,6 @@
}
String GLTFDocument::_get_type_name(const GLTFType p_component) {
-
static const char *names[] = {
"float",
"vec2",
@@ -1059,7 +1036,6 @@
}
Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> state, const double *src, const int count, const GLTFType type, const int component_type, const bool normalized, const int byte_offset, const bool for_vertex, GLTFBufferViewIndex &r_accessor) {
-
const int component_count_for_type[7] = {
1, 2, 3, 4, 4, 9, 16
};
@@ -1074,7 +1050,6 @@
switch (component_type) {
case COMPONENT_TYPE_BYTE:
case COMPONENT_TYPE_UNSIGNED_BYTE: {
-
if (type == TYPE_MAT2) {
skip_every = 2;
skip_bytes = 2;
@@ -1258,7 +1233,6 @@
}
Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> state, double *dst, const GLTFBufferViewIndex p_buffer_view, const int skip_every, const int skip_bytes, const int element_size, const int count, const GLTFType type, const int component_count, const int component_type, const int component_size, const bool normalized, const int byte_offset, const bool for_vertex) {
-
const Ref<GLTFBufferView> bv = state->buffer_views[p_buffer_view];
int stride = element_size;
@@ -1287,11 +1261,9 @@
//fill everything as doubles
for (int i = 0; i < count; i++) {
-
const uint8_t *src = &bufptr[offset + i * stride];
for (int j = 0; j < component_count; j++) {
-
if (skip_every && j > 0 && (j % skip_every) == 0) {
src += skip_bytes;
}
@@ -1348,7 +1320,6 @@
}
int GLTFDocument::_get_component_type_size(const int component_type) {
-
switch (component_type) {
case COMPONENT_TYPE_BYTE:
case COMPONENT_TYPE_UNSIGNED_BYTE:
@@ -1372,7 +1343,6 @@
}
Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
//spec, for reference:
//https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
@@ -1395,7 +1365,6 @@
switch (a->component_type) {
case COMPONENT_TYPE_BYTE:
case COMPONENT_TYPE_UNSIGNED_BYTE: {
-
if (a->type == TYPE_MAT2) {
skip_every = 2;
skip_bytes = 2;
@@ -1424,7 +1393,6 @@
double *dst = dst_buffer.ptrw();
if (a->buffer_view >= 0) {
-
ERR_FAIL_INDEX_V(a->buffer_view, state->buffer_views.size(), Vector<double>());
const Error err = _decode_buffer_view(state, dst, a->buffer_view, skip_every, skip_bytes, element_size, a->count, a->type, component_count, a->component_type, component_size, a->normalized, a->byte_offset, p_for_vertex);
@@ -1466,7 +1434,6 @@
}
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref<GLTFState> state, const Vector<int32_t> p_attribs, const bool p_for_vertex) {
-
if (p_attribs.size() == 0) {
return -1;
}
@@ -1513,7 +1480,6 @@
}
Vector<int> GLTFDocument::_decode_accessor_as_ints(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<int> ret;
@@ -1532,7 +1498,6 @@
}
Vector<float> GLTFDocument::_decode_accessor_as_floats(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<float> ret;
@@ -1551,7 +1516,6 @@
}
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref<GLTFState> state, const Vector<Vector2> p_attribs, const bool p_for_vertex) {
-
if (p_attribs.size() == 0) {
return -1;
}
@@ -1611,7 +1575,6 @@
}
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref<GLTFState> state, const Vector<Color> p_attribs, const bool p_for_vertex) {
-
if (p_attribs.size() == 0) {
return -1;
}
@@ -1684,7 +1647,6 @@
}
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref<GLTFState> state, const Vector<Color> p_attribs, const bool p_for_vertex) {
-
if (p_attribs.size() == 0) {
return -1;
}
@@ -1760,7 +1722,6 @@
}
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref<GLTFState> state, const Vector<Color> p_attribs, const bool p_for_vertex) {
-
if (p_attribs.size() == 0) {
return -1;
}
@@ -1834,7 +1795,6 @@
}
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quats(Ref<GLTFState> state, const Vector<Quat> p_attribs, const bool p_for_vertex) {
-
if (p_attribs.size() == 0) {
return -1;
}
@@ -1909,7 +1869,6 @@
}
Vector<Vector2> GLTFDocument::_decode_accessor_as_vec2(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Vector2> ret;
@@ -1977,7 +1936,6 @@
}
GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref<GLTFState> state, const Vector<Vector3> p_attribs, const bool p_for_vertex) {
-
if (p_attribs.size() == 0) {
return -1;
}
@@ -2197,7 +2155,6 @@
}
Vector<Vector3> GLTFDocument::_decode_accessor_as_vec3(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Vector3> ret;
@@ -2217,7 +2174,6 @@
}
Vector<Color> GLTFDocument::_decode_accessor_as_color(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Color> ret;
@@ -2243,7 +2199,6 @@
return ret;
}
Vector<Quat> GLTFDocument::_decode_accessor_as_quat(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Quat> ret;
@@ -2262,7 +2217,6 @@
return ret;
}
Vector<Transform2D> GLTFDocument::_decode_accessor_as_xform2d(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Transform2D> ret;
@@ -2279,7 +2233,6 @@
}
Vector<Basis> GLTFDocument::_decode_accessor_as_basis(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Basis> ret;
@@ -2297,7 +2250,6 @@
}
Vector<Transform> GLTFDocument::_decode_accessor_as_xform(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Transform> ret;
@@ -2318,7 +2270,6 @@
Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
Array meshes;
for (GLTFMeshIndex gltf_mesh_i = 0; gltf_mesh_i < state->meshes.size(); gltf_mesh_i++) {
-
print_verbose("glTF: Serializing mesh: " + itos(gltf_mesh_i));
Ref<Mesh> godot_mesh = state->meshes.write[gltf_mesh_i]->mesh;
if (godot_mesh.is_null()) {
@@ -2411,7 +2362,6 @@
{
Vector<Vector2> a = array[Mesh::ARRAY_TEX_UV2];
if (a.size()) {
-
attributes["TEXCOORD_1"] = _encode_accessor_as_vec2(state, a, true);
}
}
@@ -2501,7 +2451,6 @@
//blend shapes
print_verbose("glTF: Mesh has targets");
if (godot_mesh->get_blend_shape_count()) {
-
Array array_morphs = godot_mesh->surface_get_blend_shape_arrays(surface_i);
for (int morph_i = 0; morph_i < array_morphs.size(); morph_i++) {
target_names.push_back(godot_mesh->get_blend_shape_name(morph_i));
@@ -2593,13 +2542,11 @@
return OK;
}
Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
-
if (!state->json.has("meshes"))
return OK;
Array meshes = state->json["meshes"];
for (GLTFMeshIndex i = 0; i < meshes.size(); i++) {
-
print_verbose("glTF: Parsing mesh: " + itos(i));
Dictionary d = meshes[i];
@@ -2611,7 +2558,6 @@
const Dictionary &extras = d.has("extras") ? (Dictionary)d["extras"] : Dictionary();
for (int j = 0; j < primitives.size(); j++) {
-
Dictionary p = primitives[j];
Array array;
@@ -2763,7 +2709,6 @@
}
for (int k = 0; k < targets.size(); k++) {
-
const Dictionary &t = targets[k];
Array array_copy;
@@ -2781,7 +2726,6 @@
const int size = src_varr.size();
ERR_FAIL_COND_V(size == 0, ERR_PARSE_ERROR);
{
-
const int max_idx = varr.size();
varr.resize(size);
@@ -2822,13 +2766,11 @@
Vector<float> tangents_v4;
{
-
int max_idx = tangents_v3.size();
int size4 = src_tangents.size();
tangents_v4.resize(size4);
for (int l = 0; l < size4 / 4; l++) {
-
if (l < max_idx) {
tangents_v4.write[l * 4 + 0] = tangents_v3[l].x + src_tangents[l * 4 + 0];
tangents_v4.write[l * 4 + 1] = tangents_v3[l].y + src_tangents[l * 4 + 1];
@@ -2868,9 +2810,9 @@
array_mesh->surface_set_material(array_mesh->get_surface_count() - 1, mat);
} else {
- Ref<SpatialMaterial> mat;
+ Ref<StandardMaterial3D> mat;
mat.instance();
- mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
array_mesh->surface_set_material(array_mesh->get_surface_count() - 1, mat);
}
@@ -2905,10 +2847,8 @@
}
Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path) {
-
Array images;
for (int i = 0; i < state->images.size(); i++) {
-
Dictionary d;
ERR_CONTINUE(state->images[i].is_null());
@@ -2927,13 +2867,13 @@
bv->byte_offset = state->buffers[bi].size();
ERR_FAIL_INDEX_V(bi, state->buffers.size(), ERR_PARAMETER_RANGE_ERROR);
- PoolVector<uint8_t> buffer;
+ Vector<uint8_t> buffer;
Error err = PNGDriverCommon::image_to_png(image, buffer);
ERR_FAIL_COND_V_MSG(err, err, "Can't convert image to PNG.");
bv->byte_length = buffer.size();
state->buffers.write[bi].resize(state->buffers[bi].size() + bv->byte_length);
- copymem(&state->buffers.write[bi].write[bv->byte_offset], buffer.write().ptr(), buffer.size());
+ copymem(&state->buffers.write[bi].write[bv->byte_offset], buffer.ptr(), buffer.size());
ERR_FAIL_COND_V(bv->byte_offset + bv->byte_length > state->buffers[bi].size(), ERR_FILE_CORRUPT);
state->buffer_views.push_back(bv);
@@ -2973,48 +2913,94 @@
}
Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_path) {
-
- if (!state->json.has("images"))
+ if (!state->json.has("images")) {
return OK;
+ }
+
+ // Ref: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#images
const Array &images = state->json["images"];
for (int i = 0; i < images.size(); i++) {
-
const Dictionary &d = images[i];
+ // glTF 2.0 supports PNG and JPEG types, which can be specified as (from spec):
+ // "- a URI to an external file in one of the supported images formats, or
+ // - a URI with embedded base64-encoded data, or
+ // - a reference to a bufferView; in that case mimeType must be defined."
+ // Since mimeType is optional for external files and base64 data, we'll have to
+ // fall back on letting Godot parse the data to figure out if it's PNG or JPEG.
+
+ // We'll assume that we use either URI or bufferView, so let's warn the user
+ // if their image somehow uses both. And fail if it has neither.
+ ERR_CONTINUE_MSG(!d.has("uri") && !d.has("bufferView"), "Invalid image definition in glTF file, it should specific an 'uri' or 'bufferView'.");
+ if (d.has("uri") && d.has("bufferView")) {
+ WARN_PRINT("Invalid image definition in glTF file using both 'uri' and 'bufferView'. 'bufferView' will take precedence.");
+ }
+
String mimetype;
- if (d.has("mimeType")) {
+ if (d.has("mimeType")) { // Should be "image/png" or "image/jpeg".
mimetype = d["mimeType"];
}
Vector<uint8_t> data;
- const uint8_t *data_ptr = NULL;
+ const uint8_t *data_ptr = nullptr;
int data_size = 0;
if (d.has("uri")) {
+ // Handles the first two bullet points from the spec (embedded data, or external file).
String uri = d["uri"];
- if (uri.findn("data:application/octet-stream;base64") == 0 ||
- uri.findn("data:" + mimetype + ";base64") == 0) {
- //embedded data
+ if (uri.begins_with("data:")) { // Embedded data using base64.
+ // Validate data MIME types and throw a warning if it's one we don't know/support.
+ if (!uri.begins_with("data:application/octet-stream;base64") &&
+ !uri.begins_with("data:application/gltf-buffer;base64") &&
+ !uri.begins_with("data:image/png;base64") &&
+ !uri.begins_with("data:image/jpeg;base64")) {
+ WARN_PRINT(vformat("glTF: Image index '%d' uses an unsupported URI data type: %s. Skipping it.", i, uri));
+ state->images.push_back(Ref<Texture2D>()); // Placeholder to keep count.
+ continue;
+ }
data = _parse_base64_uri(uri);
data_ptr = data.ptr();
data_size = data.size();
- } else {
-
- uri = p_base_path.plus_file(uri).replace("\\", "/"); //fix for windows
- Ref<Texture> texture = ResourceLoader::load(uri);
- state->images.push_back(texture);
- continue;
+ // mimeType is optional, but if we have it defined in the URI, let's use it.
+ if (mimetype.empty()) {
+ if (uri.begins_with("data:image/png;base64")) {
+ mimetype = "image/png";
+ } else if (uri.begins_with("data:image/jpeg;base64")) {
+ mimetype = "image/jpeg";
+ }
+ }
+ } else { // Relative path to an external image file.
+ uri = p_base_path.plus_file(uri).replace("\\", "/"); // Fix for Windows.
+ // The spec says that if mimeType is defined, we should enforce it.
+ // So we should only rely on ResourceLoader::load if mimeType is not defined,
+ // otherwise we should use the same logic as for buffers.
+ if (mimetype == "image/png" || mimetype == "image/jpeg") {
+ // Load data buffer and rely on PNG and JPEG-specific logic below to load the image.
+ // This makes it possible to load a file with a wrong extension but correct MIME type,
+ // e.g. "foo.jpg" containing PNG data and with MIME type "image/png". ResourceLoader would fail.
+ data = FileAccess::get_file_as_array(uri);
+ ERR_FAIL_COND_V_MSG(data.size() == 0, ERR_PARSE_ERROR, "glTF: Couldn't load image file as an array: " + uri);
+ data_ptr = data.ptr();
+ data_size = data.size();
+ } else {
+ // Good old ResourceLoader will rely on file extension.
+ Ref<Texture2D> texture = ResourceLoader::load(uri);
+ state->images.push_back(texture);
+ continue;
+ }
}
- }
+ } else if (d.has("bufferView")) {
+ // Handles the third bullet point from the spec (bufferView).
+ ERR_FAIL_COND_V_MSG(mimetype.empty(), ERR_FILE_CORRUPT,
+ vformat("glTF: Image index '%d' specifies 'bufferView' but no 'mimeType', which is invalid.", i));
- if (d.has("bufferView")) {
const GLTFBufferViewIndex bvi = d["bufferView"];
ERR_FAIL_INDEX_V(bvi, state->buffer_views.size(), ERR_PARAMETER_RANGE_ERROR);
- const Ref<GLTFBufferView> bv = state->buffer_views[bvi];
+ Ref<GLTFBufferView> bv = state->buffer_views[bvi];
const GLTFBufferIndex bi = bv->buffer;
ERR_FAIL_INDEX_V(bi, state->buffers.size(), ERR_PARAMETER_RANGE_ERROR);
@@ -3025,51 +3011,42 @@
data_size = bv->byte_length;
}
- ERR_FAIL_COND_V(mimetype == "", ERR_FILE_CORRUPT);
+ Ref<Image> img;
- if (mimetype.findn("png") != -1) {
- //is a png
- ERR_FAIL_COND_V(Image::_png_mem_loader_func == NULL, ERR_UNAVAILABLE);
-
- const Ref<Image> img = Image::_png_mem_loader_func(data_ptr, data_size);
-
- ERR_FAIL_COND_V(img.is_null(), ERR_FILE_CORRUPT);
-
- Ref<ImageTexture> t;
- t.instance();
- t->create_from_image(img);
-
- state->images.push_back(t);
- continue;
+ if (mimetype == "image/png") { // Load buffer as PNG.
+ ERR_FAIL_COND_V(Image::_png_mem_loader_func == nullptr, ERR_UNAVAILABLE);
+ img = Image::_png_mem_loader_func(data_ptr, data_size);
+ } else if (mimetype == "image/jpeg") { // Loader buffer as JPEG.
+ ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == nullptr, ERR_UNAVAILABLE);
+ img = Image::_jpg_mem_loader_func(data_ptr, data_size);
+ } else {
+ // We can land here if we got an URI with base64-encoded data with application/* MIME type,
+ // and the optional mimeType property was not defined to tell us how to handle this data (or was invalid).
+ // So let's try PNG first, then JPEG.
+ ERR_FAIL_COND_V(Image::_png_mem_loader_func == nullptr, ERR_UNAVAILABLE);
+ img = Image::_png_mem_loader_func(data_ptr, data_size);
+ if (img.is_null()) {
+ ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == nullptr, ERR_UNAVAILABLE);
+ img = Image::_jpg_mem_loader_func(data_ptr, data_size);
+ }
}
- if (mimetype.findn("jpeg") != -1) {
- ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == NULL, ERR_UNAVAILABLE);
-
- //is a jpg
- const Ref<Image> img = Image::_jpg_mem_loader_func(data_ptr, data_size);
-
- ERR_FAIL_COND_V(img.is_null(), ERR_FILE_CORRUPT);
+ ERR_FAIL_COND_V_MSG(img.is_null(), ERR_FILE_CORRUPT,
+ vformat("glTF: Couldn't load image index '%d' with its given mimetype: %s.", i, mimetype));
- Ref<ImageTexture> t;
- t.instance();
- t->create_from_image(img);
-
- state->images.push_back(t);
-
- continue;
- }
+ Ref<ImageTexture> t;
+ t.instance();
+ t->create_from_image(img);
- ERR_FAIL_V(ERR_FILE_CORRUPT);
+ state->images.push_back(t);
}
- print_verbose("Total images: " + itos(state->images.size()));
+ print_verbose("glTF: Total images: " + itos(state->images.size()));
return OK;
}
Error GLTFDocument::_serialize_textures(Ref<GLTFState> state) {
-
if (!state->textures.size()) {
return OK;
}
@@ -3088,13 +3065,11 @@
}
Error GLTFDocument::_parse_textures(Ref<GLTFState> state) {
-
if (!state->json.has("textures"))
return OK;
const Array &textures = state->json["textures"];
for (GLTFTextureIndex i = 0; i < textures.size(); i++) {
-
const Dictionary &d = textures[i];
ERR_FAIL_COND_V(!d.has("source"), ERR_PARSE_ERROR);
@@ -3108,7 +3083,7 @@
return OK;
}
-GLTFTextureIndex GLTFDocument::_set_texture(Ref<GLTFState> state, Ref<Texture> p_texture) {
+GLTFTextureIndex GLTFDocument::_set_texture(Ref<GLTFState> state, Ref<Texture2D> p_texture) {
ERR_FAIL_COND_V(p_texture.is_null(), -1);
Ref<GLTFTexture> gltf_texture;
gltf_texture.instance();
@@ -3136,7 +3111,6 @@
int32_t width = target_image->get_size().x;
const int32_t bytes_in_pixel = 4;
pixels.resize(height * width * bytes_in_pixel);
- target_image->lock();
for (int32_t y = 0; y < height; y++) {
for (int32_t x = 0; x < width; x++) {
int32_t pixel_index = x + (width * y);
@@ -3148,9 +3122,7 @@
pixels.write[index + 3] = uint8_t(pixel.a * 255.0);
}
}
- target_image->unlock();
rjm_texbleed(pixels.ptrw(), width, height, 3, bytes_in_pixel, bytes_in_pixel * width);
- target_image->lock();
for (int32_t y = 0; y < height; y++) {
for (int32_t x = 0; x < width; x++) {
Color pixel;
@@ -3163,18 +3135,16 @@
target_image->set_pixel(x, y, pixel);
}
}
- target_image->unlock();
target_image->generate_mipmaps();
return target_image;
}
Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
-
Array materials;
for (int32_t i = 0; i < state->materials.size(); i++) {
Dictionary d;
- Ref<SpatialMaterial> material = state->materials[i];
+ Ref<StandardMaterial3D> material = state->materials[i];
if (material.is_null()) {
materials.push_back(d);
continue;
@@ -3195,7 +3165,7 @@
}
{
Dictionary bct;
- Ref<Texture> albedo_texture = material->get_texture(SpatialMaterial::TEXTURE_ALBEDO);
+ Ref<Texture2D> albedo_texture = material->get_texture(StandardMaterial3D::TEXTURE_ALBEDO);
Dictionary texture_transform = _serialize_texture_transform_uv1(material);
GLTFTextureIndex gltf_texture_index = -1;
@@ -3212,17 +3182,17 @@
mr["metallicFactor"] = material->get_metallic();
mr["roughnessFactor"] = material->get_roughness();
- bool has_roughness = material->get_texture(SpatialMaterial::TEXTURE_ROUGHNESS).is_valid() && material->get_texture(SpatialMaterial::TEXTURE_ROUGHNESS)->get_data().is_valid();
- bool has_ao = material->get_feature(SpatialMaterial::FEATURE_AMBIENT_OCCLUSION) && material->get_texture(SpatialMaterial::TEXTURE_AMBIENT_OCCLUSION).is_valid();
- bool has_metalness = material->get_texture(SpatialMaterial::TEXTURE_METALLIC).is_valid() && material->get_texture(SpatialMaterial::TEXTURE_METALLIC)->get_data().is_valid();
+ bool has_roughness = material->get_texture(StandardMaterial3D::TEXTURE_ROUGHNESS).is_valid() && material->get_texture(StandardMaterial3D::TEXTURE_ROUGHNESS)->get_data().is_valid();
+ bool has_ao = material->get_feature(StandardMaterial3D::FEATURE_AMBIENT_OCCLUSION) && material->get_texture(StandardMaterial3D::TEXTURE_AMBIENT_OCCLUSION).is_valid();
+ bool has_metalness = material->get_texture(StandardMaterial3D::TEXTURE_METALLIC).is_valid() && material->get_texture(StandardMaterial3D::TEXTURE_METALLIC)->get_data().is_valid();
if (has_ao || has_roughness || has_metalness) {
Dictionary mrt;
- Ref<Texture> roughness_texture = material->get_texture(SpatialMaterial::TEXTURE_ROUGHNESS);
- SpatialMaterial::TextureChannel roughness_channel = material->get_roughness_texture_channel();
- Ref<Texture> metallic_texture = material->get_texture(SpatialMaterial::TEXTURE_METALLIC);
- SpatialMaterial::TextureChannel metalness_channel = material->get_metallic_texture_channel();
- Ref<Texture> ao_texture = material->get_texture(SpatialMaterial::TEXTURE_AMBIENT_OCCLUSION);
- SpatialMaterial::TextureChannel ao_channel = material->get_ao_texture_channel();
+ Ref<Texture2D> roughness_texture = material->get_texture(StandardMaterial3D::TEXTURE_ROUGHNESS);
+ StandardMaterial3D::TextureChannel roughness_channel = material->get_roughness_texture_channel();
+ Ref<Texture2D> metallic_texture = material->get_texture(StandardMaterial3D::TEXTURE_METALLIC);
+ StandardMaterial3D::TextureChannel metalness_channel = material->get_metallic_texture_channel();
+ Ref<Texture2D> ao_texture = material->get_texture(StandardMaterial3D::TEXTURE_AMBIENT_OCCLUSION);
+ StandardMaterial3D::TextureChannel ao_channel = material->get_ao_texture_channel();
Ref<ImageTexture> orm_texture;
orm_texture.instance();
Ref<Image> orm_image;
@@ -3256,7 +3226,7 @@
metallness_image->decompress();
}
}
- Ref<Texture> albedo_texture = material->get_texture(SpatialMaterial::TEXTURE_ALBEDO);
+ Ref<Texture2D> albedo_texture = material->get_texture(StandardMaterial3D::TEXTURE_ALBEDO);
if (albedo_texture.is_valid() && albedo_texture->get_data().is_valid()) {
height = albedo_texture->get_height();
width = albedo_texture->get_width();
@@ -3271,71 +3241,45 @@
if (metallness_image.is_valid() && metallness_image->get_size() != Vector2(width, height)) {
metallness_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
}
- orm_image->lock();
for (int32_t h = 0; h < height; h++) {
for (int32_t w = 0; w < width; w++) {
Color c = Color(1.0f, 1.0f, 1.0f);
if (has_ao) {
- if (SpatialMaterial::TextureChannel::TEXTURE_CHANNEL_RED == ao_channel) {
- ao_image->lock();
+ if (StandardMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == ao_channel) {
c.r = ao_image->get_pixel(w, h).r;
- ao_image->unlock();
- } else if (SpatialMaterial::TextureChannel::TEXTURE_CHANNEL_GREEN == ao_channel) {
- ao_image->lock();
+ } else if (StandardMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == ao_channel) {
c.r = ao_image->get_pixel(w, h).g;
- ao_image->unlock();
- } else if (SpatialMaterial::TextureChannel::TEXTURE_CHANNEL_BLUE == ao_channel) {
- ao_image->lock();
+ } else if (StandardMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == ao_channel) {
c.r = ao_image->get_pixel(w, h).b;
- ao_image->unlock();
- } else if (SpatialMaterial::TextureChannel::TEXTURE_CHANNEL_ALPHA == ao_channel) {
- ao_image->lock();
+ } else if (StandardMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == ao_channel) {
c.r = ao_image->get_pixel(w, h).a;
- ao_image->unlock();
}
}
if (has_roughness) {
- if (SpatialMaterial::TextureChannel::TEXTURE_CHANNEL_RED == roughness_channel) {
- roughness_image->lock();
+ if (StandardMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == roughness_channel) {
c.g = roughness_image->get_pixel(w, h).r;
- roughness_image->unlock();
- } else if (SpatialMaterial::TextureChannel::TEXTURE_CHANNEL_GREEN == roughness_channel) {
- roughness_image->lock();
+ } else if (StandardMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == roughness_channel) {
c.g = roughness_image->get_pixel(w, h).g;
- roughness_image->unlock();
- } else if (SpatialMaterial::TextureChannel::TEXTURE_CHANNEL_BLUE == roughness_channel) {
- roughness_image->lock();
+ } else if (StandardMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == roughness_channel) {
c.g = roughness_image->get_pixel(w, h).b;
- roughness_image->unlock();
- } else if (SpatialMaterial::TextureChannel::TEXTURE_CHANNEL_ALPHA == roughness_channel) {
- roughness_image->lock();
+ } else if (StandardMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == roughness_channel) {
c.g = roughness_image->get_pixel(w, h).a;
- roughness_image->unlock();
}
}
if (has_metalness) {
- if (SpatialMaterial::TextureChannel::TEXTURE_CHANNEL_RED == metalness_channel) {
- metallness_image->lock();
+ if (StandardMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == metalness_channel) {
c.b = metallness_image->get_pixel(w, h).r;
- metallness_image->unlock();
- } else if (SpatialMaterial::TextureChannel::TEXTURE_CHANNEL_GREEN == metalness_channel) {
- metallness_image->lock();
+ } else if (StandardMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == metalness_channel) {
c.b = metallness_image->get_pixel(w, h).g;
- metallness_image->unlock();
- } else if (SpatialMaterial::TextureChannel::TEXTURE_CHANNEL_BLUE == metalness_channel) {
- metallness_image->lock();
+ } else if (StandardMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == metalness_channel) {
c.b = metallness_image->get_pixel(w, h).b;
- metallness_image->unlock();
- } else if (SpatialMaterial::TextureChannel::TEXTURE_CHANNEL_ALPHA == metalness_channel) {
- metallness_image->lock();
+ } else if (StandardMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == metalness_channel) {
c.b = metallness_image->get_pixel(w, h).a;
- metallness_image->unlock();
}
}
orm_image->set_pixel(w, h, c);
}
}
- orm_image->unlock();
orm_image->generate_mipmaps();
orm_texture->create_from_image(orm_image);
GLTFTextureIndex orm_texture_index = -1;
@@ -3357,17 +3301,16 @@
d["pbrMetallicRoughness"] = mr;
}
- if (material->get_feature(SpatialMaterial::FEATURE_NORMAL_MAPPING)) {
+ if (material->get_feature(StandardMaterial3D::FEATURE_NORMAL_MAPPING)) {
Dictionary nt;
Ref<ImageTexture> tex;
tex.instance();
{
- Ref<Texture> normal_texture = material->get_texture(SpatialMaterial::TEXTURE_NORMAL);
+ Ref<Texture2D> normal_texture = material->get_texture(StandardMaterial3D::TEXTURE_NORMAL);
// Code for uncompressing RG normal maps
Ref<Image> img = normal_texture->get_data();
img->decompress();
img->convert(Image::FORMAT_RGBA8);
- img->lock();
for (int32_t y = 0; y < img->get_height(); y++) {
for (int32_t x = 0; x < img->get_width(); x++) {
Color c = img->get_pixel(x, y);
@@ -3379,10 +3322,10 @@
img->set_pixel(x, y, c);
}
}
- img->unlock();
img = dilate(img);
tex->create_from_image(img);
}
+ Ref<Texture2D> normal_texture = material->get_texture(StandardMaterial3D::TEXTURE_NORMAL);
GLTFTextureIndex gltf_texture_index = -1;
if (tex.is_valid() && tex->get_data().is_valid()) {
tex->set_name(material->get_name() + "_normal");
@@ -3395,7 +3338,7 @@
}
}
- if (material->get_feature(SpatialMaterial::FEATURE_EMISSION)) {
+ if (material->get_feature(StandardMaterial3D::FEATURE_EMISSION)) {
const Color c = material->get_emission().to_srgb();
Array arr;
arr.push_back(c.r);
@@ -3403,9 +3346,9 @@
arr.push_back(c.b);
d["emissiveFactor"] = arr;
}
- if (material->get_feature(SpatialMaterial::FEATURE_EMISSION)) {
+ if (material->get_feature(StandardMaterial3D::FEATURE_EMISSION)) {
Dictionary et;
- Ref<Texture> emission_texture = material->get_texture(SpatialMaterial::TEXTURE_EMISSION);
+ Ref<Texture2D> emission_texture = material->get_texture(StandardMaterial3D::TEXTURE_EMISSION);
GLTFTextureIndex gltf_texture_index = -1;
if (emission_texture.is_valid() && emission_texture->get_data().is_valid()) {
emission_texture->set_name(material->get_name() + "_emission");
@@ -3417,14 +3360,14 @@
d["emissiveTexture"] = et;
}
}
- const bool ds = material->get_cull_mode() == SpatialMaterial::CULL_DISABLED;
+ const bool ds = material->get_cull_mode() == StandardMaterial3D::CULL_DISABLED;
if (ds) {
d["doubleSided"] = ds;
}
- if (material->get_flag(SpatialMaterial::FLAG_USE_ALPHA_SCISSOR) && !material->get_feature(SpatialMaterial::FEATURE_TRANSPARENT)) {
+ if (material->get_transparency() == StandardMaterial3D::TRANSPARENCY_ALPHA_SCISSOR) {
d["alphaMode"] = "MASK";
d["alphaCutoff"] = material->get_alpha_scissor_threshold();
- } else if (material->get_feature(SpatialMaterial::FEATURE_TRANSPARENT)) {
+ } else if (material->get_transparency() != StandardMaterial3D::TRANSPARENCY_DISABLED) {
d["alphaMode"] = "BLEND";
}
materials.push_back(d);
@@ -3436,21 +3379,19 @@
}
Error GLTFDocument::_parse_materials(Ref<GLTFState> state) {
-
if (!state->json.has("materials"))
return OK;
const Array &materials = state->json["materials"];
for (GLTFMaterialIndex i = 0; i < materials.size(); i++) {
-
const Dictionary &d = materials[i];
- Ref<SpatialMaterial> material;
+ Ref<StandardMaterial3D> material;
material.instance();
if (d.has("name")) {
material->set_name(d["name"]);
}
- material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
Dictionary pbr_spec_gloss_extensions;
if (d.has("extensions")) {
pbr_spec_gloss_extensions = d["extensions"];
@@ -3464,10 +3405,10 @@
if (sgm.has("diffuseTexture")) {
const Dictionary &diffuse_texture_dict = sgm["diffuseTexture"];
if (diffuse_texture_dict.has("index")) {
- Ref<Texture> diffuse_texture = _get_texture(state, diffuse_texture_dict["index"]);
+ Ref<Texture2D> diffuse_texture = _get_texture(state, diffuse_texture_dict["index"]);
if (diffuse_texture.is_valid()) {
spec_gloss->diffuse_img = diffuse_texture->get_data();
- material->set_texture(SpatialMaterial::TEXTURE_ALBEDO, diffuse_texture);
+ material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, diffuse_texture);
}
}
}
@@ -3492,7 +3433,7 @@
if (sgm.has("specularGlossinessTexture")) {
const Dictionary &spec_gloss_texture = sgm["specularGlossinessTexture"];
if (spec_gloss_texture.has("index")) {
- const Ref<Texture> orig_texture = _get_texture(state, spec_gloss_texture["index"]);
+ const Ref<Texture2D> orig_texture = _get_texture(state, spec_gloss_texture["index"]);
if (orig_texture.is_valid()) {
spec_gloss->spec_gloss_img = orig_texture->get_data();
}
@@ -3500,7 +3441,6 @@
}
spec_gloss_to_rough_metal(spec_gloss, material);
} else if (d.has("pbrMetallicRoughness")) {
-
const Dictionary &mr = d["pbrMetallicRoughness"];
if (mr.has("baseColorFactor")) {
const Array &arr = mr["baseColorFactor"];
@@ -3513,7 +3453,7 @@
if (mr.has("baseColorTexture")) {
const Dictionary &bct = mr["baseColorTexture"];
if (bct.has("index")) {
- material->set_texture(SpatialMaterial::TEXTURE_ALBEDO, _get_texture(state, bct["index"]));
+ material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, _get_texture(state, bct["index"]));
}
if (bct.has("extensions")) {
const Dictionary &extensions = bct["extensions"];
@@ -3551,10 +3491,10 @@
const Dictionary &bct = mr["metallicRoughnessTexture"];
if (bct.has("index")) {
const Ref<Texture> t = _get_texture(state, bct["index"]);
- material->set_texture(SpatialMaterial::TEXTURE_METALLIC, t);
- material->set_metallic_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_BLUE);
- material->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, t);
- material->set_roughness_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_GREEN);
+ material->set_texture(StandardMaterial3D::TEXTURE_METALLIC, t);
+ material->set_metallic_texture_channel(StandardMaterial3D::TEXTURE_CHANNEL_BLUE);
+ material->set_texture(StandardMaterial3D::TEXTURE_ROUGHNESS, t);
+ material->set_roughness_texture_channel(StandardMaterial3D::TEXTURE_CHANNEL_GREEN);
if (!mr.has("metallicFactor")) {
material->set_metallic(1);
}
@@ -3568,8 +3508,8 @@
if (d.has("normalTexture")) {
const Dictionary &bct = d["normalTexture"];
if (bct.has("index")) {
- material->set_texture(SpatialMaterial::TEXTURE_NORMAL, _get_texture(state, bct["index"]));
- material->set_feature(SpatialMaterial::FEATURE_NORMAL_MAPPING, true);
+ material->set_texture(StandardMaterial3D::TEXTURE_NORMAL, _get_texture(state, bct["index"]));
+ material->set_feature(StandardMaterial3D::FEATURE_NORMAL_MAPPING, true);
}
if (bct.has("scale")) {
material->set_normal_scale(bct["scale"]);
@@ -3578,9 +3518,9 @@
if (d.has("occlusionTexture")) {
const Dictionary &bct = d["occlusionTexture"];
if (bct.has("index")) {
- material->set_texture(SpatialMaterial::TEXTURE_AMBIENT_OCCLUSION, _get_texture(state, bct["index"]));
- material->set_ao_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_RED);
- material->set_feature(SpatialMaterial::FEATURE_AMBIENT_OCCLUSION, true);
+ material->set_texture(StandardMaterial3D::TEXTURE_AMBIENT_OCCLUSION, _get_texture(state, bct["index"]));
+ material->set_ao_texture_channel(StandardMaterial3D::TEXTURE_CHANNEL_RED);
+ material->set_feature(StandardMaterial3D::FEATURE_AMBIENT_OCCLUSION, true);
}
}
@@ -3588,7 +3528,7 @@
const Array &arr = d["emissiveFactor"];
ERR_FAIL_COND_V(arr.size() != 3, ERR_PARSE_ERROR);
const Color c = Color(arr[0], arr[1], arr[2]).to_srgb();
- material->set_feature(SpatialMaterial::FEATURE_EMISSION, true);
+ material->set_feature(StandardMaterial3D::FEATURE_EMISSION, true);
material->set_emission(c);
}
@@ -3596,8 +3536,8 @@
if (d.has("emissiveTexture")) {
const Dictionary &bct = d["emissiveTexture"];
if (bct.has("index")) {
- material->set_texture(SpatialMaterial::TEXTURE_EMISSION, _get_texture(state, bct["index"]));
- material->set_feature(SpatialMaterial::FEATURE_EMISSION, true);
+ material->set_texture(StandardMaterial3D::TEXTURE_EMISSION, _get_texture(state, bct["index"]));
+ material->set_feature(StandardMaterial3D::FEATURE_EMISSION, true);
material->set_emission(Color(0, 0, 0));
}
}
@@ -3605,17 +3545,16 @@
if (d.has("doubleSided")) {
const bool ds = d["doubleSided"];
if (ds) {
- material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ material->set_cull_mode(StandardMaterial3D::CULL_DISABLED);
}
}
if (d.has("alphaMode")) {
const String &am = d["alphaMode"];
if (am == "BLEND") {
- material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- material->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
+ material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS);
} else if (am == "MASK") {
- material->set_flag(SpatialMaterial::FLAG_USE_ALPHA_SCISSOR, true);
+ material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA_SCISSOR);
if (d.has("alphaCutoff")) {
material->set_alpha_scissor_threshold(d["alphaCutoff"]);
} else {
@@ -3632,7 +3571,7 @@
return OK;
}
-void GLTFDocument::spec_gloss_to_rough_metal(Ref<GLTFSpecGloss> r_spec_gloss, Ref<SpatialMaterial> p_material) {
+void GLTFDocument::spec_gloss_to_rough_metal(Ref<GLTFSpecGloss> r_spec_gloss, Ref<StandardMaterial3D> p_material) {
if (r_spec_gloss->spec_gloss_img.is_null()) {
return;
}
@@ -3652,20 +3591,13 @@
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);
r_spec_gloss->spec_gloss_img->resize(r_spec_gloss->diffuse_img->get_width(), r_spec_gloss->diffuse_img->get_height(), Image::INTERPOLATE_LANCZOS);
}
- rm_img->lock();
- if (r_spec_gloss->diffuse_img.is_valid()) {
- r_spec_gloss->diffuse_img->lock();
- r_spec_gloss->spec_gloss_img->lock();
- }
for (int32_t y = 0; y < r_spec_gloss->spec_gloss_img->get_height(); y++) {
for (int32_t x = 0; x < r_spec_gloss->spec_gloss_img->get_width(); x++) {
const Color specular_pixel = r_spec_gloss->spec_gloss_img->get_pixel(x, y).to_linear();
Color specular = Color(specular_pixel.r, specular_pixel.g, specular_pixel.b);
specular *= r_spec_gloss->specular_factor;
Color diffuse = Color(1.0f, 1.0f, 1.0f);
- if (r_spec_gloss->diffuse_img.is_valid()) {
- diffuse *= r_spec_gloss->diffuse_img->get_pixel(x, y).to_linear();
- }
+ diffuse *= r_spec_gloss->diffuse_img->get_pixel(x, y).to_linear();
float metallic = 0.0f;
Color base_color;
spec_gloss_to_metal_base_color(specular, diffuse, base_color, metallic);
@@ -3686,28 +3618,23 @@
}
}
}
- if (r_spec_gloss->diffuse_img.is_valid()) {
- r_spec_gloss->diffuse_img->unlock();
- r_spec_gloss->spec_gloss_img->unlock();
- }
- rm_img->unlock();
rm_img->generate_mipmaps();
r_spec_gloss->diffuse_img->generate_mipmaps();
Ref<ImageTexture> diffuse_image_texture;
diffuse_image_texture.instance();
diffuse_image_texture->create_from_image(r_spec_gloss->diffuse_img);
- p_material->set_texture(SpatialMaterial::TEXTURE_ALBEDO, diffuse_image_texture);
+ p_material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, diffuse_image_texture);
Ref<ImageTexture> rm_image_texture;
rm_image_texture.instance();
rm_image_texture->create_from_image(rm_img);
if (has_roughness) {
- p_material->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, rm_image_texture);
- p_material->set_roughness_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_GREEN);
+ p_material->set_texture(StandardMaterial3D::TEXTURE_ROUGHNESS, rm_image_texture);
+ p_material->set_roughness_texture_channel(StandardMaterial3D::TEXTURE_CHANNEL_GREEN);
}
if (has_metal) {
- p_material->set_texture(SpatialMaterial::TEXTURE_METALLIC, rm_image_texture);
- p_material->set_metallic_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_BLUE);
+ p_material->set_texture(StandardMaterial3D::TEXTURE_METALLIC, rm_image_texture);
+ p_material->set_metallic_texture_channel(StandardMaterial3D::TEXTURE_CHANNEL_BLUE);
}
}
@@ -3750,7 +3677,6 @@
}
bool GLTFDocument::_capture_nodes_in_skin(Ref<GLTFState> state, Ref<GLTFSkin> skin, const GLTFNodeIndex node_index) {
-
bool found_joint = false;
for (int i = 0; i < state->nodes[node_index]->children.size(); ++i) {
@@ -3774,7 +3700,6 @@
}
void GLTFDocument::_capture_nodes_for_multirooted_skin(Ref<GLTFState> state, Ref<GLTFSkin> skin) {
-
DisjointSet<GLTFNodeIndex> disjoint_set;
for (int i = 0; i < skin->joints.size(); ++i) {
@@ -3808,7 +3733,6 @@
// Go up the tree till all of the multiple roots of the skin are at the same hierarchy level.
// This sucks, but 99% of all game engines (not just Godot) would have this same issue.
for (int i = 0; i < roots.size(); ++i) {
-
GLTFNodeIndex current_node = roots[i];
while (state->nodes[current_node]->height > maxHeight) {
GLTFNodeIndex parent = state->nodes[current_node]->parent;
@@ -3856,7 +3780,6 @@
}
Error GLTFDocument::_expand_skin(Ref<GLTFState> state, Ref<GLTFSkin> skin) {
-
_capture_nodes_for_multirooted_skin(state, skin);
// Grab all nodes that lay in between skin joints/nodes
@@ -3902,7 +3825,6 @@
}
Error GLTFDocument::_verify_skin(Ref<GLTFState> state, Ref<GLTFSkin> skin) {
-
// This may seem duplicated from expand_skins, but this is really a sanity check! (so it kinda is)
// In case additional interpolating logic is added to the skins, this will help ensure that you
// do not cause it to self implode into a fiery blaze
@@ -3968,7 +3890,6 @@
}
Error GLTFDocument::_parse_skins(Ref<GLTFState> state) {
-
if (!state->json.has("skins"))
return OK;
@@ -3976,7 +3897,6 @@
// Create the base skins, and mark nodes that are joints
for (int i = 0; i < skins.size(); i++) {
-
const Dictionary &d = skins[i];
Ref<GLTFSkin> skin;
@@ -4027,7 +3947,6 @@
}
Error GLTFDocument::_determine_skeletons(Ref<GLTFState> state) {
-
// Using a disjoint set, we are going to potentially combine all skins that are actually branches
// of a main skeleton, or treat skins defining the same set of nodes as ONE skeleton.
// This is another unclear issue caused by the current glTF specification.
@@ -4063,7 +3982,7 @@
skeleton_sets.get_representatives(groups_representatives);
Vector<GLTFNodeIndex> highest_group_members;
- Vector<Vector<GLTFNodeIndex> > groups;
+ Vector<Vector<GLTFNodeIndex>> groups;
for (int i = 0; i < groups_representatives.size(); ++i) {
Vector<GLTFNodeIndex> group;
skeleton_sets.get_members(group, groups_representatives[i]);
@@ -4105,7 +4024,6 @@
// Mark all the skins actual skeletons, after we have merged them
for (GLTFSkeletonIndex skel_i = 0; skel_i < skeleton_owners.size(); ++skel_i) {
-
const GLTFNodeIndex skeleton_owner = skeleton_owners[skel_i];
Ref<GLTFSkeleton> skeleton;
skeleton.instance();
@@ -4161,7 +4079,6 @@
}
Error GLTFDocument::_reparent_non_joint_skeleton_subtrees(Ref<GLTFState> state, Ref<GLTFSkeleton> skeleton, const Vector<GLTFNodeIndex> &non_joints) {
-
DisjointSet<GLTFNodeIndex> subtree_set;
// Populate the disjoint set with ONLY non joints that are in the skeleton hierarchy (non_joints vector)
@@ -4276,7 +4193,6 @@
}
Error GLTFDocument::_determine_skeleton_roots(Ref<GLTFState> state, const GLTFSkeletonIndex skel_i) {
-
DisjointSet<GLTFNodeIndex> disjoint_set;
for (GLTFNodeIndex i = 0; i < state->nodes.size(); ++i) {
@@ -4331,14 +4247,13 @@
Error GLTFDocument::_create_skeletons(Ref<GLTFState> state) {
for (GLTFSkeletonIndex skel_i = 0; skel_i < state->skeletons.size(); ++skel_i) {
-
Ref<GLTFSkeleton> gltf_skeleton = state->skeletons.write[skel_i];
- Skeleton *skeleton = memnew(Skeleton);
+ Skeleton3D *skeleton = memnew(Skeleton3D);
gltf_skeleton->godot_skeleton = skeleton;
// Make a unique name, no gltf node represents this skeleton
- skeleton->set_name(_gen_unique_name(state, "Skeleton"));
+ skeleton->set_name(_gen_unique_name(state, "Skeleton3D"));
List<GLTFNodeIndex> bones;
@@ -4420,7 +4335,6 @@
}
Error GLTFDocument::_serialize_skins(Ref<GLTFState> state) {
-
Array json_skins;
for (GLTFNodeIndex node_i = 0; node_i < state->nodes.size(); node_i++) {
Dictionary json_skin;
@@ -4432,11 +4346,11 @@
if (!node) {
continue;
}
- MeshInstance *mi = Object::cast_to<MeshInstance>(node);
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(node);
if (!mi) {
continue;
}
- Skeleton *skeleton = Object::cast_to<Skeleton>(mi->get_node(mi->get_skeleton_path()));
+ Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(mi->get_node(mi->get_skeleton_path()));
if (!skeleton) {
continue;
}
@@ -4488,8 +4402,6 @@
state->nodes.write[node_index]->joint = true;
gltf_skin->inverse_binds.push_back(skin->get_bind_pose(bind_i));
json_joints.push_back(node_index);
- // print_verbose("glTF: bind pose " + itos(bind_i) + " " + skin->get_bind_pose(bind_i));
- // print_verbose("glTF: bone rest " + itos(bone_index) + " " + skeleton->get_bone_rest(bone_index));
}
for (int32_t joint_i = 0; joint_i < gltf_skin->joints.size(); joint_i++) {
@@ -4577,7 +4489,6 @@
}
for (int i = 0; i < skin_a->get_bind_count(); ++i) {
-
if (skin_a->get_bind_bone(i) != skin_b->get_bind_bone(i)) {
return false;
}
@@ -4608,7 +4519,6 @@
}
Error GLTFDocument::_serialize_lights(Ref<GLTFState> state) {
-
Array lights;
for (GLTFLightIndex i = 0; i < state->lights.size(); i++) {
Dictionary d;
@@ -4655,11 +4565,9 @@
}
Error GLTFDocument::_serialize_cameras(Ref<GLTFState> state) {
-
Array cameras;
cameras.resize(state->cameras.size());
for (GLTFCameraIndex i = 0; i < state->cameras.size(); i++) {
-
Dictionary d;
Ref<GLTFCamera> camera = state->cameras[i];
@@ -4749,14 +4657,12 @@
}
Error GLTFDocument::_parse_cameras(Ref<GLTFState> state) {
-
if (!state->json.has("cameras"))
return OK;
const Array cameras = state->json["cameras"];
for (GLTFCameraIndex i = 0; i < cameras.size(); i++) {
-
const Dictionary &d = cameras[i];
Ref<GLTFCamera> camera;
@@ -4764,7 +4670,6 @@
ERR_FAIL_COND_V(!d.has("type"), ERR_PARSE_ERROR);
const String &type = d["type"];
if (type == "orthographic") {
-
camera->set_perspective(false);
if (d.has("orthographic")) {
const Dictionary &og = d["orthographic"];
@@ -4776,7 +4681,6 @@
camera->set_fov_size(10);
}
} else if (type == "perspective") {
-
camera->set_perspective(true);
if (d.has("perspective")) {
const Dictionary &ppt = d["perspective"];
@@ -4788,7 +4692,7 @@
camera->set_fov_size(10);
}
} else {
- ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "Camera should be in 'orthographic' or 'perspective'");
+ ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "Camera3D should be in 'orthographic' or 'perspective'");
}
state->cameras.push_back(camera);
@@ -4843,7 +4747,6 @@
Array samplers;
for (Map<int, GLTFAnimation::Track>::Element *track_i = gltf_animation->get_tracks().front(); track_i; track_i = track_i->next()) {
-
GLTFAnimation::Track track = track_i->get();
if (track.translation_track.times.size()) {
Dictionary t;
@@ -4956,14 +4859,12 @@
}
Error GLTFDocument::_parse_animations(Ref<GLTFState> state) {
-
if (!state->json.has("animations"))
return OK;
const Array &animations = state->json["animations"];
for (GLTFAnimationIndex i = 0; i < animations.size(); i++) {
-
const Dictionary &d = animations[i];
Ref<GLTFAnimation> animation;
@@ -4984,7 +4885,6 @@
}
for (int j = 0; j < channels.size(); j++) {
-
const Dictionary &c = channels[j];
if (!c.has("target"))
continue;
@@ -5093,7 +4993,6 @@
}
void GLTFDocument::_assign_scene_names(Ref<GLTFState> state) {
-
for (int i = 0; i < state->nodes.size(); i++) {
Ref<GLTFNode> n = state->nodes[i];
@@ -5103,11 +5002,11 @@
if (n->get_name().empty()) {
if (n->mesh >= 0) {
- n->set_name("Mesh");
+ n->set_name(_gen_unique_name(state, "Mesh"));
} else if (n->camera >= 0) {
- n->set_name("Camera");
+ n->set_name(_gen_unique_name(state, "Camera3D"));
} else {
- n->set_name("Node");
+ n->set_name(_gen_unique_name(state, "Node"));
}
}
@@ -5115,12 +5014,11 @@
}
}
-BoneAttachment *GLTFDocument::_generate_bone_attachment(Ref<GLTFState> state, Skeleton *skeleton, const GLTFNodeIndex node_index) {
-
+BoneAttachment3D *GLTFDocument::_generate_bone_attachment(Ref<GLTFState> state, Skeleton3D *skeleton, const GLTFNodeIndex node_index) {
Ref<GLTFNode> gltf_node = state->nodes[node_index];
Ref<GLTFNode> bone_node = state->nodes[gltf_node->parent];
- BoneAttachment *bone_attachment = memnew(BoneAttachment);
+ BoneAttachment3D *bone_attachment = memnew(BoneAttachment3D);
print_verbose("glTF: Creating bone attachment for: " + gltf_node->get_name());
ERR_FAIL_COND_V(!bone_node->joint, nullptr);
@@ -5130,7 +5028,7 @@
return bone_attachment;
}
-GLTFMeshIndex GLTFDocument::_convert_mesh_instance(Ref<GLTFState> state, MeshInstance *p_mesh_instance) {
+GLTFMeshIndex GLTFDocument::_convert_mesh_instance(Ref<GLTFState> state, MeshInstance3D *p_mesh_instance) {
Ref<GLTFMesh> mesh;
mesh.instance();
if (p_mesh_instance->get_mesh().is_null()) {
@@ -5167,19 +5065,19 @@
return state->meshes.size() - 1;
}
-MeshInstance *GLTFDocument::_generate_mesh_instance(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) {
+MeshInstance3D *GLTFDocument::_generate_mesh_instance(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) {
Ref<GLTFNode> gltf_node = state->nodes[node_index];
ERR_FAIL_INDEX_V(gltf_node->mesh, state->meshes.size(), nullptr);
- MeshInstance *mi = memnew(MeshInstance);
+ MeshInstance3D *mi = memnew(MeshInstance3D);
print_verbose("glTF: Creating mesh for: " + gltf_node->get_name());
Ref<GLTFMesh> mesh = state->meshes.write[gltf_node->mesh];
mi->set_mesh(mesh->mesh);
if (mesh->mesh->get_name().empty()) {
- mesh->mesh->set_name(gltf_node->get_name());
+ mesh->mesh->set_name(_gen_unique_name(state, gltf_node->get_name()));
}
for (int i = 0; i < mesh->blend_weights.size(); i++) {
@@ -5189,7 +5087,7 @@
return mi;
}
-Light *GLTFDocument::_generate_light(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) {
+Light3D *GLTFDocument::_generate_light(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) {
Ref<GLTFNode> gltf_node = state->nodes[node_index];
ERR_FAIL_INDEX_V(gltf_node->light, state->lights.size(), nullptr);
@@ -5207,8 +5105,8 @@
}
if (l->type == "directional") {
- DirectionalLight *light = memnew(DirectionalLight);
- light->set_param(Light::PARAM_ENERGY, intensity);
+ DirectionalLight3D *light = memnew(DirectionalLight3D);
+ light->set_param(Light3D::PARAM_ENERGY, intensity);
light->set_color(l->color);
return light;
}
@@ -5218,35 +5116,35 @@
// We want to have double intensity give double brightness, so we need half the attenuation.
const float attenuation = range / intensity;
if (l->type == "point") {
- OmniLight *light = memnew(OmniLight);
- light->set_param(OmniLight::PARAM_ATTENUATION, attenuation);
- light->set_param(OmniLight::PARAM_RANGE, range);
+ OmniLight3D *light = memnew(OmniLight3D);
+ light->set_param(OmniLight3D::PARAM_ATTENUATION, attenuation);
+ light->set_param(OmniLight3D::PARAM_RANGE, range);
light->set_color(l->color);
return light;
}
if (l->type == "spot") {
- SpotLight *light = memnew(SpotLight);
- light->set_param(SpotLight::PARAM_ATTENUATION, attenuation);
- light->set_param(SpotLight::PARAM_RANGE, range);
- light->set_param(SpotLight::PARAM_SPOT_ANGLE, Math::rad2deg(l->outer_cone_angle));
+ SpotLight3D *light = memnew(SpotLight3D);
+ light->set_param(SpotLight3D::PARAM_ATTENUATION, attenuation);
+ light->set_param(SpotLight3D::PARAM_RANGE, range);
+ light->set_param(SpotLight3D::PARAM_SPOT_ANGLE, Math::rad2deg(l->outer_cone_angle));
light->set_color(l->color);
// Line of best fit derived from guessing, see https://www.desmos.com/calculator/biiflubp8b
// The points in desmos are not exact, except for (1, infinity).
float angle_ratio = l->inner_cone_angle / l->outer_cone_angle;
float angle_attenuation = 0.2 / (1 - angle_ratio) - 0.1;
- light->set_param(SpotLight::PARAM_SPOT_ATTENUATION, angle_attenuation);
+ light->set_param(SpotLight3D::PARAM_SPOT_ATTENUATION, angle_attenuation);
return light;
}
return nullptr;
}
-Camera *GLTFDocument::_generate_camera(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) {
+Camera3D *GLTFDocument::_generate_camera(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) {
Ref<GLTFNode> gltf_node = state->nodes[node_index];
ERR_FAIL_INDEX_V(gltf_node->camera, state->cameras.size(), nullptr);
- Camera *camera = memnew(Camera);
+ Camera3D *camera = memnew(Camera3D);
print_verbose("glTF: Creating camera for: " + gltf_node->get_name());
Ref<GLTFCamera> c = state->cameras[gltf_node->camera];
@@ -5259,13 +5157,13 @@
return camera;
}
-GLTFCameraIndex GLTFDocument::_convert_camera(Ref<GLTFState> state, Camera *p_camera) {
+GLTFCameraIndex GLTFDocument::_convert_camera(Ref<GLTFState> state, Camera3D *p_camera) {
print_verbose("glTF: Converting camera: " + p_camera->get_name());
Ref<GLTFCamera> c;
c.instance();
- if (p_camera->get_projection() == Camera::Projection::PROJECTION_PERSPECTIVE) {
+ if (p_camera->get_projection() == Camera3D::Projection::PROJECTION_PERSPECTIVE) {
c->set_perspective(true);
c->set_fov_size(p_camera->get_fov());
c->set_zfar(p_camera->get_zfar());
@@ -5280,33 +5178,33 @@
return camera_index;
}
-GLTFLightIndex GLTFDocument::_convert_light(Ref<GLTFState> state, Light *p_light) {
+GLTFLightIndex GLTFDocument::_convert_light(Ref<GLTFState> state, Light3D *p_light) {
print_verbose("glTF: Converting light: " + p_light->get_name());
Ref<GLTFLight> l;
l.instance();
l->color = p_light->get_color();
- if (cast_to<DirectionalLight>(p_light)) {
+ if (cast_to<DirectionalLight3D>(p_light)) {
l->type = "directional";
- DirectionalLight *light = cast_to<DirectionalLight>(p_light);
- l->intensity = light->get_param(DirectionalLight::PARAM_ENERGY);
+ DirectionalLight3D *light = cast_to<DirectionalLight3D>(p_light);
+ l->intensity = light->get_param(DirectionalLight3D::PARAM_ENERGY);
l->range = FLT_MAX; // Range for directional lights is infinite in Godot.
- } else if (cast_to<OmniLight>(p_light)) {
+ } else if (cast_to<OmniLight3D>(p_light)) {
l->type = "point";
- OmniLight *light = cast_to<OmniLight>(p_light);
- l->range = light->get_param(OmniLight::PARAM_RANGE);
- float attenuation = p_light->get_param(OmniLight::PARAM_ATTENUATION);
+ OmniLight3D *light = cast_to<OmniLight3D>(p_light);
+ l->range = light->get_param(OmniLight3D::PARAM_RANGE);
+ float attenuation = p_light->get_param(OmniLight3D::PARAM_ATTENUATION);
l->intensity = l->range / attenuation;
- } else if (cast_to<SpotLight>(p_light)) {
+ } else if (cast_to<SpotLight3D>(p_light)) {
l->type = "spot";
- SpotLight *light = cast_to<SpotLight>(p_light);
- l->range = light->get_param(SpotLight::PARAM_RANGE);
- float attenuation = light->get_param(SpotLight::PARAM_ATTENUATION);
+ SpotLight3D *light = cast_to<SpotLight3D>(p_light);
+ l->range = light->get_param(SpotLight3D::PARAM_RANGE);
+ float attenuation = light->get_param(SpotLight3D::PARAM_ATTENUATION);
l->intensity = l->range / attenuation;
- l->outer_cone_angle = Math::deg2rad(light->get_param(SpotLight::PARAM_SPOT_ANGLE));
+ l->outer_cone_angle = Math::deg2rad(light->get_param(SpotLight3D::PARAM_SPOT_ANGLE));
// This equation is the inverse of the import equation (which has a desmos link).
- float angle_ratio = 1 - (0.2 / (0.1 + light->get_param(SpotLight::PARAM_SPOT_ATTENUATION)));
+ float angle_ratio = 1 - (0.2 / (0.1 + light->get_param(SpotLight3D::PARAM_SPOT_ATTENUATION)));
angle_ratio = MAX(0, angle_ratio);
l->inner_cone_angle = l->outer_cone_angle * angle_ratio;
}
@@ -5316,37 +5214,36 @@
return light_index;
}
-GLTFSkeletonIndex GLTFDocument::_convert_skeleton(Ref<GLTFState> state, Skeleton *p_skeleton, GLTFNodeIndex p_node_index) {
+GLTFSkeletonIndex GLTFDocument::_convert_skeleton(Ref<GLTFState> state, Skeleton3D *p_skeleton, GLTFNodeIndex p_node_index) {
print_verbose("glTF: Converting skeleton: " + p_skeleton->get_name());
Ref<GLTFSkeleton> gltf_skeleton;
gltf_skeleton.instance();
+ gltf_skeleton->set_name(_gen_unique_name(state, p_skeleton->get_name()));
gltf_skeleton->godot_skeleton = p_skeleton;
state->skeleton_to_node.insert(state->skeletons.size(), p_node_index);
state->skeletons.push_back(gltf_skeleton);
return state->skeletons.size() - 1;
}
-void GLTFDocument::_convert_spatial(Ref<GLTFState> state, Spatial *p_spatial, Ref<GLTFNode> p_node) {
+void GLTFDocument::_convert_spatial(Ref<GLTFState> state, Node3D *p_spatial, Ref<GLTFNode> p_node) {
Transform xform = p_spatial->get_transform();
p_node->scale = xform.basis.get_scale();
p_node->rotation = xform.basis.get_rotation_quat();
p_node->translation = xform.origin;
}
-Spatial *GLTFDocument::_generate_spatial(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) {
+Node3D *GLTFDocument::_generate_spatial(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) {
Ref<GLTFNode> gltf_node = state->nodes[node_index];
- Spatial *spatial = memnew(Spatial);
+ Node3D *spatial = memnew(Node3D);
print_verbose("glTF: Converting spatial: " + gltf_node->get_name());
return spatial;
}
void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, Node *p_root, const GLTFNodeIndex p_gltf_parent, const GLTFNodeIndex p_gltf_root) {
-
- bool retflag;
- Spatial *spatial = Object::cast_to<Spatial>(p_current);
- Node2D *node_2d = Object::cast_to<Node2D>(p_current);
- _check_visibility(node_2d, spatial, retflag);
+ bool retflag = true;
+ Node3D *spatial = cast_to<Node3D>(p_current);
+ _check_visibility(p_current, retflag);
if (retflag) {
return;
}
@@ -5354,39 +5251,41 @@
Ref<GLTFNode> gltf_node;
gltf_node.instance();
gltf_node->set_name(_gen_unique_name(state, p_current->get_name()));
- if (cast_to<MeshInstance>(p_current)) {
+
+ if (cast_to<Node3D>(p_current)) {
+ _convert_spatial(state, spatial, gltf_node);
+ }
+
+ if (cast_to<MeshInstance3D>(p_current)) {
_convert_mesh_to_gltf(p_current, state, spatial, gltf_node);
- } else if (cast_to<BoneAttachment>(p_current)) {
+ } else if (cast_to<BoneAttachment3D>(p_current)) {
_convert_bone_attachment_to_gltf(p_current, state, gltf_node, retflag);
return;
- } else if (cast_to<Skeleton>(p_current)) {
+ } else if (cast_to<Skeleton3D>(p_current)) {
_convert_skeleton_to_gltf(p_current, state, p_gltf_parent, p_gltf_root, gltf_node, p_root);
return;
- } else if (cast_to<MultiMeshInstance>(p_current)) {
+ } else if (cast_to<MultiMeshInstance3D>(p_current)) {
_convert_mult_mesh_instance_to_gltf(p_current, p_gltf_parent, p_gltf_root, gltf_node, state, p_root);
- } else if (cast_to<CSGShape>(p_current)) {
- if (p_current->get_parent() && !cast_to<CSGShape>(p_current->get_parent())) {
+ } else if (cast_to<CSGShape3D>(p_current)) {
+ if (p_current->get_parent() && !cast_to<CSGShape3D>(p_current->get_parent())) {
_convert_csg_shape_to_gltf(p_current, p_gltf_parent, gltf_node, state);
- _convert_spatial(state, spatial, gltf_node);
}
} else if (cast_to<GridMap>(p_current)) {
_convert_grid_map_to_gltf(p_current, p_gltf_parent, p_gltf_root, gltf_node, state, p_root);
- } else if (cast_to<Camera>(p_current)) {
- Camera *camera = Object::cast_to<Camera>(p_current);
+ } else if (cast_to<Camera3D>(p_current)) {
+ Camera3D *camera = Object::cast_to<Camera3D>(p_current);
_convert_camera_to_gltf(camera, state, spatial, gltf_node);
- } else if (cast_to<Light>(p_current)) {
- Light *light = Object::cast_to<Light>(p_current);
+ } else if (cast_to<Light3D>(p_current)) {
+ Light3D *light = Object::cast_to<Light3D>(p_current);
_convert_light_to_gltf(light, state, spatial, gltf_node);
} else if (cast_to<AnimationPlayer>(p_current)) {
AnimationPlayer *animation_player = Object::cast_to<AnimationPlayer>(p_current);
_convert_animation_player_to_gltf(animation_player, state, p_gltf_parent, p_gltf_root, gltf_node, p_current, p_root);
return;
- } else {
- _convert_spatial_to_gltf(spatial, state, gltf_node);
}
GLTFNodeIndex current_node_i = state->nodes.size();
- _create_gltf_node(state, current_node_i, p_current, p_gltf_parent, gltf_node);
+ _create_gltf_node(state, current_node_i, p_current, p_gltf_parent, p_gltf_root, gltf_node);
for (int node_i = 0; node_i < p_current->get_child_count(); node_i++) {
_convert_scene_node(state, p_current->get_child(node_i), p_root, current_node_i, p_gltf_root);
@@ -5394,9 +5293,9 @@
}
void GLTFDocument::_convert_csg_shape_to_gltf(Node *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> gltf_node, Ref<GLTFState> state) {
- CSGShape *csg = Object::cast_to<CSGShape>(p_current);
+ CSGShape3D *csg = Object::cast_to<CSGShape3D>(p_current);
// HACK to call _make_dirty function
- CSGShape::Operation operation = csg->get_operation();
+ CSGShape3D::Operation operation = csg->get_operation();
csg->set_operation(operation);
// END HACK
csg->call("_update_shape");
@@ -5420,41 +5319,35 @@
gltf_node->mesh = state->meshes.size();
state->meshes.push_back(gltf_mesh);
gltf_node->xform = csg->get_meshes()[0];
- gltf_node->set_name(csg->get_name());
+ gltf_node->set_name(_gen_unique_name(state, csg->get_name()));
}
void GLTFDocument::_create_gltf_node(Ref<GLTFState> state, GLTFNodeIndex current_node_i, Node *p_scene_parent,
- GLTFNodeIndex p_parent_node_index, Ref<GLTFNode> gltf_node) {
- gltf_node->parent = p_parent_node_index;
+ GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_gltf_node, Ref<GLTFNode> gltf_node) {
state->scene_nodes.insert(current_node_i, p_scene_parent);
state->nodes.push_back(gltf_node);
- if (p_parent_node_index != current_node_i) {
+ if (p_parent_node_index != p_root_gltf_node) {
+ gltf_node->parent = p_parent_node_index;
state->nodes.write[p_parent_node_index]->children.push_back(current_node_i);
}
}
void GLTFDocument::_convert_animation_player_to_gltf(AnimationPlayer *animation_player, Ref<GLTFState> state, const GLTFNodeIndex &p_gltf_current, const GLTFNodeIndex &p_gltf_root_index, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent, Node *p_root) {
- if (animation_player) {
- state->animation_players.push_back(animation_player);
- print_verbose(String("glTF: Converting animation player: ") + animation_player->get_name());
- if (p_gltf_current != p_gltf_root_index) {
- p_gltf_node.unref();
- }
- for (int node_i = 0; node_i < p_scene_parent->get_child_count(); node_i++) {
- _convert_scene_node(state, p_scene_parent->get_child(node_i), p_root, p_gltf_current, p_gltf_root_index);
- }
+ ERR_FAIL_COND(!animation_player);
+ state->animation_players.push_back(animation_player);
+ print_verbose(String("glTF: Converting animation player: ") + animation_player->get_name());
+ if (p_gltf_current != p_gltf_root_index) {
+ p_gltf_node.unref();
}
-}
-
-void GLTFDocument::_convert_spatial_to_gltf(Spatial *spatial, Ref<GLTFState> state, Ref<GLTFNode> gltf_node) {
- if (spatial) {
- _convert_spatial(state, spatial, gltf_node);
- print_verbose(String("glTF: Converting spatial: ") + spatial->get_name());
+ for (int node_i = 0; node_i < p_scene_parent->get_child_count(); node_i++) {
+ _convert_scene_node(state, p_scene_parent->get_child(node_i), p_root, p_gltf_current, p_gltf_root_index);
}
}
-void GLTFDocument::_check_visibility(Node2D *node_2d, Spatial *spatial, bool &retflag) {
+void GLTFDocument::_check_visibility(Node *p_node, bool &retflag) {
retflag = true;
+ Node3D *spatial = Object::cast_to<Node3D>(p_node);
+ Node2D *node_2d = Object::cast_to<Node2D>(p_node);
if (node_2d && !node_2d->is_visible()) {
return;
}
@@ -5464,116 +5357,105 @@
retflag = false;
}
-void GLTFDocument::_convert_camera_to_gltf(Camera *camera, Ref<GLTFState> state, Spatial *spatial, Ref<GLTFNode> gltf_node) {
- if (camera) {
- GLTFCameraIndex camera_index = _convert_camera(state, camera);
- if (camera_index != -1) {
- _convert_spatial(state, spatial, gltf_node);
- gltf_node->camera = camera_index;
- }
+void GLTFDocument::_convert_camera_to_gltf(Camera3D *camera, Ref<GLTFState> state, Node3D *spatial, Ref<GLTFNode> gltf_node) {
+ ERR_FAIL_COND(!camera);
+ GLTFCameraIndex camera_index = _convert_camera(state, camera);
+ if (camera_index != -1) {
+ gltf_node->camera = camera_index;
}
}
-void GLTFDocument::_convert_light_to_gltf(Light *light, Ref<GLTFState> state, Spatial *spatial, Ref<GLTFNode> gltf_node) {
- if (light) {
- GLTFLightIndex light_index = _convert_light(state, light);
- if (light_index != -1) {
- _convert_spatial(state, spatial, gltf_node);
- gltf_node->light = light_index;
- }
+void GLTFDocument::_convert_light_to_gltf(Light3D *light, Ref<GLTFState> state, Node3D *spatial, Ref<GLTFNode> gltf_node) {
+ ERR_FAIL_COND(!light);
+ GLTFLightIndex light_index = _convert_light(state, light);
+ if (light_index != -1) {
+ gltf_node->light = light_index;
}
}
void GLTFDocument::_convert_grid_map_to_gltf(Node *p_scene_parent, const GLTFNodeIndex &p_parent_node_index, const GLTFNodeIndex &p_root_node_index, Ref<GLTFNode> gltf_node, Ref<GLTFState> state, Node *p_root_node) {
GridMap *grid_map = Object::cast_to<GridMap>(p_scene_parent);
- if (grid_map) {
- Array cells = grid_map->get_used_cells();
- for (int32_t k = 0; k < cells.size(); k++) {
- GLTFNode *new_gltf_node = memnew(GLTFNode);
- new_gltf_node->parent = p_parent_node_index;
- gltf_node->children.push_back(state->nodes.size());
- state->nodes.push_back(new_gltf_node);
- Vector3 cell_location = cells[k];
- int32_t cell = grid_map->get_cell_item(
- cell_location.x, cell_location.y, cell_location.z);
- Ref<Mesh> mesh =
- grid_map->get_mesh_library()->get_item_mesh(cell);
- Transform cell_xform;
- cell_xform.basis.set_orthogonal_index(
- grid_map->get_cell_item_orientation(
- cell_location.x, cell_location.y, cell_location.z));
- cell_xform.basis.scale(Vector3(grid_map->get_cell_scale(),
- grid_map->get_cell_scale(),
- grid_map->get_cell_scale()));
- cell_xform.set_origin(grid_map->map_to_world(
- cell_location.x, cell_location.y, cell_location.z));
- Ref<GLTFMesh> gltf_mesh;
- gltf_mesh->mesh = mesh;
- new_gltf_node->mesh = state->meshes.size();
- state->meshes.push_back(gltf_mesh);
- new_gltf_node->xform = cell_xform * grid_map->get_transform();
- new_gltf_node->set_name(grid_map->get_mesh_library()->get_item_name(cell));
- }
+ ERR_FAIL_COND(!grid_map);
+ Array cells = grid_map->get_used_cells();
+ for (int32_t k = 0; k < cells.size(); k++) {
+ GLTFNode *new_gltf_node = memnew(GLTFNode);
+ new_gltf_node->parent = p_parent_node_index;
+ gltf_node->children.push_back(state->nodes.size());
+ state->nodes.push_back(new_gltf_node);
+ Vector3 cell_location = cells[k];
+ int32_t cell = grid_map->get_cell_item(
+ Vector3(cell_location.x, cell_location.y, cell_location.z));
+ Ref<Mesh> mesh =
+ grid_map->get_mesh_library()->get_item_mesh(cell);
+ Transform cell_xform;
+ cell_xform.basis.set_orthogonal_index(
+ grid_map->get_cell_item_orientation(
+ Vector3(cell_location.x, cell_location.y, cell_location.z)));
+ cell_xform.basis.scale(Vector3(grid_map->get_cell_scale(),
+ grid_map->get_cell_scale(),
+ grid_map->get_cell_scale()));
+ cell_xform.set_origin(grid_map->map_to_world(
+ Vector3(cell_location.x, cell_location.y, cell_location.z)));
+ Ref<GLTFMesh> gltf_mesh;
+ gltf_mesh->mesh = mesh;
+ new_gltf_node->mesh = state->meshes.size();
+ state->meshes.push_back(gltf_mesh);
+ new_gltf_node->xform = cell_xform * grid_map->get_transform();
+ new_gltf_node->set_name(_gen_unique_name(state, grid_map->get_mesh_library()->get_item_name(cell)));
}
}
void GLTFDocument::_convert_mult_mesh_instance_to_gltf(Node *p_scene_parent, const GLTFNodeIndex &p_parent_node_index, const GLTFNodeIndex &p_root_node_index, Ref<GLTFNode> gltf_node, Ref<GLTFState> state, Node *p_root_node) {
- MultiMeshInstance *multi_mesh_instance = Object::cast_to<MultiMeshInstance>(p_scene_parent);
- if (multi_mesh_instance) {
- Ref<MultiMesh> multi_mesh = multi_mesh_instance->get_multimesh();
- if (multi_mesh.is_valid()) {
- for (int32_t instance_i = 0; instance_i < multi_mesh->get_instance_count();
- instance_i++) {
- GLTFNode *new_gltf_node = memnew(GLTFNode);
- Transform transform;
- if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_2D) {
- Transform2D xform_2d = multi_mesh->get_instance_transform_2d(instance_i);
- transform.origin =
- Vector3(xform_2d.get_origin().x, 0, xform_2d.get_origin().y);
- real_t rotation = xform_2d.get_rotation();
- Quat quat;
- quat.set_axis_angle(Vector3(0, 1, 0), rotation);
- Size2 scale = xform_2d.get_scale();
- transform.basis.set_quat_scale(quat,
- Vector3(scale.x, 0, scale.y));
- transform =
- multi_mesh_instance->get_transform() * transform;
- } else if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_3D) {
- transform = multi_mesh_instance->get_transform() *
- multi_mesh->get_instance_transform(instance_i);
- }
- Ref<ArrayMesh> mesh = multi_mesh->get_mesh();
- Ref<GLTFMesh> gltf_mesh;
- if (multi_mesh_instance->get_material_override().is_valid()) {
- for (int32_t material_i = 0; material_i < mesh->get_surface_count();
- material_i++) {
- mesh->surface_set_material(material_i, multi_mesh_instance->get_material_override());
- }
- }
- gltf_mesh->mesh = mesh;
- new_gltf_node->mesh = state->meshes.size();
- state->meshes.push_back(gltf_mesh);
- new_gltf_node->xform = transform;
- new_gltf_node->set_name(multi_mesh_instance->get_name());
- new_gltf_node->parent = p_parent_node_index;
- gltf_node->children.push_back(state->nodes.size());
- state->nodes.push_back(new_gltf_node);
+ MultiMeshInstance3D *multi_mesh_instance = Object::cast_to<MultiMeshInstance3D>(p_scene_parent);
+ ERR_FAIL_COND(!multi_mesh_instance);
+ Ref<MultiMesh> multi_mesh = multi_mesh_instance->get_multimesh();
+ if (multi_mesh.is_valid()) {
+ for (int32_t instance_i = 0; instance_i < multi_mesh->get_instance_count();
+ instance_i++) {
+ GLTFNode *new_gltf_node = memnew(GLTFNode);
+ Transform transform;
+ if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_2D) {
+ Transform2D xform_2d = multi_mesh->get_instance_transform_2d(instance_i);
+ transform.origin =
+ Vector3(xform_2d.get_origin().x, 0, xform_2d.get_origin().y);
+ real_t rotation = xform_2d.get_rotation();
+ Quat quat;
+ quat.set_axis_angle(Vector3(0, 1, 0), rotation);
+ Size2 scale = xform_2d.get_scale();
+ transform.basis.set_quat_scale(quat,
+ Vector3(scale.x, 0, scale.y));
+ transform =
+ multi_mesh_instance->get_transform() * transform;
+ } else if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_3D) {
+ transform = multi_mesh_instance->get_transform() *
+ multi_mesh->get_instance_transform(instance_i);
+ }
+ Ref<ArrayMesh> mesh = multi_mesh->get_mesh();
+ Ref<GLTFMesh> gltf_mesh;
+ if (multi_mesh_instance->get_material_override().is_valid()) {
+ for (int32_t material_i = 0; material_i < mesh->get_surface_count();
+ material_i++) {
+ mesh->surface_set_material(material_i, multi_mesh_instance->get_material_override());
+ }
}
+ gltf_mesh->mesh = mesh;
+ new_gltf_node->mesh = state->meshes.size();
+ state->meshes.push_back(gltf_mesh);
+ new_gltf_node->xform = transform;
+ new_gltf_node->set_name(_gen_unique_name(state, multi_mesh_instance->get_name()));
+ new_gltf_node->parent = p_parent_node_index;
+ gltf_node->children.push_back(state->nodes.size());
+ state->nodes.push_back(new_gltf_node);
}
}
}
void GLTFDocument::_convert_skeleton_to_gltf(Node *p_scene_parent, Ref<GLTFState> state, const GLTFNodeIndex &p_parent_node_index, const GLTFNodeIndex &p_root_node_index, Ref<GLTFNode> gltf_node, Node *p_root_node) {
- Skeleton *skeleton = Object::cast_to<Skeleton>(p_scene_parent);
+ Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_scene_parent);
if (skeleton) {
GLTFSkeletonIndex gltf_skeleton_index = -1;
gltf_skeleton_index = _convert_skeleton(state, skeleton, p_parent_node_index);
- if (gltf_skeleton_index != -1) {
- gltf_node->skeleton = gltf_skeleton_index;
- }
- if (p_parent_node_index != p_root_node_index) {
- gltf_node.unref();
- }
+ gltf_node->skeleton = gltf_skeleton_index;
for (int node_i = 0; node_i < p_scene_parent->get_child_count(); node_i++) {
_convert_scene_node(state, p_scene_parent->get_child(node_i), p_root_node, p_parent_node_index, p_root_node_index);
}
@@ -5582,12 +5464,11 @@
void GLTFDocument::_convert_bone_attachment_to_gltf(Node *p_scene_parent, Ref<GLTFState> state, Ref<GLTFNode> gltf_node, bool &retflag) {
retflag = true;
- BoneAttachment *bone_attachment = Object::cast_to<BoneAttachment>(p_scene_parent);
+ BoneAttachment3D *bone_attachment = Object::cast_to<BoneAttachment3D>(p_scene_parent);
if (bone_attachment) {
Node *node = bone_attachment->get_parent();
while (node) {
-
- Skeleton *bone_attachment_skeleton = Object::cast_to<Skeleton>(node);
+ Skeleton3D *bone_attachment_skeleton = Object::cast_to<Skeleton3D>(node);
if (bone_attachment_skeleton) {
for (GLTFSkeletonIndex skeleton_i = 0; skeleton_i < state->skeletons.size(); skeleton_i++) {
if (state->skeletons[skeleton_i]->godot_skeleton != bone_attachment_skeleton) {
@@ -5606,28 +5487,26 @@
retflag = false;
}
-void GLTFDocument::_convert_mesh_to_gltf(Node *p_scene_parent, Ref<GLTFState> state, Spatial *spatial, Ref<GLTFNode> gltf_node) {
- MeshInstance *mi = Object::cast_to<MeshInstance>(p_scene_parent);
+void GLTFDocument::_convert_mesh_to_gltf(Node *p_scene_parent, Ref<GLTFState> state, Node3D *spatial, Ref<GLTFNode> gltf_node) {
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_scene_parent);
if (mi) {
GLTFMeshIndex gltf_mesh_index = _convert_mesh_instance(state, mi);
if (gltf_mesh_index != -1) {
- _convert_spatial(state, spatial, gltf_node);
gltf_node->mesh = gltf_mesh_index;
}
}
}
-void GLTFDocument::_generate_scene_node(Ref<GLTFState> state, Node *scene_parent, Spatial *scene_root, const GLTFNodeIndex node_index) {
-
+void GLTFDocument::_generate_scene_node(Ref<GLTFState> state, Node *scene_parent, Node3D *scene_root, const GLTFNodeIndex node_index) {
Ref<GLTFNode> gltf_node = state->nodes[node_index];
- Spatial *current_node = nullptr;
+ Node3D *current_node = nullptr;
// Is our parent a skeleton
- Skeleton *active_skeleton = Object::cast_to<Skeleton>(scene_parent);
+ Skeleton3D *active_skeleton = Object::cast_to<Skeleton3D>(scene_parent);
if (gltf_node->skeleton >= 0) {
- Skeleton *skeleton = state->skeletons[gltf_node->skeleton]->godot_skeleton;
+ Skeleton3D *skeleton = state->skeletons[gltf_node->skeleton]->godot_skeleton;
if (active_skeleton != skeleton) {
ERR_FAIL_COND_MSG(active_skeleton != nullptr, "glTF: Generating scene detected direct parented Skeletons");
@@ -5645,13 +5524,13 @@
// If we have an active skeleton, and the node is node skinned, we need to create a bone attachment
if (current_node == nullptr && active_skeleton != nullptr && gltf_node->skin < 0) {
- BoneAttachment *bone_attachment = _generate_bone_attachment(state, active_skeleton, node_index);
+ BoneAttachment3D *bone_attachment = _generate_bone_attachment(state, active_skeleton, node_index);
scene_parent->add_child(bone_attachment);
bone_attachment->set_owner(scene_root);
// There is no gltf_node that represent this, so just directly create a unique name
- bone_attachment->set_name(_gen_unique_name(state, "BoneAttachment"));
+ bone_attachment->set_name(_gen_unique_name(state, "BoneAttachment3D"));
// We change the scene_parent to our bone attachment now. We do not set current_node because we want to make the node
// and attach it to the bone_attachment
@@ -5689,18 +5568,15 @@
template <class T>
struct EditorSceneImporterGLTFInterpolate {
-
T lerp(const T &a, const T &b, float c) const {
-
return a + (b - a) * c;
}
T catmull_rom(const T &p0, const T &p1, const T &p2, const T &p3, float t) {
-
const float t2 = t * t;
const float t3 = t2 * t;
- return 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 + (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3);
+ 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);
}
T bezier(T start, T control_1, T control_2, T end, float t) {
@@ -5718,7 +5594,6 @@
// thank you for existing, partial specialization
template <>
struct EditorSceneImporterGLTFInterpolate<Quat> {
-
Quat lerp(const Quat &a, const Quat &b, const float c) const {
ERR_FAIL_COND_V_MSG(!a.is_normalized(), Quat(), "The quaternion \"a\" must be normalized.");
ERR_FAIL_COND_V_MSG(!b.is_normalized(), Quat(), "The quaternion \"b\" must be normalized.");
@@ -5743,7 +5618,6 @@
template <class T>
T GLTFDocument::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) {
-
//could use binary search, worth it?
int idx = -1;
for (int i = 0; i < p_times.size(); i++) {
@@ -5756,7 +5630,6 @@
switch (p_interp) {
case GLTFAnimation::INTERP_LINEAR: {
-
if (idx == -1) {
return p_values[0];
} else if (idx >= p_times.size() - 1) {
@@ -5768,7 +5641,6 @@
return interp.lerp(p_values[idx], p_values[idx + 1], c);
} break;
case GLTFAnimation::INTERP_STEP: {
-
if (idx == -1) {
return p_values[0];
} else if (idx >= p_times.size() - 1) {
@@ -5778,7 +5650,6 @@
return p_values[idx];
} break;
case GLTFAnimation::INTERP_CATMULLROMSPLINE: {
-
if (idx == -1) {
return p_values[1];
} else if (idx >= p_times.size() - 1) {
@@ -5790,7 +5661,6 @@
return interp.catmull_rom(p_values[idx - 1], p_values[idx], p_values[idx + 1], p_values[idx + 3], c);
} break;
case GLTFAnimation::INTERP_CUBIC_SPLINE: {
-
if (idx == -1) {
return p_values[1];
} else if (idx >= p_times.size() - 1) {
@@ -5812,7 +5682,6 @@
}
void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, const GLTFAnimationIndex index, const int bake_fps) {
-
Ref<GLTFAnimation> anim = state->animations[index];
String name = anim->get_name();
@@ -5832,7 +5701,6 @@
float length = 0;
for (Map<int, GLTFAnimation::Track>::Element *track_i = anim->get_tracks().front(); track_i; track_i = track_i->next()) {
-
const GLTFAnimation::Track &track = track_i->get();
//need to find the path
NodePath node_path;
@@ -5846,7 +5714,7 @@
const Ref<GLTFNode> gltf_node = state->nodes[track_i->key()];
if (gltf_node->skeleton >= 0) {
- const Skeleton *sk = Object::cast_to<Skeleton>(state->scene_nodes.find(node_index)->get());
+ const Skeleton3D *sk = Object::cast_to<Skeleton3D>(state->scene_nodes.find(node_index)->get());
ERR_FAIL_COND(sk == nullptr);
const String path = ap->get_parent()->get_path_to(sk);
@@ -5902,7 +5770,6 @@
bool last = false;
while (true) {
-
Vector3 pos = base_pos;
Quat rot = base_rot;
Vector3 scale = base_scale;
@@ -5920,12 +5787,11 @@
}
if (gltf_node->skeleton >= 0) {
-
Transform xform;
xform.basis.set_quat_scale(rot, scale);
xform.origin = pos;
- const Skeleton *skeleton = state->skeletons[gltf_node->skeleton]->godot_skeleton;
+ const Skeleton3D *skeleton = state->skeletons[gltf_node->skeleton]->godot_skeleton;
const int bone_idx = skeleton->find_bone(gltf_node->get_name());
xform = skeleton->get_bone_rest(bone_idx).affine_inverse() * xform;
@@ -6001,8 +5867,7 @@
Ref<GLTFNode> node;
node.instance();
String bone_name = state->skeletons[skeleton_i]->godot_skeleton->get_bone_name(bone_i);
- bone_name = _sanitize_bone_name(bone_name);
- node->set_name(_gen_unique_name(state, bone_name));
+ node->set_name(_gen_unique_bone_name(state, skeleton_i, bone_name));
Transform xform = state->skeletons[skeleton_i]->godot_skeleton->get_bone_rest(bone_i);
node->scale = xform.basis.get_scale();
@@ -6044,7 +5909,7 @@
if (!mi_element) {
continue;
}
- MeshInstance *mi = Object::cast_to<MeshInstance>(mi_element->get());
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(mi_element->get());
ERR_CONTINUE(!mi);
Transform xform = mi->get_transform();
@@ -6094,12 +5959,12 @@
const GLTFSkinIndex skin_i = node->skin;
Map<GLTFNodeIndex, Node *>::Element *mi_element = state->scene_nodes.find(node_i);
- MeshInstance *mi = Object::cast_to<MeshInstance>(mi_element->get());
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(mi_element->get());
ERR_FAIL_COND(mi == nullptr);
const GLTFSkeletonIndex skel_i = state->skins.write[node->skin]->skeleton;
Ref<GLTFSkeleton> gltf_skeleton = state->skeletons.write[skel_i];
- Skeleton *skeleton = gltf_skeleton->godot_skeleton;
+ Skeleton3D *skeleton = gltf_skeleton->godot_skeleton;
ERR_FAIL_COND(skeleton == nullptr);
mi->get_parent()->remove_child(mi);
@@ -6303,7 +6168,6 @@
}
void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, String p_animation_track_name) {
-
Ref<Animation> animation = ap->get_animation(p_animation_track_name);
Ref<GLTFAnimation> gltf_animation;
gltf_animation.instance();
@@ -6379,7 +6243,7 @@
const String suffix = node_suffix[1];
const NodePath path = node;
Node *godot_node = ap->get_parent()->get_node_or_null(node);
- MeshInstance *mi = Object::cast_to<MeshInstance>(godot_node);
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(godot_node);
if (!mi) {
continue;
}
@@ -6551,7 +6415,6 @@
}
Error GLTFDocument::parse(Ref<GLTFState> state, String p_path, bool p_read_binary) {
-
Error err;
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err);
if (!f) {
@@ -6672,9 +6535,8 @@
Dictionary GLTFDocument::_serialize_texture_transform_uv2(Ref<Material> p_material) {
Dictionary extension;
- Ref<SpatialMaterial> mat = p_material;
+ Ref<StandardMaterial3D> mat = p_material;
if (mat.is_valid()) {
-
Dictionary texture_transform;
Array offset;
offset.resize(2);
@@ -6694,9 +6556,8 @@
Dictionary GLTFDocument::_serialize_texture_transform_uv1(Ref<Material> p_material) {
Dictionary extension;
- Ref<SpatialMaterial> mat = p_material;
+ Ref<StandardMaterial3D> mat = p_material;
if (mat.is_valid()) {
-
Dictionary texture_transform;
Array offset;
offset.resize(2);
@@ -6772,7 +6633,6 @@
f->close();
} else {
-
err = _encode_buffer_bins(state, p_path);
ERR_FAIL_COND_V(err != OK, err);
FileAccessRef f = FileAccess::open(p_path, FileAccess::WRITE, &err);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment