summaryrefslogtreecommitdiff
path: root/scene/3d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d')
-rw-r--r--scene/3d/area_3d.cpp4
-rw-r--r--scene/3d/area_3d.h4
-rw-r--r--scene/3d/audio_stream_player_3d.cpp4
-rw-r--r--scene/3d/cpu_particles_3d.cpp1
-rw-r--r--scene/3d/decal.cpp235
-rw-r--r--scene/3d/decal.h114
-rw-r--r--scene/3d/light_3d.cpp57
-rw-r--r--scene/3d/light_3d.h8
-rw-r--r--scene/3d/mesh_instance_3d.cpp21
-rw-r--r--scene/3d/path_3d.cpp12
-rw-r--r--scene/3d/physics_body_3d.cpp132
-rw-r--r--scene/3d/physics_body_3d.h24
-rw-r--r--scene/3d/physics_joint_3d.cpp6
-rw-r--r--scene/3d/skeleton_3d.cpp12
-rw-r--r--scene/3d/skeleton_3d.h2
-rw-r--r--scene/3d/skeleton_ik_3d.cpp12
-rw-r--r--scene/3d/spring_arm_3d.cpp6
-rw-r--r--scene/3d/visual_instance_3d.cpp75
-rw-r--r--scene/3d/visual_instance_3d.h12
-rw-r--r--scene/3d/voxelizer.cpp18
-rw-r--r--scene/3d/xr_nodes.cpp8
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 {