diff options
Diffstat (limited to 'modules/gltf/gltf_document.cpp')
-rw-r--r-- | modules/gltf/gltf_document.cpp | 112 |
1 files changed, 67 insertions, 45 deletions
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 2f8320d7c9..5a931ed839 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -2523,14 +2523,16 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) { if (p.has("mode")) { const int mode = p["mode"]; ERR_FAIL_INDEX_V(mode, 7, ERR_FILE_CORRUPT); + // Convert mesh.primitive.mode to Godot Mesh enum. See: + // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#_mesh_primitive_mode static const Mesh::PrimitiveType primitives2[7] = { - Mesh::PRIMITIVE_POINTS, - Mesh::PRIMITIVE_LINES, - Mesh::PRIMITIVE_LINES, //loop not supported, should ce converted - Mesh::PRIMITIVE_LINES, - Mesh::PRIMITIVE_TRIANGLES, - Mesh::PRIMITIVE_TRIANGLE_STRIP, - Mesh::PRIMITIVE_TRIANGLES, //fan not supported, should be converted + Mesh::PRIMITIVE_POINTS, // 0 POINTS + Mesh::PRIMITIVE_LINES, // 1 LINES + Mesh::PRIMITIVE_LINES, // 2 LINE_LOOP; loop not supported, should be converted + Mesh::PRIMITIVE_LINE_STRIP, // 3 LINE_STRIP + Mesh::PRIMITIVE_TRIANGLES, // 4 TRIANGLES + Mesh::PRIMITIVE_TRIANGLE_STRIP, // 5 TRIANGLE_STRIP + Mesh::PRIMITIVE_TRIANGLES, // 6 TRIANGLE_FAN fan not supported, should be converted #ifndef _MSC_VER #warning line loop and triangle fan are not supported and need to be converted to lines and triangles #endif @@ -3390,29 +3392,32 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) { tex.instantiate(); { Ref<Texture2D> normal_texture = material->get_texture(BaseMaterial3D::TEXTURE_NORMAL); - // Code for uncompressing RG normal maps - Ref<Image> img = normal_texture->get_image(); - Ref<ImageTexture> img_tex = img; - if (img_tex.is_valid()) { - img = img_tex->get_image(); - } - img->decompress(); - img->convert(Image::FORMAT_RGBA8); - img->convert_ra_rgba8_to_rg(); - 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); - Vector2 red_green = Vector2(c.r, c.g); - red_green = red_green * Vector2(2.0f, 2.0f) - Vector2(1.0f, 1.0f); - float blue = 1.0f - red_green.dot(red_green); - blue = MAX(0.0f, blue); - c.b = Math::sqrt(blue); - img->set_pixel(x, y, c); + if (normal_texture.is_valid()) { + // Code for uncompressing RG normal maps + Ref<Image> img = normal_texture->get_image(); + if (img.is_valid()) { + Ref<ImageTexture> img_tex = img; + if (img_tex.is_valid()) { + img = img_tex->get_image(); + } + img->decompress(); + img->convert(Image::FORMAT_RGBA8); + img->convert_ra_rgba8_to_rg(); + 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); + Vector2 red_green = Vector2(c.r, c.g); + red_green = red_green * Vector2(2.0f, 2.0f) - Vector2(1.0f, 1.0f); + float blue = 1.0f - red_green.dot(red_green); + blue = MAX(0.0f, blue); + c.b = Math::sqrt(blue); + img->set_pixel(x, y, c); + } + } + tex->create_from_image(img); } } - tex->create_from_image(img); } - Ref<Texture2D> normal_texture = material->get_texture(BaseMaterial3D::TEXTURE_NORMAL); GLTFTextureIndex gltf_texture_index = -1; if (tex.is_valid() && tex->get_image().is_valid()) { tex->set_name(material->get_name() + "_normal"); @@ -6846,7 +6851,7 @@ Node *GLTFDocument::generate_scene(Ref<GLTFState> state, int32_t p_bake_fps) { _process_mesh_instances(state, root); if (state->animations.size()) { AnimationPlayer *ap = memnew(AnimationPlayer); - root->add_child(ap); + root->add_child(ap, true); ap->set_owner(root); for (int i = 0; i < state->animations.size(); i++) { _import_animation(state, ap, i, p_bake_fps); @@ -6896,78 +6901,83 @@ Error GLTFDocument::append_from_buffer(PackedByteArray p_bytes, String p_base_pa Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> state, const String &p_search_path, float p_bake_fps) { Error err; - /* STEP 0 PARSE SCENE */ + + /* PARSE EXTENSIONS */ + err = _parse_gltf_extensions(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE SCENE */ err = _parse_scenes(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 1 PARSE NODES */ + /* PARSE NODES */ err = _parse_nodes(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 2 PARSE BUFFERS */ + /* PARSE BUFFERS */ err = _parse_buffers(state, p_search_path); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 3 PARSE BUFFER VIEWS */ + /* PARSE BUFFER VIEWS */ err = _parse_buffer_views(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 4 PARSE ACCESSORS */ + /* PARSE ACCESSORS */ err = _parse_accessors(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 5 PARSE IMAGES */ + /* PARSE IMAGES */ err = _parse_images(state, p_search_path); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 6 PARSE TEXTURES */ + /* PARSE TEXTURES */ err = _parse_textures(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 7 PARSE TEXTURES */ + /* PARSE TEXTURES */ err = _parse_materials(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 9 PARSE SKINS */ + /* PARSE SKINS */ err = _parse_skins(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 10 DETERMINE SKELETONS */ + /* DETERMINE SKELETONS */ err = _determine_skeletons(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 11 CREATE SKELETONS */ + /* CREATE SKELETONS */ err = _create_skeletons(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 12 CREATE SKINS */ + /* CREATE SKINS */ err = _create_skins(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 13 PARSE MESHES (we have enough info now) */ + /* PARSE MESHES (we have enough info now) */ err = _parse_meshes(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 14 PARSE LIGHTS */ + /* PARSE LIGHTS */ err = _parse_lights(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 15 PARSE CAMERAS */ + /* PARSE CAMERAS */ err = _parse_cameras(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 16 PARSE ANIMATIONS */ + /* PARSE ANIMATIONS */ err = _parse_animations(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 17 ASSIGN SCENE NAMES */ + /* ASSIGN SCENE NAMES */ _assign_scene_names(state); Node3D *root = memnew(Node3D); @@ -6994,3 +7004,15 @@ Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> r_state, uint ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); return err; } + +Error GLTFDocument::_parse_gltf_extensions(Ref<GLTFState> state) { + ERR_FAIL_NULL_V(state, ERR_PARSE_ERROR); + if (state->json.has("extensionsRequired") && state->json["extensionsRequired"].get_type() == Variant::ARRAY) { + Array extensions_required = state->json["extensionsRequired"]; + if (extensions_required.find("KHR_draco_mesh_compression") != -1) { + ERR_PRINT("glTF2 extension KHR_draco_mesh_compression is not supported."); + return ERR_UNAVAILABLE; + } + } + return OK; +} |