diff options
Diffstat (limited to 'scene/3d')
-rw-r--r-- | scene/3d/area_3d.cpp | 4 | ||||
-rw-r--r-- | scene/3d/area_3d.h | 4 | ||||
-rw-r--r-- | scene/3d/audio_stream_player_3d.cpp | 4 | ||||
-rw-r--r-- | scene/3d/cpu_particles_3d.cpp | 1 | ||||
-rw-r--r-- | scene/3d/decal.cpp | 235 | ||||
-rw-r--r-- | scene/3d/decal.h | 114 | ||||
-rw-r--r-- | scene/3d/light_3d.cpp | 57 | ||||
-rw-r--r-- | scene/3d/light_3d.h | 8 | ||||
-rw-r--r-- | scene/3d/mesh_instance_3d.cpp | 21 | ||||
-rw-r--r-- | scene/3d/path_3d.cpp | 12 | ||||
-rw-r--r-- | scene/3d/physics_body_3d.cpp | 132 | ||||
-rw-r--r-- | scene/3d/physics_body_3d.h | 24 | ||||
-rw-r--r-- | scene/3d/physics_joint_3d.cpp | 6 | ||||
-rw-r--r-- | scene/3d/skeleton_3d.cpp | 12 | ||||
-rw-r--r-- | scene/3d/skeleton_3d.h | 2 | ||||
-rw-r--r-- | scene/3d/skeleton_ik_3d.cpp | 12 | ||||
-rw-r--r-- | scene/3d/spring_arm_3d.cpp | 6 | ||||
-rw-r--r-- | scene/3d/visual_instance_3d.cpp | 75 | ||||
-rw-r--r-- | scene/3d/visual_instance_3d.h | 12 | ||||
-rw-r--r-- | scene/3d/voxelizer.cpp | 18 | ||||
-rw-r--r-- | scene/3d/xr_nodes.cpp | 8 |
21 files changed, 690 insertions, 77 deletions
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index 17ae553e5e..b72483d71b 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -416,7 +416,7 @@ bool Area3D::is_monitoring() const { return monitoring; } -Array Area3D::get_overlapping_bodies() const { +TypedArray<Node3D> Area3D::get_overlapping_bodies() const { ERR_FAIL_COND_V(!monitoring, Array()); Array ret; @@ -451,7 +451,7 @@ bool Area3D::is_monitorable() const { return monitorable; } -Array Area3D::get_overlapping_areas() const { +TypedArray<Area3D> Area3D::get_overlapping_areas() const { ERR_FAIL_COND_V(!monitoring, Array()); Array ret; diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index ff6c0b6b08..f6503c6d2d 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -184,8 +184,8 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_overlapping_bodies() const; - Array get_overlapping_areas() const; //function for script + TypedArray<Node3D> get_overlapping_bodies() const; + TypedArray<Area3D> get_overlapping_areas() const; //function for script bool overlaps_area(Node *p_area) const; bool overlaps_body(Node *p_body) const; diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 097368853e..28a8b01437 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -556,7 +556,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { for (int i = 0; i < vol_index_max; i++) { - output.reverb_vol[i] = output.reverb_vol[i].linear_interpolate(center_frame, attenuation); + output.reverb_vol[i] = output.reverb_vol[i].lerp(center_frame, attenuation); } } else { for (int i = 0; i < vol_index_max; i++) { @@ -567,7 +567,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { for (int i = 0; i < vol_index_max; i++) { - output.reverb_vol[i] = output.vol[i].linear_interpolate(output.reverb_vol[i] * attenuation, uniformity); + output.reverb_vol[i] = output.vol[i].lerp(output.reverb_vol[i] * attenuation, uniformity); output.reverb_vol[i] *= area_send; } diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 12c105b0f4..4c25f55f0b 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -69,6 +69,7 @@ void CPUParticles3D::set_amount(int p_amount) { for (int i = 0; i < p_amount; i++) { w[i].active = false; + w[i].custom[3] = 0.0; // Make sure w component isn't garbage data } } diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp new file mode 100644 index 0000000000..4c824aedc4 --- /dev/null +++ b/scene/3d/decal.cpp @@ -0,0 +1,235 @@ +/*************************************************************************/ +/* decal.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ + +#include "decal.h" + +void Decal::set_extents(const Vector3 &p_extents) { + extents = p_extents; + RS::get_singleton()->decal_set_extents(decal, p_extents); + update_gizmo(); + _change_notify("extents"); +} + +Vector3 Decal::get_extents() const { + return extents; +} + +void Decal::set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture) { + ERR_FAIL_INDEX(p_type, TEXTURE_MAX); + textures[p_type] = p_texture; + RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + RS::get_singleton()->decal_set_texture(decal, RS::DecalTexture(p_type), texture_rid); +} +Ref<Texture2D> Decal::get_texture(DecalTexture p_type) const { + ERR_FAIL_INDEX_V(p_type, TEXTURE_MAX, Ref<Texture2D>()); + return textures[p_type]; +} + +void Decal::set_emission_energy(float p_energy) { + emission_energy = p_energy; + RS::get_singleton()->decal_set_emission_energy(decal, emission_energy); +} +float Decal::get_emission_energy() const { + return emission_energy; +} + +void Decal::set_albedo_mix(float p_mix) { + albedo_mix = p_mix; + RS::get_singleton()->decal_set_albedo_mix(decal, albedo_mix); +} +float Decal::get_albedo_mix() const { + return albedo_mix; +} + +void Decal::set_upper_fade(float p_fade) { + upper_fade = p_fade; + RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade); +} +float Decal::get_upper_fade() const { + return upper_fade; +} + +void Decal::set_lower_fade(float p_fade) { + lower_fade = p_fade; + RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade); +} +float Decal::get_lower_fade() const { + return lower_fade; +} + +void Decal::set_normal_fade(float p_fade) { + normal_fade = p_fade; + RS::get_singleton()->decal_set_normal_fade(decal, normal_fade); +} +float Decal::get_normal_fade() const { + return normal_fade; +} + +void Decal::set_modulate(Color p_modulate) { + modulate = p_modulate; + RS::get_singleton()->decal_set_modulate(decal, p_modulate); +} + +Color Decal::get_modulate() const { + return modulate; +} + +void Decal::set_enable_distance_fade(bool p_enable) { + distance_fade_enabled = p_enable; + RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); +} +bool Decal::is_distance_fade_enabled() const { + return distance_fade_enabled; +} + +void Decal::set_distance_fade_begin(float p_distance) { + distance_fade_begin = p_distance; + RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); +} +float Decal::get_distance_fade_begin() const { + return distance_fade_begin; +} + +void Decal::set_distance_fade_length(float p_length) { + distance_fade_length = p_length; + RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); +} +float Decal::get_distance_fade_length() const { + return distance_fade_length; +} + +void Decal::set_cull_mask(uint32_t p_layers) { + cull_mask = p_layers; + RS::get_singleton()->decal_set_cull_mask(decal, cull_mask); +} +uint32_t Decal::get_cull_mask() const { + return cull_mask; +} + +AABB Decal::get_aabb() const { + + AABB aabb; + aabb.position = -extents; + aabb.size = extents * 2.0; + return aabb; +} +Vector<Face3> Decal::get_faces(uint32_t p_usage_flags) const { + + return Vector<Face3>(); +} + +void Decal::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_extents", "extents"), &Decal::set_extents); + ClassDB::bind_method(D_METHOD("get_extents"), &Decal::get_extents); + + ClassDB::bind_method(D_METHOD("set_texture", "type", "texture"), &Decal::set_texture); + ClassDB::bind_method(D_METHOD("get_texture", "type"), &Decal::get_texture); + + ClassDB::bind_method(D_METHOD("set_emission_energy", "energy"), &Decal::set_emission_energy); + ClassDB::bind_method(D_METHOD("get_emission_energy"), &Decal::get_emission_energy); + + ClassDB::bind_method(D_METHOD("set_albedo_mix", "energy"), &Decal::set_albedo_mix); + ClassDB::bind_method(D_METHOD("get_albedo_mix"), &Decal::get_albedo_mix); + + ClassDB::bind_method(D_METHOD("set_modulate", "color"), &Decal::set_modulate); + ClassDB::bind_method(D_METHOD("get_modulate"), &Decal::get_modulate); + + ClassDB::bind_method(D_METHOD("set_upper_fade", "fade"), &Decal::set_upper_fade); + ClassDB::bind_method(D_METHOD("get_upper_fade"), &Decal::get_upper_fade); + + ClassDB::bind_method(D_METHOD("set_lower_fade", "fade"), &Decal::set_lower_fade); + ClassDB::bind_method(D_METHOD("get_lower_fade"), &Decal::get_lower_fade); + + ClassDB::bind_method(D_METHOD("set_normal_fade", "fade"), &Decal::set_normal_fade); + ClassDB::bind_method(D_METHOD("get_normal_fade"), &Decal::get_normal_fade); + + ClassDB::bind_method(D_METHOD("set_enable_distance_fade", "enable"), &Decal::set_enable_distance_fade); + ClassDB::bind_method(D_METHOD("is_distance_fade_enabled"), &Decal::is_distance_fade_enabled); + + ClassDB::bind_method(D_METHOD("set_distance_fade_begin", "distance"), &Decal::set_distance_fade_begin); + ClassDB::bind_method(D_METHOD("get_distance_fade_begin"), &Decal::get_distance_fade_begin); + + ClassDB::bind_method(D_METHOD("set_distance_fade_length", "distance"), &Decal::set_distance_fade_length); + ClassDB::bind_method(D_METHOD("get_distance_fade_length"), &Decal::get_distance_fade_length); + + ClassDB::bind_method(D_METHOD("set_cull_mask", "mask"), &Decal::set_cull_mask); + ClassDB::bind_method(D_METHOD("get_cull_mask"), &Decal::get_cull_mask); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater"), "set_extents", "get_extents"); + ADD_GROUP("Textures", "texture_"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_NORMAL); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_orm", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ORM); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_emission", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION); + ADD_GROUP("Parameters", ""); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_energy", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_emission_energy", "get_emission_energy"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "albedo_mix", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_albedo_mix", "get_albedo_mix"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_fade", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_normal_fade", "get_normal_fade"); + ADD_GROUP("Vertical Fade", ""); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "upper_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_upper_fade", "get_upper_fade"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lower_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_lower_fade", "get_lower_fade"); + ADD_GROUP("Distance Fade", "distance_fade_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_fade_enabled"), "set_enable_distance_fade", "is_distance_fade_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_begin"), "set_distance_fade_begin", "get_distance_fade_begin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_length"), "set_distance_fade_length", "get_distance_fade_length"); + ADD_GROUP("Cull Mask", ""); + ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); + + BIND_ENUM_CONSTANT(TEXTURE_ALBEDO); + BIND_ENUM_CONSTANT(TEXTURE_NORMAL); + BIND_ENUM_CONSTANT(TEXTURE_ORM); + BIND_ENUM_CONSTANT(TEXTURE_EMISSION); + BIND_ENUM_CONSTANT(TEXTURE_MAX); +} + +Decal::Decal() { + + extents = Vector3(1, 1, 1); + emission_energy = 1.0; + modulate = Color(1, 1, 1, 1); + albedo_mix = 1.0; + cull_mask = (1 << 20) - 1; + upper_fade = 0.3; + lower_fade = 0.3; + normal_fade = 0; + distance_fade_enabled = false; + distance_fade_begin = 10; + distance_fade_length = 1; + + decal = RenderingServer::get_singleton()->decal_create(); + RS::get_singleton()->instance_set_base(get_instance(), decal); +} + +Decal::~Decal() { + + RS::get_singleton()->free(decal); +} diff --git a/scene/3d/decal.h b/scene/3d/decal.h new file mode 100644 index 0000000000..665444829d --- /dev/null +++ b/scene/3d/decal.h @@ -0,0 +1,114 @@ +/*************************************************************************/ +/* decal.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ + +#ifndef DECAL_H +#define DECAL_H + +#include "scene/3d/visual_instance_3d.h" +#include "scene/resources/texture.h" +#include "servers/rendering_server.h" + +class Decal : public VisualInstance3D { + GDCLASS(Decal, VisualInstance3D); + +public: + enum DecalTexture { + TEXTURE_ALBEDO, + TEXTURE_NORMAL, + TEXTURE_ORM, + TEXTURE_EMISSION, + TEXTURE_MAX + }; + +private: + RID decal; + Vector3 extents; + Ref<Texture2D> textures[TEXTURE_MAX]; + float emission_energy; + float albedo_mix; + Color modulate; + uint32_t cull_mask; + float normal_fade; + float upper_fade; + float lower_fade; + bool distance_fade_enabled; + float distance_fade_begin; + float distance_fade_length; + +protected: + static void _bind_methods(); + +public: + void set_extents(const Vector3 &p_extents); + Vector3 get_extents() const; + + void set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture(DecalTexture p_type) const; + + void set_emission_energy(float p_energy); + float get_emission_energy() const; + + void set_albedo_mix(float p_mix); + float get_albedo_mix() const; + + void set_modulate(Color p_modulate); + Color get_modulate() const; + + void set_upper_fade(float p_energy); + float get_upper_fade() const; + + void set_lower_fade(float p_fade); + float get_lower_fade() const; + + void set_normal_fade(float p_fade); + float get_normal_fade() const; + + void set_enable_distance_fade(bool p_enable); + bool is_distance_fade_enabled() const; + + void set_distance_fade_begin(float p_distance); + float get_distance_fade_begin() const; + + void set_distance_fade_length(float p_length); + float get_distance_fade_length() const; + + void set_cull_mask(uint32_t p_layers); + uint32_t get_cull_mask() const; + + virtual AABB get_aabb() const; + virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; + + Decal(); + ~Decal(); +}; + +VARIANT_ENUM_CAST(Decal::DecalTexture); + +#endif // DECAL_H diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index c822b70a4b..c048f60ebd 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -70,7 +70,7 @@ void Light3D::set_shadow(bool p_enable) { shadow = p_enable; RS::get_singleton()->light_set_shadow(light, p_enable); - if (type == RenderingServer::LIGHT_SPOT) { + if (type == RenderingServer::LIGHT_SPOT || type == RenderingServer::LIGHT_OMNI) { update_configuration_warning(); } } @@ -166,6 +166,18 @@ Light3D::BakeMode Light3D::get_bake_mode() const { return bake_mode; } +void Light3D::set_projector(const Ref<Texture2D> &p_texture) { + + projector = p_texture; + RID tex_id = projector.is_valid() ? projector->get_rid() : RID(); + RS::get_singleton()->light_set_projector(light, tex_id); + update_configuration_warning(); +} + +Ref<Texture2D> Light3D::get_projector() const { + return projector; +} + void Light3D::_update_visibility() { if (!is_inside_tree()) @@ -216,6 +228,18 @@ bool Light3D::is_editor_only() const { } void Light3D::_validate_property(PropertyInfo &property) const { + + if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_size") { + property.usage = 0; + } + + if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_projector") { + property.usage = 0; + } + + if (get_light_type() != RS::LIGHT_DIRECTIONAL && property.name == "light_angular_distance") { + property.usage = 0; + } } void Light3D::_bind_methods() { @@ -247,10 +271,16 @@ void Light3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bake_mode", "bake_mode"), &Light3D::set_bake_mode); ClassDB::bind_method(D_METHOD("get_bake_mode"), &Light3D::get_bake_mode); + ClassDB::bind_method(D_METHOD("set_projector", "projector"), &Light3D::set_projector); + ClassDB::bind_method(D_METHOD("get_projector"), &Light3D::get_projector); + ADD_GROUP("Light", "light_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_color", "get_color"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_ENERGY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_INDIRECT_ENERGY); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_projector", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_projector", "get_projector"); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_size", PROPERTY_HINT_RANGE, "0,64,0.01,or_greater"), "set_param", "get_param", PARAM_SIZE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_angular_distance", PROPERTY_HINT_RANGE, "0,90,0.01"), "set_param", "get_param", PARAM_SIZE); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_negative"), "set_negative", "is_negative"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SPECULAR); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_bake_mode", PROPERTY_HINT_ENUM, "Disable,Indirect,All"), "set_bake_mode", "get_bake_mode"); @@ -262,6 +292,7 @@ void Light3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_normal_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_transmittance_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_TRANSMITTANCE_BIAS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_blur", PROPERTY_HINT_RANGE, "0.1,8,0.01"), "set_param", "get_param", PARAM_SHADOW_BLUR); ADD_GROUP("Editor", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); ADD_GROUP("", ""); @@ -270,6 +301,7 @@ void Light3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_INDIRECT_ENERGY); BIND_ENUM_CONSTANT(PARAM_SPECULAR); BIND_ENUM_CONSTANT(PARAM_RANGE); + BIND_ENUM_CONSTANT(PARAM_SIZE); BIND_ENUM_CONSTANT(PARAM_ATTENUATION); BIND_ENUM_CONSTANT(PARAM_SPOT_ANGLE); BIND_ENUM_CONSTANT(PARAM_SPOT_ATTENUATION); @@ -281,6 +313,7 @@ void Light3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_SHADOW_NORMAL_BIAS); BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS); BIND_ENUM_CONSTANT(PARAM_SHADOW_PANCAKE_SIZE); + BIND_ENUM_CONSTANT(PARAM_SHADOW_BLUR); BIND_ENUM_CONSTANT(PARAM_TRANSMITTANCE_BIAS); BIND_ENUM_CONSTANT(PARAM_MAX); @@ -315,6 +348,7 @@ Light3D::Light3D(RenderingServer::LightType p_type) { set_param(PARAM_INDIRECT_ENERGY, 1); set_param(PARAM_SPECULAR, 0.5); set_param(PARAM_RANGE, 5); + set_param(PARAM_SIZE, 0); set_param(PARAM_ATTENUATION, 1); set_param(PARAM_SPOT_ANGLE, 45); set_param(PARAM_SPOT_ATTENUATION, 1); @@ -324,6 +358,7 @@ Light3D::Light3D(RenderingServer::LightType p_type) { set_param(PARAM_SHADOW_SPLIT_3_OFFSET, 0.5); set_param(PARAM_SHADOW_FADE_START, 0.8); set_param(PARAM_SHADOW_PANCAKE_SIZE, 20.0); + set_param(PARAM_SHADOW_BLUR, 1.0); set_param(PARAM_SHADOW_BIAS, 0.02); set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0); set_param(PARAM_TRANSMITTANCE_BIAS, 0.05); @@ -430,6 +465,19 @@ OmniLight3D::ShadowMode OmniLight3D::get_shadow_mode() const { return shadow_mode; } +String OmniLight3D::get_configuration_warning() const { + String warning = Light3D::get_configuration_warning(); + + if (!has_shadow() && get_projector().is_valid()) { + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Projector texture only works with shadows active."); + } + + return warning; +} + void OmniLight3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &OmniLight3D::set_shadow_mode); @@ -461,6 +509,13 @@ String SpotLight3D::get_configuration_warning() const { warning += TTR("A SpotLight3D with an angle wider than 90 degrees cannot cast shadows."); } + if (!has_shadow() && get_projector().is_valid()) { + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Projector texture only works with shadows active."); + } + return warning; } diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index ad2a1d5a84..6e78217342 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -46,6 +46,7 @@ public: PARAM_INDIRECT_ENERGY = RS::LIGHT_PARAM_INDIRECT_ENERGY, PARAM_SPECULAR = RS::LIGHT_PARAM_SPECULAR, PARAM_RANGE = RS::LIGHT_PARAM_RANGE, + PARAM_SIZE = RS::LIGHT_PARAM_SIZE, PARAM_ATTENUATION = RS::LIGHT_PARAM_ATTENUATION, PARAM_SPOT_ANGLE = RS::LIGHT_PARAM_SPOT_ANGLE, PARAM_SPOT_ATTENUATION = RS::LIGHT_PARAM_SPOT_ATTENUATION, @@ -57,6 +58,7 @@ public: PARAM_SHADOW_NORMAL_BIAS = RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS, PARAM_SHADOW_BIAS = RS::LIGHT_PARAM_SHADOW_BIAS, PARAM_SHADOW_PANCAKE_SIZE = RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE, + PARAM_SHADOW_BLUR = RS::LIGHT_PARAM_SHADOW_BLUR, PARAM_TRANSMITTANCE_BIAS = RS::LIGHT_PARAM_TRANSMITTANCE_BIAS, PARAM_MAX = RS::LIGHT_PARAM_MAX }; @@ -79,6 +81,7 @@ private: bool editor_only; void _update_visibility(); BakeMode bake_mode; + Ref<Texture2D> projector; // bind helpers @@ -123,6 +126,9 @@ public: void set_bake_mode(BakeMode p_mode); BakeMode get_bake_mode() const; + void set_projector(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_projector() const; + virtual AABB get_aabb() const; virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; @@ -194,6 +200,8 @@ public: void set_shadow_mode(ShadowMode p_mode); ShadowMode get_shadow_mode() const; + virtual String get_configuration_warning() const; + OmniLight3D(); }; diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index d56a095a5b..cdc8db8aea 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -307,19 +307,22 @@ Ref<Material> MeshInstance3D::get_surface_material(int p_surface) const { Ref<Material> MeshInstance3D::get_active_material(int p_surface) const { - if (get_material_override() != Ref<Material>()) { - return get_material_override(); - } else if (p_surface < materials.size()) { - return materials[p_surface]; - } else { - Ref<Mesh> mesh = get_mesh(); + Ref<Material> material_override = get_material_override(); + if (material_override.is_valid()) { + return material_override; + } - if (mesh.is_null() || p_surface >= mesh->get_surface_count()) { - return Ref<Material>(); - } + Ref<Material> surface_material = get_surface_material(p_surface); + if (surface_material.is_valid()) { + return surface_material; + } + Ref<Mesh> mesh = get_mesh(); + if (mesh.is_valid()) { return mesh->surface_get_material(p_surface); } + + return Ref<Material>(); } void MeshInstance3D::_mesh_changed() { diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index f06135f53d..4a425d1e0e 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -316,16 +316,14 @@ void PathFollow3D::set_offset(float p_offset) { offset = p_offset; if (path) { - if (path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { + if (path->get_curve().is_valid()) { float path_length = path->get_curve()->get_baked_length(); if (loop) { - while (offset > path_length) - offset -= path_length; - - while (offset < 0) - offset += path_length; - + offset = Math::fposmod(offset, path_length); + if (!Math::is_zero_approx(p_offset) && Math::is_zero_approx(offset)) { + offset = path_length; + } } else { offset = CLAMP(offset, 0, path_length); } diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 2b6eb8ac8a..3991efc7c0 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -110,7 +110,7 @@ bool PhysicsBody3D::get_collision_layer_bit(int p_bit) const { return get_collision_layer() & (1 << p_bit); } -Array PhysicsBody3D::get_collision_exceptions() { +TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer3D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; @@ -2134,6 +2134,10 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_joint_offset", "offset"), &PhysicalBone3D::set_joint_offset); ClassDB::bind_method(D_METHOD("get_joint_offset"), &PhysicalBone3D::get_joint_offset); + ClassDB::bind_method(D_METHOD("set_joint_rotation", "euler"), &PhysicalBone3D::set_joint_rotation); + ClassDB::bind_method(D_METHOD("get_joint_rotation"), &PhysicalBone3D::get_joint_rotation); + ClassDB::bind_method(D_METHOD("set_joint_rotation_degrees", "euler_degrees"), &PhysicalBone3D::set_joint_rotation_degrees); + ClassDB::bind_method(D_METHOD("get_joint_rotation_degrees"), &PhysicalBone3D::get_joint_rotation_degrees); ClassDB::bind_method(D_METHOD("set_body_offset", "offset"), &PhysicalBone3D::set_body_offset); ClassDB::bind_method(D_METHOD("get_body_offset"), &PhysicalBone3D::get_body_offset); @@ -2159,9 +2163,23 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &PhysicalBone3D::set_gravity_scale); ClassDB::bind_method(D_METHOD("get_gravity_scale"), &PhysicalBone3D::get_gravity_scale); + ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &PhysicalBone3D::set_linear_damp); + ClassDB::bind_method(D_METHOD("get_linear_damp"), &PhysicalBone3D::get_linear_damp); + + ClassDB::bind_method(D_METHOD("set_angular_damp", "angular_damp"), &PhysicalBone3D::set_angular_damp); + ClassDB::bind_method(D_METHOD("get_angular_damp"), &PhysicalBone3D::get_angular_damp); + + ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &PhysicalBone3D::set_can_sleep); + ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &PhysicalBone3D::is_able_to_sleep); + + ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicalBone3D::set_axis_lock); + ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicalBone3D::get_axis_lock); + ADD_GROUP("Joint", "joint_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "joint_offset"), "set_joint_offset", "get_joint_offset"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_joint_rotation_degrees", "get_joint_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_NONE, "", 0), "set_joint_rotation", "get_joint_rotation"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "body_offset"), "set_body_offset", "get_body_offset"); @@ -2170,6 +2188,17 @@ void PhysicalBone3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-10,10,0.01"), "set_gravity_scale", "get_gravity_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); + + ADD_GROUP("Axis Lock", "axis_lock_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z); BIND_ENUM_CONSTANT(JOINT_TYPE_NONE); BIND_ENUM_CONSTANT(JOINT_TYPE_PIN); @@ -2187,6 +2216,19 @@ Skeleton3D *PhysicalBone3D::find_skeleton_parent(Node *p_parent) { return s ? s : find_skeleton_parent(p_parent->get_parent()); } +void PhysicalBone3D::_update_joint_offset() { + _fix_joint_offset(); + + set_ignore_transform_notification(true); + reset_to_rest_position(); + set_ignore_transform_notification(false); + +#ifdef TOOLS_ENABLED + if (get_gizmo().is_valid()) + get_gizmo()->redraw(); +#endif +} + void PhysicalBone3D::_fix_joint_offset() { // Clamp joint origin to bone origin if (parent_skeleton) { @@ -2370,16 +2412,31 @@ PhysicalBone3D::JointType PhysicalBone3D::get_joint_type() const { void PhysicalBone3D::set_joint_offset(const Transform &p_offset) { joint_offset = p_offset; - _fix_joint_offset(); + _update_joint_offset(); + _change_notify("joint_rotation_degrees"); +} - set_ignore_transform_notification(true); - reset_to_rest_position(); - set_ignore_transform_notification(false); +const Transform &PhysicalBone3D::get_joint_offset() const { + return joint_offset; +} -#ifdef TOOLS_ENABLED - if (get_gizmo().is_valid()) - get_gizmo()->redraw(); -#endif +void PhysicalBone3D::set_joint_rotation(const Vector3 &p_euler_rad) { + joint_offset.basis.set_euler_scale(p_euler_rad, joint_offset.basis.get_scale()); + + _update_joint_offset(); + _change_notify("joint_offset"); +} + +Vector3 PhysicalBone3D::get_joint_rotation() const { + return joint_offset.basis.get_rotation(); +} + +void PhysicalBone3D::set_joint_rotation_degrees(const Vector3 &p_euler_deg) { + set_joint_rotation(p_euler_deg * Math_PI / 180.0); +} + +Vector3 PhysicalBone3D::get_joint_rotation_degrees() const { + return get_joint_rotation() * 180.0 / Math_PI; } const Transform &PhysicalBone3D::get_body_offset() const { @@ -2390,20 +2447,7 @@ void PhysicalBone3D::set_body_offset(const Transform &p_offset) { body_offset = p_offset; body_offset_inverse = body_offset.affine_inverse(); - _fix_joint_offset(); - - set_ignore_transform_notification(true); - reset_to_rest_position(); - set_ignore_transform_notification(false); - -#ifdef TOOLS_ENABLED - if (get_gizmo().is_valid()) - get_gizmo()->redraw(); -#endif -} - -const Transform &PhysicalBone3D::get_joint_offset() const { - return joint_offset; + _update_joint_offset(); } void PhysicalBone3D::set_simulate_physics(bool p_simulate) { @@ -2496,6 +2540,43 @@ real_t PhysicalBone3D::get_gravity_scale() const { return gravity_scale; } +void PhysicalBone3D::set_linear_damp(real_t p_linear_damp) { + ERR_FAIL_COND(p_linear_damp < -1); + linear_damp = p_linear_damp; + PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP, linear_damp); +} + +real_t PhysicalBone3D::get_linear_damp() const { + return linear_damp; +} + +void PhysicalBone3D::set_angular_damp(real_t p_angular_damp) { + ERR_FAIL_COND(p_angular_damp < -1); + angular_damp = p_angular_damp; + PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP, angular_damp); +} + +real_t PhysicalBone3D::get_angular_damp() const { + return angular_damp; +} + +void PhysicalBone3D::set_can_sleep(bool p_active) { + can_sleep = p_active; + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_CAN_SLEEP, p_active); +} + +bool PhysicalBone3D::is_able_to_sleep() const { + return can_sleep; +} + +void PhysicalBone3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { + PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); +} + +bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { + return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); +} + PhysicalBone3D::PhysicalBone3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC), #ifdef TOOLS_ENABLED @@ -2510,7 +2591,10 @@ PhysicalBone3D::PhysicalBone3D() : bounce(0), mass(1), friction(1), - gravity_scale(1) { + gravity_scale(1), + linear_damp(-1), + angular_damp(-1), + can_sleep(true) { reset_physics_simulation_state(); } diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index bf7854b68d..0e719f5108 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -68,7 +68,7 @@ public: void set_collision_mask_bit(int p_bit, bool p_value); bool get_collision_mask_bit(int p_bit) const; - Array get_collision_exceptions(); + TypedArray<PhysicsBody3D> get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); @@ -562,6 +562,9 @@ private: real_t mass; real_t friction; real_t gravity_scale; + real_t linear_damp; + real_t angular_damp; + bool can_sleep; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -575,6 +578,7 @@ protected: private: static Skeleton3D *find_skeleton_parent(Node *p_parent); + void _update_joint_offset(); void _fix_joint_offset(); void _reload_joint(); @@ -599,6 +603,12 @@ public: void set_joint_offset(const Transform &p_offset); const Transform &get_joint_offset() const; + void set_joint_rotation(const Vector3 &p_euler_rad); + Vector3 get_joint_rotation() const; + + void set_joint_rotation_degrees(const Vector3 &p_euler_deg); + Vector3 get_joint_rotation_degrees() const; + void set_body_offset(const Transform &p_offset); const Transform &get_body_offset() const; @@ -624,6 +634,18 @@ public: void set_gravity_scale(real_t p_gravity_scale); real_t get_gravity_scale() const; + void set_linear_damp(real_t p_linear_damp); + real_t get_linear_damp() const; + + void set_angular_damp(real_t p_angular_damp); + real_t get_angular_damp() const; + + void set_can_sleep(bool p_active); + bool is_able_to_sleep() const; + + void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); + bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; + void apply_central_impulse(const Vector3 &p_impulse); void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse); diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/physics_joint_3d.cpp index 591c17a91e..140d887d9a 100644 --- a/scene/3d/physics_joint_3d.cpp +++ b/scene/3d/physics_joint_3d.cpp @@ -807,6 +807,9 @@ void Generic6DOFJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_LINEAR_DAMPING); BIND_ENUM_CONSTANT(PARAM_LINEAR_MOTOR_TARGET_VELOCITY); BIND_ENUM_CONSTANT(PARAM_LINEAR_MOTOR_FORCE_LIMIT); + BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_STIFFNESS); + BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_DAMPING); + BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); BIND_ENUM_CONSTANT(PARAM_ANGULAR_LOWER_LIMIT); BIND_ENUM_CONSTANT(PARAM_ANGULAR_UPPER_LIMIT); BIND_ENUM_CONSTANT(PARAM_ANGULAR_LIMIT_SOFTNESS); @@ -816,6 +819,9 @@ void Generic6DOFJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_ANGULAR_ERP); BIND_ENUM_CONSTANT(PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); BIND_ENUM_CONSTANT(PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_STIFFNESS); + BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_DAMPING); + BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); BIND_ENUM_CONSTANT(PARAM_MAX); BIND_ENUM_CONSTANT(FLAG_ENABLE_LINEAR_LIMIT); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 59a6e23005..973822653a 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -33,6 +33,7 @@ #include "core/engine.h" #include "core/message_queue.h" #include "core/project_settings.h" +#include "core/type_info.h" #include "scene/3d/physics_body_3d.h" #include "scene/resources/surface_tool.h" @@ -770,7 +771,7 @@ void _pb_start_simulation(const Skeleton3D *p_skeleton, Node *p_node, const Vect } } -void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) { +void Skeleton3D::physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones) { set_physics_process_internal(false); Vector<int> sim_bones; @@ -780,12 +781,9 @@ void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) { sim_bones.resize(p_bones.size()); int c = 0; for (int i = sim_bones.size() - 1; 0 <= i; --i) { - Variant::Type type = p_bones.get(i).get_type(); - if (Variant::STRING == type || Variant::STRING_NAME == type) { - int bone_id = find_bone(p_bones.get(i)); - if (bone_id != -1) - sim_bones.write[c++] = bone_id; - } + int bone_id = find_bone(p_bones[i]); + if (bone_id != -1) + sim_bones.write[c++] = bone_id; } sim_bones.resize(c); } diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 08b8691658..0bccd3f8fc 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -222,7 +222,7 @@ private: public: void physical_bones_stop_simulation(); - void physical_bones_start_simulation_on(const Array &p_bones); + void physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones); void physical_bones_add_collision_exception(RID p_exception); void physical_bones_remove_collision_exception(RID p_exception); #endif // _3D_DISABLED diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index 7366290ed3..10bdd71d73 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -287,14 +287,22 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove return; // Skip solving } - p_task->skeleton->clear_bones_global_pose_override(); + p_task->skeleton->set_bone_global_pose_override(p_task->chain.chain_root.bone, Transform(), 0.0, true); + + if (p_task->chain.middle_chain_item) { + p_task->skeleton->set_bone_global_pose_override(p_task->chain.middle_chain_item->bone, Transform(), 0.0, true); + } + + for (int i = 0; i < p_task->chain.tips.size(); i += 1) { + p_task->skeleton->set_bone_global_pose_override(p_task->chain.tips[i].chain_item->bone, Transform(), 0.0, true); + } make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse().scaled(p_task->skeleton->get_global_transform().get_basis().get_scale()), blending_delta); update_chain(p_task->skeleton, &p_task->chain.chain_root); if (p_use_magnet && p_task->chain.middle_chain_item) { - p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.linear_interpolate(p_magnet_position, blending_delta); + p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.lerp(p_magnet_position, blending_delta); solve_simple(p_task, true); } solve_simple(p_task, false); diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp index 281be3f7d3..0ffde7aa8f 100644 --- a/scene/3d/spring_arm_3d.cpp +++ b/scene/3d/spring_arm_3d.cpp @@ -45,15 +45,15 @@ void SpringArm3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: if (!Engine::get_singleton()->is_editor_hint()) { - set_process_internal(true); + set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: if (!Engine::get_singleton()->is_editor_hint()) { - set_process_internal(false); + set_physics_process_internal(false); } break; - case NOTIFICATION_INTERNAL_PROCESS: + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: process_spring(); break; } diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 775a9b76e2..604bc53422 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -217,6 +217,62 @@ float GeometryInstance3D::get_lod_max_hysteresis() const { void GeometryInstance3D::_notification(int p_what) { } +const StringName *GeometryInstance3D::_instance_uniform_get_remap(const StringName p_name) const { + StringName *r = instance_uniform_property_remap.getptr(p_name); + if (!r) { + String s = p_name; + if (s.begins_with("shader_params/")) { + StringName name = s.replace("shader_params/", ""); + instance_uniform_property_remap[p_name] = name; + return instance_uniform_property_remap.getptr(p_name); + } + + return nullptr; + } + + return r; +} + +bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) { + const StringName *r = _instance_uniform_get_remap(p_name); + if (r) { + set_shader_instance_uniform(*r, p_value); + return true; + } + + return false; +} + +bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const { + const StringName *r = _instance_uniform_get_remap(p_name); + if (r) { + r_ret = get_shader_instance_uniform(*r); + return true; + } + + return false; +} +void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { + List<PropertyInfo> pinfo; + RS::get_singleton()->instance_geometry_get_shader_parameter_list(get_instance(), &pinfo); + for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { + PropertyInfo pi = E->get(); + bool has_def_value = false; + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), pi.name); + if (def_value.get_type() != Variant::NIL) { + has_def_value = true; + } + if (instance_uniforms.has(pi.name)) { + pi.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE | (has_def_value ? (PROPERTY_USAGE_CHECKABLE | PROPERTY_USAGE_CHECKED) : 0); + } else { + pi.usage = PROPERTY_USAGE_EDITOR | (has_def_value ? PROPERTY_USAGE_CHECKABLE : 0); //do not save if not changed + } + + pi.name = "shader_params/" + pi.name; + p_list->push_back(pi); + } +} + void GeometryInstance3D::set_flag(Flags p_flag, bool p_value) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); @@ -258,6 +314,22 @@ float GeometryInstance3D::get_extra_cull_margin() const { return extra_cull_margin; } +void GeometryInstance3D::set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value) { + + if (p_value.get_type() == Variant::NIL) { + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), p_uniform); + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, def_value); + instance_uniforms.erase(p_value); + } else { + instance_uniforms[p_uniform] = p_value; + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, p_value); + } +} + +Variant GeometryInstance3D::get_shader_instance_uniform(const StringName &p_uniform) const { + + return RS::get_singleton()->instance_geometry_get_shader_parameter(get_instance(), p_uniform); +} void GeometryInstance3D::set_custom_aabb(AABB aabb) { RS::get_singleton()->instance_set_custom_aabb(get_instance(), aabb); @@ -280,6 +352,9 @@ void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lod_max_distance", "mode"), &GeometryInstance3D::set_lod_max_distance); ClassDB::bind_method(D_METHOD("get_lod_max_distance"), &GeometryInstance3D::get_lod_max_distance); + ClassDB::bind_method(D_METHOD("set_shader_instance_uniform", "uniform", "value"), &GeometryInstance3D::set_shader_instance_uniform); + ClassDB::bind_method(D_METHOD("get_shader_instance_uniform", "uniform"), &GeometryInstance3D::get_shader_instance_uniform); + ClassDB::bind_method(D_METHOD("set_lod_min_hysteresis", "mode"), &GeometryInstance3D::set_lod_min_hysteresis); ClassDB::bind_method(D_METHOD("get_lod_min_hysteresis"), &GeometryInstance3D::get_lod_min_hysteresis); diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index 9476c28848..cc5f92066f 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -108,9 +108,18 @@ private: float lod_min_hysteresis; float lod_max_hysteresis; + mutable HashMap<StringName, Variant> instance_uniforms; + mutable HashMap<StringName, StringName> instance_uniform_property_remap; + float extra_cull_margin; + const StringName *_instance_uniform_get_remap(const StringName p_name) const; + protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + void _notification(int p_what); static void _bind_methods(); @@ -139,6 +148,9 @@ public: void set_extra_cull_margin(float p_margin); float get_extra_cull_margin() const; + void set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value); + Variant get_shader_instance_uniform(const StringName &p_uniform) const; + void set_custom_aabb(AABB aabb); GeometryInstance3D(); diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index 203c3cd812..f30c58be55 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -592,22 +592,16 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec Vector<Vector3> vertices = a[Mesh::ARRAY_VERTEX]; const Vector3 *vr = vertices.ptr(); Vector<Vector2> uv = a[Mesh::ARRAY_TEX_UV]; - const Vector2 *uvr; + const Vector2 *uvr = nullptr; Vector<Vector3> normals = a[Mesh::ARRAY_NORMAL]; - const Vector3 *nr; + const Vector3 *nr = nullptr; Vector<int> index = a[Mesh::ARRAY_INDEX]; - bool read_uv = false; - bool read_normals = false; - if (uv.size()) { - uvr = uv.ptr(); - read_uv = true; } if (normals.size()) { - read_normals = true; nr = normals.ptr(); } @@ -626,13 +620,13 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]); } - if (read_uv) { + if (uvr) { for (int k = 0; k < 3; k++) { uvs[k] = uvr[ir[j * 3 + k]]; } } - if (read_normals) { + if (nr) { for (int k = 0; k < 3; k++) { normal[k] = nr[ir[j * 3 + k]]; } @@ -659,13 +653,13 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec vtxs[k] = p_xform.xform(vr[j * 3 + k]); } - if (read_uv) { + if (uvr) { for (int k = 0; k < 3; k++) { uvs[k] = uvr[j * 3 + k]; } } - if (read_normals) { + if (nr) { for (int k = 0; k < 3; k++) { normal[k] = nr[j * 3 + k]; } diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index 0373114e7d..6f41629bac 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "xr_nodes.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "servers/xr/xr_interface.h" #include "servers/xr_server.h" @@ -206,7 +206,7 @@ void XRController3D::_notification(int p_what) { // check button states for (int i = 0; i < 16; i++) { bool was_pressed = (button_states & mask) == mask; - bool is_pressed = InputFilter::get_singleton()->is_joy_button_pressed(joy_id, i); + bool is_pressed = Input::get_singleton()->is_joy_button_pressed(joy_id, i); if (!was_pressed && is_pressed) { emit_signal("button_pressed", i); @@ -306,7 +306,7 @@ bool XRController3D::is_button_pressed(int p_button) const { return false; }; - return InputFilter::get_singleton()->is_joy_button_pressed(joy_id, p_button); + return Input::get_singleton()->is_joy_button_pressed(joy_id, p_button); }; float XRController3D::get_joystick_axis(int p_axis) const { @@ -315,7 +315,7 @@ float XRController3D::get_joystick_axis(int p_axis) const { return 0.0; }; - return InputFilter::get_singleton()->get_joy_axis(joy_id, p_axis); + return Input::get_singleton()->get_joy_axis(joy_id, p_axis); }; real_t XRController3D::get_rumble() const { |