Implement KHR_node_visibility in the GLTF module

This commit is contained in:
Aaron Franke
2024-06-28 14:06:29 -07:00
parent 215acd52e8
commit 8459f4cdaf
7 changed files with 108 additions and 18 deletions

View File

@@ -443,6 +443,17 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> p_state) {
extensions["KHR_lights_punctual"] = lights_punctual;
lights_punctual["light"] = gltf_node->light;
}
if (!gltf_node->visible) {
Dictionary khr_node_visibility;
extensions["KHR_node_visibility"] = khr_node_visibility;
khr_node_visibility["visible"] = gltf_node->visible;
if (!p_state->extensions_used.has("KHR_node_visibility")) {
p_state->extensions_used.push_back("KHR_node_visibility");
if (_visibility_mode == VISIBILITY_MODE_INCLUDE_REQUIRED) {
p_state->extensions_required.push_back("KHR_node_visibility");
}
}
}
if (gltf_node->mesh != -1) {
node["mesh"] = gltf_node->mesh;
}
@@ -637,6 +648,12 @@ Error GLTFDocument::_parse_nodes(Ref<GLTFState> p_state) {
node->light = light;
}
}
if (extensions.has("KHR_node_visibility")) {
Dictionary khr_node_visibility = extensions["KHR_node_visibility"];
if (khr_node_visibility.has("visible")) {
node->visible = khr_node_visibility["visible"];
}
}
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
ERR_CONTINUE(ext.is_null());
Error err = ext->parse_node_extensions(p_state, node, extensions);
@@ -5844,11 +5861,6 @@ Node3D *GLTFDocument::_generate_spatial(Ref<GLTFState> p_state, const GLTFNodeIn
}
void GLTFDocument::_convert_scene_node(Ref<GLTFState> p_state, Node *p_current, const GLTFNodeIndex p_gltf_parent, const GLTFNodeIndex p_gltf_root) {
bool retflag = true;
_check_visibility(p_current, retflag);
if (retflag) {
return;
}
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint() && p_gltf_root != -1 && p_current->get_owner() == nullptr) {
WARN_VERBOSE("glTF export warning: Node '" + p_current->get_name() + "' has no owner. This is likely a temporary node generated by a @tool script. This would not be saved when saving the Godot scene, therefore it will not be exported to glTF.");
@@ -5857,6 +5869,13 @@ void GLTFDocument::_convert_scene_node(Ref<GLTFState> p_state, Node *p_current,
#endif // TOOLS_ENABLED
Ref<GLTFNode> gltf_node;
gltf_node.instantiate();
if (p_current->has_method("is_visible")) {
bool visible = p_current->call("is_visible");
if (!visible && _visibility_mode == VISIBILITY_MODE_EXCLUDE) {
return;
}
gltf_node->visible = visible;
}
gltf_node->set_original_name(p_current->get_name());
gltf_node->set_name(_gen_unique_name(p_state, p_current->get_name()));
gltf_node->merge_meta_from(p_current);
@@ -5979,19 +5998,6 @@ void GLTFDocument::_convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeInd
#endif // MODULE_CSG_ENABLED
}
void GLTFDocument::_check_visibility(Node *p_node, bool &r_retflag) {
r_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;
}
if (spatial && !spatial->is_visible()) {
return;
}
r_retflag = false;
}
void GLTFDocument::_convert_camera_to_gltf(Camera3D *camera, Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node) {
ERR_FAIL_NULL(camera);
GLTFCameraIndex camera_index = _convert_camera(p_state, camera);
@@ -6275,6 +6281,7 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIn
if (!gltf_node_name.is_empty()) {
current_node->set_name(gltf_node_name);
}
current_node->set_visible(gltf_node->visible);
// Note: p_scene_parent and p_scene_root must either both be null or both be valid.
if (p_scene_root == nullptr) {
// If the root node argument is null, this is the root node.
@@ -8165,12 +8172,18 @@ void GLTFDocument::_bind_methods() {
BIND_ENUM_CONSTANT(ROOT_NODE_MODE_KEEP_ROOT);
BIND_ENUM_CONSTANT(ROOT_NODE_MODE_MULTI_ROOT);
BIND_ENUM_CONSTANT(VISIBILITY_MODE_INCLUDE_REQUIRED);
BIND_ENUM_CONSTANT(VISIBILITY_MODE_INCLUDE_OPTIONAL);
BIND_ENUM_CONSTANT(VISIBILITY_MODE_EXCLUDE);
ClassDB::bind_method(D_METHOD("set_image_format", "image_format"), &GLTFDocument::set_image_format);
ClassDB::bind_method(D_METHOD("get_image_format"), &GLTFDocument::get_image_format);
ClassDB::bind_method(D_METHOD("set_lossy_quality", "lossy_quality"), &GLTFDocument::set_lossy_quality);
ClassDB::bind_method(D_METHOD("get_lossy_quality"), &GLTFDocument::get_lossy_quality);
ClassDB::bind_method(D_METHOD("set_root_node_mode", "root_node_mode"), &GLTFDocument::set_root_node_mode);
ClassDB::bind_method(D_METHOD("get_root_node_mode"), &GLTFDocument::get_root_node_mode);
ClassDB::bind_method(D_METHOD("set_visibility_mode", "visibility_mode"), &GLTFDocument::set_visibility_mode);
ClassDB::bind_method(D_METHOD("get_visibility_mode"), &GLTFDocument::get_visibility_mode);
ClassDB::bind_method(D_METHOD("append_from_file", "path", "state", "flags", "base_path"),
&GLTFDocument::append_from_file, DEFVAL(0), DEFVAL(String()));
ClassDB::bind_method(D_METHOD("append_from_buffer", "bytes", "base_path", "state", "flags"),
@@ -8187,6 +8200,7 @@ void GLTFDocument::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "image_format"), "set_image_format", "get_image_format");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lossy_quality"), "set_lossy_quality", "get_lossy_quality");
ADD_PROPERTY(PropertyInfo(Variant::INT, "root_node_mode"), "set_root_node_mode", "get_root_node_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_mode"), "set_visibility_mode", "get_visibility_mode");
ClassDB::bind_static_method("GLTFDocument", D_METHOD("import_object_model_property", "state", "json_pointer"), &GLTFDocument::import_object_model_property);
ClassDB::bind_static_method("GLTFDocument", D_METHOD("export_object_model_property", "state", "node_path", "godot_node", "gltf_node_index"), &GLTFDocument::export_object_model_property);
@@ -8257,6 +8271,7 @@ HashSet<String> GLTFDocument::get_supported_gltf_extensions_hashset() {
supported_extensions.insert("KHR_materials_emissive_strength");
supported_extensions.insert("KHR_materials_pbrSpecularGlossiness");
supported_extensions.insert("KHR_materials_unlit");
supported_extensions.insert("KHR_node_visibility");
supported_extensions.insert("KHR_texture_transform");
for (Ref<GLTFDocumentExtension> ext : all_document_extensions) {
ERR_CONTINUE(ext.is_null());
@@ -8657,6 +8672,14 @@ GLTFDocument::RootNodeMode GLTFDocument::get_root_node_mode() const {
return _root_node_mode;
}
void GLTFDocument::set_visibility_mode(VisibilityMode p_visibility_mode) {
_visibility_mode = p_visibility_mode;
}
GLTFDocument::VisibilityMode GLTFDocument::get_visibility_mode() const {
return _visibility_mode;
}
String GLTFDocument::_gen_unique_name_static(HashSet<String> &r_unique_names, const String &p_name) {
const String s_name = p_name.validate_node_name();