1 | /**************************************************************************/ |
2 | /* visual_instance_3d.cpp */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #include "visual_instance_3d.h" |
32 | |
33 | #include "core/core_string_names.h" |
34 | #include "scene/scene_string_names.h" |
35 | |
36 | AABB VisualInstance3D::get_aabb() const { |
37 | AABB ret; |
38 | GDVIRTUAL_CALL(_get_aabb, ret); |
39 | return ret; |
40 | } |
41 | |
42 | void VisualInstance3D::_update_visibility() { |
43 | if (!is_inside_tree()) { |
44 | return; |
45 | } |
46 | |
47 | RS::get_singleton()->instance_set_visible(get_instance(), is_visible_in_tree()); |
48 | } |
49 | |
50 | void VisualInstance3D::_notification(int p_what) { |
51 | switch (p_what) { |
52 | case NOTIFICATION_ENTER_WORLD: { |
53 | ERR_FAIL_COND(get_world_3d().is_null()); |
54 | RenderingServer::get_singleton()->instance_set_scenario(instance, get_world_3d()->get_scenario()); |
55 | _update_visibility(); |
56 | } break; |
57 | |
58 | case NOTIFICATION_TRANSFORM_CHANGED: { |
59 | Transform3D gt = get_global_transform(); |
60 | RenderingServer::get_singleton()->instance_set_transform(instance, gt); |
61 | } break; |
62 | |
63 | case NOTIFICATION_EXIT_WORLD: { |
64 | RenderingServer::get_singleton()->instance_set_scenario(instance, RID()); |
65 | RenderingServer::get_singleton()->instance_attach_skeleton(instance, RID()); |
66 | } break; |
67 | |
68 | case NOTIFICATION_VISIBILITY_CHANGED: { |
69 | _update_visibility(); |
70 | } break; |
71 | } |
72 | } |
73 | |
74 | RID VisualInstance3D::get_instance() const { |
75 | return instance; |
76 | } |
77 | |
78 | void VisualInstance3D::set_layer_mask(uint32_t p_mask) { |
79 | layers = p_mask; |
80 | RenderingServer::get_singleton()->instance_set_layer_mask(instance, p_mask); |
81 | } |
82 | |
83 | uint32_t VisualInstance3D::get_layer_mask() const { |
84 | return layers; |
85 | } |
86 | |
87 | void VisualInstance3D::set_layer_mask_value(int p_layer_number, bool p_value) { |
88 | ERR_FAIL_COND_MSG(p_layer_number < 1, "Render layer number must be between 1 and 20 inclusive." ); |
89 | ERR_FAIL_COND_MSG(p_layer_number > 20, "Render layer number must be between 1 and 20 inclusive." ); |
90 | uint32_t mask = get_layer_mask(); |
91 | if (p_value) { |
92 | mask |= 1 << (p_layer_number - 1); |
93 | } else { |
94 | mask &= ~(1 << (p_layer_number - 1)); |
95 | } |
96 | set_layer_mask(mask); |
97 | } |
98 | |
99 | bool VisualInstance3D::get_layer_mask_value(int p_layer_number) const { |
100 | ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Render layer number must be between 1 and 20 inclusive." ); |
101 | ERR_FAIL_COND_V_MSG(p_layer_number > 20, false, "Render layer number must be between 1 and 20 inclusive." ); |
102 | return layers & (1 << (p_layer_number - 1)); |
103 | } |
104 | |
105 | void VisualInstance3D::set_sorting_offset(float p_offset) { |
106 | sorting_offset = p_offset; |
107 | RenderingServer::get_singleton()->instance_set_pivot_data(instance, sorting_offset, sorting_use_aabb_center); |
108 | } |
109 | |
110 | float VisualInstance3D::get_sorting_offset() const { |
111 | return sorting_offset; |
112 | } |
113 | |
114 | void VisualInstance3D::set_sorting_use_aabb_center(bool p_enabled) { |
115 | sorting_use_aabb_center = p_enabled; |
116 | RenderingServer::get_singleton()->instance_set_pivot_data(instance, sorting_offset, sorting_use_aabb_center); |
117 | } |
118 | |
119 | bool VisualInstance3D::is_sorting_use_aabb_center() const { |
120 | return sorting_use_aabb_center; |
121 | } |
122 | |
123 | void VisualInstance3D::_validate_property(PropertyInfo &p_property) const { |
124 | if (p_property.name == "sorting_offset" || p_property.name == "sorting_use_aabb_center" ) { |
125 | p_property.usage = PROPERTY_USAGE_NONE; |
126 | } |
127 | } |
128 | |
129 | void VisualInstance3D::_bind_methods() { |
130 | ClassDB::bind_method(D_METHOD("set_base" , "base" ), &VisualInstance3D::set_base); |
131 | ClassDB::bind_method(D_METHOD("get_base" ), &VisualInstance3D::get_base); |
132 | ClassDB::bind_method(D_METHOD("get_instance" ), &VisualInstance3D::get_instance); |
133 | ClassDB::bind_method(D_METHOD("set_layer_mask" , "mask" ), &VisualInstance3D::set_layer_mask); |
134 | ClassDB::bind_method(D_METHOD("get_layer_mask" ), &VisualInstance3D::get_layer_mask); |
135 | ClassDB::bind_method(D_METHOD("set_layer_mask_value" , "layer_number" , "value" ), &VisualInstance3D::set_layer_mask_value); |
136 | ClassDB::bind_method(D_METHOD("get_layer_mask_value" , "layer_number" ), &VisualInstance3D::get_layer_mask_value); |
137 | ClassDB::bind_method(D_METHOD("set_sorting_offset" , "offset" ), &VisualInstance3D::set_sorting_offset); |
138 | ClassDB::bind_method(D_METHOD("get_sorting_offset" ), &VisualInstance3D::get_sorting_offset); |
139 | ClassDB::bind_method(D_METHOD("set_sorting_use_aabb_center" , "enabled" ), &VisualInstance3D::set_sorting_use_aabb_center); |
140 | ClassDB::bind_method(D_METHOD("is_sorting_use_aabb_center" ), &VisualInstance3D::is_sorting_use_aabb_center); |
141 | |
142 | GDVIRTUAL_BIND(_get_aabb); |
143 | ADD_PROPERTY(PropertyInfo(Variant::INT, "layers" , PROPERTY_HINT_LAYERS_3D_RENDER), "set_layer_mask" , "get_layer_mask" ); |
144 | |
145 | ADD_GROUP("Sorting" , "sorting_" ); |
146 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sorting_offset" ), "set_sorting_offset" , "get_sorting_offset" ); |
147 | ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sorting_use_aabb_center" ), "set_sorting_use_aabb_center" , "is_sorting_use_aabb_center" ); |
148 | } |
149 | |
150 | void VisualInstance3D::set_base(const RID &p_base) { |
151 | RenderingServer::get_singleton()->instance_set_base(instance, p_base); |
152 | base = p_base; |
153 | } |
154 | |
155 | RID VisualInstance3D::get_base() const { |
156 | return base; |
157 | } |
158 | |
159 | VisualInstance3D::VisualInstance3D() { |
160 | instance = RenderingServer::get_singleton()->instance_create(); |
161 | RenderingServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id()); |
162 | set_notify_transform(true); |
163 | } |
164 | |
165 | VisualInstance3D::~VisualInstance3D() { |
166 | ERR_FAIL_NULL(RenderingServer::get_singleton()); |
167 | RenderingServer::get_singleton()->free(instance); |
168 | } |
169 | |
170 | void GeometryInstance3D::set_material_override(const Ref<Material> &p_material) { |
171 | if (material_override.is_valid()) { |
172 | material_override->disconnect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); |
173 | } |
174 | material_override = p_material; |
175 | if (material_override.is_valid()) { |
176 | material_override->connect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); |
177 | } |
178 | RS::get_singleton()->instance_geometry_set_material_override(get_instance(), p_material.is_valid() ? p_material->get_rid() : RID()); |
179 | } |
180 | |
181 | Ref<Material> GeometryInstance3D::get_material_override() const { |
182 | return material_override; |
183 | } |
184 | |
185 | void GeometryInstance3D::set_material_overlay(const Ref<Material> &p_material) { |
186 | material_overlay = p_material; |
187 | RS::get_singleton()->instance_geometry_set_material_overlay(get_instance(), p_material.is_valid() ? p_material->get_rid() : RID()); |
188 | } |
189 | |
190 | Ref<Material> GeometryInstance3D::get_material_overlay() const { |
191 | return material_overlay; |
192 | } |
193 | |
194 | void GeometryInstance3D::set_transparency(float p_transparency) { |
195 | transparency = CLAMP(p_transparency, 0.0f, 1.0f); |
196 | RS::get_singleton()->instance_geometry_set_transparency(get_instance(), transparency); |
197 | } |
198 | |
199 | float GeometryInstance3D::get_transparency() const { |
200 | return transparency; |
201 | } |
202 | |
203 | void GeometryInstance3D::set_visibility_range_begin(float p_dist) { |
204 | visibility_range_begin = p_dist; |
205 | RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin, (RS::VisibilityRangeFadeMode)visibility_range_fade_mode); |
206 | update_configuration_warnings(); |
207 | } |
208 | |
209 | float GeometryInstance3D::get_visibility_range_begin() const { |
210 | return visibility_range_begin; |
211 | } |
212 | |
213 | void GeometryInstance3D::set_visibility_range_end(float p_dist) { |
214 | visibility_range_end = p_dist; |
215 | RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin, (RS::VisibilityRangeFadeMode)visibility_range_fade_mode); |
216 | update_configuration_warnings(); |
217 | } |
218 | |
219 | float GeometryInstance3D::get_visibility_range_end() const { |
220 | return visibility_range_end; |
221 | } |
222 | |
223 | void GeometryInstance3D::set_visibility_range_begin_margin(float p_dist) { |
224 | visibility_range_begin_margin = p_dist; |
225 | RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin, (RS::VisibilityRangeFadeMode)visibility_range_fade_mode); |
226 | update_configuration_warnings(); |
227 | } |
228 | |
229 | float GeometryInstance3D::get_visibility_range_begin_margin() const { |
230 | return visibility_range_begin_margin; |
231 | } |
232 | |
233 | void GeometryInstance3D::set_visibility_range_end_margin(float p_dist) { |
234 | visibility_range_end_margin = p_dist; |
235 | RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin, (RS::VisibilityRangeFadeMode)visibility_range_fade_mode); |
236 | update_configuration_warnings(); |
237 | } |
238 | |
239 | float GeometryInstance3D::get_visibility_range_end_margin() const { |
240 | return visibility_range_end_margin; |
241 | } |
242 | |
243 | void GeometryInstance3D::set_visibility_range_fade_mode(VisibilityRangeFadeMode p_mode) { |
244 | visibility_range_fade_mode = p_mode; |
245 | RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin, (RS::VisibilityRangeFadeMode)visibility_range_fade_mode); |
246 | update_configuration_warnings(); |
247 | } |
248 | |
249 | GeometryInstance3D::VisibilityRangeFadeMode GeometryInstance3D::get_visibility_range_fade_mode() const { |
250 | return visibility_range_fade_mode; |
251 | } |
252 | |
253 | const StringName *GeometryInstance3D::_instance_uniform_get_remap(const StringName p_name) const { |
254 | StringName *r = instance_shader_parameter_property_remap.getptr(p_name); |
255 | if (!r) { |
256 | String s = p_name; |
257 | #ifndef DISABLE_DEPRECATED |
258 | if (s.begins_with("shader_uniforms/" )) { |
259 | s = s.replace("shader_uniforms/" , "instance_shader_parameters/" ); |
260 | } |
261 | #endif // DISABLE_DEPRECATED |
262 | if (s.begins_with("instance_shader_parameters/" )) { |
263 | StringName pname = StringName(s); |
264 | StringName name = s.replace("instance_shader_parameters/" , "" ); |
265 | instance_shader_parameter_property_remap[pname] = name; |
266 | return instance_shader_parameter_property_remap.getptr(pname); |
267 | } |
268 | return nullptr; |
269 | } |
270 | |
271 | return r; |
272 | } |
273 | |
274 | bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) { |
275 | const StringName *r = _instance_uniform_get_remap(p_name); |
276 | if (r) { |
277 | set_instance_shader_parameter(*r, p_value); |
278 | return true; |
279 | } |
280 | #ifndef DISABLE_DEPRECATED |
281 | if (p_name == SceneStringNames::get_singleton()->use_in_baked_light && bool(p_value)) { |
282 | set_gi_mode(GI_MODE_STATIC); |
283 | return true; |
284 | } |
285 | |
286 | if (p_name == SceneStringNames::get_singleton()->use_dynamic_gi && bool(p_value)) { |
287 | set_gi_mode(GI_MODE_DYNAMIC); |
288 | return true; |
289 | } |
290 | #endif // DISABLE_DEPRECATED |
291 | return false; |
292 | } |
293 | |
294 | bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const { |
295 | const StringName *r = _instance_uniform_get_remap(p_name); |
296 | if (r) { |
297 | r_ret = get_instance_shader_parameter(*r); |
298 | return true; |
299 | } |
300 | |
301 | return false; |
302 | } |
303 | |
304 | void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { |
305 | List<PropertyInfo> pinfo; |
306 | RS::get_singleton()->instance_geometry_get_shader_parameter_list(get_instance(), &pinfo); |
307 | for (PropertyInfo &pi : pinfo) { |
308 | bool has_def_value = false; |
309 | Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), pi.name); |
310 | if (def_value.get_type() != Variant::NIL) { |
311 | has_def_value = true; |
312 | } |
313 | if (instance_shader_parameters.has(pi.name)) { |
314 | pi.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE | (has_def_value ? (PROPERTY_USAGE_CHECKABLE | PROPERTY_USAGE_CHECKED) : PROPERTY_USAGE_NONE); |
315 | } else { |
316 | pi.usage = PROPERTY_USAGE_EDITOR | (has_def_value ? PROPERTY_USAGE_CHECKABLE : PROPERTY_USAGE_NONE); //do not save if not changed |
317 | } |
318 | |
319 | pi.name = "instance_shader_parameters/" + pi.name; |
320 | p_list->push_back(pi); |
321 | } |
322 | } |
323 | |
324 | void GeometryInstance3D::set_cast_shadows_setting(ShadowCastingSetting p_shadow_casting_setting) { |
325 | shadow_casting_setting = p_shadow_casting_setting; |
326 | |
327 | RS::get_singleton()->instance_geometry_set_cast_shadows_setting(get_instance(), (RS::ShadowCastingSetting)p_shadow_casting_setting); |
328 | } |
329 | |
330 | GeometryInstance3D::ShadowCastingSetting GeometryInstance3D::get_cast_shadows_setting() const { |
331 | return shadow_casting_setting; |
332 | } |
333 | |
334 | void GeometryInstance3D::(float p_margin) { |
335 | ERR_FAIL_COND(p_margin < 0); |
336 | extra_cull_margin = p_margin; |
337 | RS::get_singleton()->instance_set_extra_visibility_margin(get_instance(), extra_cull_margin); |
338 | } |
339 | |
340 | float GeometryInstance3D::() const { |
341 | return extra_cull_margin; |
342 | } |
343 | |
344 | void GeometryInstance3D::set_lod_bias(float p_bias) { |
345 | ERR_FAIL_COND(p_bias < 0.0); |
346 | lod_bias = p_bias; |
347 | RS::get_singleton()->instance_geometry_set_lod_bias(get_instance(), lod_bias); |
348 | } |
349 | |
350 | float GeometryInstance3D::get_lod_bias() const { |
351 | return lod_bias; |
352 | } |
353 | |
354 | void GeometryInstance3D::set_instance_shader_parameter(const StringName &p_name, const Variant &p_value) { |
355 | if (p_value.get_type() == Variant::NIL) { |
356 | Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), p_name); |
357 | RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_name, def_value); |
358 | instance_shader_parameters.erase(p_value); |
359 | } else { |
360 | instance_shader_parameters[p_name] = p_value; |
361 | if (p_value.get_type() == Variant::OBJECT) { |
362 | RID tex_id = p_value; |
363 | RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_name, tex_id); |
364 | } else { |
365 | RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_name, p_value); |
366 | } |
367 | } |
368 | } |
369 | |
370 | Variant GeometryInstance3D::get_instance_shader_parameter(const StringName &p_name) const { |
371 | return RS::get_singleton()->instance_geometry_get_shader_parameter(get_instance(), p_name); |
372 | } |
373 | |
374 | void GeometryInstance3D::set_custom_aabb(AABB p_aabb) { |
375 | if (p_aabb == custom_aabb) { |
376 | return; |
377 | } |
378 | custom_aabb = p_aabb; |
379 | RS::get_singleton()->instance_set_custom_aabb(get_instance(), custom_aabb); |
380 | } |
381 | |
382 | AABB GeometryInstance3D::get_custom_aabb() const { |
383 | return custom_aabb; |
384 | } |
385 | |
386 | void GeometryInstance3D::set_lightmap_scale(LightmapScale p_scale) { |
387 | ERR_FAIL_INDEX(p_scale, LIGHTMAP_SCALE_MAX); |
388 | lightmap_scale = p_scale; |
389 | } |
390 | |
391 | GeometryInstance3D::LightmapScale GeometryInstance3D::get_lightmap_scale() const { |
392 | return lightmap_scale; |
393 | } |
394 | |
395 | void GeometryInstance3D::set_gi_mode(GIMode p_mode) { |
396 | switch (p_mode) { |
397 | case GI_MODE_DISABLED: { |
398 | RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false); |
399 | RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_USE_DYNAMIC_GI, false); |
400 | } break; |
401 | case GI_MODE_STATIC: { |
402 | RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_USE_BAKED_LIGHT, true); |
403 | RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_USE_DYNAMIC_GI, false); |
404 | |
405 | } break; |
406 | case GI_MODE_DYNAMIC: { |
407 | RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false); |
408 | RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_USE_DYNAMIC_GI, true); |
409 | } break; |
410 | } |
411 | |
412 | gi_mode = p_mode; |
413 | } |
414 | |
415 | GeometryInstance3D::GIMode GeometryInstance3D::get_gi_mode() const { |
416 | return gi_mode; |
417 | } |
418 | |
419 | void GeometryInstance3D::set_ignore_occlusion_culling(bool p_enabled) { |
420 | ignore_occlusion_culling = p_enabled; |
421 | RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, ignore_occlusion_culling); |
422 | } |
423 | |
424 | bool GeometryInstance3D::is_ignoring_occlusion_culling() { |
425 | return ignore_occlusion_culling; |
426 | } |
427 | |
428 | PackedStringArray GeometryInstance3D::get_configuration_warnings() const { |
429 | PackedStringArray warnings = Node::get_configuration_warnings(); |
430 | |
431 | if (!Math::is_zero_approx(visibility_range_end) && visibility_range_end <= visibility_range_begin) { |
432 | warnings.push_back(RTR("The GeometryInstance3D visibility range's End distance is set to a non-zero value, but is lower than the Begin distance.\nThis means the GeometryInstance3D will never be visible.\nTo resolve this, set the End distance to 0 or to a value greater than the Begin distance." )); |
433 | } |
434 | |
435 | if ((visibility_range_fade_mode == VISIBILITY_RANGE_FADE_SELF || visibility_range_fade_mode == VISIBILITY_RANGE_FADE_DEPENDENCIES) && !Math::is_zero_approx(visibility_range_begin) && Math::is_zero_approx(visibility_range_begin_margin)) { |
436 | warnings.push_back(RTR("The GeometryInstance3D is configured to fade in smoothly over distance, but the fade transition distance is set to 0.\nTo resolve this, increase Visibility Range Begin Margin above 0." )); |
437 | } |
438 | |
439 | if ((visibility_range_fade_mode == VISIBILITY_RANGE_FADE_SELF || visibility_range_fade_mode == VISIBILITY_RANGE_FADE_DEPENDENCIES) && !Math::is_zero_approx(visibility_range_end) && Math::is_zero_approx(visibility_range_end_margin)) { |
440 | warnings.push_back(RTR("The GeometryInstance3D is configured to fade out smoothly over distance, but the fade transition distance is set to 0.\nTo resolve this, increase Visibility Range End Margin above 0." )); |
441 | } |
442 | |
443 | return warnings; |
444 | } |
445 | |
446 | void GeometryInstance3D::_validate_property(PropertyInfo &p_property) const { |
447 | if (p_property.name == "sorting_offset" || p_property.name == "sorting_use_aabb_center" ) { |
448 | p_property.usage = PROPERTY_USAGE_DEFAULT; |
449 | } |
450 | } |
451 | |
452 | void GeometryInstance3D::_bind_methods() { |
453 | ClassDB::bind_method(D_METHOD("set_material_override" , "material" ), &GeometryInstance3D::set_material_override); |
454 | ClassDB::bind_method(D_METHOD("get_material_override" ), &GeometryInstance3D::get_material_override); |
455 | |
456 | ClassDB::bind_method(D_METHOD("set_material_overlay" , "material" ), &GeometryInstance3D::set_material_overlay); |
457 | ClassDB::bind_method(D_METHOD("get_material_overlay" ), &GeometryInstance3D::get_material_overlay); |
458 | |
459 | ClassDB::bind_method(D_METHOD("set_cast_shadows_setting" , "shadow_casting_setting" ), &GeometryInstance3D::set_cast_shadows_setting); |
460 | ClassDB::bind_method(D_METHOD("get_cast_shadows_setting" ), &GeometryInstance3D::get_cast_shadows_setting); |
461 | |
462 | ClassDB::bind_method(D_METHOD("set_lod_bias" , "bias" ), &GeometryInstance3D::set_lod_bias); |
463 | ClassDB::bind_method(D_METHOD("get_lod_bias" ), &GeometryInstance3D::get_lod_bias); |
464 | |
465 | ClassDB::bind_method(D_METHOD("set_transparency" , "transparency" ), &GeometryInstance3D::set_transparency); |
466 | ClassDB::bind_method(D_METHOD("get_transparency" ), &GeometryInstance3D::get_transparency); |
467 | |
468 | ClassDB::bind_method(D_METHOD("set_visibility_range_end_margin" , "distance" ), &GeometryInstance3D::set_visibility_range_end_margin); |
469 | ClassDB::bind_method(D_METHOD("get_visibility_range_end_margin" ), &GeometryInstance3D::get_visibility_range_end_margin); |
470 | |
471 | ClassDB::bind_method(D_METHOD("set_visibility_range_end" , "distance" ), &GeometryInstance3D::set_visibility_range_end); |
472 | ClassDB::bind_method(D_METHOD("get_visibility_range_end" ), &GeometryInstance3D::get_visibility_range_end); |
473 | |
474 | ClassDB::bind_method(D_METHOD("set_visibility_range_begin_margin" , "distance" ), &GeometryInstance3D::set_visibility_range_begin_margin); |
475 | ClassDB::bind_method(D_METHOD("get_visibility_range_begin_margin" ), &GeometryInstance3D::get_visibility_range_begin_margin); |
476 | |
477 | ClassDB::bind_method(D_METHOD("set_visibility_range_begin" , "distance" ), &GeometryInstance3D::set_visibility_range_begin); |
478 | ClassDB::bind_method(D_METHOD("get_visibility_range_begin" ), &GeometryInstance3D::get_visibility_range_begin); |
479 | |
480 | ClassDB::bind_method(D_METHOD("set_visibility_range_fade_mode" , "mode" ), &GeometryInstance3D::set_visibility_range_fade_mode); |
481 | ClassDB::bind_method(D_METHOD("get_visibility_range_fade_mode" ), &GeometryInstance3D::get_visibility_range_fade_mode); |
482 | |
483 | ClassDB::bind_method(D_METHOD("set_instance_shader_parameter" , "name" , "value" ), &GeometryInstance3D::set_instance_shader_parameter); |
484 | ClassDB::bind_method(D_METHOD("get_instance_shader_parameter" , "name" ), &GeometryInstance3D::get_instance_shader_parameter); |
485 | |
486 | ClassDB::bind_method(D_METHOD("set_extra_cull_margin" , "margin" ), &GeometryInstance3D::set_extra_cull_margin); |
487 | ClassDB::bind_method(D_METHOD("get_extra_cull_margin" ), &GeometryInstance3D::get_extra_cull_margin); |
488 | |
489 | ClassDB::bind_method(D_METHOD("set_lightmap_scale" , "scale" ), &GeometryInstance3D::set_lightmap_scale); |
490 | ClassDB::bind_method(D_METHOD("get_lightmap_scale" ), &GeometryInstance3D::get_lightmap_scale); |
491 | |
492 | ClassDB::bind_method(D_METHOD("set_gi_mode" , "mode" ), &GeometryInstance3D::set_gi_mode); |
493 | ClassDB::bind_method(D_METHOD("get_gi_mode" ), &GeometryInstance3D::get_gi_mode); |
494 | |
495 | ClassDB::bind_method(D_METHOD("set_ignore_occlusion_culling" , "ignore_culling" ), &GeometryInstance3D::set_ignore_occlusion_culling); |
496 | ClassDB::bind_method(D_METHOD("is_ignoring_occlusion_culling" ), &GeometryInstance3D::is_ignoring_occlusion_culling); |
497 | |
498 | ClassDB::bind_method(D_METHOD("set_custom_aabb" , "aabb" ), &GeometryInstance3D::set_custom_aabb); |
499 | ClassDB::bind_method(D_METHOD("get_custom_aabb" ), &GeometryInstance3D::get_custom_aabb); |
500 | |
501 | ClassDB::bind_method(D_METHOD("get_aabb" ), &GeometryInstance3D::get_aabb); |
502 | |
503 | ADD_GROUP("Geometry" , "" ); |
504 | ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_override" , PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial" , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE), "set_material_override" , "get_material_override" ); |
505 | ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_overlay" , PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial" , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE), "set_material_overlay" , "get_material_overlay" ); |
506 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "transparency" , PROPERTY_HINT_RANGE, "0.0,1.0,0.01" ), "set_transparency" , "get_transparency" ); |
507 | ADD_PROPERTY(PropertyInfo(Variant::INT, "cast_shadow" , PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only" ), "set_cast_shadows_setting" , "get_cast_shadows_setting" ); |
508 | 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" ); |
509 | ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb" , PROPERTY_HINT_NONE, "suffix:m" ), "set_custom_aabb" , "get_custom_aabb" ); |
510 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_bias" , PROPERTY_HINT_RANGE, "0.001,128,0.001" ), "set_lod_bias" , "get_lod_bias" ); |
511 | ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_occlusion_culling" ), "set_ignore_occlusion_culling" , "is_ignoring_occlusion_culling" ); |
512 | |
513 | ADD_GROUP("Global Illumination" , "gi_" ); |
514 | ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_mode" , PROPERTY_HINT_ENUM, "Disabled,Static (VoxelGI/SDFGI/LightmapGI),Dynamic (VoxelGI only)" ), "set_gi_mode" , "get_gi_mode" ); |
515 | ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_lightmap_scale" , PROPERTY_HINT_ENUM, String::utf8("1×,2×,4×,8×" )), "set_lightmap_scale" , "get_lightmap_scale" ); |
516 | |
517 | ADD_GROUP("Visibility Range" , "visibility_range_" ); |
518 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin" , PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m" ), "set_visibility_range_begin" , "get_visibility_range_begin" ); |
519 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin_margin" , PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m" ), "set_visibility_range_begin_margin" , "get_visibility_range_begin_margin" ); |
520 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end" , PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m" ), "set_visibility_range_end" , "get_visibility_range_end" ); |
521 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end_margin" , PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m" ), "set_visibility_range_end_margin" , "get_visibility_range_end_margin" ); |
522 | ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_range_fade_mode" , PROPERTY_HINT_ENUM, "Disabled,Self,Dependencies" ), "set_visibility_range_fade_mode" , "get_visibility_range_fade_mode" ); |
523 | |
524 | BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_OFF); |
525 | BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_ON); |
526 | BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_DOUBLE_SIDED); |
527 | BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_SHADOWS_ONLY); |
528 | |
529 | BIND_ENUM_CONSTANT(GI_MODE_DISABLED); |
530 | BIND_ENUM_CONSTANT(GI_MODE_STATIC); |
531 | BIND_ENUM_CONSTANT(GI_MODE_DYNAMIC); |
532 | |
533 | BIND_ENUM_CONSTANT(LIGHTMAP_SCALE_1X); |
534 | BIND_ENUM_CONSTANT(LIGHTMAP_SCALE_2X); |
535 | BIND_ENUM_CONSTANT(LIGHTMAP_SCALE_4X); |
536 | BIND_ENUM_CONSTANT(LIGHTMAP_SCALE_8X); |
537 | BIND_ENUM_CONSTANT(LIGHTMAP_SCALE_MAX); |
538 | |
539 | BIND_ENUM_CONSTANT(VISIBILITY_RANGE_FADE_DISABLED); |
540 | BIND_ENUM_CONSTANT(VISIBILITY_RANGE_FADE_SELF); |
541 | BIND_ENUM_CONSTANT(VISIBILITY_RANGE_FADE_DEPENDENCIES); |
542 | } |
543 | |
544 | GeometryInstance3D::GeometryInstance3D() { |
545 | } |
546 | |
547 | GeometryInstance3D::~GeometryInstance3D() { |
548 | if (material_overlay.is_valid()) { |
549 | set_material_overlay(Ref<Material>()); |
550 | } |
551 | if (material_override.is_valid()) { |
552 | set_material_override(Ref<Material>()); |
553 | } |
554 | } |
555 | |