diff options
Diffstat (limited to 'scene/3d/visual_instance_3d.cpp')
-rw-r--r-- | scene/3d/visual_instance_3d.cpp | 164 |
1 files changed, 106 insertions, 58 deletions
diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index e93ad5ecbf..8026b12c2b 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -1,47 +1,42 @@ -/*************************************************************************/ -/* visual_instance_3d.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* visual_instance_3d.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "visual_instance_3d.h" +#include "core/core_string_names.h" #include "scene/scene_string_names.h" AABB VisualInstance3D::get_aabb() const { AABB ret; - if (GDVIRTUAL_CALL(_get_aabb, ret)) { - return ret; - } - return AABB(); -} - -AABB VisualInstance3D::get_transformed_aabb() const { - return get_global_transform().xform(get_aabb()); + GDVIRTUAL_CALL(_get_aabb, ret); + return ret; } void VisualInstance3D::_update_visibility() { @@ -80,10 +75,6 @@ RID VisualInstance3D::get_instance() const { return instance; } -RID VisualInstance3D::_get_visual_instance_rid() const { - return instance; -} - void VisualInstance3D::set_layer_mask(uint32_t p_mask) { layers = p_mask; RenderingServer::get_singleton()->instance_set_layer_mask(instance, p_mask); @@ -111,8 +102,31 @@ bool VisualInstance3D::get_layer_mask_value(int p_layer_number) const { return layers & (1 << (p_layer_number - 1)); } +void VisualInstance3D::set_sorting_offset(float p_offset) { + sorting_offset = p_offset; + RenderingServer::get_singleton()->instance_set_pivot_data(instance, sorting_offset, sorting_use_aabb_center); +} + +float VisualInstance3D::get_sorting_offset() const { + return sorting_offset; +} + +void VisualInstance3D::set_sorting_use_aabb_center(bool p_enabled) { + sorting_use_aabb_center = p_enabled; + RenderingServer::get_singleton()->instance_set_pivot_data(instance, sorting_offset, sorting_use_aabb_center); +} + +bool VisualInstance3D::is_sorting_use_aabb_center() const { + return sorting_use_aabb_center; +} + +void VisualInstance3D::_validate_property(PropertyInfo &p_property) const { + if (p_property.name == "sorting_offset" || p_property.name == "sorting_use_aabb_center") { + p_property.usage = PROPERTY_USAGE_NONE; + } +} + void VisualInstance3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("_get_visual_instance_rid"), &VisualInstance3D::_get_visual_instance_rid); ClassDB::bind_method(D_METHOD("set_base", "base"), &VisualInstance3D::set_base); ClassDB::bind_method(D_METHOD("get_base"), &VisualInstance3D::get_base); ClassDB::bind_method(D_METHOD("get_instance"), &VisualInstance3D::get_instance); @@ -120,11 +134,17 @@ void VisualInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_layer_mask"), &VisualInstance3D::get_layer_mask); ClassDB::bind_method(D_METHOD("set_layer_mask_value", "layer_number", "value"), &VisualInstance3D::set_layer_mask_value); ClassDB::bind_method(D_METHOD("get_layer_mask_value", "layer_number"), &VisualInstance3D::get_layer_mask_value); - - ClassDB::bind_method(D_METHOD("get_transformed_aabb"), &VisualInstance3D::get_transformed_aabb); + ClassDB::bind_method(D_METHOD("set_sorting_offset", "offset"), &VisualInstance3D::set_sorting_offset); + ClassDB::bind_method(D_METHOD("get_sorting_offset"), &VisualInstance3D::get_sorting_offset); + ClassDB::bind_method(D_METHOD("set_sorting_use_aabb_center", "enabled"), &VisualInstance3D::set_sorting_use_aabb_center); + ClassDB::bind_method(D_METHOD("is_sorting_use_aabb_center"), &VisualInstance3D::is_sorting_use_aabb_center); GDVIRTUAL_BIND(_get_aabb); ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_3D_RENDER), "set_layer_mask", "get_layer_mask"); + + ADD_GROUP("Sorting", "sorting_"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sorting_offset"), "set_sorting_offset", "get_sorting_offset"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sorting_use_aabb_center"), "set_sorting_use_aabb_center", "is_sorting_use_aabb_center"); } void VisualInstance3D::set_base(const RID &p_base) { @@ -143,11 +163,18 @@ VisualInstance3D::VisualInstance3D() { } VisualInstance3D::~VisualInstance3D() { + ERR_FAIL_NULL(RenderingServer::get_singleton()); RenderingServer::get_singleton()->free(instance); } void GeometryInstance3D::set_material_override(const Ref<Material> &p_material) { + if (material_override.is_valid()) { + material_override->disconnect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + } material_override = p_material; + if (material_override.is_valid()) { + material_override->connect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + } RS::get_singleton()->instance_geometry_set_material_override(get_instance(), p_material.is_valid() ? p_material->get_rid() : RID()); } @@ -164,7 +191,7 @@ Ref<Material> GeometryInstance3D::get_material_overlay() const { return material_overlay; } -void GeometryInstance3D::set_transparecy(float p_transparency) { +void GeometryInstance3D::set_transparency(float p_transparency) { transparency = CLAMP(p_transparency, 0.0f, 1.0f); RS::get_singleton()->instance_geometry_set_transparency(get_instance(), transparency); } @@ -224,15 +251,20 @@ GeometryInstance3D::VisibilityRangeFadeMode GeometryInstance3D::get_visibility_r } const StringName *GeometryInstance3D::_instance_uniform_get_remap(const StringName p_name) const { - StringName *r = instance_uniform_property_remap.getptr(p_name); + StringName *r = instance_shader_parameter_property_remap.getptr(p_name); if (!r) { String s = p_name; +#ifndef DISABLE_DEPRECATED if (s.begins_with("shader_uniforms/")) { - StringName name = s.replace("shader_uniforms/", ""); - instance_uniform_property_remap[p_name] = name; - return instance_uniform_property_remap.getptr(p_name); + s = s.replace("shader_uniforms/", "instance_shader_parameters/"); + } +#endif // DISABLE_DEPRECATED + if (s.begins_with("instance_shader_parameters/")) { + StringName pname = StringName(s); + StringName name = s.replace("instance_shader_parameters/", ""); + instance_shader_parameter_property_remap[pname] = name; + return instance_shader_parameter_property_remap.getptr(pname); } - return nullptr; } @@ -255,7 +287,7 @@ bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) set_gi_mode(GI_MODE_DYNAMIC); return true; } -#endif +#endif // DISABLE_DEPRECATED return false; } @@ -278,13 +310,13 @@ void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { if (def_value.get_type() != Variant::NIL) { has_def_value = true; } - if (instance_uniforms.has(pi.name)) { + if (instance_shader_parameters.has(pi.name)) { pi.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE | (has_def_value ? (PROPERTY_USAGE_CHECKABLE | PROPERTY_USAGE_CHECKED) : PROPERTY_USAGE_NONE); } else { pi.usage = PROPERTY_USAGE_EDITOR | (has_def_value ? PROPERTY_USAGE_CHECKABLE : PROPERTY_USAGE_NONE); //do not save if not changed } - pi.name = "shader_uniforms/" + pi.name; + pi.name = "instance_shader_parameters/" + pi.name; p_list->push_back(pi); } } @@ -323,9 +355,9 @@ void GeometryInstance3D::set_instance_shader_parameter(const StringName &p_name, if (p_value.get_type() == Variant::NIL) { Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), p_name); RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_name, def_value); - instance_uniforms.erase(p_value); + instance_shader_parameters.erase(p_value); } else { - instance_uniforms[p_name] = p_value; + instance_shader_parameters[p_name] = p_value; if (p_value.get_type() == Variant::OBJECT) { RID tex_id = p_value; RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_name, tex_id); @@ -339,8 +371,16 @@ Variant GeometryInstance3D::get_instance_shader_parameter(const StringName &p_na return RS::get_singleton()->instance_geometry_get_shader_parameter(get_instance(), p_name); } -void GeometryInstance3D::set_custom_aabb(AABB aabb) { - RS::get_singleton()->instance_set_custom_aabb(get_instance(), aabb); +void GeometryInstance3D::set_custom_aabb(AABB p_aabb) { + if (p_aabb == custom_aabb) { + return; + } + custom_aabb = p_aabb; + RS::get_singleton()->instance_set_custom_aabb(get_instance(), custom_aabb); +} + +AABB GeometryInstance3D::get_custom_aabb() const { + return custom_aabb; } void GeometryInstance3D::set_lightmap_scale(LightmapScale p_scale) { @@ -403,6 +443,12 @@ PackedStringArray GeometryInstance3D::get_configuration_warnings() const { return warnings; } +void GeometryInstance3D::_validate_property(PropertyInfo &p_property) const { + if (p_property.name == "sorting_offset" || p_property.name == "sorting_use_aabb_center") { + p_property.usage = PROPERTY_USAGE_DEFAULT; + } +} + void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_material_override", "material"), &GeometryInstance3D::set_material_override); ClassDB::bind_method(D_METHOD("get_material_override"), &GeometryInstance3D::get_material_override); @@ -416,7 +462,7 @@ void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lod_bias", "bias"), &GeometryInstance3D::set_lod_bias); ClassDB::bind_method(D_METHOD("get_lod_bias"), &GeometryInstance3D::get_lod_bias); - ClassDB::bind_method(D_METHOD("set_transparency", "transparency"), &GeometryInstance3D::set_transparecy); + ClassDB::bind_method(D_METHOD("set_transparency", "transparency"), &GeometryInstance3D::set_transparency); ClassDB::bind_method(D_METHOD("get_transparency"), &GeometryInstance3D::get_transparency); ClassDB::bind_method(D_METHOD("set_visibility_range_end_margin", "distance"), &GeometryInstance3D::set_visibility_range_end_margin); @@ -450,6 +496,7 @@ void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_ignoring_occlusion_culling"), &GeometryInstance3D::is_ignoring_occlusion_culling); ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &GeometryInstance3D::set_custom_aabb); + ClassDB::bind_method(D_METHOD("get_custom_aabb"), &GeometryInstance3D::get_custom_aabb); ClassDB::bind_method(D_METHOD("get_aabb"), &GeometryInstance3D::get_aabb); @@ -459,6 +506,7 @@ void GeometryInstance3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "transparency", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_transparency", "get_transparency"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), "set_cast_shadows_setting", "get_cast_shadows_setting"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "extra_cull_margin", PROPERTY_HINT_RANGE, "0,16384,0.01,suffix:m"), "set_extra_cull_margin", "get_extra_cull_margin"); + ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, "suffix:m"), "set_custom_aabb", "get_custom_aabb"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_bias", PROPERTY_HINT_RANGE, "0.001,128,0.001"), "set_lod_bias", "get_lod_bias"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_occlusion_culling"), "set_ignore_occlusion_culling", "is_ignoring_occlusion_culling"); |