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
36AABB VisualInstance3D::get_aabb() const {
37 AABB ret;
38 GDVIRTUAL_CALL(_get_aabb, ret);
39 return ret;
40}
41
42void 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
50void 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
74RID VisualInstance3D::get_instance() const {
75 return instance;
76}
77
78void 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
83uint32_t VisualInstance3D::get_layer_mask() const {
84 return layers;
85}
86
87void 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
99bool 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
105void 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
110float VisualInstance3D::get_sorting_offset() const {
111 return sorting_offset;
112}
113
114void 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
119bool VisualInstance3D::is_sorting_use_aabb_center() const {
120 return sorting_use_aabb_center;
121}
122
123void 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
129void 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
150void VisualInstance3D::set_base(const RID &p_base) {
151 RenderingServer::get_singleton()->instance_set_base(instance, p_base);
152 base = p_base;
153}
154
155RID VisualInstance3D::get_base() const {
156 return base;
157}
158
159VisualInstance3D::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
165VisualInstance3D::~VisualInstance3D() {
166 ERR_FAIL_NULL(RenderingServer::get_singleton());
167 RenderingServer::get_singleton()->free(instance);
168}
169
170void 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
181Ref<Material> GeometryInstance3D::get_material_override() const {
182 return material_override;
183}
184
185void 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
190Ref<Material> GeometryInstance3D::get_material_overlay() const {
191 return material_overlay;
192}
193
194void 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
199float GeometryInstance3D::get_transparency() const {
200 return transparency;
201}
202
203void 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
209float GeometryInstance3D::get_visibility_range_begin() const {
210 return visibility_range_begin;
211}
212
213void 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
219float GeometryInstance3D::get_visibility_range_end() const {
220 return visibility_range_end;
221}
222
223void 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
229float GeometryInstance3D::get_visibility_range_begin_margin() const {
230 return visibility_range_begin_margin;
231}
232
233void 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
239float GeometryInstance3D::get_visibility_range_end_margin() const {
240 return visibility_range_end_margin;
241}
242
243void 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
249GeometryInstance3D::VisibilityRangeFadeMode GeometryInstance3D::get_visibility_range_fade_mode() const {
250 return visibility_range_fade_mode;
251}
252
253const 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
274bool 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
294bool 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
304void 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
324void 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
330GeometryInstance3D::ShadowCastingSetting GeometryInstance3D::get_cast_shadows_setting() const {
331 return shadow_casting_setting;
332}
333
334void GeometryInstance3D::set_extra_cull_margin(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
340float GeometryInstance3D::get_extra_cull_margin() const {
341 return extra_cull_margin;
342}
343
344void 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
350float GeometryInstance3D::get_lod_bias() const {
351 return lod_bias;
352}
353
354void 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
370Variant 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
374void 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
382AABB GeometryInstance3D::get_custom_aabb() const {
383 return custom_aabb;
384}
385
386void GeometryInstance3D::set_lightmap_scale(LightmapScale p_scale) {
387 ERR_FAIL_INDEX(p_scale, LIGHTMAP_SCALE_MAX);
388 lightmap_scale = p_scale;
389}
390
391GeometryInstance3D::LightmapScale GeometryInstance3D::get_lightmap_scale() const {
392 return lightmap_scale;
393}
394
395void 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
415GeometryInstance3D::GIMode GeometryInstance3D::get_gi_mode() const {
416 return gi_mode;
417}
418
419void 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
424bool GeometryInstance3D::is_ignoring_occlusion_culling() {
425 return ignore_occlusion_culling;
426}
427
428PackedStringArray 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
446void 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
452void 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
544GeometryInstance3D::GeometryInstance3D() {
545}
546
547GeometryInstance3D::~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