diff options
Diffstat (limited to 'scene')
30 files changed, 278 insertions, 153 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 932db8f001..25ad6bd5c9 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -645,6 +645,9 @@ void AnimatedSprite::_reset_timeout() { void AnimatedSprite::set_animation(const StringName &p_animation) { + ERR_EXPLAIN(vformat("There is no animation with name '%s'.", p_animation)); + ERR_FAIL_COND(frames->get_animation_names().find(p_animation) == -1); + if (animation == p_animation) return; diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index faefd85968..73f583111b 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -37,7 +37,7 @@ void AudioStreamPlayer2D::_mix_audio() { if (!stream_playback.is_valid() || !active || - (stream_paused && !stream_fade_out)) { + (stream_paused && !stream_paused_fade_out)) { return; } @@ -50,7 +50,7 @@ void AudioStreamPlayer2D::_mix_audio() { AudioFrame *buffer = mix_buffer.ptrw(); int buffer_size = mix_buffer.size(); - if (stream_fade_out) { + if (stream_paused_fade_out) { // Short fadeout ramp buffer_size = MIN(buffer_size, 128); } @@ -84,10 +84,10 @@ void AudioStreamPlayer2D::_mix_audio() { } //mix! - AudioFrame target_volume = stream_fade_out ? AudioFrame(0.f, 0.f) : current.vol; - AudioFrame vol_prev = stream_fade_in ? AudioFrame(0.f, 0.f) : prev_outputs[i].vol; + AudioFrame target_volume = stream_paused_fade_out ? AudioFrame(0.f, 0.f) : current.vol; + AudioFrame vol_prev = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : prev_outputs[i].vol; AudioFrame vol_inc = (target_volume - vol_prev) / float(buffer_size); - AudioFrame vol = stream_fade_in ? AudioFrame(0.f, 0.f) : current.vol; + AudioFrame vol = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : current.vol; int cc = AudioServer::get_singleton()->get_channel_count(); @@ -139,15 +139,9 @@ void AudioStreamPlayer2D::_mix_audio() { active = false; } - if (stream_stop) { - active = false; - set_physics_process_internal(false); - setplay = -1; - } - output_ready = false; - stream_fade_in = false; - stream_fade_out = false; + stream_paused_fade_in = false; + stream_paused_fade_out = false; } void AudioStreamPlayer2D::_notification(int p_what) { @@ -329,7 +323,6 @@ void AudioStreamPlayer2D::play(float p_from_pos) { } if (stream_playback.is_valid()) { - stream_stop = false; active = true; setplay = p_from_pos; output_ready = false; @@ -347,8 +340,9 @@ void AudioStreamPlayer2D::seek(float p_seconds) { void AudioStreamPlayer2D::stop() { if (stream_playback.is_valid()) { - stream_stop = true; - stream_fade_out = true; + active = false; + set_physics_process_internal(false); + setplay = -1; } } @@ -463,8 +457,8 @@ void AudioStreamPlayer2D::set_stream_paused(bool p_pause) { if (p_pause != stream_paused) { stream_paused = p_pause; - stream_fade_in = p_pause ? false : true; - stream_fade_out = p_pause ? true : false; + stream_paused_fade_in = p_pause ? false : true; + stream_paused_fade_out = p_pause ? true : false; } } @@ -549,9 +543,8 @@ AudioStreamPlayer2D::AudioStreamPlayer2D() { output_ready = false; area_mask = 1; stream_paused = false; - stream_fade_in = false; - stream_fade_out = false; - stream_stop = false; + stream_paused_fade_in = false; + stream_paused_fade_out = false; AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); } diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h index 0cd18fb93b..e9cdfa2303 100644 --- a/scene/2d/audio_stream_player_2d.h +++ b/scene/2d/audio_stream_player_2d.h @@ -73,9 +73,8 @@ private: float pitch_scale; bool autoplay; bool stream_paused; - bool stream_fade_in; - bool stream_fade_out; - bool stream_stop; + bool stream_paused_fade_in; + bool stream_paused_fade_out; StringName bus; void _mix_audio(); diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp index 57e0a5b118..72b5f2fb12 100644 --- a/scene/2d/navigation_2d.cpp +++ b/scene/2d/navigation_2d.cpp @@ -542,7 +542,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect if (CLOCK_TANGENT(apex_point, portal_left, left) >= 0) { //process - if (portal_left.distance_squared_to(apex_point) < CMP_EPSILON || CLOCK_TANGENT(apex_point, left, portal_right) > 0) { + if (Math::is_zero_approx(portal_left.distance_squared_to(apex_point)) || CLOCK_TANGENT(apex_point, left, portal_right) > 0) { left_poly = p; portal_left = left; } else { @@ -552,7 +552,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect left_poly = p; portal_left = apex_point; portal_right = apex_point; - if (!path.size() || path[path.size() - 1].distance_to(apex_point) > CMP_EPSILON) + if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_to(apex_point))) path.push_back(apex_point); skip = true; } @@ -560,7 +560,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect if (!skip && CLOCK_TANGENT(apex_point, portal_right, right) <= 0) { //process - if (portal_right.distance_squared_to(apex_point) < CMP_EPSILON || CLOCK_TANGENT(apex_point, right, portal_left) < 0) { + if (Math::is_zero_approx(portal_right.distance_squared_to(apex_point)) || CLOCK_TANGENT(apex_point, right, portal_left) < 0) { right_poly = p; portal_right = right; } else { @@ -570,7 +570,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect right_poly = p; portal_right = apex_point; portal_left = apex_point; - if (!path.size() || path[path.size() - 1].distance_to(apex_point) > CMP_EPSILON) + if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_to(apex_point))) path.push_back(apex_point); } } @@ -596,7 +596,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect } } - if (!path.size() || path[path.size() - 1].distance_squared_to(begin_point) > CMP_EPSILON) { + if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_squared_to(begin_point))) { path.push_back(begin_point); // Add the begin point } else { path.write[path.size() - 1] = begin_point; // Replace first midpoint by the exact begin point @@ -604,7 +604,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect path.invert(); - if (path.size() <= 1 || path[path.size() - 1].distance_squared_to(end_point) > CMP_EPSILON) { + if (path.size() <= 1 || !Math::is_zero_approx(path[path.size() - 1].distance_squared_to(end_point))) { path.push_back(end_point); // Add the end point } else { path.write[path.size() - 1] = end_point; // Replace last midpoint by the exact end point diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 8bc48914d5..ff8c218575 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -38,7 +38,7 @@ void AudioStreamPlayer3D::_mix_audio() { if (!stream_playback.is_valid() || !active || - (stream_paused && !stream_fade_out)) { + (stream_paused && !stream_paused_fade_out)) { return; } @@ -53,7 +53,7 @@ void AudioStreamPlayer3D::_mix_audio() { AudioFrame *buffer = mix_buffer.ptrw(); int buffer_size = mix_buffer.size(); - if (stream_fade_out) { + if (stream_paused_fade_out) { // Short fadeout ramp buffer_size = MIN(buffer_size, 128); } @@ -109,10 +109,10 @@ void AudioStreamPlayer3D::_mix_audio() { int buffers = AudioServer::get_singleton()->get_channel_count(); for (int k = 0; k < buffers; k++) { - AudioFrame target_volume = stream_fade_out ? AudioFrame(0.f, 0.f) : current.vol[k]; - AudioFrame vol_prev = stream_fade_in ? AudioFrame(0.f, 0.f) : prev_outputs[i].vol[k]; + AudioFrame target_volume = stream_paused_fade_out ? AudioFrame(0.f, 0.f) : current.vol[k]; + AudioFrame vol_prev = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : prev_outputs[i].vol[k]; AudioFrame vol_inc = (target_volume - vol_prev) / float(buffer_size); - AudioFrame vol = stream_fade_in ? AudioFrame(0.f, 0.f) : current.vol[k]; + AudioFrame vol = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : current.vol[k]; if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, k)) continue; //may have been deleted, will be updated on process @@ -198,15 +198,9 @@ void AudioStreamPlayer3D::_mix_audio() { active = false; } - if (stream_stop) { - active = false; - set_physics_process_internal(false); - setplay = -1; - } - output_ready = false; - stream_fade_in = false; - stream_fade_out = false; + stream_paused_fade_in = false; + stream_paused_fade_out = false; } float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const { @@ -663,7 +657,6 @@ float AudioStreamPlayer3D::get_pitch_scale() const { void AudioStreamPlayer3D::play(float p_from_pos) { if (stream_playback.is_valid()) { - stream_stop = false; active = true; setplay = p_from_pos; output_ready = false; @@ -681,8 +674,9 @@ void AudioStreamPlayer3D::seek(float p_seconds) { void AudioStreamPlayer3D::stop() { if (stream_playback.is_valid()) { - stream_stop = true; - stream_fade_out = true; + active = false; + set_physics_process_internal(false); + setplay = -1; } } @@ -878,8 +872,8 @@ void AudioStreamPlayer3D::set_stream_paused(bool p_pause) { if (p_pause != stream_paused) { stream_paused = p_pause; - stream_fade_in = stream_paused ? false : true; - stream_fade_out = stream_paused ? true : false; + stream_paused_fade_in = stream_paused ? false : true; + stream_paused_fade_out = stream_paused ? true : false; } } @@ -1024,9 +1018,8 @@ AudioStreamPlayer3D::AudioStreamPlayer3D() { out_of_range_mode = OUT_OF_RANGE_MIX; doppler_tracking = DOPPLER_TRACKING_DISABLED; stream_paused = false; - stream_fade_in = false; - stream_fade_out = false; - stream_stop = false; + stream_paused_fade_in = false; + stream_paused_fade_out = false; velocity_tracker.instance(); AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h index ad83c47afc..98bc74b2e4 100644 --- a/scene/3d/audio_stream_player_3d.h +++ b/scene/3d/audio_stream_player_3d.h @@ -110,9 +110,8 @@ private: float pitch_scale; bool autoplay; bool stream_paused; - bool stream_fade_in; - bool stream_fade_out; - bool stream_stop; + bool stream_paused_fade_in; + bool stream_paused_fade_out; StringName bus; void _mix_audio(); diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 368cebeeab..54d7681a3a 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -55,16 +55,23 @@ void Camera::_update_camera_mode() { case PROJECTION_ORTHOGONAL: { set_orthogonal(size, near, far); } break; + case PROJECTION_FRUSTUM: { + set_frustum(size, frustum_offset, near, far); + } break; } } void Camera::_validate_property(PropertyInfo &p_property) const { if (p_property.name == "fov") { - if (mode == PROJECTION_ORTHOGONAL) { + if (mode != PROJECTION_PERSPECTIVE) { p_property.usage = PROPERTY_USAGE_NOEDITOR; } } else if (p_property.name == "size") { - if (mode == PROJECTION_PERSPECTIVE) { + if (mode != PROJECTION_ORTHOGONAL && mode != PROJECTION_FRUSTUM) { + p_property.usage = PROPERTY_USAGE_NOEDITOR; + } + } else if (p_property.name == "frustum_offset") { + if (mode != PROJECTION_FRUSTUM) { p_property.usage = PROPERTY_USAGE_NOEDITOR; } } @@ -177,8 +184,24 @@ void Camera::set_orthogonal(float p_size, float p_z_near, float p_z_far) { update_gizmo(); } +void Camera::set_frustum(float p_size, Vector2 p_offset, float p_z_near, float p_z_far) { + if (!force_change && size == p_size && frustum_offset == p_offset && p_z_near == near && p_z_far == far && mode == PROJECTION_FRUSTUM) + return; + + size = p_size; + frustum_offset = p_offset; + + near = p_z_near; + far = p_z_far; + mode = PROJECTION_FRUSTUM; + force_change = false; + + VisualServer::get_singleton()->camera_set_frustum(camera, size, frustum_offset, near, far); + update_gizmo(); +} + void Camera::set_projection(Camera::Projection p_mode) { - if (p_mode == PROJECTION_PERSPECTIVE || p_mode == PROJECTION_ORTHOGONAL) { + if (p_mode == PROJECTION_PERSPECTIVE || p_mode == PROJECTION_ORTHOGONAL || p_mode == PROJECTION_FRUSTUM) { mode = p_mode; _update_camera_mode(); _change_notify(); @@ -470,16 +493,19 @@ void Camera::_bind_methods() { ClassDB::bind_method(D_METHOD("project_position", "screen_point"), &Camera::project_position); ClassDB::bind_method(D_METHOD("set_perspective", "fov", "z_near", "z_far"), &Camera::set_perspective); ClassDB::bind_method(D_METHOD("set_orthogonal", "size", "z_near", "z_far"), &Camera::set_orthogonal); + ClassDB::bind_method(D_METHOD("set_frustum", "size", "offset", "z_near", "z_far"), &Camera::set_frustum); ClassDB::bind_method(D_METHOD("make_current"), &Camera::make_current); ClassDB::bind_method(D_METHOD("clear_current", "enable_next"), &Camera::clear_current, DEFVAL(true)); ClassDB::bind_method(D_METHOD("set_current"), &Camera::set_current); ClassDB::bind_method(D_METHOD("is_current"), &Camera::is_current); ClassDB::bind_method(D_METHOD("get_camera_transform"), &Camera::get_camera_transform); ClassDB::bind_method(D_METHOD("get_fov"), &Camera::get_fov); + ClassDB::bind_method(D_METHOD("get_frustum_offset"), &Camera::get_frustum_offset); ClassDB::bind_method(D_METHOD("get_size"), &Camera::get_size); ClassDB::bind_method(D_METHOD("get_zfar"), &Camera::get_zfar); ClassDB::bind_method(D_METHOD("get_znear"), &Camera::get_znear); ClassDB::bind_method(D_METHOD("set_fov"), &Camera::set_fov); + ClassDB::bind_method(D_METHOD("set_frustum_offset"), &Camera::set_frustum_offset); ClassDB::bind_method(D_METHOD("set_size"), &Camera::set_size); ClassDB::bind_method(D_METHOD("set_zfar"), &Camera::set_zfar); ClassDB::bind_method(D_METHOD("set_znear"), &Camera::set_znear); @@ -510,15 +536,17 @@ void Camera::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal"), "set_projection", "get_projection"); + 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::REAL, "fov", PROPERTY_HINT_RANGE, "1,179,0.1"), "set_fov", "get_fov"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "size", PROPERTY_HINT_RANGE, "0.1,16384,0.01"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frustum_offset"), "set_frustum_offset", "get_frustum_offset"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "near", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01,or_greater"), "set_znear", "get_znear"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "far", PROPERTY_HINT_EXP_RANGE, "0.1,8192,0.1,or_greater"), "set_zfar", "get_zfar"); BIND_ENUM_CONSTANT(PROJECTION_PERSPECTIVE); BIND_ENUM_CONSTANT(PROJECTION_ORTHOGONAL); + BIND_ENUM_CONSTANT(PROJECTION_FRUSTUM); BIND_ENUM_CONSTANT(KEEP_WIDTH); BIND_ENUM_CONSTANT(KEEP_HEIGHT); @@ -543,6 +571,10 @@ float Camera::get_znear() const { return near; } +Vector2 Camera::get_frustum_offset() const { + return frustum_offset; +} + float Camera::get_zfar() const { return far; @@ -570,6 +602,11 @@ void Camera::set_znear(float p_znear) { _update_camera_mode(); } +void Camera::set_frustum_offset(Vector2 p_offset) { + frustum_offset = p_offset; + _update_camera_mode(); +} + void Camera::set_zfar(float p_zfar) { far = p_zfar; _update_camera_mode(); @@ -648,6 +685,7 @@ Camera::Camera() { camera = VisualServer::get_singleton()->camera_create(); size = 1; fov = 0; + frustum_offset = Vector2(); near = 0; far = 0; current = false; diff --git a/scene/3d/camera.h b/scene/3d/camera.h index a531324a85..fe8cb84f0d 100644 --- a/scene/3d/camera.h +++ b/scene/3d/camera.h @@ -46,7 +46,8 @@ public: enum Projection { PROJECTION_PERSPECTIVE, - PROJECTION_ORTHOGONAL + PROJECTION_ORTHOGONAL, + PROJECTION_FRUSTUM }; enum KeepAspect { @@ -68,6 +69,7 @@ private: float fov; float size; + Vector2 frustum_offset; float near, far; float v_offset; float h_offset; @@ -110,6 +112,7 @@ public: void set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far); void set_orthogonal(float p_size, float p_z_near, float p_z_far); + void set_frustum(float p_size, Vector2 p_offset, float p_near, float p_far); void set_projection(Camera::Projection p_mode); void make_current(); @@ -123,12 +126,15 @@ public: float get_size() const; float get_zfar() const; float get_znear() const; + Vector2 get_frustum_offset() const; + Projection get_projection() const; void set_fov(float p_fov); void set_size(float p_size); void set_zfar(float p_zfar); void set_znear(float p_znear); + void set_frustum_offset(Vector2 p_offset); virtual Transform get_camera_transform() const; diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index 469a1e87db..d4e242dcb7 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -1394,6 +1394,7 @@ CPUParticles::CPUParticles() { redraw = false; multimesh = VisualServer::get_singleton()->multimesh_create(); + VisualServer::get_singleton()->multimesh_set_visible_instances(multimesh, 0); set_base(multimesh); set_emitting(true); diff --git a/scene/3d/path.cpp b/scene/3d/path.cpp index 190967d76c..84078911cb 100644 --- a/scene/3d/path.cpp +++ b/scene/3d/path.cpp @@ -173,7 +173,7 @@ void PathFollow::_update_transform() { float dot = t_prev.dot(t_cur); float angle = Math::acos(CLAMP(dot, -1, 1)); - if (likely(Math::abs(angle) > CMP_EPSILON)) { + if (likely(!Math::is_zero_approx(angle))) { if (rotation_mode == ROTATION_Y) { // assuming we're referring to global Y-axis. is this correct? axis.x = 0; @@ -184,7 +184,7 @@ void PathFollow::_update_transform() { // all components are allowed } - if (likely(axis.length() > CMP_EPSILON)) { + if (likely(!Math::is_zero_approx(axis.length()))) { t.rotate_basis(axis.normalized(), angle); } } @@ -193,7 +193,7 @@ void PathFollow::_update_transform() { float tilt_angle = c->interpolate_baked_tilt(o); Vector3 tilt_axis = t_cur; // not sure what tilt is supposed to do, is this correct?? - if (likely(Math::abs(tilt_angle) > CMP_EPSILON)) { + if (likely(!Math::is_zero_approx(Math::abs(tilt_angle)))) { if (rotation_mode == ROTATION_Y) { tilt_axis.x = 0; tilt_axis.z = 0; @@ -203,7 +203,7 @@ void PathFollow::_update_transform() { // all components are allowed } - if (likely(tilt_axis.length() > CMP_EPSILON)) { + if (likely(!Math::is_zero_approx(tilt_axis.length()))) { t.rotate_basis(tilt_axis.normalized(), tilt_angle); } } diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp index c7f7b14a8f..fde135c972 100644 --- a/scene/3d/vehicle_body.cpp +++ b/scene/3d/vehicle_body.cpp @@ -716,7 +716,7 @@ void VehicleBody::_update_friction(PhysicsDirectBodyState *s) { real_t rollingFriction = 0.f; if (wheelInfo.m_raycastInfo.m_isInContact) { - if (engine_force != 0.f) { + if (engine_force != 0.f && wheelInfo.engine_traction != false) { rollingFriction = -engine_force * s->get_step(); } else { real_t defaultRollingFrictionImpulse = 0.f; diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp index 1bbf1b7bc7..1aded826c0 100644 --- a/scene/3d/visual_instance.cpp +++ b/scene/3d/visual_instance.cpp @@ -123,6 +123,8 @@ void VisualInstance::_bind_methods() { ClassDB::bind_method(D_METHOD("_get_visual_instance_rid"), &VisualInstance::_get_visual_instance_rid); ClassDB::bind_method(D_METHOD("set_base", "base"), &VisualInstance::set_base); + ClassDB::bind_method(D_METHOD("get_base"), &VisualInstance::get_base); + ClassDB::bind_method(D_METHOD("get_instance"), &VisualInstance::get_instance); ClassDB::bind_method(D_METHOD("set_layer_mask", "mask"), &VisualInstance::set_layer_mask); ClassDB::bind_method(D_METHOD("get_layer_mask"), &VisualInstance::get_layer_mask); ClassDB::bind_method(D_METHOD("set_layer_mask_bit", "layer", "enabled"), &VisualInstance::set_layer_mask_bit); @@ -136,6 +138,12 @@ void VisualInstance::_bind_methods() { void VisualInstance::set_base(const RID &p_base) { VisualServer::get_singleton()->instance_set_base(instance, p_base); + base = p_base; +} + +RID VisualInstance::get_base() const { + + return base; } VisualInstance::VisualInstance() { diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h index 3b6fccf65f..f5b7479bb1 100644 --- a/scene/3d/visual_instance.h +++ b/scene/3d/visual_instance.h @@ -43,6 +43,7 @@ class VisualInstance : public Spatial { GDCLASS(VisualInstance, Spatial); OBJ_CATEGORY("3D Visual Nodes"); + RID base; RID instance; uint32_t layers; @@ -69,6 +70,7 @@ public: virtual AABB get_transformed_aabb() const; // helper void set_base(const RID &p_base); + RID get_base() const; void set_layer_mask(uint32_t p_mask); uint32_t get_layer_mask() const; diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp index 750ed97ae6..75b419ca58 100644 --- a/scene/3d/voxel_light_baker.cpp +++ b/scene/3d/voxel_light_baker.cpp @@ -835,7 +835,7 @@ void VoxelLightBaker::plot_light_directional(const Vector3 &p_direction, const C for (int i = 0; i < 3; i++) { - if (ABS(light_axis[i]) < CMP_EPSILON) + if (Math::is_zero_approx(light_axis[i])) continue; clip[clip_planes].normal[i] = 1.0; @@ -978,7 +978,7 @@ void VoxelLightBaker::plot_light_omni(const Vector3 &p_pos, const Color &p_color for (int c = 0; c < 3; c++) { - if (ABS(light_axis[c]) < CMP_EPSILON) + if (Math::is_zero_approx(light_axis[c])) continue; clip[clip_planes].normal[c] = 1.0; @@ -1113,7 +1113,7 @@ void VoxelLightBaker::plot_light_spot(const Vector3 &p_pos, const Vector3 &p_axi for (int c = 0; c < 3; c++) { - if (ABS(light_axis[c]) < CMP_EPSILON) + if (Math::is_zero_approx(light_axis[c])) continue; clip[clip_planes].normal[c] = 1.0; diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp index 47278b8fc1..144e58d8b9 100644 --- a/scene/audio/audio_stream_player.cpp +++ b/scene/audio/audio_stream_player.cpp @@ -32,33 +32,10 @@ #include "core/engine.h" -void AudioStreamPlayer::_mix_internal(bool p_fadeout) { - - int bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus); - - //get data - AudioFrame *buffer = mix_buffer.ptrw(); - int buffer_size = mix_buffer.size(); - - if (p_fadeout) { - // Short fadeout ramp - buffer_size = MIN(buffer_size, 128); - } - - stream_playback->mix(buffer, pitch_scale, buffer_size); - - //multiply volume interpolating to avoid clicks if this changes - float target_volume = p_fadeout ? -80.0 : volume_db; - float vol = Math::db2linear(mix_volume_db); - float vol_inc = (Math::db2linear(target_volume) - vol) / float(buffer_size); - for (int i = 0; i < buffer_size; i++) { - buffer[i] *= vol; - vol += vol_inc; - } +void AudioStreamPlayer::_mix_to_bus(const AudioFrame *p_frames,int p_amount) { - //set volume for next mix - mix_volume_db = target_volume; + int bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus); AudioFrame *targets[4] = { NULL, NULL, NULL, NULL }; @@ -83,42 +60,84 @@ void AudioStreamPlayer::_mix_internal(bool p_fadeout) { for (int c = 0; c < 4; c++) { if (!targets[c]) break; - for (int i = 0; i < buffer_size; i++) { - targets[c][i] += buffer[i]; + for (int i = 0; i < p_amount; i++) { + targets[c][i] += p_frames[i]; } } } + +void AudioStreamPlayer::_mix_internal(bool p_fadeout) { + + + //get data + AudioFrame *buffer = mix_buffer.ptrw(); + int buffer_size = mix_buffer.size(); + + if (p_fadeout) { + // Short fadeout ramp + buffer_size = MIN(buffer_size, 128); + } + + stream_playback->mix(buffer, pitch_scale, buffer_size); + + //multiply volume interpolating to avoid clicks if this changes + float target_volume = p_fadeout ? -80.0 : volume_db; + float vol = Math::db2linear(mix_volume_db); + float vol_inc = (Math::db2linear(target_volume) - vol) / float(buffer_size); + + for (int i = 0; i < buffer_size; i++) { + buffer[i] *= vol; + vol += vol_inc; + } + + //set volume for next mix + mix_volume_db = target_volume; + + _mix_to_bus(buffer,buffer_size); + +} + void AudioStreamPlayer::_mix_audio() { + if (use_fadeout) { + _mix_to_bus(fadeout_buffer.ptr(),fadeout_buffer.size()); + use_fadeout=false; + } + if (!stream_playback.is_valid() || !active || - (stream_paused && !stream_fade)) { + (stream_paused && !stream_paused_fade)) { return; } - if (stream_fade) { - _mix_internal(true); - stream_fade = false; - - if (stream_stop) { - stream_playback->stop(); - active = false; - set_process_internal(false); + if (stream_paused) { + if (stream_paused_fade) { + _mix_internal(true); + stream_paused_fade = false; } return; } - if (setseek >= 0.0) { + if (setstop) { + _mix_internal(true); + stream_playback->stop(); + setstop=false; + } + + if (setseek >= 0.0 && !stop_has_priority) { if (stream_playback->is_playing()) { //fade out to avoid pops _mix_internal(true); } + stream_playback->start(setseek); setseek = -1.0; //reset seek mix_volume_db = volume_db; //reset ramp } + stop_has_priority = false; + _mix_internal(false); } @@ -135,7 +154,7 @@ void AudioStreamPlayer::_notification(int p_what) { if (p_what == NOTIFICATION_INTERNAL_PROCESS) { if (!active || (setseek < 0 && !stream_playback->is_playing())) { - active = false; + active = false; set_process_internal(false); emit_signal("finished"); } @@ -162,6 +181,28 @@ void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) { AudioServer::get_singleton()->lock(); + if (active && stream_playback.is_valid() && !stream_paused) { + //changing streams out of the blue is not a great idea, but at least + //lets try to somehow avoid a click + + AudioFrame *buffer = fadeout_buffer.ptrw(); + int buffer_size = fadeout_buffer.size(); + + stream_playback->mix(buffer, pitch_scale, buffer_size); + + //multiply volume interpolating to avoid clicks if this changes + float target_volume = -80.0; + float vol = Math::db2linear(mix_volume_db); + float vol_inc = (Math::db2linear(target_volume) - vol) / float(buffer_size); + + for (int i = 0; i < buffer_size; i++) { + buffer[i] *= vol; + vol += vol_inc; + } + + use_fadeout=true; + } + mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size()); if (stream_playback.is_valid()) { @@ -169,6 +210,7 @@ void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) { stream.unref(); active = false; setseek = -1; + setstop = false; } if (p_stream.is_valid()) { @@ -209,8 +251,8 @@ void AudioStreamPlayer::play(float p_from_pos) { if (stream_playback.is_valid()) { //mix_volume_db = volume_db; do not reset volume ramp here, can cause clicks - stream_stop = false; setseek = p_from_pos; + stop_has_priority=false; active = true; set_process_internal(true); } @@ -225,16 +267,16 @@ void AudioStreamPlayer::seek(float p_seconds) { void AudioStreamPlayer::stop() { - if (stream_playback.is_valid()) { - stream_stop = true; - stream_fade = true; + if (stream_playback.is_valid() && active) { + setstop=true; + stop_has_priority=true; } } bool AudioStreamPlayer::is_playing() const { if (stream_playback.is_valid()) { - return active; //&& stream_playback->is_playing(); + return active && !setstop; //&& stream_playback->is_playing(); } return false; @@ -301,7 +343,7 @@ void AudioStreamPlayer::set_stream_paused(bool p_pause) { if (p_pause != stream_paused) { stream_paused = p_pause; - stream_fade = p_pause ? true : false; + stream_paused_fade = p_pause ? true : false; } } @@ -315,7 +357,7 @@ void AudioStreamPlayer::_validate_property(PropertyInfo &property) const { if (property.name == "bus") { String options; - for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { + for (int i = 0; i <AudioServer::get_singleton()->get_bus_count(); i++) { if (i > 0) options += ","; String name = AudioServer::get_singleton()->get_bus_name(i); @@ -397,9 +439,11 @@ AudioStreamPlayer::AudioStreamPlayer() { setseek = -1; active = false; stream_paused = false; - stream_fade = false; - stream_stop = false; + stream_paused_fade = false; mix_target = MIX_TARGET_STEREO; + fadeout_buffer.resize(512); + setstop=false; + use_fadeout=false; AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); } diff --git a/scene/audio/audio_stream_player.h b/scene/audio/audio_stream_player.h index 590bef95b0..0b782b67e7 100644 --- a/scene/audio/audio_stream_player.h +++ b/scene/audio/audio_stream_player.h @@ -49,17 +49,20 @@ private: Ref<AudioStreamPlayback> stream_playback; Ref<AudioStream> stream; Vector<AudioFrame> mix_buffer; + Vector<AudioFrame> fadeout_buffer; + bool use_fadeout; volatile float setseek; volatile bool active; + volatile bool setstop; + volatile bool stop_has_priority; float mix_volume_db; float pitch_scale; float volume_db; bool autoplay; bool stream_paused; - bool stream_fade; - bool stream_stop; + bool stream_paused_fade; StringName bus; MixTarget mix_target; @@ -72,6 +75,7 @@ private: bool _is_active() const; void _bus_layout_changed(); + void _mix_to_bus(const AudioFrame *p_frames, int p_amount); protected: void _validate_property(PropertyInfo &property) const; diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 7455c766fe..accf8aa7c2 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -831,6 +831,8 @@ void ColorPickerButton::_update_picker() { add_child(popup); picker->connect("color_changed", this, "_color_changed"); popup->connect("modal_closed", this, "_modal_closed"); + popup->connect("about_to_show", this, "set_pressed", varray(true)); + popup->connect("popup_hide", this, "set_pressed", varray(false)); picker->set_pick_color(color); picker->set_edit_alpha(edit_alpha); } @@ -861,4 +863,6 @@ ColorPickerButton::ColorPickerButton() { picker = NULL; popup = NULL; edit_alpha = true; + + set_toggle_mode(true); } diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 30ad81bb2e..dabff08fea 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -1053,7 +1053,7 @@ void GraphEdit::set_connection_activity(const StringName &p_from, int p_from_por if (E->get().from == p_from && E->get().from_port == p_from_port && E->get().to == p_to && E->get().to_port == p_to_port) { - if (ABS(E->get().activity - p_activity) < CMP_EPSILON) { + if (Math::is_equal_approx(E->get().activity, p_activity)) { //update only if changed top_layer->update(); connections_layer->update(); diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 73367aadea..5f21d73ab2 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -126,15 +126,19 @@ MenuButton::MenuButton() { switch_on_hover = false; set_flat(true); + set_toggle_mode(true); set_disable_shortcuts(false); set_enabled_focus_mode(FOCUS_NONE); + set_process_unhandled_key_input(true); + set_action_mode(ACTION_MODE_BUTTON_PRESS); + popup = memnew(PopupMenu); popup->hide(); add_child(popup); popup->set_as_toplevel(true); popup->set_pass_on_modal_close_click(false); - set_process_unhandled_key_input(true); - set_action_mode(ACTION_MODE_BUTTON_PRESS); + popup->connect("about_to_show", this, "set_pressed", varray(true)); // For when switching from another MenuButton. + popup->connect("popup_hide", this, "set_pressed", varray(false)); } MenuButton::~MenuButton() { diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 20d780591d..8c75393d01 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -345,6 +345,7 @@ void OptionButton::_bind_methods() { OptionButton::OptionButton() { current = -1; + set_toggle_mode(true); set_text_align(ALIGN_LEFT); set_action_mode(ACTION_MODE_BUTTON_PRESS); @@ -355,6 +356,7 @@ OptionButton::OptionButton() { popup->set_pass_on_modal_close_click(false); popup->connect("id_pressed", this, "_selected"); popup->connect("id_focused", this, "_focused"); + popup->connect("popup_hide", this, "set_pressed", varray(false)); } OptionButton::~OptionButton() { diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 0155ad793f..101eb2ac88 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -753,6 +753,8 @@ void RichTextLabel::_scroll_changed(double) { else scroll_following = false; + scroll_updated = true; + update(); } @@ -778,7 +780,6 @@ void RichTextLabel::_update_scroll() { main->first_invalid_line = 0; //invalidate ALL _validate_line_caches(main); } - scroll_updated = true; } void RichTextLabel::_notification(int p_what) { @@ -901,13 +902,21 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const { - if (selection.click) + if (!underline_meta || selection.click) return CURSOR_ARROW; if (main->first_invalid_line < main->lines.size()) return CURSOR_ARROW; //invalid - return get_default_cursor_shape(); + int line = 0; + Item *item = NULL; + + ((RichTextLabel *)(this))->_find_click(main, p_pos, &item, &line); + + if (item && ((RichTextLabel *)(this))->_find_meta(item, NULL)) + return CURSOR_POINTING_HAND; + + return CURSOR_ARROW; } void RichTextLabel::_gui_input(Ref<InputEvent> p_event) { diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 3d36408ff3..9c6fa703fa 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -965,6 +965,7 @@ void TextEdit::_notification(int p_what) { // draw info icons if (draw_info_gutter && text.has_info_icon(line)) { + int vertical_gap = (get_row_height() * 40) / 100; int horizontal_gap = (cache.info_gutter_width * 30) / 100; int gutter_left = cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width; @@ -979,8 +980,8 @@ void TextEdit::_notification(int p_what) { } Size2i icon_pos; - int xofs = horizontal_gap - (info_icon->get_width()) / 2; - int yofs = (get_row_height() - info_icon->get_height()) / 2; + int xofs = horizontal_gap - (info_icon->get_width() / 4); + int yofs = vertical_gap - (info_icon->get_height() / 4); icon_pos.x = gutter_left + xofs + ofs_x; icon_pos.y = ofs_y + yofs; @@ -4427,8 +4428,8 @@ void TextEdit::_update_caches() { #endif cache.row_height = cache.font->get_height() + cache.line_spacing; cache.tab_icon = get_icon("tab"); - cache.folded_icon = get_icon("GuiTreeArrowRight", "EditorIcons"); - cache.can_fold_icon = get_icon("GuiTreeArrowDown", "EditorIcons"); + cache.folded_icon = get_icon("folded"); + cache.can_fold_icon = get_icon("fold"); cache.folded_eol_icon = get_icon("GuiEllipsis", "EditorIcons"); text.set_font(cache.font); @@ -5414,6 +5415,9 @@ void TextEdit::undo() { TextOperation op = undo_stack_pos->get(); _do_text_op(op, true); + if (op.from_line != op.to_line || op.to_column != op.from_column + 1) + select(op.from_line, op.from_column, op.to_line, op.to_column); + current_op.version = op.prev_version; if (undo_stack_pos->get().chain_backward) { while (true) { @@ -5540,6 +5544,7 @@ int TextEdit::get_indent_size() { void TextEdit::set_draw_tabs(bool p_draw) { draw_tabs = p_draw; + update(); } bool TextEdit::is_drawing_tabs() const { @@ -6258,8 +6263,12 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_show_line_numbers", "enable"), &TextEdit::set_show_line_numbers); ClassDB::bind_method(D_METHOD("is_show_line_numbers_enabled"), &TextEdit::is_show_line_numbers_enabled); + ClassDB::bind_method(D_METHOD("set_draw_tabs"), &TextEdit::set_draw_tabs); + ClassDB::bind_method(D_METHOD("is_drawing_tabs"), &TextEdit::is_drawing_tabs); ClassDB::bind_method(D_METHOD("set_breakpoint_gutter_enabled", "enable"), &TextEdit::set_breakpoint_gutter_enabled); ClassDB::bind_method(D_METHOD("is_breakpoint_gutter_enabled"), &TextEdit::is_breakpoint_gutter_enabled); + ClassDB::bind_method(D_METHOD("set_draw_fold_gutter"), &TextEdit::set_draw_fold_gutter); + ClassDB::bind_method(D_METHOD("is_drawing_fold_gutter"), &TextEdit::is_drawing_fold_gutter); ClassDB::bind_method(D_METHOD("set_hiding_enabled", "enable"), &TextEdit::set_hiding_enabled); ClassDB::bind_method(D_METHOD("is_hiding_enabled"), &TextEdit::is_hiding_enabled); @@ -6306,7 +6315,9 @@ void TextEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_current_line"), "set_highlight_current_line", "is_highlight_current_line_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "syntax_highlighting"), "set_syntax_coloring", "is_syntax_coloring_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_line_numbers"), "set_show_line_numbers", "is_show_line_numbers_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_tabs"), "set_draw_tabs", "is_drawing_tabs"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "breakpoint_gutter"), "set_breakpoint_gutter_enabled", "is_breakpoint_gutter_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fold_gutter"), "set_draw_fold_gutter", "is_drawing_fold_gutter"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), "set_highlight_all_occurrences", "is_highlight_all_occurrences_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled"); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 81c38cec89..125e0a2882 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1160,7 +1160,7 @@ void SceneTree::_update_root_rect() { WARN_PRINT("Font oversampling only works with the resize modes 'Keep Width', 'Keep Height', and 'Expand'."); } - if (stretch_aspect == STRETCH_ASPECT_IGNORE || ABS(viewport_aspect - video_mode_aspect) < CMP_EPSILON) { + if (stretch_aspect == STRETCH_ASPECT_IGNORE || Math::is_equal_approx(viewport_aspect, video_mode_aspect)) { //same aspect or ignore aspect viewport_size = desired_res; screen_size = video_mode; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 52f63ddc1d..ae2c571201 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2482,11 +2482,7 @@ void Viewport::_gui_hid_control(Control *p_control) { if (gui.mouse_over == p_control) gui.mouse_over = NULL; if (gui.tooltip == p_control) - gui.tooltip = NULL; - if (gui.tooltip == p_control) { - gui.tooltip = NULL; _gui_cancel_tooltip(); - } } void Viewport::_gui_remove_control(Control *p_control) { diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 9face3e476..47f5b152f0 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -782,7 +782,11 @@ void unregister_scene_types() { ResourceLoader::remove_resource_format_loader(resource_loader_bmfont); resource_loader_bmfont.unref(); + //SpatialMaterial is not initialised when 3D is disabled, so it shouldn't be cleaned up either +#ifndef _3D_DISABLED SpatialMaterial::finish_shaders(); +#endif // _3D_DISABLED + ParticlesMaterial::finish_shaders(); CanvasItemMaterial::finish_shaders(); SceneStringNames::free(); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index e58ec9d71e..9c79b2ba3b 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -1477,7 +1477,7 @@ int Animation::_find(const Vector<K> &p_keys, float p_time) const { middle = (low + high) / 2; - if (Math::abs(p_time - keys[middle].time) < CMP_EPSILON) { //match + if (Math::is_equal_approx(p_time, keys[middle].time)) { //match return middle; } else if (p_time < keys[middle].time) high = middle - 1; //search low end of array @@ -1680,10 +1680,10 @@ T Animation::_interpolate(const Vector<TKey<T> > &p_keys, float p_time, Interpol float delta = p_keys[next].time - p_keys[idx].time; float from = p_time - p_keys[idx].time; - if (Math::absf(delta) > CMP_EPSILON) - c = from / delta; - else + if (Math::is_zero_approx(delta)) c = 0; + else + c = from / delta; } else { @@ -1691,10 +1691,10 @@ T Animation::_interpolate(const Vector<TKey<T> > &p_keys, float p_time, Interpol float delta = (length - p_keys[idx].time) + p_keys[next].time; float from = p_time - p_keys[idx].time; - if (Math::absf(delta) > CMP_EPSILON) - c = from / delta; - else + if (Math::is_zero_approx(delta)) c = 0; + else + c = from / delta; } } else { @@ -1707,10 +1707,10 @@ T Animation::_interpolate(const Vector<TKey<T> > &p_keys, float p_time, Interpol float delta = endtime + p_keys[next].time; float from = endtime + p_time; - if (Math::absf(delta) > CMP_EPSILON) - c = from / delta; - else + if (Math::is_zero_approx(delta)) c = 0; + else + c = from / delta; } } else { // no loop @@ -1723,10 +1723,10 @@ T Animation::_interpolate(const Vector<TKey<T> > &p_keys, float p_time, Interpol float delta = p_keys[next].time - p_keys[idx].time; float from = p_time - p_keys[idx].time; - if (Math::absf(delta) > CMP_EPSILON) - c = from / delta; - else + if (Math::is_zero_approx(delta)) c = 0; + else + c = from / delta; } else { @@ -2774,9 +2774,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons const Vector3 &v1 = t1.value.loc; const Vector3 &v2 = t2.value.loc; - if (v0.distance_to(v2) < CMP_EPSILON) { + if (Math::is_zero_approx(v0.distance_to(v2))) { //0 and 2 are close, let's see if 1 is close - if (v0.distance_to(v1) > CMP_EPSILON) { + if (!Math::is_zero_approx(v0.distance_to(v1))) { //not close, not optimizable return false; } @@ -2813,9 +2813,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons //localize both to rotation from q0 - if ((q0 - q2).length() < CMP_EPSILON) { + if (Math::is_zero_approx((q0 - q2).length())) { - if ((q0 - q1).length() > CMP_EPSILON) + if (!Math::is_zero_approx((q0 - q1).length())) return false; } else { @@ -2863,9 +2863,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons const Vector3 &v1 = t1.value.scale; const Vector3 &v2 = t2.value.scale; - if (v0.distance_to(v2) < CMP_EPSILON) { + if (Math::is_zero_approx(v0.distance_to(v2))) { //0 and 2 are close, let's see if 1 is close - if (v0.distance_to(v1) > CMP_EPSILON) { + if (!Math::is_zero_approx(v0.distance_to(v1))) { //not close, not optimizable return false; } diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index c7a815d8a4..5ae57fdb52 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -423,6 +423,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("completion", "TextEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3, 0, 0, 0, 0)); theme->set_icon("tab", "TextEdit", make_icon(tab_png)); + theme->set_icon("folded", "TextEdit", make_icon(arrow_right_png)); + theme->set_icon("fold", "TextEdit", make_icon(arrow_down_png)); theme->set_font("font", "TextEdit", default_font); @@ -795,7 +797,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font("bold_italics_font", "RichTextLabel", default_font); theme->set_font("mono_font", "RichTextLabel", default_font); - theme->set_color("default_color", "RichTextLabel", control_font_color); + theme->set_color("default_color", "RichTextLabel", Color(1, 1, 1)); theme->set_color("font_color_selected", "RichTextLabel", font_color_selection); theme->set_color("selection_color", "RichTextLabel", Color(0.1, 0.1, 1, 0.8)); diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp index c9c9855945..be0b9f9ac3 100644 --- a/scene/resources/multimesh.cpp +++ b/scene/resources/multimesh.cpp @@ -288,7 +288,7 @@ void MultiMesh::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_format", PROPERTY_HINT_ENUM, "2D,3D"), "set_transform_format", "get_transform_format"); ADD_PROPERTY(PropertyInfo(Variant::INT, "custom_data_format", PROPERTY_HINT_ENUM, "None,Byte,Float"), "set_custom_data_format", "get_custom_data_format"); ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"), "set_instance_count", "get_instance_count"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_instance_count", PROPERTY_HINT_RANGE, "-1,16384,1,or_greater"), "set_visible_instance_count_count", "get_visible_instance_count_count"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_instance_count", PROPERTY_HINT_RANGE, "-1,16384,1,or_greater"), "set_visible_instance_count", "get_visible_instance_count"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh"); ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_transform_array", "_get_transform_array"); ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "color_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_color_array", "_get_color_array"); diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 626ed9f5b4..2c6f30f429 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -535,7 +535,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map float a = value; float b = original; - if (Math::abs(a - b) < CMP_EPSILON) + if (Math::is_equal_approx(a, b)) continue; } else if (bool(Variant::evaluate(Variant::OP_EQUAL, value, original))) { diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 4229147ba2..b8f21948c3 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -240,6 +240,9 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po if (!g->nodes.has(p_from_node)) return false; + if (p_from_node == p_to_node) + return false; + if (p_from_port < 0 || p_from_port >= g->nodes[p_from_node].node->get_output_port_count()) return false; |