Path: blob/master/tests/scene/test_gltf_document.cpp
45991 views
/**************************************************************************/1/* test_gltf_document.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "tests/test_macros.h"3132TEST_FORCE_LINK(test_gltf_document)3334#ifndef _3D_DISABLED3536#include "modules/modules_enabled.gen.h" // For gltf.3738#ifdef MODULE_GLTF_ENABLED3940#include "tests/test_utils.h"4142#include "modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.h"43#include "modules/gltf/gltf_document.h"4445namespace TestGLTFDocument {4647struct GLTFArraySize {48String key;49int val;50};5152struct GLTFKeyValue {53String key;54Variant val;55};5657struct GLTFTestCase {58String filename;59String copyright;60String generator;61String version;62Vector<GLTFArraySize> array_sizes;63Vector<GLTFArraySize> json_array_sizes;64Vector<GLTFKeyValue> keyvalues;65};6667const GLTFTestCase glTF_test_cases[] = {68{ "models/cube.gltf",69"",70"Khronos glTF Blender I/O v4.3.47",71"2.0",72// Here are the array sizes.73{74{ "nodes", 1 },75{ "buffers", 1 },76{ "buffer_views", 13 },77{ "accessors", 13 },78{ "meshes", 1 },79{ "materials", 2 },80{ "root_nodes", 1 },81{ "textures", 0 },82{ "texture_samplers", 0 },83{ "images", 0 },84{ "skins", 0 },85{ "cameras", 0 },86{ "lights", 0 },87{ "skeletons", 0 },88{ "animations", 1 },89},90// Here are the json array sizes.91{92{ "scenes", 1 },93{ "nodes", 1 },94{ "animations", 1 },95{ "meshes", 1 },96{ "accessors", 13 },97{ "bufferViews", 13 },98{ "buffers", 1 },99},100// Here are the key-value pairs.101{102{ "major_version", 2 },103{ "minor_version", 0 },104{ "scene_name", "cube" },105{ "filename", "cube" } } },106{ "models/suzanne.glb",107"this is example text",108"Khronos glTF Blender I/O v4.3.47",109"2.0",110// Here are the array sizes.111{112{ "glb_data", 68908 },113{ "nodes", 2 },114{ "buffers", 1 },115{ "buffer_views", 5 },116{ "accessors", 4 },117{ "meshes", 1 },118{ "materials", 1 },119{ "root_nodes", 2 },120{ "textures", 1 },121{ "texture_samplers", 1 },122{ "images", 1 },123{ "skins", 0 },124{ "cameras", 1 },125{ "lights", 0 },126{ "unique_names", 4 },127{ "skeletons", 0 },128{ "animations", 0 },129},130// Here are the json array sizes.131{132{ "scenes", 1 },133{ "nodes", 2 },134{ "cameras", 1 },135{ "materials", 1 },136{ "meshes", 1 },137{ "textures", 1 },138{ "images", 1 },139{ "accessors", 4 },140{ "bufferViews", 5 },141{ "buffers", 1 },142},143// Here are the key-value pairs.144{145{ "major_version", 2 },146{ "minor_version", 0 },147{ "scene_name", "suzanne" },148{ "filename", "suzanne" } } },149};150151void register_gltf_extension() {152GLTFDocument::unregister_all_gltf_document_extensions();153154// Ensures meshes become a MeshInstance3D and not an ImporterMeshInstance3D.155Ref<GLTFDocumentExtensionConvertImporterMesh> extension_GLTFDocumentExtensionConvertImporterMesh;156extension_GLTFDocumentExtensionConvertImporterMesh.instantiate();157GLTFDocument::register_gltf_document_extension(extension_GLTFDocumentExtensionConvertImporterMesh);158}159160void test_gltf_document_values(Ref<GLTFDocument> &p_gltf_document, Ref<GLTFState> &p_gltf_state, const GLTFTestCase &p_test_case) {161const Error err = p_gltf_document->append_from_file(TestUtils::get_data_path(p_test_case.filename), p_gltf_state);162REQUIRE(err == OK);163164for (GLTFArraySize array_size : p_test_case.array_sizes) {165CHECK_MESSAGE(((Array)(p_gltf_state->getvar(array_size.key))).size() == array_size.val, "Expected \"", array_size.key, "\" to have ", array_size.val, " elements.");166}167168for (GLTFArraySize array_size : p_test_case.json_array_sizes) {169CHECK(p_gltf_state->get_json().has(array_size.key));170CHECK_MESSAGE(((Array)(p_gltf_state->get_json()[array_size.key])).size() == array_size.val, "Expected \"", array_size.key, "\" to have ", array_size.val, " elements.");171}172173for (GLTFKeyValue key_value : p_test_case.keyvalues) {174CHECK_MESSAGE(p_gltf_state->getvar(key_value.key) == key_value.val, "Expected \"", key_value.key, "\" to be \"", key_value.val, "\".");175}176177CHECK(p_gltf_state->get_copyright() == p_test_case.copyright);178CHECK(((Dictionary)p_gltf_state->get_json()["asset"])["generator"] == p_test_case.generator);179CHECK(((Dictionary)p_gltf_state->get_json()["asset"])["version"] == p_test_case.version);180}181182void test_gltf_save(Node *p_node) {183Ref<GLTFDocument> gltf_document_save;184gltf_document_save.instantiate();185Ref<GLTFState> gltf_state_save;186gltf_state_save.instantiate();187188gltf_document_save->append_from_scene(p_node, gltf_state_save);189190// Check saving the scene to gltf and glb.191const Error err_save_gltf = gltf_document_save->write_to_filesystem(gltf_state_save, TestUtils::get_temp_path("cube.gltf"));192const Error err_save_glb = gltf_document_save->write_to_filesystem(gltf_state_save, TestUtils::get_temp_path("cube.glb"));193CHECK(err_save_gltf == OK);194CHECK(err_save_glb == OK);195}196197TEST_CASE("[SceneTree][GLTFDocument] Load cube.gltf") {198register_gltf_extension();199200Ref<GLTFDocument> gltf_document;201gltf_document.instantiate();202Ref<GLTFState> gltf_state;203gltf_state.instantiate();204205test_gltf_document_values(gltf_document, gltf_state, glTF_test_cases[0]);206207Node *node = gltf_document->generate_scene(gltf_state);208209// Check the loaded scene.210CHECK(node->is_class("Node3D"));211CHECK(node->get_name() == "cube");212213CHECK(node->get_child(0)->is_class("MeshInstance3D"));214CHECK(node->get_child(0)->get_name() == "Cube");215216CHECK(node->get_child(1)->is_class("AnimationPlayer"));217CHECK(node->get_child(1)->get_name() == "AnimationPlayer");218219test_gltf_save(node);220221// Clean up the node.222memdelete(node);223}224225TEST_CASE("[SceneTree][GLTFDocument] Load suzanne.glb") {226register_gltf_extension();227228Ref<GLTFDocument> gltf_document;229gltf_document.instantiate();230Ref<GLTFState> gltf_state;231gltf_state.instantiate();232233test_gltf_document_values(gltf_document, gltf_state, glTF_test_cases[1]);234235Node *node = gltf_document->generate_scene(gltf_state);236237// Check the loaded scene.238CHECK(node->is_class("Node3D"));239CHECK(node->get_name() == "suzanne");240241CHECK(node->get_child(0)->is_class("MeshInstance3D"));242CHECK(node->get_child(0)->get_name() == "Suzanne");243244CHECK(node->get_child(1)->is_class("Camera3D"));245CHECK(node->get_child(1)->get_name() == "Camera");246247test_gltf_save(node);248249// Clean up the node.250memdelete(node);251}252253} // namespace TestGLTFDocument254255#endif // MODULE_GLTF_ENABLED256257#endif // _3D_DISABLED258259260