summaryrefslogtreecommitdiff
path: root/scene/3d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d')
-rw-r--r--scene/3d/area_3d.cpp16
-rw-r--r--scene/3d/area_3d.h6
-rw-r--r--scene/3d/audio_stream_player_3d.cpp24
-rw-r--r--scene/3d/audio_stream_player_3d.h2
-rw-r--r--scene/3d/bone_attachment_3d.cpp5
-rw-r--r--scene/3d/camera_3d.cpp4
-rw-r--r--scene/3d/decal.cpp38
-rw-r--r--scene/3d/decal.h10
-rw-r--r--scene/3d/fog_volume.cpp44
-rw-r--r--scene/3d/fog_volume.h10
-rw-r--r--scene/3d/gpu_particles_collision_3d.cpp184
-rw-r--r--scene/3d/gpu_particles_collision_3d.h50
-rw-r--r--scene/3d/label_3d.cpp63
-rw-r--r--scene/3d/label_3d.h16
-rw-r--r--scene/3d/light_3d.cpp13
-rw-r--r--scene/3d/navigation_agent_3d.cpp220
-rw-r--r--scene/3d/navigation_agent_3d.h40
-rw-r--r--scene/3d/navigation_link_3d.cpp98
-rw-r--r--scene/3d/navigation_link_3d.h17
-rw-r--r--scene/3d/occluder_instance_3d.cpp5
-rw-r--r--scene/3d/physics_body_3d.cpp5
-rw-r--r--scene/3d/reflection_probe.cpp56
-rw-r--r--scene/3d/reflection_probe.h12
-rw-r--r--scene/3d/sprite_3d.cpp394
-rw-r--r--scene/3d/sprite_3d.h51
-rw-r--r--scene/3d/voxel_gi.cpp48
-rw-r--r--scene/3d/voxel_gi.h10
27 files changed, 1106 insertions, 335 deletions
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp
index 72f186c676..5901e38bb4 100644
--- a/scene/3d/area_3d.cpp
+++ b/scene/3d/area_3d.cpp
@@ -51,13 +51,13 @@ bool Area3D::is_gravity_a_point() const {
return gravity_is_point;
}
-void Area3D::set_gravity_point_distance_scale(real_t p_scale) {
- gravity_distance_scale = p_scale;
- PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE, p_scale);
+void Area3D::set_gravity_point_unit_distance(real_t p_scale) {
+ gravity_point_unit_distance = p_scale;
+ PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_UNIT_DISTANCE, p_scale);
}
-real_t Area3D::get_gravity_point_distance_scale() const {
- return gravity_distance_scale;
+real_t Area3D::get_gravity_point_unit_distance() const {
+ return gravity_point_unit_distance;
}
void Area3D::set_gravity_point_center(const Vector3 &p_center) {
@@ -655,8 +655,8 @@ void Area3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_gravity_is_point", "enable"), &Area3D::set_gravity_is_point);
ClassDB::bind_method(D_METHOD("is_gravity_a_point"), &Area3D::is_gravity_a_point);
- ClassDB::bind_method(D_METHOD("set_gravity_point_distance_scale", "distance_scale"), &Area3D::set_gravity_point_distance_scale);
- ClassDB::bind_method(D_METHOD("get_gravity_point_distance_scale"), &Area3D::get_gravity_point_distance_scale);
+ ClassDB::bind_method(D_METHOD("set_gravity_point_unit_distance", "distance_scale"), &Area3D::set_gravity_point_unit_distance);
+ ClassDB::bind_method(D_METHOD("get_gravity_point_unit_distance"), &Area3D::get_gravity_point_unit_distance);
ClassDB::bind_method(D_METHOD("set_gravity_point_center", "center"), &Area3D::set_gravity_point_center);
ClassDB::bind_method(D_METHOD("get_gravity_point_center"), &Area3D::get_gravity_point_center);
@@ -741,7 +741,7 @@ void Area3D::_bind_methods() {
ADD_GROUP("Gravity", "gravity_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "gravity_space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_gravity_space_override_mode", "get_gravity_space_override_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gravity_point", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_gravity_is_point", "is_gravity_a_point");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_point_distance_scale", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp"), "set_gravity_point_distance_scale", "get_gravity_point_distance_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_point_unit_distance", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp,suffix:m"), "set_gravity_point_unit_distance", "get_gravity_point_unit_distance");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_point_center", PROPERTY_HINT_NONE, "suffix:m"), "set_gravity_point_center", "get_gravity_point_center");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_direction"), "set_gravity_direction", "get_gravity_direction");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, U"-32,32,0.001,or_less,or_greater,suffix:m/s\u00B2"), "set_gravity", "get_gravity");
diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h
index 91b91f741a..607e0d2af8 100644
--- a/scene/3d/area_3d.h
+++ b/scene/3d/area_3d.h
@@ -51,7 +51,7 @@ private:
Vector3 gravity_vec;
real_t gravity = 0.0;
bool gravity_is_point = false;
- real_t gravity_distance_scale = 0.0;
+ real_t gravity_point_unit_distance = 0.0;
SpaceOverride linear_damp_space_override = SPACE_OVERRIDE_DISABLED;
SpaceOverride angular_damp_space_override = SPACE_OVERRIDE_DISABLED;
@@ -155,8 +155,8 @@ public:
void set_gravity_is_point(bool p_enabled);
bool is_gravity_a_point() const;
- void set_gravity_point_distance_scale(real_t p_scale);
- real_t get_gravity_point_distance_scale() const;
+ void set_gravity_point_unit_distance(real_t p_scale);
+ real_t get_gravity_point_unit_distance() const;
void set_gravity_point_center(const Vector3 &p_center);
const Vector3 &get_gravity_point_center() const;
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index 7ed18d2d41..436b936586 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -284,14 +284,12 @@ void AudioStreamPlayer3D::_notification(int p_what) {
volume_vector = _update_panning();
}
- if (setplay.get() >= 0 && stream.is_valid()) {
+ if (setplayback.is_valid() && setplay.get() >= 0) {
active.set();
- Ref<AudioStreamPlayback> new_playback = stream->instantiate_playback();
- ERR_FAIL_COND_MSG(new_playback.is_null(), "Failed to instantiate playback.");
HashMap<StringName, Vector<AudioFrame>> bus_map;
bus_map[_get_actual_bus()] = volume_vector;
- AudioServer::get_singleton()->start_playback_stream(new_playback, bus_map, setplay.get(), actual_pitch_scale, linear_attenuation, attenuation_filter_cutoff_hz);
- stream_playbacks.push_back(new_playback);
+ AudioServer::get_singleton()->start_playback_stream(setplayback, bus_map, setplay.get(), actual_pitch_scale, linear_attenuation, attenuation_filter_cutoff_hz);
+ setplayback.unref();
setplay.set(-1);
}
@@ -580,14 +578,21 @@ void AudioStreamPlayer3D::play(float p_from_pos) {
if (stream->is_monophonic() && is_playing()) {
stop();
}
+ Ref<AudioStreamPlayback> stream_playback = stream->instantiate_playback();
+ ERR_FAIL_COND_MSG(stream_playback.is_null(), "Failed to instantiate playback.");
+
+ stream_playbacks.push_back(stream_playback);
+ setplayback = stream_playback;
setplay.set(p_from_pos);
active.set();
set_physics_process_internal(true);
}
void AudioStreamPlayer3D::seek(float p_seconds) {
- stop();
- play(p_seconds);
+ if (is_playing()) {
+ stop();
+ play(p_seconds);
+ }
}
void AudioStreamPlayer3D::stop() {
@@ -783,6 +788,10 @@ bool AudioStreamPlayer3D::get_stream_paused() const {
return false;
}
+bool AudioStreamPlayer3D::has_stream_playback() {
+ return !stream_playbacks.is_empty();
+}
+
Ref<AudioStreamPlayback> AudioStreamPlayer3D::get_stream_playback() {
ERR_FAIL_COND_V_MSG(stream_playbacks.is_empty(), Ref<AudioStreamPlayback>(), "Player is inactive. Call play() before requesting get_stream_playback().");
return stream_playbacks[stream_playbacks.size() - 1];
@@ -875,6 +884,7 @@ void AudioStreamPlayer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_panning_strength", "panning_strength"), &AudioStreamPlayer3D::set_panning_strength);
ClassDB::bind_method(D_METHOD("get_panning_strength"), &AudioStreamPlayer3D::get_panning_strength);
+ ClassDB::bind_method(D_METHOD("has_stream_playback"), &AudioStreamPlayer3D::has_stream_playback);
ClassDB::bind_method(D_METHOD("get_stream_playback"), &AudioStreamPlayer3D::get_stream_playback);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream");
diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h
index 67cec91896..bba8f10761 100644
--- a/scene/3d/audio_stream_player_3d.h
+++ b/scene/3d/audio_stream_player_3d.h
@@ -69,6 +69,7 @@ private:
SafeFlag active{ false };
SafeNumeric<float> setplay{ -1.0 };
+ Ref<AudioStreamPlayback> setplayback;
AttenuationModel attenuation_model = ATTENUATION_INVERSE_DISTANCE;
float volume_db = 0.0;
@@ -188,6 +189,7 @@ public:
void set_panning_strength(float p_panning_strength);
float get_panning_strength() const;
+ bool has_stream_playback();
Ref<AudioStreamPlayback> get_stream_playback();
AudioStreamPlayer3D();
diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp
index fe7f6837f0..ba5ff02862 100644
--- a/scene/3d/bone_attachment_3d.cpp
+++ b/scene/3d/bone_attachment_3d.cpp
@@ -81,11 +81,6 @@ bool BoneAttachment3D::_get(const StringName &p_path, Variant &r_ret) const {
}
void BoneAttachment3D::_get_property_list(List<PropertyInfo> *p_list) const {
- p_list->push_back(PropertyInfo(Variant::BOOL, "override_pose", PROPERTY_HINT_NONE, ""));
- if (override_pose) {
- p_list->push_back(PropertyInfo(Variant::INT, "override_mode", PROPERTY_HINT_ENUM, "Global Pose Override,Local Pose Override,Custom Pose"));
- }
-
p_list->push_back(PropertyInfo(Variant::BOOL, "use_external_skeleton", PROPERTY_HINT_NONE, ""));
if (use_external_skeleton) {
p_list->push_back(PropertyInfo(Variant::NODE_PATH, "external_skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton3D"));
diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp
index e91948c6e1..47eb1eaa40 100644
--- a/scene/3d/camera_3d.cpp
+++ b/scene/3d/camera_3d.cpp
@@ -554,7 +554,7 @@ void Camera3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal,Frustum"), "set_projection", "get_projection");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov", PROPERTY_HINT_RANGE, "1,179,0.1,degrees"), "set_fov", "get_fov");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.001,16384,0.001,suffix:m"), "set_size", "get_size");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.001,16384,0.001,or_greater,suffix:m"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frustum_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_frustum_offset", "get_frustum_offset");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "near", PROPERTY_HINT_RANGE, "0.001,10,0.001,or_greater,exp,suffix:m"), "set_near", "get_near");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "far", PROPERTY_HINT_RANGE, "0.01,4000,0.01,or_greater,exp,suffix:m"), "set_far", "get_far");
@@ -602,7 +602,7 @@ void Camera3D::set_fov(real_t p_fov) {
}
void Camera3D::set_size(real_t p_size) {
- ERR_FAIL_COND(p_size < 0.001 || p_size > 16384);
+ ERR_FAIL_COND(p_size <= CMP_EPSILON);
size = p_size;
_update_camera_mode();
}
diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp
index fbcb1c8f2c..e122adcc8c 100644
--- a/scene/3d/decal.cpp
+++ b/scene/3d/decal.cpp
@@ -30,14 +30,14 @@
#include "decal.h"
-void Decal::set_extents(const Vector3 &p_extents) {
- extents = p_extents;
- RS::get_singleton()->decal_set_extents(decal, p_extents);
+void Decal::set_size(const Vector3 &p_size) {
+ size = p_size;
+ RS::get_singleton()->decal_set_size(decal, p_size);
update_gizmos();
}
-Vector3 Decal::get_extents() const {
- return extents;
+Vector3 Decal::get_size() const {
+ return size;
}
void Decal::set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture) {
@@ -147,8 +147,8 @@ uint32_t Decal::get_cull_mask() const {
AABB Decal::get_aabb() const {
AABB aabb;
- aabb.position = -extents;
- aabb.size = extents * 2.0;
+ aabb.position = -size / 2;
+ aabb.size = size;
return aabb;
}
@@ -181,8 +181,8 @@ PackedStringArray Decal::get_configuration_warnings() const {
}
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_size", "size"), &Decal::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &Decal::get_size);
ClassDB::bind_method(D_METHOD("set_texture", "type", "texture"), &Decal::set_texture);
ClassDB::bind_method(D_METHOD("get_texture", "type"), &Decal::get_texture);
@@ -217,7 +217,7 @@ void Decal::_bind_methods() {
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,suffix:m"), "set_extents", "get_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,suffix:m"), "set_size", "get_size");
ADD_GROUP("Textures", "texture_");
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO);
@@ -252,6 +252,24 @@ void Decal::_bind_methods() {
BIND_ENUM_CONSTANT(TEXTURE_MAX);
}
+#ifndef DISABLE_DEPRECATED
+bool Decal::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ set_size((Vector3)p_value * 2);
+ return true;
+ }
+ return false;
+}
+
+bool Decal::_get(const StringName &p_name, Variant &r_property) const {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ r_property = size / 2;
+ return true;
+ }
+ return false;
+}
+#endif // DISABLE_DEPRECATED
+
Decal::Decal() {
decal = RenderingServer::get_singleton()->decal_create();
RS::get_singleton()->instance_set_base(get_instance(), decal);
diff --git a/scene/3d/decal.h b/scene/3d/decal.h
index 5797a2f645..171b52815a 100644
--- a/scene/3d/decal.h
+++ b/scene/3d/decal.h
@@ -47,7 +47,7 @@ public:
private:
RID decal;
- Vector3 extents = Vector3(1, 1, 1);
+ Vector3 size = Vector3(2, 2, 2);
Ref<Texture2D> textures[TEXTURE_MAX];
real_t emission_energy = 1.0;
real_t albedo_mix = 1.0;
@@ -63,12 +63,16 @@ private:
protected:
static void _bind_methods();
void _validate_property(PropertyInfo &p_property) const;
+#ifndef DISABLE_DEPRECATED
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_property) const;
+#endif // DISABLE_DEPRECATED
public:
virtual PackedStringArray get_configuration_warnings() const override;
- void set_extents(const Vector3 &p_extents);
- Vector3 get_extents() const;
+ void set_size(const Vector3 &p_size);
+ Vector3 get_size() const;
void set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_texture(DecalTexture p_type) const;
diff --git a/scene/3d/fog_volume.cpp b/scene/3d/fog_volume.cpp
index 30dfb45836..9b0a7bb302 100644
--- a/scene/3d/fog_volume.cpp
+++ b/scene/3d/fog_volume.cpp
@@ -34,36 +34,54 @@
///////////////////////////
void FogVolume::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &FogVolume::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &FogVolume::get_extents);
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &FogVolume::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &FogVolume::get_size);
ClassDB::bind_method(D_METHOD("set_shape", "shape"), &FogVolume::set_shape);
ClassDB::bind_method(D_METHOD("get_shape"), &FogVolume::get_shape);
ClassDB::bind_method(D_METHOD("set_material", "material"), &FogVolume::set_material);
ClassDB::bind_method(D_METHOD("get_material"), &FogVolume::get_material);
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "shape", PROPERTY_HINT_ENUM, "Ellipsoid (Local),Cone (Local),Cylinder (Local),Box (Local),World (Global)"), "set_shape", "get_shape");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "FogMaterial,ShaderMaterial"), "set_material", "get_material");
}
void FogVolume::_validate_property(PropertyInfo &p_property) const {
- if (p_property.name == "extents" && shape == RS::FOG_VOLUME_SHAPE_WORLD) {
+ if (p_property.name == "size" && shape == RS::FOG_VOLUME_SHAPE_WORLD) {
p_property.usage = PROPERTY_USAGE_NONE;
return;
}
}
-void FogVolume::set_extents(const Vector3 &p_extents) {
- extents = p_extents;
- extents.x = MAX(0.0, extents.x);
- extents.y = MAX(0.0, extents.y);
- extents.z = MAX(0.0, extents.z);
- RS::get_singleton()->fog_volume_set_extents(_get_volume(), extents);
+#ifndef DISABLE_DEPRECATED
+bool FogVolume::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ set_size((Vector3)p_value * 2);
+ return true;
+ }
+ return false;
+}
+
+bool FogVolume::_get(const StringName &p_name, Variant &r_property) const {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ r_property = size / 2;
+ return true;
+ }
+ return false;
+}
+#endif // DISABLE_DEPRECATED
+
+void FogVolume::set_size(const Vector3 &p_size) {
+ size = p_size;
+ size.x = MAX(0.0, size.x);
+ size.y = MAX(0.0, size.y);
+ size.z = MAX(0.0, size.z);
+ RS::get_singleton()->fog_volume_set_size(_get_volume(), size);
update_gizmos();
}
-Vector3 FogVolume::get_extents() const {
- return extents;
+Vector3 FogVolume::get_size() const {
+ return size;
}
void FogVolume::set_shape(RS::FogVolumeShape p_type) {
@@ -94,7 +112,7 @@ Ref<Material> FogVolume::get_material() const {
AABB FogVolume::get_aabb() const {
if (shape != RS::FOG_VOLUME_SHAPE_WORLD) {
- return AABB(-extents, extents * 2);
+ return AABB(-size / 2, size);
}
return AABB();
}
diff --git a/scene/3d/fog_volume.h b/scene/3d/fog_volume.h
index fa02834762..f7e861e3d0 100644
--- a/scene/3d/fog_volume.h
+++ b/scene/3d/fog_volume.h
@@ -40,7 +40,7 @@
class FogVolume : public VisualInstance3D {
GDCLASS(FogVolume, VisualInstance3D);
- Vector3 extents = Vector3(1, 1, 1);
+ Vector3 size = Vector3(2, 2, 2);
Ref<Material> material;
RS::FogVolumeShape shape = RS::FOG_VOLUME_SHAPE_BOX;
@@ -50,10 +50,14 @@ protected:
_FORCE_INLINE_ RID _get_volume() { return volume; }
static void _bind_methods();
void _validate_property(PropertyInfo &p_property) const;
+#ifndef DISABLE_DEPRECATED
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_property) const;
+#endif // DISABLE_DEPRECATED
public:
- void set_extents(const Vector3 &p_extents);
- Vector3 get_extents() const;
+ void set_size(const Vector3 &p_size);
+ Vector3 get_size() const;
void set_shape(RS::FogVolumeShape p_type);
RS::FogVolumeShape get_shape() const;
diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp
index d1f2dfb25f..137d578291 100644
--- a/scene/3d/gpu_particles_collision_3d.cpp
+++ b/scene/3d/gpu_particles_collision_3d.cpp
@@ -95,24 +95,42 @@ GPUParticlesCollisionSphere3D::~GPUParticlesCollisionSphere3D() {
///////////////////////////
void GPUParticlesCollisionBox3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionBox3D::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionBox3D::get_extents);
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &GPUParticlesCollisionBox3D::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &GPUParticlesCollisionBox3D::get_size);
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_size", "get_size");
}
-void GPUParticlesCollisionBox3D::set_extents(const Vector3 &p_extents) {
- extents = p_extents;
- RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
+#ifndef DISABLE_DEPRECATED
+bool GPUParticlesCollisionBox3D::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ set_size((Vector3)p_value * 2);
+ return true;
+ }
+ return false;
+}
+
+bool GPUParticlesCollisionBox3D::_get(const StringName &p_name, Variant &r_property) const {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ r_property = size / 2;
+ return true;
+ }
+ return false;
+}
+#endif // DISABLE_DEPRECATED
+
+void GPUParticlesCollisionBox3D::set_size(const Vector3 &p_size) {
+ size = p_size;
+ RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), size / 2);
update_gizmos();
}
-Vector3 GPUParticlesCollisionBox3D::get_extents() const {
- return extents;
+Vector3 GPUParticlesCollisionBox3D::get_size() const {
+ return size;
}
AABB GPUParticlesCollisionBox3D::get_aabb() const {
- return AABB(-extents, extents * 2);
+ return AABB(-size / 2, size);
}
GPUParticlesCollisionBox3D::GPUParticlesCollisionBox3D() :
@@ -359,7 +377,7 @@ Vector3i GPUParticlesCollisionSDF3D::get_estimated_cell_size() const {
static const int subdivs[RESOLUTION_MAX] = { 16, 32, 64, 128, 256, 512 };
int subdiv = subdivs[get_resolution()];
- AABB aabb(-extents, extents * 2);
+ AABB aabb(-size / 2, size);
float cell_size = aabb.get_longest_axis_size() / float(subdiv);
@@ -374,7 +392,7 @@ Ref<Image> GPUParticlesCollisionSDF3D::bake() {
static const int subdivs[RESOLUTION_MAX] = { 16, 32, 64, 128, 256, 512 };
int subdiv = subdivs[get_resolution()];
- AABB aabb(-extents, extents * 2);
+ AABB aabb(-size / 2, size);
float cell_size = aabb.get_longest_axis_size() / float(subdiv);
@@ -515,8 +533,8 @@ PackedStringArray GPUParticlesCollisionSDF3D::get_configuration_warnings() const
}
void GPUParticlesCollisionSDF3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionSDF3D::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionSDF3D::get_extents);
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &GPUParticlesCollisionSDF3D::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &GPUParticlesCollisionSDF3D::get_size);
ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionSDF3D::set_resolution);
ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionSDF3D::get_resolution);
@@ -532,7 +550,7 @@ void GPUParticlesCollisionSDF3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bake_mask_value", "layer_number", "value"), &GPUParticlesCollisionSDF3D::set_bake_mask_value);
ClassDB::bind_method(D_METHOD("get_bake_mask_value", "layer_number"), &GPUParticlesCollisionSDF3D::get_bake_mask_value);
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution", PROPERTY_HINT_ENUM, "16,32,64,128,256,512"), "set_resolution", "get_resolution");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "thickness", PROPERTY_HINT_RANGE, "0.0,2.0,0.01,suffix:m"), "set_thickness", "get_thickness");
ADD_PROPERTY(PropertyInfo(Variant::INT, "bake_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_bake_mask", "get_bake_mask");
@@ -547,6 +565,24 @@ void GPUParticlesCollisionSDF3D::_bind_methods() {
BIND_ENUM_CONSTANT(RESOLUTION_MAX);
}
+#ifndef DISABLE_DEPRECATED
+bool GPUParticlesCollisionSDF3D::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ set_size((Vector3)p_value * 2);
+ return true;
+ }
+ return false;
+}
+
+bool GPUParticlesCollisionSDF3D::_get(const StringName &p_name, Variant &r_property) const {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ r_property = size / 2;
+ return true;
+ }
+ return false;
+}
+#endif // DISABLE_DEPRECATED
+
void GPUParticlesCollisionSDF3D::set_thickness(float p_thickness) {
thickness = p_thickness;
}
@@ -555,14 +591,14 @@ float GPUParticlesCollisionSDF3D::get_thickness() const {
return thickness;
}
-void GPUParticlesCollisionSDF3D::set_extents(const Vector3 &p_extents) {
- extents = p_extents;
- RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
+void GPUParticlesCollisionSDF3D::set_size(const Vector3 &p_size) {
+ size = p_size;
+ RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), size / 2);
update_gizmos();
}
-Vector3 GPUParticlesCollisionSDF3D::get_extents() const {
- return extents;
+Vector3 GPUParticlesCollisionSDF3D::get_size() const {
+ return size;
}
void GPUParticlesCollisionSDF3D::set_resolution(Resolution p_resolution) {
@@ -610,7 +646,7 @@ Ref<Texture3D> GPUParticlesCollisionSDF3D::get_texture() const {
}
AABB GPUParticlesCollisionSDF3D::get_aabb() const {
- return AABB(-extents, extents * 2);
+ return AABB(-size / 2, size);
}
GPUParticlesCollisionSDF3D::BakeBeginFunc GPUParticlesCollisionSDF3D::bake_begin_function = nullptr;
@@ -675,8 +711,8 @@ void GPUParticlesCollisionHeightField3D::_notification(int p_what) {
}
void GPUParticlesCollisionHeightField3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionHeightField3D::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionHeightField3D::get_extents);
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &GPUParticlesCollisionHeightField3D::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &GPUParticlesCollisionHeightField3D::get_size);
ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionHeightField3D::set_resolution);
ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionHeightField3D::get_resolution);
@@ -687,7 +723,7 @@ void GPUParticlesCollisionHeightField3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_follow_camera_enabled", "enabled"), &GPUParticlesCollisionHeightField3D::set_follow_camera_enabled);
ClassDB::bind_method(D_METHOD("is_follow_camera_enabled"), &GPUParticlesCollisionHeightField3D::is_follow_camera_enabled);
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution", PROPERTY_HINT_ENUM, "256 (Fastest),512 (Fast),1024 (Average),2048 (Slow),4096 (Slower),8192 (Slowest)"), "set_resolution", "get_resolution");
ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "When Moved (Fast),Always (Slow)"), "set_update_mode", "get_update_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_camera_enabled"), "set_follow_camera_enabled", "is_follow_camera_enabled");
@@ -704,15 +740,33 @@ void GPUParticlesCollisionHeightField3D::_bind_methods() {
BIND_ENUM_CONSTANT(UPDATE_MODE_ALWAYS);
}
-void GPUParticlesCollisionHeightField3D::set_extents(const Vector3 &p_extents) {
- extents = p_extents;
- RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
+#ifndef DISABLE_DEPRECATED
+bool GPUParticlesCollisionHeightField3D::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ set_size((Vector3)p_value * 2);
+ return true;
+ }
+ return false;
+}
+
+bool GPUParticlesCollisionHeightField3D::_get(const StringName &p_name, Variant &r_property) const {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ r_property = size / 2;
+ return true;
+ }
+ return false;
+}
+#endif // DISABLE_DEPRECATED
+
+void GPUParticlesCollisionHeightField3D::set_size(const Vector3 &p_size) {
+ size = p_size;
+ RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), size / 2);
update_gizmos();
RS::get_singleton()->particles_collision_height_field_update(_get_collision());
}
-Vector3 GPUParticlesCollisionHeightField3D::get_extents() const {
- return extents;
+Vector3 GPUParticlesCollisionHeightField3D::get_size() const {
+ return size;
}
void GPUParticlesCollisionHeightField3D::set_resolution(Resolution p_resolution) {
@@ -745,7 +799,7 @@ bool GPUParticlesCollisionHeightField3D::is_follow_camera_enabled() const {
}
AABB GPUParticlesCollisionHeightField3D::get_aabb() const {
- return AABB(-extents, extents * 2);
+ return AABB(-size / 2, size);
}
GPUParticlesCollisionHeightField3D::GPUParticlesCollisionHeightField3D() :
@@ -857,24 +911,42 @@ GPUParticlesAttractorSphere3D::~GPUParticlesAttractorSphere3D() {
///////////////////////////
void GPUParticlesAttractorBox3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorBox3D::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorBox3D::get_extents);
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &GPUParticlesAttractorBox3D::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &GPUParticlesAttractorBox3D::get_size);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_size", "get_size");
+}
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents");
+#ifndef DISABLE_DEPRECATED
+bool GPUParticlesAttractorBox3D::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ set_size((Vector3)p_value * 2);
+ return true;
+ }
+ return false;
}
-void GPUParticlesAttractorBox3D::set_extents(const Vector3 &p_extents) {
- extents = p_extents;
- RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
+bool GPUParticlesAttractorBox3D::_get(const StringName &p_name, Variant &r_property) const {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ r_property = size / 2;
+ return true;
+ }
+ return false;
+}
+#endif // DISABLE_DEPRECATED
+
+void GPUParticlesAttractorBox3D::set_size(const Vector3 &p_size) {
+ size = p_size;
+ RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), size / 2);
update_gizmos();
}
-Vector3 GPUParticlesAttractorBox3D::get_extents() const {
- return extents;
+Vector3 GPUParticlesAttractorBox3D::get_size() const {
+ return size;
}
AABB GPUParticlesAttractorBox3D::get_aabb() const {
- return AABB(-extents, extents * 2);
+ return AABB(-size / 2, size);
}
GPUParticlesAttractorBox3D::GPUParticlesAttractorBox3D() :
@@ -887,24 +959,42 @@ GPUParticlesAttractorBox3D::~GPUParticlesAttractorBox3D() {
///////////////////////////
void GPUParticlesAttractorVectorField3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorVectorField3D::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorVectorField3D::get_extents);
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &GPUParticlesAttractorVectorField3D::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &GPUParticlesAttractorVectorField3D::get_size);
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GPUParticlesAttractorVectorField3D::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &GPUParticlesAttractorVectorField3D::get_texture);
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture");
}
-void GPUParticlesAttractorVectorField3D::set_extents(const Vector3 &p_extents) {
- extents = p_extents;
- RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
+#ifndef DISABLE_DEPRECATED
+bool GPUParticlesAttractorVectorField3D::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ set_size((Vector3)p_value * 2);
+ return true;
+ }
+ return false;
+}
+
+bool GPUParticlesAttractorVectorField3D::_get(const StringName &p_name, Variant &r_property) const {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ r_property = size / 2;
+ return true;
+ }
+ return false;
+}
+#endif // DISABLE_DEPRECATED
+
+void GPUParticlesAttractorVectorField3D::set_size(const Vector3 &p_size) {
+ size = p_size;
+ RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), size / 2);
update_gizmos();
}
-Vector3 GPUParticlesAttractorVectorField3D::get_extents() const {
- return extents;
+Vector3 GPUParticlesAttractorVectorField3D::get_size() const {
+ return size;
}
void GPUParticlesAttractorVectorField3D::set_texture(const Ref<Texture3D> &p_texture) {
@@ -918,7 +1008,7 @@ Ref<Texture3D> GPUParticlesAttractorVectorField3D::get_texture() const {
}
AABB GPUParticlesAttractorVectorField3D::get_aabb() const {
- return AABB(-extents, extents * 2);
+ return AABB(-size / 2, size);
}
GPUParticlesAttractorVectorField3D::GPUParticlesAttractorVectorField3D() :
diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h
index 3c569ac73d..1649320069 100644
--- a/scene/3d/gpu_particles_collision_3d.h
+++ b/scene/3d/gpu_particles_collision_3d.h
@@ -74,14 +74,18 @@ public:
class GPUParticlesCollisionBox3D : public GPUParticlesCollision3D {
GDCLASS(GPUParticlesCollisionBox3D, GPUParticlesCollision3D);
- Vector3 extents = Vector3(1, 1, 1);
+ Vector3 size = Vector3(2, 2, 2);
protected:
static void _bind_methods();
+#ifndef DISABLE_DEPRECATED
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_property) const;
+#endif // DISABLE_DEPRECATED
public:
- void set_extents(const Vector3 &p_extents);
- Vector3 get_extents() const;
+ void set_size(const Vector3 &p_size);
+ Vector3 get_size() const;
virtual AABB get_aabb() const override;
@@ -108,7 +112,7 @@ public:
typedef void (*BakeEndFunc)();
private:
- Vector3 extents = Vector3(1, 1, 1);
+ Vector3 size = Vector3(2, 2, 2);
Resolution resolution = RESOLUTION_64;
uint32_t bake_mask = 0xFFFFFFFF;
Ref<Texture3D> texture;
@@ -160,6 +164,10 @@ private:
protected:
static void _bind_methods();
+#ifndef DISABLE_DEPRECATED
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_property) const;
+#endif // DISABLE_DEPRECATED
public:
virtual PackedStringArray get_configuration_warnings() const override;
@@ -167,8 +175,8 @@ public:
void set_thickness(float p_thickness);
float get_thickness() const;
- void set_extents(const Vector3 &p_extents);
- Vector3 get_extents() const;
+ void set_size(const Vector3 &p_size);
+ Vector3 get_size() const;
void set_resolution(Resolution p_resolution);
Resolution get_resolution() const;
@@ -217,7 +225,7 @@ public:
};
private:
- Vector3 extents = Vector3(1, 1, 1);
+ Vector3 size = Vector3(2, 2, 2);
Resolution resolution = RESOLUTION_1024;
bool follow_camera_mode = false;
@@ -226,10 +234,14 @@ private:
protected:
void _notification(int p_what);
static void _bind_methods();
+#ifndef DISABLE_DEPRECATED
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_property) const;
+#endif // DISABLE_DEPRECATED
public:
- void set_extents(const Vector3 &p_extents);
- Vector3 get_extents() const;
+ void set_size(const Vector3 &p_size);
+ Vector3 get_size() const;
void set_resolution(Resolution p_resolution);
Resolution get_resolution() const;
@@ -301,14 +313,18 @@ public:
class GPUParticlesAttractorBox3D : public GPUParticlesAttractor3D {
GDCLASS(GPUParticlesAttractorBox3D, GPUParticlesAttractor3D);
- Vector3 extents = Vector3(1, 1, 1);
+ Vector3 size = Vector3(2, 2, 2);
protected:
static void _bind_methods();
+#ifndef DISABLE_DEPRECATED
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_property) const;
+#endif // DISABLE_DEPRECATED
public:
- void set_extents(const Vector3 &p_extents);
- Vector3 get_extents() const;
+ void set_size(const Vector3 &p_size);
+ Vector3 get_size() const;
virtual AABB get_aabb() const override;
@@ -319,15 +335,19 @@ public:
class GPUParticlesAttractorVectorField3D : public GPUParticlesAttractor3D {
GDCLASS(GPUParticlesAttractorVectorField3D, GPUParticlesAttractor3D);
- Vector3 extents = Vector3(1, 1, 1);
+ Vector3 size = Vector3(2, 2, 2);
Ref<Texture3D> texture;
protected:
static void _bind_methods();
+#ifndef DISABLE_DEPRECATED
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_property) const;
+#endif // DISABLE_DEPRECATED
public:
- void set_extents(const Vector3 &p_extents);
- Vector3 get_extents() const;
+ void set_size(const Vector3 &p_size);
+ Vector3 get_size() const;
void set_texture(const Ref<Texture3D> &p_texture);
Ref<Texture3D> get_texture() const;
diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp
index d0f71768d2..b39ca43d2e 100644
--- a/scene/3d/label_3d.cpp
+++ b/scene/3d/label_3d.cpp
@@ -109,6 +109,15 @@ void Label3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &Label3D::set_alpha_scissor_threshold);
ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &Label3D::get_alpha_scissor_threshold);
+ ClassDB::bind_method(D_METHOD("set_alpha_hash_scale", "threshold"), &Label3D::set_alpha_hash_scale);
+ ClassDB::bind_method(D_METHOD("get_alpha_hash_scale"), &Label3D::get_alpha_hash_scale);
+
+ ClassDB::bind_method(D_METHOD("set_alpha_antialiasing", "alpha_aa"), &Label3D::set_alpha_antialiasing);
+ ClassDB::bind_method(D_METHOD("get_alpha_antialiasing"), &Label3D::get_alpha_antialiasing);
+
+ ClassDB::bind_method(D_METHOD("set_alpha_antialiasing_edge", "edge"), &Label3D::set_alpha_antialiasing_edge);
+ ClassDB::bind_method(D_METHOD("get_alpha_antialiasing_edge"), &Label3D::get_alpha_antialiasing_edge);
+
ClassDB::bind_method(D_METHOD("set_texture_filter", "mode"), &Label3D::set_texture_filter);
ClassDB::bind_method(D_METHOD("get_texture_filter"), &Label3D::get_texture_filter);
@@ -127,8 +136,11 @@ void Label3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "double_sided"), "set_draw_flag", "get_draw_flag", FLAG_DOUBLE_SIDED);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "no_depth_test"), "set_draw_flag", "get_draw_flag", FLAG_DISABLE_DEPTH_TEST);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "fixed_size"), "set_draw_flag", "get_draw_flag", FLAG_FIXED_SIZE);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass"), "set_alpha_cut_mode", "get_alpha_cut_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass,Alpha Hash"), "set_alpha_cut_mode", "get_alpha_cut_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_hash_scale", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_alpha_hash_scale", "get_alpha_hash_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_antialiasing_mode", PROPERTY_HINT_ENUM, "Disabled,Alpha Edge Blend,Alpha Edge Clip"), "set_alpha_antialiasing", "get_alpha_antialiasing");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_antialiasing_edge", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_antialiasing_edge", "get_alpha_antialiasing_edge");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter");
ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority");
ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_outline_render_priority", "get_outline_render_priority");
@@ -162,6 +174,7 @@ void Label3D::_bind_methods() {
BIND_ENUM_CONSTANT(ALPHA_CUT_DISABLED);
BIND_ENUM_CONSTANT(ALPHA_CUT_DISCARD);
BIND_ENUM_CONSTANT(ALPHA_CUT_OPAQUE_PREPASS);
+ BIND_ENUM_CONSTANT(ALPHA_CUT_HASH);
}
void Label3D::_validate_property(PropertyInfo &p_property) const {
@@ -350,13 +363,24 @@ void Label3D::_generate_glyph_surfaces(const Glyph &p_glyph, Vector2 &r_offset,
RS::get_singleton()->material_set_param(surf.material, "uv2_offset", Vector3(0, 0, 0));
RS::get_singleton()->material_set_param(surf.material, "uv2_scale", Vector3(1, 1, 1));
RS::get_singleton()->material_set_param(surf.material, "alpha_scissor_threshold", alpha_scissor_threshold);
+ RS::get_singleton()->material_set_param(surf.material, "alpha_hash_scale", alpha_hash_scale);
+ RS::get_singleton()->material_set_param(surf.material, "alpha_antialiasing_edge", alpha_antialiasing_edge);
if (msdf) {
RS::get_singleton()->material_set_param(surf.material, "msdf_pixel_range", TS->font_get_msdf_pixel_range(p_glyph.font_rid));
RS::get_singleton()->material_set_param(surf.material, "msdf_outline_size", p_outline_size);
}
+ BaseMaterial3D::Transparency mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA;
+ if (get_alpha_cut_mode() == ALPHA_CUT_DISCARD) {
+ mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA_SCISSOR;
+ } else if (get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS) {
+ mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS;
+ } else if (get_alpha_cut_mode() == ALPHA_CUT_HASH) {
+ mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA_HASH;
+ }
+
RID shader_rid;
- StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), true, get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, msdf, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), texture_filter, &shader_rid);
+ StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), mat_transparency, get_draw_flag(FLAG_DOUBLE_SIDED), get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, msdf, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), texture_filter, alpha_antialiasing_mode, &shader_rid);
RS::get_singleton()->material_set_shader(surf.material, shader_rid);
RS::get_singleton()->material_set_param(surf.material, "texture_albedo", tex);
@@ -906,7 +930,7 @@ StandardMaterial3D::BillboardMode Label3D::get_billboard_mode() const {
}
void Label3D::set_alpha_cut_mode(AlphaCutMode p_mode) {
- ERR_FAIL_INDEX(p_mode, 3);
+ ERR_FAIL_INDEX(p_mode, ALPHA_CUT_MAX);
if (alpha_cut != p_mode) {
alpha_cut = p_mode;
_queue_update();
@@ -929,6 +953,17 @@ Label3D::AlphaCutMode Label3D::get_alpha_cut_mode() const {
return alpha_cut;
}
+void Label3D::set_alpha_hash_scale(float p_hash_scale) {
+ if (alpha_hash_scale != p_hash_scale) {
+ alpha_hash_scale = p_hash_scale;
+ _queue_update();
+ }
+}
+
+float Label3D::get_alpha_hash_scale() const {
+ return alpha_hash_scale;
+}
+
void Label3D::set_alpha_scissor_threshold(float p_threshold) {
if (alpha_scissor_threshold != p_threshold) {
alpha_scissor_threshold = p_threshold;
@@ -940,6 +975,28 @@ float Label3D::get_alpha_scissor_threshold() const {
return alpha_scissor_threshold;
}
+void Label3D::set_alpha_antialiasing(BaseMaterial3D::AlphaAntiAliasing p_alpha_aa) {
+ if (alpha_antialiasing_mode != p_alpha_aa) {
+ alpha_antialiasing_mode = p_alpha_aa;
+ _queue_update();
+ }
+}
+
+BaseMaterial3D::AlphaAntiAliasing Label3D::get_alpha_antialiasing() const {
+ return alpha_antialiasing_mode;
+}
+
+void Label3D::set_alpha_antialiasing_edge(float p_edge) {
+ if (alpha_antialiasing_edge != p_edge) {
+ alpha_antialiasing_edge = p_edge;
+ _queue_update();
+ }
+}
+
+float Label3D::get_alpha_antialiasing_edge() const {
+ return alpha_antialiasing_edge;
+}
+
Label3D::Label3D() {
for (int i = 0; i < FLAG_MAX; i++) {
flags[i] = (i == FLAG_DOUBLE_SIDED);
diff --git a/scene/3d/label_3d.h b/scene/3d/label_3d.h
index 96cc941209..912f485354 100644
--- a/scene/3d/label_3d.h
+++ b/scene/3d/label_3d.h
@@ -51,7 +51,9 @@ public:
enum AlphaCutMode {
ALPHA_CUT_DISABLED,
ALPHA_CUT_DISCARD,
- ALPHA_CUT_OPAQUE_PREPASS
+ ALPHA_CUT_OPAQUE_PREPASS,
+ ALPHA_CUT_HASH,
+ ALPHA_CUT_MAX
};
private:
@@ -59,6 +61,9 @@ private:
bool flags[FLAG_MAX] = {};
AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED;
float alpha_scissor_threshold = 0.5;
+ float alpha_hash_scale = 1.0;
+ StandardMaterial3D::AlphaAntiAliasing alpha_antialiasing_mode = StandardMaterial3D::ALPHA_ANTIALIASING_OFF;
+ float alpha_antialiasing_edge = 0.0f;
AABB aabb;
@@ -228,6 +233,15 @@ public:
void set_alpha_scissor_threshold(float p_threshold);
float get_alpha_scissor_threshold() const;
+ void set_alpha_hash_scale(float p_hash_scale);
+ float get_alpha_hash_scale() const;
+
+ void set_alpha_antialiasing(BaseMaterial3D::AlphaAntiAliasing p_alpha_aa);
+ BaseMaterial3D::AlphaAntiAliasing get_alpha_antialiasing() const;
+
+ void set_alpha_antialiasing_edge(float p_edge);
+ float get_alpha_antialiasing_edge() const;
+
void set_billboard_mode(StandardMaterial3D::BillboardMode p_mode);
StandardMaterial3D::BillboardMode get_billboard_mode() const;
diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp
index 77073ff763..cca84c2b85 100644
--- a/scene/3d/light_3d.cpp
+++ b/scene/3d/light_3d.cpp
@@ -157,9 +157,16 @@ AABB Light3D::get_aabb() const {
return AABB(Vector3(-1, -1, -1) * param[PARAM_RANGE], Vector3(2, 2, 2) * param[PARAM_RANGE]);
} else if (type == RenderingServer::LIGHT_SPOT) {
- real_t len = param[PARAM_RANGE];
- real_t size = Math::tan(Math::deg_to_rad(param[PARAM_SPOT_ANGLE])) * len;
- return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
+ real_t cone_slant_height = param[PARAM_RANGE];
+ real_t cone_angle_rad = Math::deg_to_rad(param[PARAM_SPOT_ANGLE]);
+
+ if (cone_angle_rad > Math_PI / 2.0) {
+ // Just return the AABB of an omni light if the spot angle is above 90 degrees.
+ return AABB(Vector3(-1, -1, -1) * cone_slant_height, Vector3(2, 2, 2) * cone_slant_height);
+ }
+
+ real_t size = Math::sin(cone_angle_rad) * cone_slant_height;
+ return AABB(Vector3(-size, -size, -cone_slant_height), Vector3(2 * size, 2 * size, cone_slant_height));
}
return AABB();
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index 0034bf78b9..5db8611d72 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -80,10 +80,10 @@ void NavigationAgent3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationAgent3D::set_navigation_map);
ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationAgent3D::get_navigation_map);
- ClassDB::bind_method(D_METHOD("set_target_location", "location"), &NavigationAgent3D::set_target_location);
- ClassDB::bind_method(D_METHOD("get_target_location"), &NavigationAgent3D::get_target_location);
+ ClassDB::bind_method(D_METHOD("set_target_position", "position"), &NavigationAgent3D::set_target_position);
+ ClassDB::bind_method(D_METHOD("get_target_position"), &NavigationAgent3D::get_target_position);
- ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent3D::get_next_location);
+ ClassDB::bind_method(D_METHOD("get_next_path_position"), &NavigationAgent3D::get_next_path_position);
ClassDB::bind_method(D_METHOD("distance_to_target"), &NavigationAgent3D::distance_to_target);
ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationAgent3D::set_velocity);
ClassDB::bind_method(D_METHOD("get_current_navigation_result"), &NavigationAgent3D::get_current_navigation_result);
@@ -92,12 +92,12 @@ void NavigationAgent3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_target_reached"), &NavigationAgent3D::is_target_reached);
ClassDB::bind_method(D_METHOD("is_target_reachable"), &NavigationAgent3D::is_target_reachable);
ClassDB::bind_method(D_METHOD("is_navigation_finished"), &NavigationAgent3D::is_navigation_finished);
- ClassDB::bind_method(D_METHOD("get_final_location"), &NavigationAgent3D::get_final_location);
+ ClassDB::bind_method(D_METHOD("get_final_position"), &NavigationAgent3D::get_final_position);
ClassDB::bind_method(D_METHOD("_avoidance_done", "new_velocity"), &NavigationAgent3D::_avoidance_done);
ADD_GROUP("Pathfinding", "");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_location", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_target_location", "get_target_location");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_target_position", "get_target_position");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_path_desired_distance", "get_path_desired_distance");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_target_desired_distance", "get_target_desired_distance");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_height_offset", PROPERTY_HINT_RANGE, "-100.0,100,0.01,suffix:m"), "set_agent_height_offset", "get_agent_height_offset");
@@ -120,6 +120,23 @@ void NavigationAgent3D::_bind_methods() {
ADD_SIGNAL(MethodInfo("link_reached", PropertyInfo(Variant::DICTIONARY, "details")));
ADD_SIGNAL(MethodInfo("navigation_finished"));
ADD_SIGNAL(MethodInfo("velocity_computed", PropertyInfo(Variant::VECTOR3, "safe_velocity")));
+
+#ifdef DEBUG_ENABLED
+ ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &NavigationAgent3D::set_debug_enabled);
+ ClassDB::bind_method(D_METHOD("get_debug_enabled"), &NavigationAgent3D::get_debug_enabled);
+ ClassDB::bind_method(D_METHOD("set_debug_use_custom", "enabled"), &NavigationAgent3D::set_debug_use_custom);
+ ClassDB::bind_method(D_METHOD("get_debug_use_custom"), &NavigationAgent3D::get_debug_use_custom);
+ ClassDB::bind_method(D_METHOD("set_debug_path_custom_color", "color"), &NavigationAgent3D::set_debug_path_custom_color);
+ ClassDB::bind_method(D_METHOD("get_debug_path_custom_color"), &NavigationAgent3D::get_debug_path_custom_color);
+ ClassDB::bind_method(D_METHOD("set_debug_path_custom_point_size", "point_size"), &NavigationAgent3D::set_debug_path_custom_point_size);
+ ClassDB::bind_method(D_METHOD("get_debug_path_custom_point_size"), &NavigationAgent3D::get_debug_path_custom_point_size);
+
+ ADD_GROUP("Debug", "");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_enabled"), "set_debug_enabled", "get_debug_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_use_custom"), "set_debug_use_custom", "get_debug_use_custom");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_path_custom_color"), "set_debug_path_custom_color", "get_debug_path_custom_color");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "debug_path_custom_point_size", PROPERTY_HINT_RANGE, "1,50,1,suffix:px"), "set_debug_path_custom_point_size", "get_debug_path_custom_point_size");
+#endif // DEBUG_ENABLED
}
void NavigationAgent3D::_notification(int p_what) {
@@ -129,6 +146,12 @@ void NavigationAgent3D::_notification(int p_what) {
// cannot use READY as ready does not get called if Node is readded to SceneTree
set_agent_parent(get_parent());
set_physics_process_internal(true);
+
+#ifdef DEBUG_ENABLED
+ if (NavigationServer3D::get_singleton()->get_debug_enabled()) {
+ debug_path_dirty = true;
+ }
+#endif // DEBUG_ENABLED
} break;
case NOTIFICATION_PARENTED: {
@@ -151,6 +174,12 @@ void NavigationAgent3D::_notification(int p_what) {
case NOTIFICATION_EXIT_TREE: {
set_agent_parent(nullptr);
set_physics_process_internal(false);
+
+#ifdef DEBUG_ENABLED
+ if (debug_path_instance.is_valid()) {
+ RS::get_singleton()->instance_set_visible(debug_path_instance, false);
+ }
+#endif // DEBUG_ENABLED
} break;
case NOTIFICATION_PAUSED: {
@@ -182,6 +211,11 @@ void NavigationAgent3D::_notification(int p_what) {
}
_check_distance_to_target();
}
+#ifdef DEBUG_ENABLED
+ if (debug_path_dirty) {
+ _update_debug_path();
+ }
+#endif // DEBUG_ENABLED
} break;
}
}
@@ -201,20 +235,36 @@ NavigationAgent3D::NavigationAgent3D() {
navigation_result = Ref<NavigationPathQueryResult3D>();
navigation_result.instantiate();
+
+#ifdef DEBUG_ENABLED
+ NavigationServer3D::get_singleton()->connect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent3D::_navigation_debug_changed));
+#endif // DEBUG_ENABLED
}
NavigationAgent3D::~NavigationAgent3D() {
ERR_FAIL_NULL(NavigationServer3D::get_singleton());
NavigationServer3D::get_singleton()->free(agent);
agent = RID(); // Pointless
+
+#ifdef DEBUG_ENABLED
+ NavigationServer3D::get_singleton()->disconnect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent3D::_navigation_debug_changed));
+
+ ERR_FAIL_NULL(RenderingServer::get_singleton());
+ if (debug_path_instance.is_valid()) {
+ RenderingServer::get_singleton()->free(debug_path_instance);
+ }
+ if (debug_path_mesh.is_valid()) {
+ RenderingServer::get_singleton()->free(debug_path_mesh->get_rid());
+ }
+#endif // DEBUG_ENABLED
}
void NavigationAgent3D::set_avoidance_enabled(bool p_enabled) {
avoidance_enabled = p_enabled;
if (avoidance_enabled) {
- NavigationServer3D::get_singleton()->agent_set_callback(agent, get_instance_id(), "_avoidance_done");
+ NavigationServer3D::get_singleton()->agent_set_callback(agent, callable_mp(this, &NavigationAgent3D::_avoidance_done));
} else {
- NavigationServer3D::get_singleton()->agent_set_callback(agent, ObjectID(), "_avoidance_done");
+ NavigationServer3D::get_singleton()->agent_set_callback(agent, Callable());
}
}
@@ -224,7 +274,8 @@ bool NavigationAgent3D::get_avoidance_enabled() const {
void NavigationAgent3D::set_agent_parent(Node *p_agent_parent) {
// remove agent from any avoidance map before changing parent or there will be leftovers on the RVO map
- NavigationServer3D::get_singleton()->agent_set_callback(agent, ObjectID(), "_avoidance_done");
+ NavigationServer3D::get_singleton()->agent_set_callback(agent, Callable());
+
if (Object::cast_to<Node3D>(p_agent_parent) != nullptr) {
// place agent on navigation map first or else the RVO agent callback creation fails silently later
agent_parent = Object::cast_to<Node3D>(p_agent_parent);
@@ -233,6 +284,7 @@ void NavigationAgent3D::set_agent_parent(Node *p_agent_parent) {
} else {
NavigationServer3D::get_singleton()->agent_set_map(get_rid(), agent_parent->get_world_3d()->get_navigation_map());
}
+
// create new avoidance callback if enabled
set_avoidance_enabled(avoidance_enabled);
} else {
@@ -344,17 +396,17 @@ real_t NavigationAgent3D::get_path_max_distance() {
return path_max_distance;
}
-void NavigationAgent3D::set_target_location(Vector3 p_location) {
- target_location = p_location;
+void NavigationAgent3D::set_target_position(Vector3 p_position) {
+ target_position = p_position;
target_position_submitted = true;
_request_repath();
}
-Vector3 NavigationAgent3D::get_target_location() const {
- return target_location;
+Vector3 NavigationAgent3D::get_target_position() const {
+ return target_position;
}
-Vector3 NavigationAgent3D::get_next_location() {
+Vector3 NavigationAgent3D::get_next_path_position() {
update_navigation();
const Vector<Vector3> &navigation_path = navigation_result->get_path();
@@ -368,7 +420,7 @@ Vector3 NavigationAgent3D::get_next_location() {
real_t NavigationAgent3D::distance_to_target() const {
ERR_FAIL_COND_V_MSG(agent_parent == nullptr, 0.0, "The agent has no parent.");
- return agent_parent->get_global_transform().origin.distance_to(target_location);
+ return agent_parent->get_global_transform().origin.distance_to(target_position);
}
bool NavigationAgent3D::is_target_reached() const {
@@ -376,7 +428,7 @@ bool NavigationAgent3D::is_target_reached() const {
}
bool NavigationAgent3D::is_target_reachable() {
- return target_desired_distance >= get_final_location().distance_to(target_location);
+ return target_desired_distance >= get_final_position().distance_to(target_position);
}
bool NavigationAgent3D::is_navigation_finished() {
@@ -384,7 +436,7 @@ bool NavigationAgent3D::is_navigation_finished() {
return navigation_finished;
}
-Vector3 NavigationAgent3D::get_final_location() {
+Vector3 NavigationAgent3D::get_final_position() {
update_navigation();
const Vector<Vector3> &navigation_path = navigation_result->get_path();
@@ -467,7 +519,7 @@ void NavigationAgent3D::update_navigation() {
if (reload_path) {
navigation_query->set_start_position(origin);
- navigation_query->set_target_position(target_location);
+ navigation_query->set_target_position(target_position);
navigation_query->set_navigation_layers(navigation_layers);
navigation_query->set_metadata_flags(path_metadata_flags);
@@ -478,6 +530,9 @@ void NavigationAgent3D::update_navigation() {
}
NavigationServer3D::get_singleton()->query_path(navigation_query, navigation_result);
+#ifdef DEBUG_ENABLED
+ debug_path_dirty = true;
+#endif // DEBUG_ENABLED
navigation_finished = false;
navigation_path_index = 0;
emit_signal(SNAME("path_changed"));
@@ -489,7 +544,7 @@ void NavigationAgent3D::update_navigation() {
// Check if we can advance the navigation path
if (navigation_finished == false) {
- // Advances to the next far away location.
+ // Advances to the next far away position.
const Vector<Vector3> &navigation_path = navigation_result->get_path();
const Vector<int32_t> &navigation_path_types = navigation_result->get_path_types();
const TypedArray<RID> &navigation_path_rids = navigation_result->get_path_rids();
@@ -499,7 +554,7 @@ void NavigationAgent3D::update_navigation() {
Dictionary details;
const Vector3 waypoint = navigation_path[navigation_path_index];
- details[SNAME("location")] = waypoint;
+ details[SNAME("position")] = waypoint;
int waypoint_type = -1;
if (path_metadata_flags.has_flag(NavigationPathQueryParameters3D::PathMetadataFlags::PATH_METADATA_INCLUDE_TYPES)) {
@@ -564,3 +619,130 @@ void NavigationAgent3D::_check_distance_to_target() {
}
}
}
+
+////////DEBUG////////////////////////////////////////////////////////////
+
+#ifdef DEBUG_ENABLED
+void NavigationAgent3D::set_debug_enabled(bool p_enabled) {
+ debug_enabled = p_enabled;
+ debug_path_dirty = true;
+}
+
+bool NavigationAgent3D::get_debug_enabled() const {
+ return debug_enabled;
+}
+
+void NavigationAgent3D::set_debug_use_custom(bool p_enabled) {
+ debug_use_custom = p_enabled;
+ debug_path_dirty = true;
+}
+
+bool NavigationAgent3D::get_debug_use_custom() const {
+ return debug_use_custom;
+}
+
+void NavigationAgent3D::set_debug_path_custom_color(Color p_color) {
+ debug_path_custom_color = p_color;
+ debug_path_dirty = true;
+}
+
+Color NavigationAgent3D::get_debug_path_custom_color() const {
+ return debug_path_custom_color;
+}
+
+void NavigationAgent3D::set_debug_path_custom_point_size(float p_point_size) {
+ debug_path_custom_point_size = p_point_size;
+ debug_path_dirty = true;
+}
+
+float NavigationAgent3D::get_debug_path_custom_point_size() const {
+ return debug_path_custom_point_size;
+}
+
+void NavigationAgent3D::_navigation_debug_changed() {
+ debug_path_dirty = true;
+}
+
+void NavigationAgent3D::_update_debug_path() {
+ if (!debug_path_dirty) {
+ return;
+ }
+ debug_path_dirty = false;
+
+ if (!debug_path_instance.is_valid()) {
+ debug_path_instance = RenderingServer::get_singleton()->instance_create();
+ }
+
+ if (!debug_path_mesh.is_valid()) {
+ debug_path_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
+ }
+
+ debug_path_mesh->clear_surfaces();
+
+ if (!(debug_enabled && NavigationServer3D::get_singleton()->get_debug_navigation_enable_agent_paths())) {
+ return;
+ }
+
+ if (!(agent_parent && agent_parent->is_inside_tree())) {
+ return;
+ }
+
+ const Vector<Vector3> &navigation_path = navigation_result->get_path();
+
+ if (navigation_path.size() <= 1) {
+ return;
+ }
+
+ Vector<Vector3> debug_path_lines_vertex_array;
+
+ for (int i = 0; i < navigation_path.size() - 1; i++) {
+ debug_path_lines_vertex_array.push_back(navigation_path[i]);
+ debug_path_lines_vertex_array.push_back(navigation_path[i + 1]);
+ }
+
+ Array debug_path_lines_mesh_array;
+ debug_path_lines_mesh_array.resize(Mesh::ARRAY_MAX);
+ debug_path_lines_mesh_array[Mesh::ARRAY_VERTEX] = debug_path_lines_vertex_array;
+
+ debug_path_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, debug_path_lines_mesh_array);
+
+ Ref<StandardMaterial3D> debug_agent_path_line_material = NavigationServer3D::get_singleton()->get_debug_navigation_agent_path_line_material();
+ if (debug_use_custom) {
+ if (!debug_agent_path_line_custom_material.is_valid()) {
+ debug_agent_path_line_custom_material = debug_agent_path_line_material->duplicate();
+ }
+ debug_agent_path_line_custom_material->set_albedo(debug_path_custom_color);
+ debug_path_mesh->surface_set_material(0, debug_agent_path_line_custom_material);
+ } else {
+ debug_path_mesh->surface_set_material(0, debug_agent_path_line_material);
+ }
+
+ Vector<Vector3> debug_path_points_vertex_array;
+
+ for (int i = 0; i < navigation_path.size(); i++) {
+ debug_path_points_vertex_array.push_back(navigation_path[i]);
+ }
+
+ Array debug_path_points_mesh_array;
+ debug_path_points_mesh_array.resize(Mesh::ARRAY_MAX);
+ debug_path_points_mesh_array[Mesh::ARRAY_VERTEX] = debug_path_lines_vertex_array;
+
+ debug_path_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_POINTS, debug_path_points_mesh_array);
+
+ Ref<StandardMaterial3D> debug_agent_path_point_material = NavigationServer3D::get_singleton()->get_debug_navigation_agent_path_point_material();
+ if (debug_use_custom) {
+ if (!debug_agent_path_point_custom_material.is_valid()) {
+ debug_agent_path_point_custom_material = debug_agent_path_point_material->duplicate();
+ }
+ debug_agent_path_point_custom_material->set_albedo(debug_path_custom_color);
+ debug_agent_path_point_custom_material->set_point_size(debug_path_custom_point_size);
+ debug_path_mesh->surface_set_material(1, debug_agent_path_point_custom_material);
+ } else {
+ debug_path_mesh->surface_set_material(1, debug_agent_path_point_material);
+ }
+
+ RS::get_singleton()->instance_set_base(debug_path_instance, debug_path_mesh->get_rid());
+ RS::get_singleton()->instance_set_scenario(debug_path_instance, agent_parent->get_world_3d()->get_scenario());
+ RS::get_singleton()->instance_set_visible(debug_path_instance, agent_parent->is_visible_in_tree());
+}
+#endif // DEBUG_ENABLED
diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h
index 91be068392..98bf395d7c 100644
--- a/scene/3d/navigation_agent_3d.h
+++ b/scene/3d/navigation_agent_3d.h
@@ -62,7 +62,7 @@ class NavigationAgent3D : public Node {
real_t path_max_distance = 3.0;
- Vector3 target_location;
+ Vector3 target_position;
bool target_position_submitted = false;
Ref<NavigationPathQueryParameters3D> navigation_query;
Ref<NavigationPathQueryResult3D> navigation_result;
@@ -76,6 +76,22 @@ class NavigationAgent3D : public Node {
// No initialized on purpose
uint32_t update_frame_id = 0;
+#ifdef DEBUG_ENABLED
+ bool debug_enabled = false;
+ bool debug_path_dirty = true;
+ RID debug_path_instance;
+ Ref<ArrayMesh> debug_path_mesh;
+ float debug_path_custom_point_size = 4.0;
+ bool debug_use_custom = false;
+ Color debug_path_custom_color = Color(1.0, 1.0, 1.0, 1.0);
+ Ref<StandardMaterial3D> debug_agent_path_line_custom_material;
+ Ref<StandardMaterial3D> debug_agent_path_point_custom_material;
+
+private:
+ void _navigation_debug_changed();
+ void _update_debug_path();
+#endif // DEBUG_ENABLED
+
protected:
static void _bind_methods();
void _notification(int p_what);
@@ -155,10 +171,10 @@ public:
void set_path_max_distance(real_t p_pmd);
real_t get_path_max_distance();
- void set_target_location(Vector3 p_location);
- Vector3 get_target_location() const;
+ void set_target_position(Vector3 p_position);
+ Vector3 get_target_position() const;
- Vector3 get_next_location();
+ Vector3 get_next_path_position();
Ref<NavigationPathQueryResult3D> get_current_navigation_result() const {
return navigation_result;
@@ -174,13 +190,27 @@ public:
bool is_target_reached() const;
bool is_target_reachable();
bool is_navigation_finished();
- Vector3 get_final_location();
+ Vector3 get_final_position();
void set_velocity(Vector3 p_velocity);
void _avoidance_done(Vector3 p_new_velocity);
PackedStringArray get_configuration_warnings() const override;
+#ifdef DEBUG_ENABLED
+ void set_debug_enabled(bool p_enabled);
+ bool get_debug_enabled() const;
+
+ void set_debug_use_custom(bool p_enabled);
+ bool get_debug_use_custom() const;
+
+ void set_debug_path_custom_color(Color p_color);
+ Color get_debug_path_custom_color() const;
+
+ void set_debug_path_custom_point_size(float p_point_size);
+ float get_debug_path_custom_point_size() const;
+#endif // DEBUG_ENABLED
+
private:
void update_navigation();
void _request_repath();
diff --git a/scene/3d/navigation_link_3d.cpp b/scene/3d/navigation_link_3d.cpp
index e058ef62d0..f47fcfaf51 100644
--- a/scene/3d/navigation_link_3d.cpp
+++ b/scene/3d/navigation_link_3d.cpp
@@ -70,10 +70,10 @@ void NavigationLink3D::_update_debug_mesh() {
Vector<Vector3> lines;
// Draw line between the points.
- lines.push_back(start_location);
- lines.push_back(end_location);
+ lines.push_back(start_position);
+ lines.push_back(end_position);
- // Draw start location search radius
+ // Draw start position search radius
for (int i = 0; i < 30; i++) {
// Create a circle
const float ra = Math::deg_to_rad((float)(i * 12));
@@ -84,21 +84,21 @@ void NavigationLink3D::_update_debug_mesh() {
// Draw axis-aligned circle
switch (up_axis) {
case Vector3::AXIS_X:
- lines.append(start_location + Vector3(0, a.x, a.y));
- lines.append(start_location + Vector3(0, b.x, b.y));
+ lines.append(start_position + Vector3(0, a.x, a.y));
+ lines.append(start_position + Vector3(0, b.x, b.y));
break;
case Vector3::AXIS_Y:
- lines.append(start_location + Vector3(a.x, 0, a.y));
- lines.append(start_location + Vector3(b.x, 0, b.y));
+ lines.append(start_position + Vector3(a.x, 0, a.y));
+ lines.append(start_position + Vector3(b.x, 0, b.y));
break;
case Vector3::AXIS_Z:
- lines.append(start_location + Vector3(a.x, a.y, 0));
- lines.append(start_location + Vector3(b.x, b.y, 0));
+ lines.append(start_position + Vector3(a.x, a.y, 0));
+ lines.append(start_position + Vector3(b.x, b.y, 0));
break;
}
}
- // Draw end location search radius
+ // Draw end position search radius
for (int i = 0; i < 30; i++) {
// Create a circle
const float ra = Math::deg_to_rad((float)(i * 12));
@@ -109,16 +109,16 @@ void NavigationLink3D::_update_debug_mesh() {
// Draw axis-aligned circle
switch (up_axis) {
case Vector3::AXIS_X:
- lines.append(end_location + Vector3(0, a.x, a.y));
- lines.append(end_location + Vector3(0, b.x, b.y));
+ lines.append(end_position + Vector3(0, a.x, a.y));
+ lines.append(end_position + Vector3(0, b.x, b.y));
break;
case Vector3::AXIS_Y:
- lines.append(end_location + Vector3(a.x, 0, a.y));
- lines.append(end_location + Vector3(b.x, 0, b.y));
+ lines.append(end_position + Vector3(a.x, 0, a.y));
+ lines.append(end_position + Vector3(b.x, 0, b.y));
break;
case Vector3::AXIS_Z:
- lines.append(end_location + Vector3(a.x, a.y, 0));
- lines.append(end_location + Vector3(b.x, b.y, 0));
+ lines.append(end_position + Vector3(a.x, a.y, 0));
+ lines.append(end_position + Vector3(b.x, b.y, 0));
break;
}
}
@@ -157,11 +157,11 @@ void NavigationLink3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationLink3D::set_navigation_layer_value);
ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationLink3D::get_navigation_layer_value);
- ClassDB::bind_method(D_METHOD("set_start_location", "location"), &NavigationLink3D::set_start_location);
- ClassDB::bind_method(D_METHOD("get_start_location"), &NavigationLink3D::get_start_location);
+ ClassDB::bind_method(D_METHOD("set_start_position", "position"), &NavigationLink3D::set_start_position);
+ ClassDB::bind_method(D_METHOD("get_start_position"), &NavigationLink3D::get_start_position);
- ClassDB::bind_method(D_METHOD("set_end_location", "location"), &NavigationLink3D::set_end_location);
- ClassDB::bind_method(D_METHOD("get_end_location"), &NavigationLink3D::get_end_location);
+ ClassDB::bind_method(D_METHOD("set_end_position", "position"), &NavigationLink3D::set_end_position);
+ ClassDB::bind_method(D_METHOD("get_end_position"), &NavigationLink3D::get_end_position);
ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationLink3D::set_enter_cost);
ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationLink3D::get_enter_cost);
@@ -172,12 +172,38 @@ void NavigationLink3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bidirectional"), "set_bidirectional", "is_bidirectional");
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "start_location"), "set_start_location", "get_start_location");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "end_location"), "set_end_location", "get_end_location");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "start_position"), "set_start_position", "get_start_position");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "end_position"), "set_end_position", "get_end_position");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "enter_cost"), "set_enter_cost", "get_enter_cost");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "travel_cost"), "set_travel_cost", "get_travel_cost");
}
+#ifndef DISABLE_DEPRECATED
+bool NavigationLink3D::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "start_location") {
+ set_start_position(p_value);
+ return true;
+ }
+ if (p_name == "end_location") {
+ set_end_position(p_value);
+ return true;
+ }
+ return false;
+}
+
+bool NavigationLink3D::_get(const StringName &p_name, Variant &r_ret) const {
+ if (p_name == "start_location") {
+ r_ret = get_start_position();
+ return true;
+ }
+ if (p_name == "end_location") {
+ r_ret = get_end_position();
+ return true;
+ }
+ return false;
+}
+#endif // DISABLE_DEPRECATED
+
void NavigationLink3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
@@ -186,8 +212,8 @@ void NavigationLink3D::_notification(int p_what) {
// Update global positions for the link.
Transform3D gt = get_global_transform();
- NavigationServer3D::get_singleton()->link_set_start_location(link, gt.xform(start_location));
- NavigationServer3D::get_singleton()->link_set_end_location(link, gt.xform(end_location));
+ NavigationServer3D::get_singleton()->link_set_start_position(link, gt.xform(start_position));
+ NavigationServer3D::get_singleton()->link_set_end_position(link, gt.xform(end_position));
}
#ifdef DEBUG_ENABLED
@@ -197,8 +223,8 @@ void NavigationLink3D::_notification(int p_what) {
case NOTIFICATION_TRANSFORM_CHANGED: {
// Update global positions for the link.
Transform3D gt = get_global_transform();
- NavigationServer3D::get_singleton()->link_set_start_location(link, gt.xform(start_location));
- NavigationServer3D::get_singleton()->link_set_end_location(link, gt.xform(end_location));
+ NavigationServer3D::get_singleton()->link_set_start_position(link, gt.xform(start_position));
+ NavigationServer3D::get_singleton()->link_set_end_position(link, gt.xform(end_position));
#ifdef DEBUG_ENABLED
if (is_inside_tree() && debug_instance.is_valid()) {
@@ -316,19 +342,19 @@ bool NavigationLink3D::get_navigation_layer_value(int p_layer_number) const {
return get_navigation_layers() & (1 << (p_layer_number - 1));
}
-void NavigationLink3D::set_start_location(Vector3 p_location) {
- if (start_location.is_equal_approx(p_location)) {
+void NavigationLink3D::set_start_position(Vector3 p_position) {
+ if (start_position.is_equal_approx(p_position)) {
return;
}
- start_location = p_location;
+ start_position = p_position;
if (!is_inside_tree()) {
return;
}
Transform3D gt = get_global_transform();
- NavigationServer3D::get_singleton()->link_set_start_location(link, gt.xform(start_location));
+ NavigationServer3D::get_singleton()->link_set_start_position(link, gt.xform(start_position));
#ifdef DEBUG_ENABLED
_update_debug_mesh();
@@ -338,19 +364,19 @@ void NavigationLink3D::set_start_location(Vector3 p_location) {
update_configuration_warnings();
}
-void NavigationLink3D::set_end_location(Vector3 p_location) {
- if (end_location.is_equal_approx(p_location)) {
+void NavigationLink3D::set_end_position(Vector3 p_position) {
+ if (end_position.is_equal_approx(p_position)) {
return;
}
- end_location = p_location;
+ end_position = p_position;
if (!is_inside_tree()) {
return;
}
Transform3D gt = get_global_transform();
- NavigationServer3D::get_singleton()->link_set_end_location(link, gt.xform(end_location));
+ NavigationServer3D::get_singleton()->link_set_end_position(link, gt.xform(end_position));
#ifdef DEBUG_ENABLED
_update_debug_mesh();
@@ -385,8 +411,8 @@ void NavigationLink3D::set_travel_cost(real_t p_travel_cost) {
PackedStringArray NavigationLink3D::get_configuration_warnings() const {
PackedStringArray warnings = Node::get_configuration_warnings();
- if (start_location.is_equal_approx(end_location)) {
- warnings.push_back(RTR("NavigationLink3D start location should be different than the end location to be useful."));
+ if (start_position.is_equal_approx(end_position)) {
+ warnings.push_back(RTR("NavigationLink3D start position should be different than the end position to be useful."));
}
return warnings;
diff --git a/scene/3d/navigation_link_3d.h b/scene/3d/navigation_link_3d.h
index 175c5cdd5d..5c9ec36189 100644
--- a/scene/3d/navigation_link_3d.h
+++ b/scene/3d/navigation_link_3d.h
@@ -40,8 +40,8 @@ class NavigationLink3D : public Node3D {
RID link;
bool bidirectional = true;
uint32_t navigation_layers = 1;
- Vector3 end_location;
- Vector3 start_location;
+ Vector3 end_position;
+ Vector3 start_position;
real_t enter_cost = 0.0;
real_t travel_cost = 1.0;
@@ -56,6 +56,11 @@ protected:
static void _bind_methods();
void _notification(int p_what);
+#ifndef DISABLE_DEPRECATED
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+#endif // DISABLE_DEPRECATED
+
public:
NavigationLink3D();
~NavigationLink3D();
@@ -72,11 +77,11 @@ public:
void set_navigation_layer_value(int p_layer_number, bool p_value);
bool get_navigation_layer_value(int p_layer_number) const;
- void set_start_location(Vector3 p_location);
- Vector3 get_start_location() const { return start_location; }
+ void set_start_position(Vector3 p_position);
+ Vector3 get_start_position() const { return start_position; }
- void set_end_location(Vector3 p_location);
- Vector3 get_end_location() const { return end_location; }
+ void set_end_position(Vector3 p_position);
+ Vector3 get_end_position() const { return end_position; }
void set_enter_cost(real_t p_enter_cost);
real_t get_enter_cost() const { return enter_cost; }
diff --git a/scene/3d/occluder_instance_3d.cpp b/scene/3d/occluder_instance_3d.cpp
index 632b27953f..594580a205 100644
--- a/scene/3d/occluder_instance_3d.cpp
+++ b/scene/3d/occluder_instance_3d.cpp
@@ -542,13 +542,14 @@ void OccluderInstance3D::_bake_surface(const Transform3D &p_transform, Array p_s
float error = -1.0f;
int target_index_count = MIN(indices.size(), 36);
+ const int simplify_options = SurfaceTool::SIMPLIFY_LOCK_BORDER;
+
uint32_t index_count = SurfaceTool::simplify_func(
(unsigned int *)indices.ptrw(),
(unsigned int *)indices.ptr(),
indices.size(),
vertices_f32.ptr(), vertices.size(), sizeof(float) * 3,
- target_index_count, target_error, &error);
-
+ target_index_count, target_error, simplify_options, &error);
indices.resize(index_count);
}
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index f4ab09cd9b..c8cfcf7d7a 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -333,6 +333,11 @@ void AnimatableBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) {
}
void AnimatableBody3D::_notification(int p_what) {
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint()) {
+ return;
+ }
+#endif
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
last_valid_transform = get_global_transform();
diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp
index 606f6140cb..62202c0b1b 100644
--- a/scene/3d/reflection_probe.cpp
+++ b/scene/3d/reflection_probe.cpp
@@ -85,38 +85,40 @@ float ReflectionProbe::get_mesh_lod_threshold() const {
return mesh_lod_threshold;
}
-void ReflectionProbe::set_extents(const Vector3 &p_extents) {
- extents = p_extents;
+void ReflectionProbe::set_size(const Vector3 &p_size) {
+ size = p_size;
for (int i = 0; i < 3; i++) {
- if (extents[i] < 0.01) {
- extents[i] = 0.01;
+ float half_size = size[i] / 2;
+ if (half_size < 0.01) {
+ half_size = 0.01;
}
- if (extents[i] - 0.01 < ABS(origin_offset[i])) {
- origin_offset[i] = SIGN(origin_offset[i]) * (extents[i] - 0.01);
+ if (half_size - 0.01 < ABS(origin_offset[i])) {
+ origin_offset[i] = SIGN(origin_offset[i]) * (half_size - 0.01);
}
}
- RS::get_singleton()->reflection_probe_set_extents(probe, extents);
+ RS::get_singleton()->reflection_probe_set_size(probe, size);
RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset);
update_gizmos();
}
-Vector3 ReflectionProbe::get_extents() const {
- return extents;
+Vector3 ReflectionProbe::get_size() const {
+ return size;
}
-void ReflectionProbe::set_origin_offset(const Vector3 &p_extents) {
- origin_offset = p_extents;
+void ReflectionProbe::set_origin_offset(const Vector3 &p_offset) {
+ origin_offset = p_offset;
for (int i = 0; i < 3; i++) {
- if (extents[i] - 0.01 < ABS(origin_offset[i])) {
- origin_offset[i] = SIGN(origin_offset[i]) * (extents[i] - 0.01);
+ float half_size = size[i] / 2;
+ if (half_size - 0.01 < ABS(origin_offset[i])) {
+ origin_offset[i] = SIGN(origin_offset[i]) * (half_size - 0.01);
}
}
- RS::get_singleton()->reflection_probe_set_extents(probe, extents);
+ RS::get_singleton()->reflection_probe_set_size(probe, size);
RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset);
update_gizmos();
@@ -174,7 +176,7 @@ ReflectionProbe::UpdateMode ReflectionProbe::get_update_mode() const {
AABB ReflectionProbe::get_aabb() const {
AABB aabb;
aabb.position = -origin_offset;
- aabb.size = origin_offset + extents;
+ aabb.size = origin_offset + size / 2;
return aabb;
}
@@ -205,8 +207,8 @@ void ReflectionProbe::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_mesh_lod_threshold", "ratio"), &ReflectionProbe::set_mesh_lod_threshold);
ClassDB::bind_method(D_METHOD("get_mesh_lod_threshold"), &ReflectionProbe::get_mesh_lod_threshold);
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &ReflectionProbe::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &ReflectionProbe::get_extents);
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &ReflectionProbe::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &ReflectionProbe::get_size);
ClassDB::bind_method(D_METHOD("set_origin_offset", "origin_offset"), &ReflectionProbe::set_origin_offset);
ClassDB::bind_method(D_METHOD("get_origin_offset"), &ReflectionProbe::get_origin_offset);
@@ -229,7 +231,7 @@ void ReflectionProbe::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Once (Fast),Always (Slow)"), "set_update_mode", "get_update_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "intensity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_intensity", "get_intensity");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_RANGE, "0,16384,0.1,or_greater,exp,suffix:m"), "set_max_distance", "get_max_distance");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_NONE, "suffix:m"), "set_extents", "get_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_NONE, "suffix:m"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "origin_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_origin_offset", "get_origin_offset");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "box_projection"), "set_enable_box_projection", "is_box_projection_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_as_interior", "is_set_as_interior");
@@ -250,6 +252,24 @@ void ReflectionProbe::_bind_methods() {
BIND_ENUM_CONSTANT(AMBIENT_COLOR);
}
+#ifndef DISABLE_DEPRECATED
+bool ReflectionProbe::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ set_size((Vector3)p_value * 2);
+ return true;
+ }
+ return false;
+}
+
+bool ReflectionProbe::_get(const StringName &p_name, Variant &r_property) const {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ r_property = size / 2;
+ return true;
+ }
+ return false;
+}
+#endif // DISABLE_DEPRECATED
+
ReflectionProbe::ReflectionProbe() {
probe = RenderingServer::get_singleton()->reflection_probe_create();
RS::get_singleton()->instance_set_base(get_instance(), probe);
diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h
index cb417c3eea..738277ad39 100644
--- a/scene/3d/reflection_probe.h
+++ b/scene/3d/reflection_probe.h
@@ -52,7 +52,7 @@ private:
RID probe;
float intensity = 1.0;
float max_distance = 0.0;
- Vector3 extents = Vector3(10, 10, 10);
+ Vector3 size = Vector3(20, 20, 20);
Vector3 origin_offset = Vector3(0, 0, 0);
bool box_projection = false;
bool enable_shadows = false;
@@ -68,6 +68,10 @@ private:
protected:
static void _bind_methods();
void _validate_property(PropertyInfo &p_property) const;
+#ifndef DISABLE_DEPRECATED
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_property) const;
+#endif // DISABLE_DEPRECATED
public:
void set_intensity(float p_intensity);
@@ -91,10 +95,10 @@ public:
void set_mesh_lod_threshold(float p_pixels);
float get_mesh_lod_threshold() const;
- void set_extents(const Vector3 &p_extents);
- Vector3 get_extents() const;
+ void set_size(const Vector3 &p_size);
+ Vector3 get_size() const;
- void set_origin_offset(const Vector3 &p_extents);
+ void set_origin_offset(const Vector3 &p_offset);
Vector3 get_origin_offset() const;
void set_as_interior(bool p_enable);
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 71d76c0d1c..59e4a0b718 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -245,8 +245,26 @@ void SpriteBase3D::draw_texture_rect(Ref<Texture2D> p_texture, Rect2 p_dst_rect,
RS::get_singleton()->mesh_set_custom_aabb(mesh_new, aabb_new);
set_aabb(aabb_new);
+ RS::get_singleton()->material_set_param(get_material(), "alpha_scissor_threshold", alpha_scissor_threshold);
+ RS::get_singleton()->material_set_param(get_material(), "alpha_hash_scale", alpha_hash_scale);
+ RS::get_singleton()->material_set_param(get_material(), "alpha_antialiasing_edge", alpha_antialiasing_edge);
+
+ BaseMaterial3D::Transparency mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_DISABLED;
+ if (get_draw_flag(FLAG_TRANSPARENT)) {
+ if (get_alpha_cut_mode() == ALPHA_CUT_DISCARD) {
+ mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA_SCISSOR;
+ } else if (get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS) {
+ mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS;
+ } else if (get_alpha_cut_mode() == ALPHA_CUT_HASH) {
+ mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA_HASH;
+ } else {
+ mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA;
+ }
+ }
+
RID shader_rid;
- StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, false, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), get_texture_filter(), &shader_rid);
+ StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), mat_transparency, get_draw_flag(FLAG_DOUBLE_SIDED), get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, false, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), get_texture_filter(), alpha_antialiasing_mode, &shader_rid);
+
if (last_shader != shader_rid) {
RS::get_singleton()->material_set_shader(get_material(), shader_rid);
last_shader = shader_rid;
@@ -433,7 +451,7 @@ bool SpriteBase3D::get_draw_flag(DrawFlags p_flag) const {
}
void SpriteBase3D::set_alpha_cut_mode(AlphaCutMode p_mode) {
- ERR_FAIL_INDEX(p_mode, 3);
+ ERR_FAIL_INDEX(p_mode, ALPHA_CUT_MAX);
alpha_cut = p_mode;
_queue_redraw();
}
@@ -442,6 +460,50 @@ SpriteBase3D::AlphaCutMode SpriteBase3D::get_alpha_cut_mode() const {
return alpha_cut;
}
+void SpriteBase3D::set_alpha_hash_scale(float p_hash_scale) {
+ if (alpha_hash_scale != p_hash_scale) {
+ alpha_hash_scale = p_hash_scale;
+ _queue_redraw();
+ }
+}
+
+float SpriteBase3D::get_alpha_hash_scale() const {
+ return alpha_hash_scale;
+}
+
+void SpriteBase3D::set_alpha_scissor_threshold(float p_threshold) {
+ if (alpha_scissor_threshold != p_threshold) {
+ alpha_scissor_threshold = p_threshold;
+ _queue_redraw();
+ }
+}
+
+float SpriteBase3D::get_alpha_scissor_threshold() const {
+ return alpha_scissor_threshold;
+}
+
+void SpriteBase3D::set_alpha_antialiasing(BaseMaterial3D::AlphaAntiAliasing p_alpha_aa) {
+ if (alpha_antialiasing_mode != p_alpha_aa) {
+ alpha_antialiasing_mode = p_alpha_aa;
+ _queue_redraw();
+ }
+}
+
+BaseMaterial3D::AlphaAntiAliasing SpriteBase3D::get_alpha_antialiasing() const {
+ return alpha_antialiasing_mode;
+}
+
+void SpriteBase3D::set_alpha_antialiasing_edge(float p_edge) {
+ if (alpha_antialiasing_edge != p_edge) {
+ alpha_antialiasing_edge = p_edge;
+ _queue_redraw();
+ }
+}
+
+float SpriteBase3D::get_alpha_antialiasing_edge() const {
+ return alpha_antialiasing_edge;
+}
+
void SpriteBase3D::set_billboard_mode(StandardMaterial3D::BillboardMode p_mode) {
ERR_FAIL_INDEX(p_mode, 3); // Cannot use BILLBOARD_PARTICLES.
billboard_mode = p_mode;
@@ -494,6 +556,18 @@ void SpriteBase3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_alpha_cut_mode", "mode"), &SpriteBase3D::set_alpha_cut_mode);
ClassDB::bind_method(D_METHOD("get_alpha_cut_mode"), &SpriteBase3D::get_alpha_cut_mode);
+ ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &SpriteBase3D::set_alpha_scissor_threshold);
+ ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &SpriteBase3D::get_alpha_scissor_threshold);
+
+ ClassDB::bind_method(D_METHOD("set_alpha_hash_scale", "threshold"), &SpriteBase3D::set_alpha_hash_scale);
+ ClassDB::bind_method(D_METHOD("get_alpha_hash_scale"), &SpriteBase3D::get_alpha_hash_scale);
+
+ ClassDB::bind_method(D_METHOD("set_alpha_antialiasing", "alpha_aa"), &SpriteBase3D::set_alpha_antialiasing);
+ ClassDB::bind_method(D_METHOD("get_alpha_antialiasing"), &SpriteBase3D::get_alpha_antialiasing);
+
+ ClassDB::bind_method(D_METHOD("set_alpha_antialiasing_edge", "edge"), &SpriteBase3D::set_alpha_antialiasing_edge);
+ ClassDB::bind_method(D_METHOD("get_alpha_antialiasing_edge"), &SpriteBase3D::get_alpha_antialiasing_edge);
+
ClassDB::bind_method(D_METHOD("set_billboard_mode", "mode"), &SpriteBase3D::set_billboard_mode);
ClassDB::bind_method(D_METHOD("get_billboard_mode"), &SpriteBase3D::get_billboard_mode);
@@ -519,7 +593,11 @@ void SpriteBase3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "double_sided"), "set_draw_flag", "get_draw_flag", FLAG_DOUBLE_SIDED);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "no_depth_test"), "set_draw_flag", "get_draw_flag", FLAG_DISABLE_DEPTH_TEST);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "fixed_size"), "set_draw_flag", "get_draw_flag", FLAG_FIXED_SIZE);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass"), "set_alpha_cut_mode", "get_alpha_cut_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass,Alpha Hash"), "set_alpha_cut_mode", "get_alpha_cut_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_hash_scale", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_alpha_hash_scale", "get_alpha_hash_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_antialiasing_mode", PROPERTY_HINT_ENUM, "Disabled,Alpha Edge Blend,Alpha Edge Clip"), "set_alpha_antialiasing", "get_alpha_antialiasing");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_antialiasing_edge", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_antialiasing_edge", "get_alpha_antialiasing_edge");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter");
ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority");
@@ -533,6 +611,7 @@ void SpriteBase3D::_bind_methods() {
BIND_ENUM_CONSTANT(ALPHA_CUT_DISABLED);
BIND_ENUM_CONSTANT(ALPHA_CUT_DISCARD);
BIND_ENUM_CONSTANT(ALPHA_CUT_OPAQUE_PREPASS);
+ BIND_ENUM_CONSTANT(ALPHA_CUT_HASH);
}
SpriteBase3D::SpriteBase3D() {
@@ -550,7 +629,6 @@ SpriteBase3D::SpriteBase3D() {
RS::get_singleton()->material_set_param(material, "uv1_scale", Vector3(1, 1, 1));
RS::get_singleton()->material_set_param(material, "uv2_offset", Vector3(0, 0, 0));
RS::get_singleton()->material_set_param(material, "uv2_scale", Vector3(1, 1, 1));
- RS::get_singleton()->material_set_param(material, "alpha_scissor_threshold", 0.5);
mesh = RenderingServer::get_singleton()->mesh_create();
@@ -866,7 +944,6 @@ void AnimatedSprite3D::_validate_property(PropertyInfo &p_property) const {
}
if (p_property.name == "animation") {
- p_property.hint = PROPERTY_HINT_ENUM;
List<StringName> names;
frames->get_animation_list(&names);
names.sort_custom<StringName::AlphCompare>();
@@ -916,6 +993,12 @@ void AnimatedSprite3D::_validate_property(PropertyInfo &p_property) const {
void AnimatedSprite3D::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_READY: {
+ if (!Engine::get_singleton()->is_editor_hint() && !frames.is_null() && frames->has_animation(autoplay)) {
+ play(autoplay);
+ }
+ } break;
+
case NOTIFICATION_INTERNAL_PROCESS: {
if (frames.is_null() || !frames->has_animation(animation)) {
return;
@@ -925,7 +1008,8 @@ void AnimatedSprite3D::_notification(int p_what) {
int i = 0;
while (remaining) {
// Animation speed may be changed by animation_finished or frame_changed signals.
- double speed = frames->get_animation_speed(animation) * Math::abs(speed_scale);
+ double speed = frames->get_animation_speed(animation) * speed_scale * custom_speed_scale * frame_speed_scale;
+ double abs_speed = Math::abs(speed);
if (speed == 0) {
return; // Do nothing.
@@ -934,53 +1018,57 @@ void AnimatedSprite3D::_notification(int p_what) {
// Frame count may be changed by animation_finished or frame_changed signals.
int fc = frames->get_frame_count(animation);
- if (timeout <= 0) {
- int last_frame = fc - 1;
- if (!playing_backwards) {
- // Forward.
+ int last_frame = fc - 1;
+ if (!signbit(speed)) {
+ // Forwards.
+ if (frame_progress >= 1.0) {
if (frame >= last_frame) {
if (frames->get_animation_loop(animation)) {
frame = 0;
- emit_signal(SceneStringNames::get_singleton()->animation_finished);
+ emit_signal("animation_looped");
} else {
frame = last_frame;
- if (!is_over) {
- is_over = true;
- emit_signal(SceneStringNames::get_singleton()->animation_finished);
- }
+ pause();
+ emit_signal(SceneStringNames::get_singleton()->animation_finished);
+ return;
}
} else {
frame++;
}
- } else {
- // Reversed.
+ _calc_frame_speed_scale();
+ frame_progress = 0.0;
+ _queue_redraw();
+ emit_signal(SceneStringNames::get_singleton()->frame_changed);
+ }
+ double to_process = MIN((1.0 - frame_progress) / abs_speed, remaining);
+ frame_progress += to_process * abs_speed;
+ remaining -= to_process;
+ } else {
+ // Backwards.
+ if (frame_progress <= 0) {
if (frame <= 0) {
if (frames->get_animation_loop(animation)) {
frame = last_frame;
- emit_signal(SceneStringNames::get_singleton()->animation_finished);
+ emit_signal("animation_looped");
} else {
frame = 0;
- if (!is_over) {
- is_over = true;
- emit_signal(SceneStringNames::get_singleton()->animation_finished);
- }
+ pause();
+ emit_signal(SceneStringNames::get_singleton()->animation_finished);
+ return;
}
} else {
frame--;
}
+ _calc_frame_speed_scale();
+ frame_progress = 1.0;
+ _queue_redraw();
+ emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
-
- timeout = _get_frame_duration();
-
- _queue_redraw();
-
- emit_signal(SceneStringNames::get_singleton()->frame_changed);
+ double to_process = MIN(frame_progress / abs_speed, remaining);
+ frame_progress -= to_process * abs_speed;
+ remaining -= to_process;
}
- double to_process = MIN(timeout / speed, remaining);
- timeout -= to_process * speed;
- remaining -= to_process;
-
i++;
if (i > fc) {
return; // Prevents freezing if to_process is each time much less than remaining.
@@ -991,25 +1079,37 @@ void AnimatedSprite3D::_notification(int p_what) {
}
void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) {
+ if (frames == p_frames) {
+ return;
+ }
+
if (frames.is_valid()) {
frames->disconnect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite3D::_res_changed));
}
-
+ stop();
frames = p_frames;
if (frames.is_valid()) {
frames->connect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite3D::_res_changed));
- }
- if (frames.is_null()) {
- frame = 0;
- } else {
- set_frame(frame);
+ List<StringName> al;
+ frames->get_animation_list(&al);
+ if (al.size() == 0) {
+ set_animation(StringName());
+ set_autoplay(String());
+ } else {
+ if (!frames->has_animation(animation)) {
+ set_animation(al[0]);
+ }
+ if (!frames->has_animation(autoplay)) {
+ set_autoplay(String());
+ }
+ }
}
notify_property_list_changed();
- _reset_timeout();
_queue_redraw();
update_configuration_warnings();
+ emit_signal("sprite_frames_changed");
}
Ref<SpriteFrames> AnimatedSprite3D::get_sprite_frames() const {
@@ -1017,44 +1117,63 @@ Ref<SpriteFrames> AnimatedSprite3D::get_sprite_frames() const {
}
void AnimatedSprite3D::set_frame(int p_frame) {
+ set_frame_and_progress(p_frame, signbit(get_playing_speed()) ? 1.0 : 0.0);
+}
+
+int AnimatedSprite3D::get_frame() const {
+ return frame;
+}
+
+void AnimatedSprite3D::set_frame_progress(real_t p_progress) {
+ frame_progress = p_progress;
+}
+
+real_t AnimatedSprite3D::get_frame_progress() const {
+ return frame_progress;
+}
+
+void AnimatedSprite3D::set_frame_and_progress(int p_frame, real_t p_progress) {
if (frames.is_null()) {
return;
}
- if (frames->has_animation(animation)) {
- int limit = frames->get_frame_count(animation);
- if (p_frame >= limit) {
- p_frame = limit - 1;
- }
- }
+ bool has_animation = frames->has_animation(animation);
+ int end_frame = has_animation ? MAX(0, frames->get_frame_count(animation) - 1) : 0;
+ bool is_changed = frame != p_frame;
if (p_frame < 0) {
- p_frame = 0;
+ frame = 0;
+ } else if (has_animation && p_frame > end_frame) {
+ frame = end_frame;
+ } else {
+ frame = p_frame;
}
- if (frame == p_frame) {
- return;
- }
+ _calc_frame_speed_scale();
+ frame_progress = p_progress;
- frame = p_frame;
- _reset_timeout();
+ if (!is_changed) {
+ return; // No change, don't redraw.
+ }
_queue_redraw();
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
-int AnimatedSprite3D::get_frame() const {
- return frame;
-}
-
void AnimatedSprite3D::set_speed_scale(float p_speed_scale) {
speed_scale = p_speed_scale;
- playing_backwards = signbit(speed_scale) != backwards;
}
float AnimatedSprite3D::get_speed_scale() const {
return speed_scale;
}
+float AnimatedSprite3D::get_playing_speed() const {
+ if (!playing) {
+ return 0;
+ }
+ return speed_scale * custom_speed_scale;
+}
+
Rect2 AnimatedSprite3D::get_item_rect() const {
if (frames.is_null() || !frames->has_animation(animation)) {
return Rect2(0, 0, 1, 1);
@@ -1085,69 +1204,131 @@ Rect2 AnimatedSprite3D::get_item_rect() const {
}
void AnimatedSprite3D::_res_changed() {
- set_frame(frame);
+ set_frame_and_progress(frame, frame_progress);
_queue_redraw();
notify_property_list_changed();
}
-void AnimatedSprite3D::set_playing(bool p_playing) {
- if (playing == p_playing) {
- return;
+bool AnimatedSprite3D::is_playing() const {
+ return playing;
+}
+
+void AnimatedSprite3D::set_autoplay(const String &p_name) {
+ if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) {
+ WARN_PRINT("Setting autoplay after the node has been added to the scene has no effect.");
}
- playing = p_playing;
- playing_backwards = signbit(speed_scale) != backwards;
- set_process_internal(playing);
- notify_property_list_changed();
+
+ autoplay = p_name;
}
-bool AnimatedSprite3D::is_playing() const {
- return playing;
+String AnimatedSprite3D::get_autoplay() const {
+ return autoplay;
}
-void AnimatedSprite3D::play(const StringName &p_animation, bool p_backwards) {
- backwards = p_backwards;
- playing_backwards = signbit(speed_scale) != backwards;
+void AnimatedSprite3D::play(const StringName &p_name, float p_custom_scale, bool p_from_end) {
+ StringName name = p_name;
+
+ if (name == StringName()) {
+ name = animation;
+ }
+
+ ERR_FAIL_COND_MSG(frames == nullptr, vformat("There is no animation with name '%s'.", name));
+ ERR_FAIL_COND_MSG(!frames->get_animation_names().has(name), vformat("There is no animation with name '%s'.", name));
- if (p_animation) {
- set_animation(p_animation);
- if (frames.is_valid() && playing_backwards && get_frame() == 0) {
- set_frame(frames->get_frame_count(p_animation) - 1);
+ if (frames->get_frame_count(name) == 0) {
+ return;
+ }
+
+ playing = true;
+ custom_speed_scale = p_custom_scale;
+
+ int end_frame = MAX(0, frames->get_frame_count(animation) - 1);
+ if (name != animation) {
+ animation = name;
+ if (p_from_end) {
+ set_frame_and_progress(end_frame, 1.0);
+ } else {
+ set_frame_and_progress(0, 0.0);
+ }
+ emit_signal("animation_changed");
+ } else {
+ bool is_backward = signbit(speed_scale * custom_speed_scale);
+ if (p_from_end && is_backward && frame == 0 && frame_progress <= 0.0) {
+ set_frame_and_progress(end_frame, 1.0);
+ } else if (!p_from_end && !is_backward && frame == end_frame && frame_progress >= 1.0) {
+ set_frame_and_progress(0, 0.0);
}
}
- is_over = false;
- set_playing(true);
+ set_process_internal(true);
+ notify_property_list_changed();
+ _queue_redraw();
+}
+
+void AnimatedSprite3D::play_backwards(const StringName &p_name) {
+ play(p_name, -1, true);
+}
+
+void AnimatedSprite3D::_stop_internal(bool p_reset) {
+ playing = false;
+ if (p_reset) {
+ custom_speed_scale = 1.0;
+ set_frame_and_progress(0, 0.0);
+ }
+ notify_property_list_changed();
+ set_process_internal(false);
+}
+
+void AnimatedSprite3D::pause() {
+ _stop_internal(false);
}
void AnimatedSprite3D::stop() {
- set_playing(false);
- backwards = false;
- _reset_timeout();
+ _stop_internal(true);
}
double AnimatedSprite3D::_get_frame_duration() {
if (frames.is_valid() && frames->has_animation(animation)) {
return frames->get_frame_duration(animation, frame);
}
- return 0.0;
+ return 1.0;
}
-void AnimatedSprite3D::_reset_timeout() {
- timeout = _get_frame_duration();
- is_over = false;
+void AnimatedSprite3D::_calc_frame_speed_scale() {
+ frame_speed_scale = 1.0 / _get_frame_duration();
}
-void AnimatedSprite3D::set_animation(const StringName &p_animation) {
- ERR_FAIL_COND_MSG(frames == nullptr, vformat("There is no animation with name '%s'.", p_animation));
- ERR_FAIL_COND_MSG(!frames->get_animation_names().has(p_animation), vformat("There is no animation with name '%s'.", p_animation));
+void AnimatedSprite3D::set_animation(const StringName &p_name) {
+ if (animation == p_name) {
+ return;
+ }
+
+ animation = p_name;
- if (animation == p_animation) {
+ emit_signal("animation_changed");
+
+ if (frames == nullptr) {
+ animation = StringName();
+ stop();
+ ERR_FAIL_MSG(vformat("There is no animation with name '%s'.", p_name));
+ }
+
+ int frame_count = frames->get_frame_count(animation);
+ if (animation == StringName() || frame_count == 0) {
+ stop();
return;
+ } else if (!frames->get_animation_names().has(animation)) {
+ animation = StringName();
+ stop();
+ ERR_FAIL_MSG(vformat("There is no animation with name '%s'.", p_name));
+ }
+
+ if (signbit(get_playing_speed())) {
+ set_frame_and_progress(frame_count - 1, 1.0);
+ } else {
+ set_frame_and_progress(0, 0.0);
}
- animation = p_animation;
- set_frame(0);
- _reset_timeout();
notify_property_list_changed();
_queue_redraw();
}
@@ -1175,35 +1356,58 @@ void AnimatedSprite3D::get_argument_options(const StringName &p_function, int p_
Node::get_argument_options(p_function, p_idx, r_options);
}
+#ifndef DISABLE_DEPRECATED
+bool AnimatedSprite3D::_set(const StringName &p_name, const Variant &p_value) {
+ if ((p_name == SNAME("frames"))) {
+ set_sprite_frames(p_value);
+ return true;
+ }
+ return false;
+}
+#endif
void AnimatedSprite3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_sprite_frames", "sprite_frames"), &AnimatedSprite3D::set_sprite_frames);
ClassDB::bind_method(D_METHOD("get_sprite_frames"), &AnimatedSprite3D::get_sprite_frames);
- ClassDB::bind_method(D_METHOD("set_animation", "animation"), &AnimatedSprite3D::set_animation);
+ ClassDB::bind_method(D_METHOD("set_animation", "name"), &AnimatedSprite3D::set_animation);
ClassDB::bind_method(D_METHOD("get_animation"), &AnimatedSprite3D::get_animation);
- ClassDB::bind_method(D_METHOD("set_playing", "playing"), &AnimatedSprite3D::set_playing);
+ ClassDB::bind_method(D_METHOD("set_autoplay", "name"), &AnimatedSprite3D::set_autoplay);
+ ClassDB::bind_method(D_METHOD("get_autoplay"), &AnimatedSprite3D::get_autoplay);
+
ClassDB::bind_method(D_METHOD("is_playing"), &AnimatedSprite3D::is_playing);
- ClassDB::bind_method(D_METHOD("play", "anim", "backwards"), &AnimatedSprite3D::play, DEFVAL(StringName()), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("play", "name", "custom_speed", "from_end"), &AnimatedSprite3D::play, DEFVAL(StringName()), DEFVAL(1.0), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("play_backwards", "name"), &AnimatedSprite3D::play_backwards, DEFVAL(StringName()));
+ ClassDB::bind_method(D_METHOD("pause"), &AnimatedSprite3D::pause);
ClassDB::bind_method(D_METHOD("stop"), &AnimatedSprite3D::stop);
ClassDB::bind_method(D_METHOD("set_frame", "frame"), &AnimatedSprite3D::set_frame);
ClassDB::bind_method(D_METHOD("get_frame"), &AnimatedSprite3D::get_frame);
+ ClassDB::bind_method(D_METHOD("set_frame_progress", "progress"), &AnimatedSprite3D::set_frame_progress);
+ ClassDB::bind_method(D_METHOD("get_frame_progress"), &AnimatedSprite3D::get_frame_progress);
+
+ ClassDB::bind_method(D_METHOD("set_frame_and_progress", "frame", "progress"), &AnimatedSprite3D::set_frame_and_progress);
+
ClassDB::bind_method(D_METHOD("set_speed_scale", "speed_scale"), &AnimatedSprite3D::set_speed_scale);
ClassDB::bind_method(D_METHOD("get_speed_scale"), &AnimatedSprite3D::get_speed_scale);
+ ClassDB::bind_method(D_METHOD("get_playing_speed"), &AnimatedSprite3D::get_playing_speed);
ClassDB::bind_method(D_METHOD("_res_changed"), &AnimatedSprite3D::_res_changed);
+ ADD_SIGNAL(MethodInfo("sprite_frames_changed"));
+ ADD_SIGNAL(MethodInfo("animation_changed"));
ADD_SIGNAL(MethodInfo("frame_changed"));
+ ADD_SIGNAL(MethodInfo("animation_looped"));
ADD_SIGNAL(MethodInfo("animation_finished"));
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sprite_frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation", PROPERTY_HINT_ENUM, ""), "set_animation", "get_animation");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "autoplay", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_autoplay", "get_autoplay");
ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "frame_progress", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_frame_progress", "get_frame_progress");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale"), "set_speed_scale", "get_speed_scale");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "set_playing", "is_playing");
}
AnimatedSprite3D::AnimatedSprite3D() {
diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h
index c5509aa723..1eb1211951 100644
--- a/scene/3d/sprite_3d.h
+++ b/scene/3d/sprite_3d.h
@@ -53,7 +53,9 @@ public:
enum AlphaCutMode {
ALPHA_CUT_DISABLED,
ALPHA_CUT_DISCARD,
- ALPHA_CUT_OPAQUE_PREPASS
+ ALPHA_CUT_OPAQUE_PREPASS,
+ ALPHA_CUT_HASH,
+ ALPHA_CUT_MAX
};
private:
@@ -85,6 +87,10 @@ private:
bool flags[FLAG_MAX] = {};
AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED;
+ float alpha_scissor_threshold = 0.5;
+ float alpha_hash_scale = 1.0;
+ StandardMaterial3D::AlphaAntiAliasing alpha_antialiasing_mode = StandardMaterial3D::ALPHA_ANTIALIASING_OFF;
+ float alpha_antialiasing_edge = 0.0f;
StandardMaterial3D::BillboardMode billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED;
StandardMaterial3D::TextureFilter texture_filter = StandardMaterial3D::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS;
bool pending_update = false;
@@ -143,6 +149,18 @@ public:
void set_alpha_cut_mode(AlphaCutMode p_mode);
AlphaCutMode get_alpha_cut_mode() const;
+ void set_alpha_scissor_threshold(float p_threshold);
+ float get_alpha_scissor_threshold() const;
+
+ void set_alpha_hash_scale(float p_hash_scale);
+ float get_alpha_hash_scale() const;
+
+ void set_alpha_antialiasing(BaseMaterial3D::AlphaAntiAliasing p_alpha_aa);
+ BaseMaterial3D::AlphaAntiAliasing get_alpha_antialiasing() const;
+
+ void set_alpha_antialiasing_edge(float p_edge);
+ float get_alpha_antialiasing_edge() const;
+
void set_billboard_mode(StandardMaterial3D::BillboardMode p_mode);
StandardMaterial3D::BillboardMode get_billboard_mode() const;
@@ -209,24 +227,29 @@ class AnimatedSprite3D : public SpriteBase3D {
GDCLASS(AnimatedSprite3D, SpriteBase3D);
Ref<SpriteFrames> frames;
+ String autoplay;
+
bool playing = false;
- bool playing_backwards = false;
- bool backwards = false;
StringName animation = "default";
int frame = 0;
float speed_scale = 1.0;
+ float custom_speed_scale = 1.0;
bool centered = false;
- bool is_over = false;
- double timeout = 0.0;
+ real_t frame_speed_scale = 1.0;
+ real_t frame_progress = 0.0;
void _res_changed();
double _get_frame_duration();
- void _reset_timeout();
+ void _calc_frame_speed_scale();
+ void _stop_internal(bool p_reset);
protected:
+#ifndef DISABLE_DEPRECATED
+ bool _set(const StringName &p_name, const Variant &p_value);
+#endif
virtual void _draw() override;
static void _bind_methods();
void _notification(int p_what);
@@ -236,20 +259,30 @@ public:
void set_sprite_frames(const Ref<SpriteFrames> &p_frames);
Ref<SpriteFrames> get_sprite_frames() const;
- void play(const StringName &p_animation = StringName(), bool p_backwards = false);
+ void play(const StringName &p_name = StringName(), float p_custom_scale = 1.0, bool p_from_end = false);
+ void play_backwards(const StringName &p_name = StringName());
+ void pause();
void stop();
- void set_playing(bool p_playing);
bool is_playing() const;
- void set_animation(const StringName &p_animation);
+ void set_animation(const StringName &p_name);
StringName get_animation() const;
+ void set_autoplay(const String &p_name);
+ String get_autoplay() const;
+
void set_frame(int p_frame);
int get_frame() const;
+ void set_frame_progress(real_t p_progress);
+ real_t get_frame_progress() const;
+
+ void set_frame_and_progress(int p_frame, real_t p_progress);
+
void set_speed_scale(float p_speed_scale);
float get_speed_scale() const;
+ float get_playing_speed() const;
virtual Rect2 get_item_rect() const override;
diff --git a/scene/3d/voxel_gi.cpp b/scene/3d/voxel_gi.cpp
index 4325152a7b..36a877246e 100644
--- a/scene/3d/voxel_gi.cpp
+++ b/scene/3d/voxel_gi.cpp
@@ -237,6 +237,24 @@ void VoxelGIData::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_interior", "is_interior");
}
+#ifndef DISABLE_DEPRECATED
+bool VoxelGI::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ set_size((Vector3)p_value * 2);
+ return true;
+ }
+ return false;
+}
+
+bool VoxelGI::_get(const StringName &p_name, Variant &r_property) const {
+ if (p_name == "extents") { // Compatibility with Godot 3.x.
+ r_property = size / 2;
+ return true;
+ }
+ return false;
+}
+#endif // DISABLE_DEPRECATED
+
VoxelGIData::VoxelGIData() {
probe = RS::get_singleton()->voxel_gi_create();
}
@@ -273,14 +291,14 @@ VoxelGI::Subdiv VoxelGI::get_subdiv() const {
return subdiv;
}
-void VoxelGI::set_extents(const Vector3 &p_extents) {
- // Prevent very small extents as these break baking if other extents are set very high.
- extents = Vector3(MAX(1.0, p_extents.x), MAX(1.0, p_extents.y), MAX(1.0, p_extents.z));
+void VoxelGI::set_size(const Vector3 &p_size) {
+ // Prevent very small size dimensions as these breaks baking if other size dimensions are set very high.
+ size = Vector3(MAX(1.0, p_size.x), MAX(1.0, p_size.y), MAX(1.0, p_size.z));
update_gizmos();
}
-Vector3 VoxelGI::get_extents() const {
- return extents;
+Vector3 VoxelGI::get_size() const {
+ return size;
}
void VoxelGI::set_camera_attributes(const Ref<CameraAttributes> &p_camera_attributes) {
@@ -300,7 +318,7 @@ void VoxelGI::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) {
Transform3D xf = get_global_transform().affine_inverse() * mi->get_global_transform();
- if (AABB(-extents, extents * 2).intersects(xf.xform(aabb))) {
+ if (AABB(-size / 2, size).intersects(xf.xform(aabb))) {
PlotMesh pm;
pm.local_xform = xf;
pm.mesh = mesh;
@@ -328,7 +346,7 @@ void VoxelGI::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) {
Transform3D xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf);
- if (AABB(-extents, extents * 2).intersects(xf.xform(aabb))) {
+ if (AABB(-size / 2, size).intersects(xf.xform(aabb))) {
PlotMesh pm;
pm.local_xform = xf;
pm.mesh = mesh;
@@ -352,7 +370,7 @@ Vector3i VoxelGI::get_estimated_cell_size() const {
static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 };
int cell_subdiv = subdiv_value[subdiv];
int axis_cell_size[3];
- AABB bounds = AABB(-extents, extents * 2.0);
+ AABB bounds = AABB(-size / 2, size);
int longest_axis = bounds.get_longest_axis_index();
axis_cell_size[longest_axis] = 1 << cell_subdiv;
@@ -390,7 +408,7 @@ void VoxelGI::bake(Node *p_from_node, bool p_create_visual_debug) {
Voxelizer baker;
- baker.begin_bake(subdiv_value[subdiv], AABB(-extents, extents * 2.0), exposure_normalization);
+ baker.begin_bake(subdiv_value[subdiv], AABB(-size / 2, size), exposure_normalization);
List<PlotMesh> mesh_list;
@@ -448,7 +466,7 @@ void VoxelGI::bake(Node *p_from_node, bool p_create_visual_debug) {
RS::get_singleton()->voxel_gi_set_baked_exposure_normalization(probe_data_new->get_rid(), exposure_normalization);
- probe_data_new->allocate(baker.get_to_cell_space_xform(), AABB(-extents, extents * 2.0), baker.get_voxel_gi_octree_size(), baker.get_voxel_gi_octree_cells(), baker.get_voxel_gi_data_cells(), df, baker.get_voxel_gi_level_cell_count());
+ probe_data_new->allocate(baker.get_to_cell_space_xform(), AABB(-size / 2, size), baker.get_voxel_gi_octree_size(), baker.get_voxel_gi_octree_cells(), baker.get_voxel_gi_data_cells(), df, baker.get_voxel_gi_level_cell_count());
set_probe_data(probe_data_new);
#ifdef TOOLS_ENABLED
@@ -468,7 +486,7 @@ void VoxelGI::_debug_bake() {
}
AABB VoxelGI::get_aabb() const {
- return AABB(-extents, extents * 2);
+ return AABB(-size / 2, size);
}
PackedStringArray VoxelGI::get_configuration_warnings() const {
@@ -489,8 +507,8 @@ void VoxelGI::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_subdiv", "subdiv"), &VoxelGI::set_subdiv);
ClassDB::bind_method(D_METHOD("get_subdiv"), &VoxelGI::get_subdiv);
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &VoxelGI::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &VoxelGI::get_extents);
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &VoxelGI::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &VoxelGI::get_size);
ClassDB::bind_method(D_METHOD("set_camera_attributes", "camera_attributes"), &VoxelGI::set_camera_attributes);
ClassDB::bind_method(D_METHOD("get_camera_attributes"), &VoxelGI::get_camera_attributes);
@@ -500,9 +518,9 @@ void VoxelGI::_bind_methods() {
ClassDB::set_method_flags(get_class_static(), _scs_create("debug_bake"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdiv", PROPERTY_HINT_ENUM, "64,128,256,512"), "set_subdiv", "get_subdiv");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_NONE, "suffix:m"), "set_extents", "get_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_NONE, "suffix:m"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_attributes", PROPERTY_HINT_RESOURCE_TYPE, "CameraAttributesPractical,CameraAttributesPhysical"), "set_camera_attributes", "get_camera_attributes");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "data", PROPERTY_HINT_RESOURCE_TYPE, "VoxelGIData", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "set_probe_data", "get_probe_data");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "data", PROPERTY_HINT_RESOURCE_TYPE, "VoxelGIData", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ALWAYS_DUPLICATE), "set_probe_data", "get_probe_data");
BIND_ENUM_CONSTANT(SUBDIV_64);
BIND_ENUM_CONSTANT(SUBDIV_128);
diff --git a/scene/3d/voxel_gi.h b/scene/3d/voxel_gi.h
index ae348daf9e..d276186dd1 100644
--- a/scene/3d/voxel_gi.h
+++ b/scene/3d/voxel_gi.h
@@ -118,7 +118,7 @@ private:
RID voxel_gi;
Subdiv subdiv = SUBDIV_128;
- Vector3 extents = Vector3(10, 10, 10);
+ Vector3 size = Vector3(20, 20, 20);
Ref<CameraAttributes> camera_attributes;
struct PlotMesh {
@@ -133,6 +133,10 @@ private:
protected:
static void _bind_methods();
+#ifndef DISABLE_DEPRECATED
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_property) const;
+#endif // DISABLE_DEPRECATED
public:
static BakeBeginFunc bake_begin_function;
@@ -145,8 +149,8 @@ public:
void set_subdiv(Subdiv p_subdiv);
Subdiv get_subdiv() const;
- void set_extents(const Vector3 &p_extents);
- Vector3 get_extents() const;
+ void set_size(const Vector3 &p_size);
+ Vector3 get_size() const;
void set_camera_attributes(const Ref<CameraAttributes> &p_camera_attributes);
Ref<CameraAttributes> get_camera_attributes() const;