diff options
Diffstat (limited to 'scene')
410 files changed, 5612 insertions, 3863 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 8a5910c10e..3d7ff5f1fd 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -276,9 +276,9 @@ void SpriteFrames::_set_animations(const Array &p_animations) { anim.speed = d["speed"]; anim.loop = d["loop"]; Array frames = d["frames"]; - for (int i = 0; i < frames.size(); i++) { + for (int j = 0; j < frames.size(); j++) { - RES res = frames[i]; + RES res = frames[j]; anim.frames.push_back(res); } @@ -312,12 +312,12 @@ void SpriteFrames::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_frames"), &SpriteFrames::_set_frames); ClassDB::bind_method(D_METHOD("_get_frames"), &SpriteFrames::_get_frames); - ADD_PROPERTYNZ(PropertyInfo(Variant::ARRAY, "frames", PROPERTY_HINT_NONE, "", 0), "_set_frames", "_get_frames"); //compatibility + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "frames", PROPERTY_HINT_NONE, "", 0), "_set_frames", "_get_frames"); //compatibility ClassDB::bind_method(D_METHOD("_set_animations"), &SpriteFrames::_set_animations); ClassDB::bind_method(D_METHOD("_get_animations"), &SpriteFrames::_get_animations); - ADD_PROPERTYNZ(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_animations", "_get_animations"); //compatibility + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_animations", "_get_animations"); //compatibility } SpriteFrames::SpriteFrames() { @@ -395,14 +395,14 @@ void AnimatedSprite::_notification(int p_what) { int fc = frames->get_frame_count(animation); if (frame >= fc - 1) { if (frames->get_animation_loop(animation)) { - emit_signal(SceneStringNames::get_singleton()->animation_finished); frame = 0; + emit_signal(SceneStringNames::get_singleton()->animation_finished); } else { + frame = fc - 1; if (!is_over) { - emit_signal(SceneStringNames::get_singleton()->animation_finished); is_over = true; + emit_signal(SceneStringNames::get_singleton()->animation_finished); } - frame = fc - 1; } } else { frame++; @@ -693,15 +693,15 @@ void AnimatedSprite::_bind_methods() { ADD_SIGNAL(MethodInfo("frame_changed")); ADD_SIGNAL(MethodInfo("animation_finished")); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames"); + 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_PROPERTYNZ(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame"); - ADD_PROPERTYNO(PropertyInfo(Variant::REAL, "speed_scale"), "set_speed_scale", "get_speed_scale"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing"); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered"); - ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "flip_v"), "set_flip_v", "is_flipped_v"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale"), "set_speed_scale", "get_speed_scale"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_v"), "set_flip_v", "is_flipped_v"); } AnimatedSprite::AnimatedSprite() { diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h index 7270ee4d0e..8753f88799 100644 --- a/scene/2d/animated_sprite.h +++ b/scene/2d/animated_sprite.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index c375374dce..2a225e5797 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -158,7 +158,9 @@ void Area2D::_body_inout(int p_status, const RID &p_body, int p_instance, int p_ Map<ObjectID, BodyState>::Element *E = body_map.find(objid); - ERR_FAIL_COND(!body_in && !E); + if (!body_in && !E) { + return; //does not exist because it was likely removed from the tree + } locked = true; @@ -399,7 +401,7 @@ void Area2D::set_monitoring(bool p_enable) { if (p_enable == monitoring) return; if (locked) { - ERR_EXPLAIN("Function blocked during in/out signal. Use call_deferred(\"set_monitoring\",true/false)"); + ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitoring\",true/false)"); } ERR_FAIL_COND(locked); @@ -424,10 +426,10 @@ bool Area2D::is_monitoring() const { void Area2D::set_monitorable(bool p_enable) { - if (locked) { - ERR_EXPLAIN("This function can't be used during the in/out signal."); + if (locked || (is_inside_tree() && Physics2DServer::get_singleton()->is_flushing_queries())) { + ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitorable\",true/false)"); + ERR_FAIL(); } - ERR_FAIL_COND(locked); if (p_enable == monitorable) return; @@ -664,19 +666,19 @@ void Area2D::_bind_methods() { ADD_SIGNAL(MethodInfo("area_entered", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"))); ADD_SIGNAL(MethodInfo("area_exited", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"))); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine"), "set_space_override_mode", "get_space_override_mode"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "gravity_point"), "set_gravity_is_point", "is_gravity_a_point"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine"), "set_space_override_mode", "get_space_override_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gravity_point"), "set_gravity_is_point", "is_gravity_a_point"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_vec"), "set_gravity_vector", "get_gravity_vector"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.001"), "set_gravity", "get_gravity"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_linear_damp", "get_linear_damp"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_angular_damp", "get_angular_damp"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,128,1"), "set_priority", "get_priority"); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring"); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,128,1"), "set_priority", "get_priority"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable"); ADD_GROUP("Collision", "collision_"); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer"); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask"); ADD_GROUP("Audio Bus", "audio_bus_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_bus_override"), "set_audio_bus_override", "is_overriding_audio_bus"); diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index cd60b6c1e1..2d1527810e 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 9de72a4fcd..7b28ad2c12 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -37,7 +37,7 @@ void AudioStreamPlayer2D::_mix_audio() { if (!stream_playback.is_valid() || !active || - (stream_paused && !stream_paused_fade_out)) { + (stream_paused && !stream_fade_out)) { return; } @@ -50,7 +50,7 @@ void AudioStreamPlayer2D::_mix_audio() { AudioFrame *buffer = mix_buffer.ptrw(); int buffer_size = mix_buffer.size(); - if (stream_paused_fade_out) { + if (stream_fade_out) { // Short fadeout ramp buffer_size = MIN(buffer_size, 128); } @@ -84,14 +84,17 @@ void AudioStreamPlayer2D::_mix_audio() { } //mix! - 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 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 vol_inc = (target_volume - vol_prev) / float(buffer_size); - AudioFrame vol = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : current.vol; + AudioFrame vol = stream_fade_in ? AudioFrame(0.f, 0.f) : current.vol; int cc = AudioServer::get_singleton()->get_channel_count(); if (cc == 1) { + if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, 0)) + continue; //may have been removed + AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 0); for (int j = 0; j < buffer_size; j++) { @@ -102,11 +105,20 @@ void AudioStreamPlayer2D::_mix_audio() { } else { AudioFrame *targets[4]; + bool valid = true; for (int k = 0; k < cc; k++) { + if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, k)) { + valid = false; //may have been removed + break; + } + targets[k] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k); } + if (!valid) + continue; + for (int j = 0; j < buffer_size; j++) { AudioFrame frame = buffer[j] * vol; @@ -127,9 +139,15 @@ void AudioStreamPlayer2D::_mix_audio() { active = false; } + if (stream_stop) { + active = false; + set_physics_process_internal(false); + setplay = -1; + } + output_ready = false; - stream_paused_fade_in = false; - stream_paused_fade_out = false; + stream_fade_in = false; + stream_fade_out = false; } void AudioStreamPlayer2D::_notification(int p_what) { @@ -311,6 +329,8 @@ void AudioStreamPlayer2D::play(float p_from_pos) { } if (stream_playback.is_valid()) { + stream_stop = false; + active = true; setplay = p_from_pos; output_ready = false; set_physics_process_internal(true); @@ -327,9 +347,8 @@ void AudioStreamPlayer2D::seek(float p_seconds) { void AudioStreamPlayer2D::stop() { if (stream_playback.is_valid()) { - active = false; - set_physics_process_internal(false); - setplay = -1; + stream_stop = true; + stream_fade_out = true; } } @@ -444,8 +463,8 @@ void AudioStreamPlayer2D::set_stream_paused(bool p_pause) { if (p_pause != stream_paused) { stream_paused = p_pause; - stream_paused_fade_in = p_pause ? false : true; - stream_paused_fade_out = p_pause ? true : false; + stream_fade_in = p_pause ? false : true; + stream_fade_out = p_pause ? true : false; } } @@ -524,8 +543,9 @@ AudioStreamPlayer2D::AudioStreamPlayer2D() { output_ready = false; area_mask = 1; stream_paused = false; - stream_paused_fade_in = false; - stream_paused_fade_out = false; + stream_fade_in = false; + stream_fade_out = false; + stream_stop = 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 e68e6eeca5..caf5c6ee49 100644 --- a/scene/2d/audio_stream_player_2d.h +++ b/scene/2d/audio_stream_player_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -73,8 +73,9 @@ private: float pitch_scale; bool autoplay; bool stream_paused; - bool stream_paused_fade_in; - bool stream_paused_fade_out; + bool stream_fade_in; + bool stream_fade_out; + bool stream_stop; StringName bus; void _mix_audio(); diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp index e06c30ec6b..4a4bc4410f 100644 --- a/scene/2d/back_buffer_copy.cpp +++ b/scene/2d/back_buffer_copy.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/back_buffer_copy.h b/scene/2d/back_buffer_copy.h index b1ee12544b..52b0c016cc 100644 --- a/scene/2d/back_buffer_copy.h +++ b/scene/2d/back_buffer_copy.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 788a39d05d..11846654c5 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -61,6 +61,20 @@ void Camera2D::_update_scroll() { }; } +void Camera2D::_update_process_mode() { + + if (Engine::get_singleton()->is_editor_hint()) { + set_process_internal(false); + set_physics_process_internal(false); + } else if (process_mode == CAMERA2D_PROCESS_IDLE) { + set_process_internal(true); + set_physics_process_internal(false); + } else { + set_process_internal(false); + set_physics_process_internal(true); + } +} + void Camera2D::set_zoom(const Vector2 &p_zoom) { zoom = p_zoom; @@ -143,7 +157,7 @@ Transform2D Camera2D::get_camera_transform() { if (smoothing_enabled && !Engine::get_singleton()->is_editor_hint()) { - float c = smoothing * get_process_delta_time(); + float c = smoothing * (process_mode == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time()); smoothed_camera_pos = ((camera_pos - smoothed_camera_pos) * c) + smoothed_camera_pos; ret_camera_pos = smoothed_camera_pos; //camera_pos=camera_pos*(1.0-smoothing)+new_camera_pos*smoothing; @@ -217,14 +231,15 @@ void Camera2D::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_INTERNAL_PROCESS: { + case NOTIFICATION_INTERNAL_PROCESS: + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { _update_scroll(); } break; case NOTIFICATION_TRANSFORM_CHANGED: { - if (!is_processing_internal()) + if (!is_processing_internal() && !is_physics_processing_internal()) _update_scroll(); } break; @@ -245,10 +260,7 @@ void Camera2D::_notification(int p_what) { add_to_group(group_name); add_to_group(canvas_group_name); - if (Engine::get_singleton()->is_editor_hint()) { - set_process_internal(false); - } - + _update_process_mode(); _update_scroll(); first = true; @@ -379,6 +391,20 @@ bool Camera2D::is_rotating() const { return rotating; } +void Camera2D::set_process_mode(Camera2DProcessMode p_mode) { + + if (process_mode == p_mode) + return; + + process_mode = p_mode; + _update_process_mode(); +} + +Camera2D::Camera2DProcessMode Camera2D::get_process_mode() const { + + return process_mode; +} + void Camera2D::_make_current(Object *p_which) { if (p_which == this) { @@ -410,6 +436,7 @@ void Camera2D::make_current() { } else { get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_make_current", this); } + _update_scroll(); } void Camera2D::clear_current() { @@ -656,6 +683,9 @@ void Camera2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_scroll"), &Camera2D::_update_scroll); + ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Camera2D::set_process_mode); + ClassDB::bind_method(D_METHOD("get_process_mode"), &Camera2D::get_process_mode); + ClassDB::bind_method(D_METHOD("_set_current", "current"), &Camera2D::_set_current); ClassDB::bind_method(D_METHOD("is_current"), &Camera2D::is_current); @@ -710,12 +740,13 @@ void Camera2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_margin_drawing_enabled", "margin_drawing_enabled"), &Camera2D::set_margin_drawing_enabled); ClassDB::bind_method(D_METHOD("is_margin_drawing_enabled"), &Camera2D::is_margin_drawing_enabled); - ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_mode", PROPERTY_HINT_ENUM, "Fixed TopLeft,Drag Center"), "set_anchor_mode", "get_anchor_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotating"), "set_rotating", "is_rotating"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "_set_current", "is_current"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "zoom"), "set_zoom", "get_zoom"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", 0), "set_custom_viewport", "get_custom_viewport"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode"); ADD_GROUP("Limit", "limit_"); ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_left"), "set_limit", "get_limit", MARGIN_LEFT); @@ -749,6 +780,8 @@ void Camera2D::_bind_methods() { BIND_ENUM_CONSTANT(ANCHOR_MODE_FIXED_TOP_LEFT); BIND_ENUM_CONSTANT(ANCHOR_MODE_DRAG_CENTER); + BIND_ENUM_CONSTANT(CAMERA2D_PROCESS_PHYSICS); + BIND_ENUM_CONSTANT(CAMERA2D_PROCESS_IDLE); } Camera2D::Camera2D() { @@ -771,6 +804,7 @@ Camera2D::Camera2D() { limit_smoothing_enabled = false; custom_viewport = NULL; custom_viewport_id = 0; + process_mode = CAMERA2D_PROCESS_IDLE; smoothing = 5.0; zoom = Vector2(1, 1); diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 99571500bf..7f16ecff41 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -44,6 +44,11 @@ public: ANCHOR_MODE_DRAG_CENTER }; + enum Camera2DProcessMode { + CAMERA2D_PROCESS_PHYSICS, + CAMERA2D_PROCESS_IDLE + }; + protected: Point2 camera_pos; Point2 smoothed_camera_pos; @@ -73,6 +78,7 @@ protected: float v_ofs; Point2 camera_screen_center; + void _update_process_mode(); void _update_scroll(); void _make_current(Object *p_which); @@ -84,6 +90,8 @@ protected: bool limit_drawing_enabled; bool margin_drawing_enabled; + Camera2DProcessMode process_mode; + protected: virtual Transform2D get_camera_transform(); void _notification(int p_what); @@ -126,6 +134,9 @@ public: void set_follow_smoothing(float p_speed); float get_follow_smoothing() const; + void set_process_mode(Camera2DProcessMode p_mode); + Camera2DProcessMode get_process_mode() const; + void make_current(); void clear_current(); bool is_current() const; @@ -156,5 +167,6 @@ public: }; VARIANT_ENUM_CAST(Camera2D::AnchorMode); +VARIANT_ENUM_CAST(Camera2D::Camera2DProcessMode); #endif // CAMERA_2D_H diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index fab0b7d433..2739f71543 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -42,18 +42,31 @@ #include "servers/visual_server.h" Mutex *CanvasItemMaterial::material_mutex = NULL; -SelfList<CanvasItemMaterial>::List CanvasItemMaterial::dirty_materials; +SelfList<CanvasItemMaterial>::List *CanvasItemMaterial::dirty_materials = NULL; Map<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData> CanvasItemMaterial::shader_map; +CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = NULL; void CanvasItemMaterial::init_shaders() { #ifndef NO_THREADS material_mutex = Mutex::create(); #endif + + dirty_materials = memnew(SelfList<CanvasItemMaterial>::List); + + shader_names = memnew(ShaderNames); + + shader_names->particles_anim_h_frames = "particles_anim_h_frames"; + shader_names->particles_anim_v_frames = "particles_anim_v_frames"; + shader_names->particles_anim_loop = "particles_anim_loop"; } void CanvasItemMaterial::finish_shaders() { + memdelete(dirty_materials); + memdelete(shader_names); + dirty_materials = NULL; + #ifndef NO_THREADS memdelete(material_mutex); #endif @@ -61,7 +74,7 @@ void CanvasItemMaterial::finish_shaders() { void CanvasItemMaterial::_update_shader() { - dirty_materials.remove(&element); + dirty_materials->remove(&element); MaterialKey mk = _compute_key(); if (mk.key == current_key.key) @@ -102,7 +115,33 @@ void CanvasItemMaterial::_update_shader() { case LIGHT_MODE_UNSHADED: code += ",unshaded"; break; case LIGHT_MODE_LIGHT_ONLY: code += ",light_only"; break; } - code += ";\n"; //that's it. + + code += ";\n"; + + if (particles_animation) { + + code += "uniform int particles_anim_h_frames;\n"; + code += "uniform int particles_anim_v_frames;\n"; + code += "uniform bool particles_anim_loop;\n"; + + code += "void vertex() {\n"; + + code += "\tfloat h_frames = float(particles_anim_h_frames);\n"; + code += "\tfloat v_frames = float(particles_anim_v_frames);\n"; + + code += "\tVERTEX.xy /= vec2(h_frames, v_frames);\n"; + + code += "\tfloat particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n"; + code += "\tfloat particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n"; + code += "\tif (!particles_anim_loop) {\n"; + code += "\t\tparticle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n"; + code += "\t} else {\n"; + code += "\t\tparticle_frame = mod(particle_frame, particle_total_frames);\n"; + code += "\t}"; + code += "\tUV /= vec2(h_frames, v_frames);\n"; + code += "\tUV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n"; + code += "}\n"; + } ShaderData shader_data; shader_data.shader = VS::get_singleton()->shader_create(); @@ -120,9 +159,9 @@ void CanvasItemMaterial::flush_changes() { if (material_mutex) material_mutex->lock(); - while (dirty_materials.first()) { + while (dirty_materials->first()) { - dirty_materials.first()->self()->_update_shader(); + dirty_materials->first()->self()->_update_shader(); } if (material_mutex) @@ -135,7 +174,7 @@ void CanvasItemMaterial::_queue_shader_change() { material_mutex->lock(); if (!element.in_list()) { - dirty_materials.add(&element); + dirty_materials->add(&element); } if (material_mutex) @@ -177,7 +216,52 @@ CanvasItemMaterial::LightMode CanvasItemMaterial::get_light_mode() const { return light_mode; } +void CanvasItemMaterial::set_particles_animation(bool p_particles_anim) { + particles_animation = p_particles_anim; + _queue_shader_change(); + _change_notify(); +} + +bool CanvasItemMaterial::get_particles_animation() const { + return particles_animation; +} + +void CanvasItemMaterial::set_particles_anim_h_frames(int p_frames) { + + particles_anim_h_frames = p_frames; + VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames); +} + +int CanvasItemMaterial::get_particles_anim_h_frames() const { + + return particles_anim_h_frames; +} +void CanvasItemMaterial::set_particles_anim_v_frames(int p_frames) { + + particles_anim_v_frames = p_frames; + VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames); +} + +int CanvasItemMaterial::get_particles_anim_v_frames() const { + + return particles_anim_v_frames; +} + +void CanvasItemMaterial::set_particles_anim_loop(bool p_loop) { + + particles_anim_loop = p_loop; + VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop); +} + +bool CanvasItemMaterial::get_particles_anim_loop() const { + + return particles_anim_loop; +} + void CanvasItemMaterial::_validate_property(PropertyInfo &property) const { + if (property.name.begins_with("particles_anim_") && !particles_animation) { + property.usage = 0; + } } RID CanvasItemMaterial::get_shader_rid() const { @@ -199,8 +283,25 @@ void CanvasItemMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_light_mode", "light_mode"), &CanvasItemMaterial::set_light_mode); ClassDB::bind_method(D_METHOD("get_light_mode"), &CanvasItemMaterial::get_light_mode); + ClassDB::bind_method(D_METHOD("set_particles_animation", "particles_anim"), &CanvasItemMaterial::set_particles_animation); + ClassDB::bind_method(D_METHOD("get_particles_animation"), &CanvasItemMaterial::get_particles_animation); + + ClassDB::bind_method(D_METHOD("set_particles_anim_h_frames", "frames"), &CanvasItemMaterial::set_particles_anim_h_frames); + ClassDB::bind_method(D_METHOD("get_particles_anim_h_frames"), &CanvasItemMaterial::get_particles_anim_h_frames); + + ClassDB::bind_method(D_METHOD("set_particles_anim_v_frames", "frames"), &CanvasItemMaterial::set_particles_anim_v_frames); + ClassDB::bind_method(D_METHOD("get_particles_anim_v_frames"), &CanvasItemMaterial::get_particles_anim_v_frames); + + ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "loop"), &CanvasItemMaterial::set_particles_anim_loop); + ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &CanvasItemMaterial::get_particles_anim_loop); + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,Premult Alpha"), "set_blend_mode", "get_blend_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mode", PROPERTY_HINT_ENUM, "Normal,Unshaded,Light Only"), "set_light_mode", "get_light_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_animation"), "set_particles_animation", "get_particles_animation"); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_h_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_h_frames", "get_particles_anim_h_frames"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_v_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_v_frames", "get_particles_anim_v_frames"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_anim_loop"), "set_particles_anim_loop", "get_particles_anim_loop"); BIND_ENUM_CONSTANT(BLEND_MODE_MIX); BIND_ENUM_CONSTANT(BLEND_MODE_ADD); @@ -218,6 +319,11 @@ CanvasItemMaterial::CanvasItemMaterial() : blend_mode = BLEND_MODE_MIX; light_mode = LIGHT_MODE_NORMAL; + particles_animation = false; + + set_particles_anim_h_frames(1); + set_particles_anim_v_frames(1); + set_particles_anim_loop(false); current_key.key = 0; current_key.invalid_key = 1; @@ -272,6 +378,9 @@ bool CanvasItem::is_visible_in_tree() const { void CanvasItem::_propagate_visibility_changed(bool p_visible) { + if (p_visible && first_draw) { //avoid propagating it twice + first_draw = false; + } notification(NOTIFICATION_VISIBILITY_CHANGED); if (p_visible) @@ -321,6 +430,11 @@ void CanvasItem::hide() { _change_notify("visible"); } +CanvasItem *CanvasItem::current_item_drawn = NULL; +CanvasItem *CanvasItem::get_current_item_drawn() { + return current_item_drawn; +} + void CanvasItem::_update_callback() { if (!is_inside_tree()) { @@ -336,11 +450,13 @@ void CanvasItem::_update_callback() { first_draw = false; } drawing = true; + current_item_drawn = this; notification(NOTIFICATION_DRAW); emit_signal(SceneStringNames::get_singleton()->draw); if (get_script_instance()) { get_script_instance()->call_multilevel_reversed(SceneStringNames::get_singleton()->_draw, NULL, 0); } + current_item_drawn = NULL; drawing = false; } //todo updating = false @@ -861,6 +977,15 @@ RID CanvasItem::get_canvas() const { return get_viewport()->find_world_2d()->get_canvas(); } +ObjectID CanvasItem::get_canvas_layer_instance_id() const { + + if (canvas_layer) { + return canvas_layer->get_instance_id(); + } else { + return 0; + } +} + CanvasItem *CanvasItem::get_toplevel() const { CanvasItem *ci = const_cast<CanvasItem *>(this); @@ -1044,7 +1169,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_string", "font", "position", "text", "modulate", "clip_w"), &CanvasItem::draw_string, DEFVAL(Color(1, 1, 1)), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("draw_char", "font", "position", "char", "next", "modulate"), &CanvasItem::draw_char, DEFVAL(Color(1, 1, 1))); ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "normal_map"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture>())); - ClassDB::bind_method(D_METHOD("draw_multimesh", "mesh", "texture", "normal_map"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture>())); + ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture", "normal_map"), &CanvasItem::draw_multimesh, DEFVAL(Ref<Texture>())); ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform); ClassDB::bind_method(D_METHOD("draw_set_transform_matrix", "xform"), &CanvasItem::draw_set_transform_matrix); @@ -1080,16 +1205,16 @@ void CanvasItem::_bind_methods() { BIND_VMETHOD(MethodInfo("_draw")); ADD_GROUP("Visibility", ""); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); - ADD_PROPERTYNO(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); - ADD_PROPERTYNO(PropertyInfo(Variant::COLOR, "self_modulate"), "set_self_modulate", "get_self_modulate"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "show_behind_parent"), "set_draw_behind_parent", "is_draw_behind_parent_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "self_modulate"), "set_self_modulate", "get_self_modulate"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_behind_parent"), "set_draw_behind_parent", "is_draw_behind_parent_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_on_top", PROPERTY_HINT_NONE, "", 0), "_set_on_top", "_is_on_top"); //compatibility - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_light_mask", "get_light_mask"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_light_mask", "get_light_mask"); ADD_GROUP("Material", ""); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,CanvasItemMaterial"), "set_material", "get_material"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "use_parent_material"), "set_use_parent_material", "get_use_parent_material"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,CanvasItemMaterial"), "set_material", "get_material"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_parent_material"), "set_use_parent_material", "get_use_parent_material"); //exporting these things doesn't really make much sense i think // ADD_PROPERTY(PropertyInfo(Variant::BOOL, "toplevel", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_as_toplevel", "is_set_as_toplevel"); // ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),"set_transform_notify","is_transform_notify_enabled"); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 36a0e4039a..bf7cfa8e75 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -70,6 +70,7 @@ private: struct { uint32_t blend_mode : 4; uint32_t light_mode : 4; + uint32_t particles_animation : 1; uint32_t invalid_key : 1; }; @@ -80,6 +81,14 @@ private: } }; + struct ShaderNames { + StringName particles_anim_h_frames; + StringName particles_anim_v_frames; + StringName particles_anim_loop; + }; + + static ShaderNames *shader_names; + struct ShaderData { RID shader; int users; @@ -95,11 +104,12 @@ private: mk.key = 0; mk.blend_mode = blend_mode; mk.light_mode = light_mode; + mk.particles_animation = particles_animation; return mk; } static Mutex *material_mutex; - static SelfList<CanvasItemMaterial>::List dirty_materials; + static SelfList<CanvasItemMaterial>::List *dirty_materials; SelfList<CanvasItemMaterial> element; void _update_shader(); @@ -108,6 +118,11 @@ private: BlendMode blend_mode; LightMode light_mode; + bool particles_animation; + + int particles_anim_h_frames; + int particles_anim_v_frames; + bool particles_anim_loop; protected: static void _bind_methods(); @@ -120,6 +135,17 @@ public: void set_light_mode(LightMode p_light_mode); LightMode get_light_mode() const; + void set_particles_animation(bool p_particles_anim); + bool get_particles_animation() const; + + void set_particles_anim_h_frames(int p_frames); + int get_particles_anim_h_frames() const; + void set_particles_anim_v_frames(int p_frames); + int get_particles_anim_v_frames() const; + + void set_particles_anim_loop(bool p_frames); + bool get_particles_anim_loop() const; + static void init_shaders(); static void finish_shaders(); static void flush_changes(); @@ -196,6 +222,8 @@ private: void _set_on_top(bool p_on_top) { set_draw_behind_parent(!p_on_top); } bool _is_on_top() const { return !is_draw_behind_parent_enabled(); } + static CanvasItem *current_item_drawn; + protected: _FORCE_INLINE_ void _notify_transform() { if (!is_inside_tree()) return; @@ -298,6 +326,8 @@ public: void draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale); void draw_set_transform_matrix(const Transform2D &p_matrix); + static CanvasItem *get_current_item_drawn(); + /* RECT / TRANSFORM */ void set_as_toplevel(bool p_toplevel); @@ -326,6 +356,7 @@ public: Rect2 get_viewport_rect() const; RID get_viewport_rid() const; RID get_canvas() const; + ObjectID get_canvas_layer_instance_id() const; Ref<World2D> get_world_2d() const; virtual void set_material(const Ref<Material> &p_material); diff --git a/scene/2d/canvas_modulate.cpp b/scene/2d/canvas_modulate.cpp index 2f8568ccbf..bd7bb97b03 100644 --- a/scene/2d/canvas_modulate.cpp +++ b/scene/2d/canvas_modulate.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/canvas_modulate.h b/scene/2d/canvas_modulate.h index 888ed95f6b..101abb4f00 100644 --- a/scene/2d/canvas_modulate.h +++ b/scene/2d/canvas_modulate.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index 7ade74e8a6..d54070df8d 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -58,6 +58,14 @@ void CollisionObject2D::_notification(int p_what) { //get space } + case NOTIFICATION_ENTER_CANVAS: { + + if (area) + Physics2DServer::get_singleton()->area_attach_canvas_instance_id(rid, get_canvas_layer_instance_id()); + else + Physics2DServer::get_singleton()->body_attach_canvas_instance_id(rid, get_canvas_layer_instance_id()); + } + case NOTIFICATION_VISIBILITY_CHANGED: { _update_pickable(); @@ -86,6 +94,14 @@ void CollisionObject2D::_notification(int p_what) { Physics2DServer::get_singleton()->body_set_space(rid, RID()); } break; + + case NOTIFICATION_EXIT_CANVAS: { + + if (area) + Physics2DServer::get_singleton()->area_attach_canvas_instance_id(rid, 0); + else + Physics2DServer::get_singleton()->body_attach_canvas_instance_id(rid, 0); + } } } @@ -147,7 +163,7 @@ void CollisionObject2D::shape_owner_set_one_way_collision(uint32_t p_owner, bool ShapeData &sd = shapes[p_owner]; sd.one_way_collision = p_enable; for (int i = 0; i < sd.shapes.size(); i++) { - Physics2DServer::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, p_enable); + Physics2DServer::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin); } } @@ -158,6 +174,27 @@ bool CollisionObject2D::is_shape_owner_one_way_collision_enabled(uint32_t p_owne return shapes[p_owner].one_way_collision; } +void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owner, float p_margin) { + + if (area) + return; //not for areas + + ERR_FAIL_COND(!shapes.has(p_owner)); + + ShapeData &sd = shapes[p_owner]; + sd.one_way_collision_margin = p_margin; + for (int i = 0; i < sd.shapes.size(); i++) { + Physics2DServer::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin); + } +} + +float CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_owner) const { + + ERR_FAIL_COND_V(!shapes.has(p_owner), 0); + + return shapes[p_owner].one_way_collision_margin; +} + void CollisionObject2D::get_shape_owners(List<uint32_t> *r_owners) { for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { @@ -374,6 +411,8 @@ void CollisionObject2D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_shape_owner_disabled", "owner_id"), &CollisionObject2D::is_shape_owner_disabled); ClassDB::bind_method(D_METHOD("shape_owner_set_one_way_collision", "owner_id", "enable"), &CollisionObject2D::shape_owner_set_one_way_collision); ClassDB::bind_method(D_METHOD("is_shape_owner_one_way_collision_enabled", "owner_id"), &CollisionObject2D::is_shape_owner_one_way_collision_enabled); + ClassDB::bind_method(D_METHOD("shape_owner_set_one_way_collision_margin", "owner_id", "margin"), &CollisionObject2D::shape_owner_set_one_way_collision_margin); + ClassDB::bind_method(D_METHOD("get_shape_owner_one_way_collision_margin", "owner_id"), &CollisionObject2D::get_shape_owner_one_way_collision_margin); ClassDB::bind_method(D_METHOD("shape_owner_add_shape", "owner_id", "shape"), &CollisionObject2D::shape_owner_add_shape); ClassDB::bind_method(D_METHOD("shape_owner_get_shape_count", "owner_id"), &CollisionObject2D::shape_owner_get_shape_count); ClassDB::bind_method(D_METHOD("shape_owner_get_shape", "owner_id", "shape_id"), &CollisionObject2D::shape_owner_get_shape); diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h index 29a00bd9f9..8aa3330f37 100644 --- a/scene/2d/collision_object_2d.h +++ b/scene/2d/collision_object_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -54,10 +54,12 @@ class CollisionObject2D : public Node2D { Vector<Shape> shapes; bool disabled; bool one_way_collision; + float one_way_collision_margin; ShapeData() { disabled = false; one_way_collision = false; + one_way_collision_margin = 0; owner = NULL; } }; @@ -98,6 +100,9 @@ public: void shape_owner_set_one_way_collision(uint32_t p_owner, bool p_enable); bool is_shape_owner_one_way_collision_enabled(uint32_t p_owner) const; + void shape_owner_set_one_way_collision_margin(uint32_t p_owner, float p_margin); + float get_shape_owner_one_way_collision_margin(uint32_t p_owner) const; + void shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2D> &p_shape); int shape_owner_get_shape_count(uint32_t p_owner) const; Ref<Shape2D> shape_owner_get_shape(uint32_t p_owner, int p_shape) const; diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 410b27c691..ef7644fcab 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -78,40 +78,7 @@ void CollisionPolygon2D::_build_polygon() { } Vector<Vector<Vector2> > CollisionPolygon2D::_decompose_in_convex() { - - Vector<Vector<Vector2> > decomp; - List<TriangulatorPoly> in_poly, out_poly; - - TriangulatorPoly inp; - inp.Init(polygon.size()); - for (int i = 0; i < polygon.size(); i++) { - inp.GetPoint(i) = polygon[i]; - } - inp.SetOrientation(TRIANGULATOR_CCW); - in_poly.push_back(inp); - TriangulatorPartition tpart; - if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed! - ERR_PRINT("Convex decomposing failed!"); - return decomp; - } - - decomp.resize(out_poly.size()); - int idx = 0; - - for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) { - - TriangulatorPoly &tp = I->get(); - - decomp.write[idx].resize(tp.GetNumPoints()); - - for (int i = 0; i < tp.GetNumPoints(); i++) { - - decomp.write[idx].write[i] = tp.GetPoint(i); - } - - idx++; - } - + Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon_in_convex(polygon); return decomp; } @@ -122,6 +89,7 @@ void CollisionPolygon2D::_update_in_shape_owner(bool p_xform_only) { return; parent->shape_owner_set_disabled(owner_id, disabled); parent->shape_owner_set_one_way_collision(owner_id, one_way_collision); + parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin); } void CollisionPolygon2D::_notification(int p_what) { @@ -311,6 +279,16 @@ bool CollisionPolygon2D::is_one_way_collision_enabled() const { return one_way_collision; } +void CollisionPolygon2D::set_one_way_collision_margin(float p_margin) { + one_way_collision_margin = p_margin; + if (parent) { + parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin); + } +} + +float CollisionPolygon2D::get_one_way_collision_margin() const { + return one_way_collision_margin; +} void CollisionPolygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &CollisionPolygon2D::set_polygon); @@ -322,11 +300,14 @@ void CollisionPolygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_disabled"), &CollisionPolygon2D::is_disabled); ClassDB::bind_method(D_METHOD("set_one_way_collision", "enabled"), &CollisionPolygon2D::set_one_way_collision); ClassDB::bind_method(D_METHOD("is_one_way_collision_enabled"), &CollisionPolygon2D::is_one_way_collision_enabled); + ClassDB::bind_method(D_METHOD("set_one_way_collision_margin", "margin"), &CollisionPolygon2D::set_one_way_collision_margin); + ClassDB::bind_method(D_METHOD("get_one_way_collision_margin"), &CollisionPolygon2D::get_one_way_collision_margin); ADD_PROPERTY(PropertyInfo(Variant::INT, "build_mode", PROPERTY_HINT_ENUM, "Solids,Segments"), "set_build_mode", "get_build_mode"); ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "one_way_collision"), "set_one_way_collision", "is_one_way_collision_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_way_collision"), "set_one_way_collision", "is_one_way_collision_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "one_way_collision_margin", PROPERTY_HINT_RANGE, "0,128,0.1"), "set_one_way_collision_margin", "get_one_way_collision_margin"); BIND_ENUM_CONSTANT(BUILD_SOLIDS); BIND_ENUM_CONSTANT(BUILD_SEGMENTS); @@ -341,4 +322,5 @@ CollisionPolygon2D::CollisionPolygon2D() { owner_id = 0; disabled = false; one_way_collision = false; + one_way_collision_margin = 1.0; } diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index 412a923292..b88679f15b 100644 --- a/scene/2d/collision_polygon_2d.h +++ b/scene/2d/collision_polygon_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -54,6 +54,7 @@ protected: CollisionObject2D *parent; bool disabled; bool one_way_collision; + float one_way_collision_margin; Vector<Vector<Vector2> > _decompose_in_convex(); @@ -84,6 +85,9 @@ public: void set_one_way_collision(bool p_enable); bool is_one_way_collision_enabled() const; + void set_one_way_collision_margin(float p_margin); + float get_one_way_collision_margin() const; + CollisionPolygon2D(); }; diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index cb9c8ecf95..5440a1d8c3 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,9 +36,9 @@ #include "scene/resources/circle_shape_2d.h" #include "scene/resources/concave_polygon_shape_2d.h" #include "scene/resources/convex_polygon_shape_2d.h" +#include "scene/resources/line_shape_2d.h" #include "scene/resources/rectangle_shape_2d.h" #include "scene/resources/segment_shape_2d.h" -#include "scene/resources/shape_line_2d.h" void CollisionShape2D::_shape_changed() { @@ -52,6 +52,7 @@ void CollisionShape2D::_update_in_shape_owner(bool p_xform_only) { return; parent->shape_owner_set_disabled(owner_id, disabled); parent->shape_owner_set_one_way_collision(owner_id, one_way_collision); + parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin); } void CollisionShape2D::_notification(int p_what) { @@ -219,6 +220,17 @@ bool CollisionShape2D::is_one_way_collision_enabled() const { return one_way_collision; } +void CollisionShape2D::set_one_way_collision_margin(float p_margin) { + one_way_collision_margin = p_margin; + if (parent) { + parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin); + } +} + +float CollisionShape2D::get_one_way_collision_margin() const { + return one_way_collision_margin; +} + void CollisionShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shape", "shape"), &CollisionShape2D::set_shape); @@ -227,11 +239,14 @@ void CollisionShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_disabled"), &CollisionShape2D::is_disabled); ClassDB::bind_method(D_METHOD("set_one_way_collision", "enabled"), &CollisionShape2D::set_one_way_collision); ClassDB::bind_method(D_METHOD("is_one_way_collision_enabled"), &CollisionShape2D::is_one_way_collision_enabled); + ClassDB::bind_method(D_METHOD("set_one_way_collision_margin", "margin"), &CollisionShape2D::set_one_way_collision_margin); + ClassDB::bind_method(D_METHOD("get_one_way_collision_margin"), &CollisionShape2D::get_one_way_collision_margin); ClassDB::bind_method(D_METHOD("_shape_changed"), &CollisionShape2D::_shape_changed); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "one_way_collision"), "set_one_way_collision", "is_one_way_collision_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_way_collision"), "set_one_way_collision", "is_one_way_collision_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "one_way_collision_margin", PROPERTY_HINT_RANGE, "0,128,0.1"), "set_one_way_collision_margin", "get_one_way_collision_margin"); } CollisionShape2D::CollisionShape2D() { @@ -242,4 +257,5 @@ CollisionShape2D::CollisionShape2D() { parent = NULL; disabled = false; one_way_collision = false; + one_way_collision_margin = 1.0; } diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h index ed2c09d53d..e913b4a866 100644 --- a/scene/2d/collision_shape_2d.h +++ b/scene/2d/collision_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -46,6 +46,7 @@ class CollisionShape2D : public Node2D { void _shape_changed(); bool disabled; bool one_way_collision; + float one_way_collision_margin; void _update_in_shape_owner(bool p_xform_only = false); @@ -65,6 +66,9 @@ public: void set_one_way_collision(bool p_enable); bool is_one_way_collision_enabled() const; + void set_one_way_collision_margin(float p_margin); + float get_one_way_collision_margin() const; + virtual String get_configuration_warning() const; CollisionShape2D(); diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index e6dcd643be..c50a8d4a1a 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,8 +29,9 @@ /*************************************************************************/ #include "cpu_particles_2d.h" - -//#include "scene/resources/particles_material.h" +#include "particles_2d.h" +#include "scene/2d/canvas_item.h" +#include "scene/resources/particles_material.h" #include "servers/visual_server.h" void CPUParticles2D::set_emitting(bool p_emitting) { @@ -237,6 +238,17 @@ String CPUParticles2D::get_configuration_warning() const { String warnings; + CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr()); + + if (get_material().is_null() || (mat && !mat->get_particles_animation())) { + if (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 || + get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid()) { + if (warnings != String()) + warnings += "\n"; + warnings += "- " + TTR("CPUParticles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled."); + } + } + return warnings; } @@ -396,6 +408,7 @@ bool CPUParticles2D::get_particle_flag(Flags p_flag) const { void CPUParticles2D::set_emission_shape(EmissionShape p_shape) { emission_shape = p_shape; + _change_notify(); } void CPUParticles2D::set_emission_sphere_radius(float p_radius) { @@ -479,6 +492,15 @@ void CPUParticles2D::_validate_property(PropertyInfo &property) const { if (property.name == "emission_normals" && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS) { property.usage = 0; } + + if (property.name == "emission_points" && emission_shape != EMISSION_SHAPE_POINTS && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS) { + property.usage = 0; + } + + if (property.name == "emission_colors" && emission_shape != EMISSION_SHAPE_POINTS && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS) { + property.usage = 0; + } + /* if (property.name.begins_with("orbit_") && !flags[FLAG_DISABLE_Z]) { property.usage = 0; @@ -531,7 +553,7 @@ void CPUParticles2D::_particles_process(float p_delta) { if (!local_coords) { emission_xform = get_global_transform(); velocity_xform = emission_xform; - emission_xform[2] = Vector2(); + velocity_xform[2] = Vector2(); } for (int i = 0; i < pcount; i++) { @@ -572,7 +594,7 @@ void CPUParticles2D::_particles_process(float p_delta) { if (restart_time >= prev_time) { restart = true; if (fractional_delta) { - local_delta = (1.0 - restart_time + time) * lifetime; + local_delta = (lifetime - restart_time + time) * lifetime; } } else if (restart_time < time) { @@ -618,9 +640,12 @@ void CPUParticles2D::_particles_process(float p_delta) { p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); float base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp(1.0f, p.angle_rand, randomness[PARAM_ANGLE]); - p.custom[0] = Math::deg2rad(base_angle); //angle - p.custom[1] = 0.0; //phase - p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation offset (0-1) + p.rotation = Math::deg2rad(base_angle); + + p.custom[0] = 0.0; // unused + p.custom[1] = 0.0; // phase [0..1] + p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation phase [0..1] + p.custom[3] = 0.0; p.transform = Transform2D(); p.time = 0; p.base_color = Color(1, 1, 1, 1); @@ -767,14 +792,9 @@ void CPUParticles2D::_particles_process(float p_delta) { } float base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp(1.0f, p.angle_rand, randomness[PARAM_ANGLE]); base_angle += p.custom[1] * lifetime * (parameters[PARAM_ANGULAR_VELOCITY] + tex_angular_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed) * 2.0f - 1.0f, randomness[PARAM_ANGULAR_VELOCITY]); - p.custom[0] = Math::deg2rad(base_angle); //angle - p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]) + p.custom[1] * (parameters[PARAM_ANIM_SPEED] + tex_anim_speed) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ANIM_SPEED]); //angle - if (flags[FLAG_ANIM_LOOP]) { - p.custom[2] = Math::fmod(p.custom[2], 1.0f); //loop - - } else { - p.custom[2] = CLAMP(p.custom[2], 0.0f, 1.0); //0 to 1 only - } + p.rotation = Math::deg2rad(base_angle); //angle + float animation_phase = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]) + p.custom[1] * (parameters[PARAM_ANIM_SPEED] + tex_anim_speed) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ANIM_SPEED]); + p.custom[2] = animation_phase; } //apply color //apply hue rotation @@ -820,13 +840,13 @@ void CPUParticles2D::_particles_process(float p_delta) { if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { if (p.velocity.length() > 0.0) { - p.transform.elements[0] = p.velocity.normalized(); + p.transform.elements[1] = p.velocity.normalized(); p.transform.elements[0] = p.transform.elements[1].tangent(); } } else { - p.transform.elements[0] = Vector2(Math::cos(p.custom[0]), -Math::sin(p.custom[0])); - p.transform.elements[1] = Vector2(Math::sin(p.custom[0]), Math::cos(p.custom[0])); + p.transform.elements[0] = Vector2(Math::cos(p.rotation), -Math::sin(p.rotation)); + p.transform.elements[1] = Vector2(Math::sin(p.rotation), Math::cos(p.rotation)); } //scale by scale @@ -1058,8 +1078,7 @@ void CPUParticles2D::_notification(int p_what) { } void CPUParticles2D::convert_from_particles(Node *p_particles) { -#if 0 - Particles *particles = Object::cast_to<Particles>(p_particles); + Particles2D *particles = Object::cast_to<Particles2D>(p_particles); ERR_FAIL_COND(!particles); set_emitting(particles->is_emitting()); @@ -1074,7 +1093,12 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { set_fractional_delta(particles->get_fractional_delta()); set_speed_scale(particles->get_speed_scale()); set_draw_order(DrawOrder(particles->get_draw_order())); - set_mesh(particles->get_draw_pass_mesh(0)); + set_texture(particles->get_texture()); + + Ref<Material> mat = particles->get_material(); + if (mat.is_valid()) { + set_material(mat); + } Ref<ParticlesMaterial> material = particles->get_process_material(); if (material.is_null()) @@ -1091,15 +1115,14 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { } set_particle_flag(FLAG_ALIGN_Y_TO_VELOCITY, material->get_flag(ParticlesMaterial::FLAG_ALIGN_Y_TO_VELOCITY)); - set_particle_flag(FLAG_ROTATE_Y, material->get_flag(ParticlesMaterial::FLAG_ROTATE_Y)); - set_particle_flag(FLAG_DISABLE_Z, material->get_flag(ParticlesMaterial::FLAG_DISABLE_Z)); - set_particle_flag(FLAG_ANIM_LOOP, material->get_flag(ParticlesMaterial::FLAG_ANIM_LOOP)); set_emission_shape(EmissionShape(material->get_emission_shape())); set_emission_sphere_radius(material->get_emission_sphere_radius()); - set_emission_rect_extents(material->get_emission_rect_extents()); + Vector2 rect_extents = Vector2(material->get_emission_box_extents().x, material->get_emission_box_extents().y); + set_emission_rect_extents(rect_extents); - set_gravity(material->get_gravity()); + Vector2 gravity = Vector2(material->get_gravity().x, material->get_gravity().y); + set_gravity(gravity); #define CONVERT_PARAM(m_param) \ set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \ @@ -1123,7 +1146,6 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { CONVERT_PARAM(PARAM_ANIM_OFFSET); #undef CONVERT_PARAM -#endif } void CPUParticles2D::_bind_methods() { @@ -1167,7 +1189,7 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_EXP_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); @@ -1253,7 +1275,7 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY); ADD_GROUP("Angular Velocity", "angular_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-360,360,0.01"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGULAR_VELOCITY); /* @@ -1283,15 +1305,15 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGLE); ADD_GROUP("Scale", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_amount", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_amount_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_amount_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_SCALE); ADD_GROUP("Color", ""); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_color_ramp", "get_color_ramp"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp"); ADD_GROUP("Hue Variation", "hue_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.1"), "set_param", "get_param", PARAM_HUE_VARIATION); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_HUE_VARIATION); ADD_GROUP("Animation", "anim_"); @@ -1301,7 +1323,6 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_OFFSET); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "anim_loop"), "set_particle_flag", "get_particle_flag", FLAG_ANIM_LOOP); BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY); BIND_ENUM_CONSTANT(PARAM_ANGULAR_VELOCITY); @@ -1357,6 +1378,7 @@ CPUParticles2D::CPUParticles2D() { set_param(PARAM_INITIAL_LINEAR_VELOCITY, 1); //set_param(PARAM_ORBIT_VELOCITY, 0); set_param(PARAM_LINEAR_ACCEL, 0); + set_param(PARAM_ANGULAR_VELOCITY, 0); set_param(PARAM_RADIAL_ACCEL, 0); set_param(PARAM_TANGENTIAL_ACCEL, 0); set_param(PARAM_DAMPING, 0); diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 4f51eb1062..b1adf62980 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -68,7 +68,6 @@ public: enum Flags { FLAG_ALIGN_Y_TO_VELOCITY, - FLAG_ANIM_LOOP, FLAG_MAX }; @@ -87,6 +86,7 @@ private: Transform2D transform; Color color; float custom[4]; + float rotation; Vector2 velocity; bool active; float angle_rand; @@ -168,7 +168,6 @@ private: PoolVector<Color> emission_colors; int emission_point_count; - bool anim_loop; Vector2 gravity; void _particles_process(float p_delta); diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index b9a48e1fdc..5b14b3e8e1 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/joints_2d.h b/scene/2d/joints_2d.h index 744994f0a7..a3951eb9d2 100644 --- a/scene/2d/joints_2d.h +++ b/scene/2d/joints_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index e6a5a0b651..d1fce74085 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -431,7 +431,7 @@ void Light2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture,ImageTexture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_texture_offset", "get_texture_offset"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); @@ -450,7 +450,7 @@ void Light2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_buffer_size", PROPERTY_HINT_RANGE, "32,16384,1"), "set_shadow_buffer_size", "get_shadow_buffer_size"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_gradient_length", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_shadow_gradient_length", "get_shadow_gradient_length"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF3,PCF5,PCF7,PCF9,PCF13"), "set_shadow_filter", "get_shadow_filter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF3,PCF5,PCF7,PCF9,PCF13"), "set_shadow_filter", "get_shadow_filter"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask"); diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index 40469cfbc8..b1940f64cd 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index ab15b49985..5334caed67 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h index d59c9100b0..498d65d764 100644 --- a/scene/2d/light_occluder_2d.h +++ b/scene/2d/light_occluder_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index e164f0ca75..105eb82afb 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -347,13 +347,13 @@ void Line2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "width"), "set_width", "get_width"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_color"), "set_default_color", "get_default_color"); ADD_GROUP("Fill", ""); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "None,Tile,Stretch"), "set_texture_mode", "get_texture_mode"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "None,Tile,Stretch"), "set_texture_mode", "get_texture_mode"); ADD_GROUP("Capping", ""); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "joint_mode", PROPERTY_HINT_ENUM, "Sharp,Bevel,Round"), "set_joint_mode", "get_joint_mode"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "begin_cap_mode", PROPERTY_HINT_ENUM, "None,Box,Round"), "set_begin_cap_mode", "get_begin_cap_mode"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "end_cap_mode", PROPERTY_HINT_ENUM, "None,Box,Round"), "set_end_cap_mode", "get_end_cap_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_mode", PROPERTY_HINT_ENUM, "Sharp,Bevel,Round"), "set_joint_mode", "get_joint_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "begin_cap_mode", PROPERTY_HINT_ENUM, "None,Box,Round"), "set_begin_cap_mode", "get_begin_cap_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "end_cap_mode", PROPERTY_HINT_ENUM, "None,Box,Round"), "set_end_cap_mode", "get_end_cap_mode"); ADD_GROUP("Border", ""); ADD_PROPERTY(PropertyInfo(Variant::REAL, "sharp_limit"), "set_sharp_limit", "get_sharp_limit"); ADD_PROPERTY(PropertyInfo(Variant::INT, "round_precision"), "set_round_precision", "get_round_precision"); diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h index 6918018c12..5bbd38e460 100644 --- a/scene/2d/line_2d.h +++ b/scene/2d/line_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp index a3f1b25e05..eb09d3c9d3 100644 --- a/scene/2d/line_builder.cpp +++ b/scene/2d/line_builder.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -279,6 +279,10 @@ void LineBuilder::build() { } } else { // No intersection: fallback + if (current_joint_mode == Line2D::LINE_JOINT_SHARP) { + // There is no fallback implementation for LINE_JOINT_SHARP so switch to the LINE_JOINT_BEVEL + current_joint_mode = Line2D::LINE_JOINT_BEVEL; + } pos_up1 = corner_pos_up; pos_down1 = corner_pos_down; } @@ -294,7 +298,6 @@ void LineBuilder::build() { if (texture_mode == Line2D::LINE_TEXTURE_TILE) { uvx1 = current_distance1 / (width * tile_aspect); } else if (texture_mode == Line2D::LINE_TEXTURE_STRETCH) { - uvx0 = current_distance0 / total_distance; uvx1 = current_distance1 / total_distance; } diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h index f9d26f12af..b961385e33 100644 --- a/scene/2d/line_builder.h +++ b/scene/2d/line_builder.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,7 +34,7 @@ #include "core/color.h" #include "core/math/vector2.h" #include "line_2d.h" -#include "scene/resources/color_ramp.h" +#include "scene/resources/gradient.h" class LineBuilder { public: diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index 9f21fe1a1f..b382ca7b33 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -51,8 +51,8 @@ void MeshInstance2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_normal_map"), &MeshInstance2D::get_normal_map); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); } void MeshInstance2D::set_mesh(const Ref<Mesh> &p_mesh) { diff --git a/scene/2d/mesh_instance_2d.h b/scene/2d/mesh_instance_2d.h index c9889c1c03..4d81c8088a 100644 --- a/scene/2d/mesh_instance_2d.h +++ b/scene/2d/mesh_instance_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/navigation2d.cpp b/scene/2d/navigation_2d.cpp index 1b789bab9d..57e0a5b118 100644 --- a/scene/2d/navigation2d.cpp +++ b/scene/2d/navigation_2d.cpp @@ -1,12 +1,12 @@ /*************************************************************************/ -/* navigation2d.cpp */ +/* navigation_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "navigation2d.h" +#include "navigation_2d.h" #define USE_ENTRY_POINT diff --git a/scene/2d/navigation2d.h b/scene/2d/navigation_2d.h index 02c46d5de1..b4d659ff5c 100644 --- a/scene/2d/navigation2d.h +++ b/scene/2d/navigation_2d.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* navigation2d.h */ +/* navigation_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -171,4 +171,4 @@ public: Navigation2D(); }; -#endif // Navigation2D2D_H +#endif // NAVIGATION_2D_H diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp index b36924e521..0f6af358bd 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,7 +32,7 @@ #include "core/core_string_names.h" #include "core/engine.h" -#include "navigation2d.h" +#include "navigation_2d.h" #include "thirdparty/misc/triangulator.h" @@ -349,8 +349,6 @@ void NavigationPolygonInstance::set_enabled(bool p_enabled) { if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) update(); - - //update_gizmo(); } bool NavigationPolygonInstance::is_enabled() const { @@ -461,26 +459,28 @@ void NavigationPolygonInstance::_notification(int p_what) { void NavigationPolygonInstance::set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly) { - if (p_navpoly == navpoly) + if (p_navpoly == navpoly) { return; + } if (navigation && nav_id != -1) { navigation->navpoly_remove(nav_id); nav_id = -1; } + if (navpoly.is_valid()) { navpoly->disconnect(CoreStringNames::get_singleton()->changed, this, "_navpoly_changed"); } navpoly = p_navpoly; - if (navpoly.is_valid()) { navpoly->connect(CoreStringNames::get_singleton()->changed, this, "_navpoly_changed"); } + _navpoly_changed(); if (navigation && navpoly.is_valid() && enabled) { nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this); } - //update_gizmo(); + _change_notify("navpoly"); update_configuration_warning(); } diff --git a/scene/2d/navigation_polygon.h b/scene/2d/navigation_polygon.h index d7684c2d94..ebbe67d949 100644 --- a/scene/2d/navigation_polygon.h +++ b/scene/2d/navigation_polygon.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 2f94c3c6f5..f4430d93f6 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -376,7 +376,7 @@ void Node2D::look_at(const Vector2 &p_pos) { float Node2D::get_angle_to(const Vector2 &p_pos) const { - return (get_global_transform().affine_inverse().xform(p_pos)).angle(); + return (to_local(p_pos) * get_scale()).angle(); } Point2 Node2D::to_local(Point2 p_global) const { @@ -435,10 +435,10 @@ void Node2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_relative_transform_to_parent", "parent"), &Node2D::get_relative_transform_to_parent); ADD_GROUP("Transform", ""); - ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees"); - ADD_PROPERTYNO(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "", 0), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position", PROPERTY_HINT_NONE, "", 0), "set_global_position", "get_global_position"); @@ -448,8 +448,8 @@ void Node2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform"); ADD_GROUP("Z Index", ""); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "z_index", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_index", "get_z_index"); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "z_as_relative"), "set_z_as_relative", "is_z_relative"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "z_index", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_index", "get_z_index"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "z_as_relative"), "set_z_as_relative", "is_z_relative"); } Node2D::Node2D() { diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index 924a84fb88..c07dc88720 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp index 027d64b813..96e13396c5 100644 --- a/scene/2d/parallax_background.cpp +++ b/scene/2d/parallax_background.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -206,7 +206,9 @@ void ParallaxBackground::_bind_methods() { ParallaxBackground::ParallaxBackground() { - base_scale = Vector2(1, 1); scale = 1.0; set_layer(-1); //behind all by default + + base_scale = Vector2(1, 1); + ignore_camera_zoom = false; } diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h index 31d1c553a2..38d59ac737 100644 --- a/scene/2d/parallax_background.h +++ b/scene/2d/parallax_background.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index 06de723f27..baf5b5967b 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h index b2b98b0ef6..b5db111a38 100644 --- a/scene/2d/parallax_layer.h +++ b/scene/2d/parallax_layer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index 7e824cdf75..9701998f5d 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,6 +30,7 @@ #include "particles_2d.h" +#include "core/os/os.h" #include "scene/resources/particles_material.h" #include "scene/scene_string_names.h" @@ -213,12 +214,30 @@ bool Particles2D::get_fractional_delta() const { String Particles2D::get_configuration_warning() const { + if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) { + return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles2D node instead. You can use the \"Convert to CPUParticles\" option for this purpose."); + } + String warnings; if (process_material.is_null()) { if (warnings != String()) warnings += "\n"; warnings += "- " + TTR("A material to process the particles is not assigned, so no behavior is imprinted."); + } else { + + CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr()); + + if (get_material().is_null() || (mat && !mat->get_particles_animation())) { + const ParticlesMaterial *process = Object::cast_to<ParticlesMaterial>(process_material.ptr()); + if (process && + (process->get_param(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 || + process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) { + if (warnings != String()) + warnings += "\n"; + warnings += "- " + TTR("Particles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled."); + } + } } return warnings; @@ -257,30 +276,6 @@ Ref<Texture> Particles2D::get_normal_map() const { void Particles2D::_validate_property(PropertyInfo &property) const { } -void Particles2D::set_v_frames(int p_count) { - - ERR_FAIL_COND(p_count < 1); - v_frames = p_count; - update(); -} - -int Particles2D::get_v_frames() const { - - return v_frames; -} - -void Particles2D::set_h_frames(int p_count) { - - ERR_FAIL_COND(p_count < 1); - h_frames = p_count; - update(); -} - -int Particles2D::get_h_frames() const { - - return h_frames; -} - void Particles2D::restart() { VS::get_singleton()->particles_restart(particles); } @@ -296,7 +291,7 @@ void Particles2D::_notification(int p_what) { if (normal_map.is_valid()) normal_rid = normal_map->get_rid(); - VS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid, normal_rid, h_frames, v_frames); + VS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid, normal_rid); #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint() && (this == get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->is_a_parent_of(this))) { @@ -361,12 +356,6 @@ void Particles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("capture_rect"), &Particles2D::capture_rect); - ClassDB::bind_method(D_METHOD("set_v_frames", "frames"), &Particles2D::set_v_frames); - ClassDB::bind_method(D_METHOD("get_v_frames"), &Particles2D::get_v_frames); - - ClassDB::bind_method(D_METHOD("set_h_frames", "frames"), &Particles2D::set_h_frames); - ClassDB::bind_method(D_METHOD("get_h_frames"), &Particles2D::get_h_frames); - ClassDB::bind_method(D_METHOD("restart"), &Particles2D::restart); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); @@ -389,8 +378,6 @@ void Particles2D::_bind_methods() { ADD_GROUP("Textures", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "h_frames", PROPERTY_HINT_RANGE, "1,1024,1"), "set_h_frames", "get_h_frames"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "v_frames", PROPERTY_HINT_RANGE, "1,1024,1"), "set_v_frames", "get_v_frames"); BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX); BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME); @@ -413,8 +400,6 @@ Particles2D::Particles2D() { set_use_local_coordinates(true); set_draw_order(DRAW_ORDER_INDEX); set_speed_scale(1); - h_frames = 1; - v_frames = 1; } Particles2D::~Particles2D() { diff --git a/scene/2d/particles_2d.h b/scene/2d/particles_2d.h index af673841b1..a0104b4b16 100644 --- a/scene/2d/particles_2d.h +++ b/scene/2d/particles_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -59,8 +59,6 @@ private: bool local_coords; int fixed_fps; bool fractional_delta; - int v_frames; - int h_frames; Ref<Material> process_material; @@ -118,12 +116,6 @@ public: virtual String get_configuration_warning() const; - void set_v_frames(int p_count); - int get_v_frames() const; - - void set_h_frames(int p_count); - int get_h_frames() const; - void restart(); Rect2 capture_rect() const; Particles2D(); diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index cdb208e6cd..fec861ad2f 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -63,6 +63,10 @@ bool Path2D::_edit_use_rect() const { bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { + if (curve.is_null()) { + return false; + } + for (int i = 0; i < curve->get_point_count(); i++) { Vector2 s[2]; s[0] = curve->get_point_position(i); @@ -166,6 +170,9 @@ void PathFollow2D::_update_transform() { return; float path_length = c->get_baked_length(); + if (path_length == 0) { + return; + } float bounded_offset = offset; if (loop) bounded_offset = Math::fposmod(bounded_offset, path_length); @@ -257,7 +264,7 @@ void PathFollow2D::_validate_property(PropertyInfo &property) const { if (path && path->get_curve().is_valid()) max = path->get_curve()->get_baked_length(); - property.hint_string = "0," + rtos(max) + ",0.01"; + property.hint_string = "0," + rtos(max) + ",0.01,or_greater"; } } @@ -299,8 +306,8 @@ void PathFollow2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lookahead", "lookahead"), &PathFollow2D::set_lookahead); ClassDB::bind_method(D_METHOD("get_lookahead"), &PathFollow2D::get_lookahead); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_EXP_RANGE, "0,10000,0.01,or_greater"), "set_offset", "get_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_greater"), "set_offset", "get_offset"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); 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::BOOL, "rotate"), "set_rotate", "is_rotating"); diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h index 64696442c3..4efad19938 100644 --- a/scene/2d/path_2d.h +++ b/scene/2d/path_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/path_texture.cpp b/scene/2d/path_texture.cpp index d36a9fb65a..3de2079ebe 100644 --- a/scene/2d/path_texture.cpp +++ b/scene/2d/path_texture.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/path_texture.h b/scene/2d/path_texture.h index 7a347c0653..313aa772c4 100644 --- a/scene/2d/path_texture.h +++ b/scene/2d/path_texture.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index d0bebd3354..1b7e1a6b8b 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,8 +32,11 @@ #include "core/core_string_names.h" #include "core/engine.h" +#include "core/list.h" #include "core/math/math_funcs.h" #include "core/method_bind_ext.gen.inc" +#include "core/object.h" +#include "core/rid.h" #include "scene/scene_string_names.h" void PhysicsBody2D::_notification(int p_what) { @@ -65,6 +68,8 @@ void PhysicsBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_layers", "mask"), &PhysicsBody2D::_set_layers); ClassDB::bind_method(D_METHOD("_get_layers"), &PhysicsBody2D::_get_layers); + + ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody2D::get_collision_exceptions); ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody2D::add_collision_exception_with); ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody2D::remove_collision_exception_with); ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_2D_PHYSICS, "", 0), "_set_layers", "_get_layers"); //for backwards compat @@ -134,6 +139,20 @@ PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : set_pickable(false); } +Array PhysicsBody2D::get_collision_exceptions() { + List<RID> exceptions; + Physics2DServer::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); + Array ret; + for (List<RID>::Element *E = exceptions.front(); E; E = E->next()) { + RID body = E->get(); + ObjectID instance_id = Physics2DServer::get_singleton()->body_get_object_instance_id(body); + Object *obj = ObjectDB::get_instance(instance_id); + PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(obj); + ret.append(physics_body); + } + return ret; +} + void PhysicsBody2D::add_collision_exception_with(Node *p_node) { ERR_FAIL_NULL(p_node); @@ -280,10 +299,10 @@ void StaticBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity"); #ifndef DISABLE_DEPRECATED - ADD_PROPERTYNO(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); #endif // DISABLE_DEPRECATED - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); } StaticBody2D::StaticBody2D() : @@ -1042,10 +1061,10 @@ void RigidBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "inertia", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", 0), "set_inertia", "get_inertia"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight"); #ifndef DISABLE_DEPRECATED - ADD_PROPERTYNO(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); #endif // DISABLE_DEPRECATED - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator"); ADD_PROPERTY(PropertyInfo(Variant::INT, "continuous_cd", PROPERTY_HINT_ENUM, "Disabled,Cast Ray,Cast Shape"), "set_continuous_collision_detection_mode", "get_continuous_collision_detection_mode"); @@ -1060,8 +1079,8 @@ void RigidBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_angular_damp", "get_angular_damp"); ADD_GROUP("Applied Forces", "applied_"); - ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "applied_force"), "set_applied_force", "get_applied_force"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "applied_torque"), "set_applied_torque", "get_applied_torque"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "applied_force"), "set_applied_force", "get_applied_force"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "applied_torque"), "set_applied_torque", "get_applied_torque"); ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); @@ -1179,6 +1198,9 @@ bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) { + if (sync_to_physics) { + ERR_PRINT("Functions move_and_slide and move_and_collide do not work together with 'sync to physics' option. Please read the documentation."); + } Transform2D gt = get_global_transform(); Physics2DServer::MotionResult result; bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, margin, &result, p_exclude_raycast_shapes); @@ -1207,7 +1229,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_ //so, if you pass 45 as limit, avoid numerical precision erros when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_infinite_inertia, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle) { +Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { Vector2 floor_motion = floor_velocity; if (on_floor && on_floor_body.is_valid()) { @@ -1218,7 +1240,8 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const } } - Vector2 motion = (floor_motion + p_linear_velocity) * get_physics_process_delta_time(); + // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky + Vector2 motion = (floor_motion + p_linear_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); Vector2 lv = p_linear_velocity; on_floor = false; @@ -1259,7 +1282,6 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const colliders.push_back(collision); motion = collision.remainder; - bool is_on_slope = false; if (p_floor_direction == Vector2()) { //all is a wall on_wall = true; @@ -1271,16 +1293,14 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const floor_velocity = collision.collider_vel; if (p_stop_on_slope) { - if (Vector2() == lv_n + p_floor_direction) { + if ((lv_n + p_floor_direction).length() < 0.01 && collision.travel.length() < 1) { Transform2D gt = get_global_transform(); - gt.elements[2] -= collision.travel; + gt.elements[2] -= collision.travel.project(p_floor_direction.tangent()); set_global_transform(gt); return Vector2(); } } - is_on_slope = true; - } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //ceiling on_ceiling = true; } else { @@ -1288,18 +1308,10 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const } } - if (p_stop_on_slope && is_on_slope) { - motion = motion.slide(p_floor_direction); - lv = lv.slide(p_floor_direction); - } else { - Vector2 n = collision.normal; - motion = motion.slide(n); - lv = lv.slide(n); - } + Vector2 n = collision.normal; + motion = motion.slide(n); + lv = lv.slide(n); } - - if (p_stop_on_slope) - break; } if (!found_collision) { @@ -1313,11 +1325,11 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const return lv; } -Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction, bool p_infinite_inertia, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle) { +Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { bool was_on_floor = on_floor; - Vector2 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_infinite_inertia, p_stop_on_slope, p_max_slides, p_floor_max_angle); + Vector2 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); if (!was_on_floor || p_snap == Vector2()) { return ret; } @@ -1326,13 +1338,27 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci Transform2D gt = get_global_transform(); if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { - gt.elements[2] += col.travel; - if (p_floor_direction != Vector2() && Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) { - on_floor = true; - on_floor_body = col.collider_rid; - floor_velocity = col.collider_vel; + bool apply = true; + if (p_floor_direction != Vector2()) { + if (Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) { + on_floor = true; + on_floor_body = col.collider_rid; + floor_velocity = col.collider_vel; + if (p_stop_on_slope) { + // move and collide may stray the object a bit because of pre un-stucking, + // so only ensure that motion happens on floor direction in this case. + col.travel = p_floor_direction * p_floor_direction.dot(col.travel); + } + + } else { + apply = false; + } + } + + if (apply) { + gt.elements[2] += col.travel; + set_global_transform(gt); } - set_global_transform(gt); } return ret; @@ -1405,6 +1431,10 @@ void KinematicBody2D::set_sync_to_physics(bool p_enable) { return; } sync_to_physics = p_enable; + + if (Engine::get_singleton()->is_editor_hint()) + return; + if (p_enable) { Physics2DServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); set_only_update_transform_changes(true); @@ -1451,10 +1481,10 @@ void KinematicBody2D::_notification(int p_what) { void KinematicBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "infinite_inertia", "stop_on_slope", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45))); - ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "infinite_inertia", "stop_on_slope", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45))); + ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move); + ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move, DEFVAL(true)); ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody2D::is_on_floor); ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody2D::is_on_ceiling); diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 29befb0375..89dd1e5341 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -67,6 +67,7 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; + Array get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); @@ -331,15 +332,15 @@ protected: public: bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true, bool p_test_only = false); - bool test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia); + bool test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia = true); bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision); void set_safe_margin(float p_margin); float get_safe_margin() const; - Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_infinite_inertia = true, bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45)); - Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_infinite_inertia = true, bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45)); + Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); + Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index fc0741cc5c..f6f1bad581 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -81,7 +81,15 @@ bool Polygon2D::_edit_use_rect() const { bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - return Geometry::is_point_in_polygon(p_point - get_offset(), Variant(polygon)); + Vector<Vector2> polygon2d = Variant(polygon); + if (internal_vertices > 0) { + polygon2d.resize(polygon2d.size() - internal_vertices); + } + return Geometry::is_point_in_polygon(p_point - get_offset(), polygon2d); +} + +void Polygon2D::_skeleton_bone_setup_changed() { + update(); } void Polygon2D::_notification(int p_what) { @@ -98,19 +106,44 @@ void Polygon2D::_notification(int p_what) { skeleton_node = Object::cast_to<Skeleton2D>(get_node(skeleton)); } - if (skeleton_node) + ObjectID new_skeleton_id = 0; + + if (skeleton_node) { VS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), skeleton_node->get_skeleton()); - else + new_skeleton_id = skeleton_node->get_instance_id(); + } else { VS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), RID()); + } + + if (new_skeleton_id != current_skeleton_id) { + Object *old_skeleton = ObjectDB::get_instance(current_skeleton_id); + if (old_skeleton) { + old_skeleton->disconnect("bone_setup_changed", this, "_skeleton_bone_setup_changed"); + } + + if (skeleton_node) { + skeleton_node->connect("bone_setup_changed", this, "_skeleton_bone_setup_changed"); + } + + current_skeleton_id = new_skeleton_id; + } Vector<Vector2> points; Vector<Vector2> uvs; Vector<int> bones; Vector<float> weights; - points.resize(polygon.size()); + int len = polygon.size(); + if ((invert || polygons.size() == 0) && internal_vertices > 0) { + //if no polygons are around, internal vertices must not be drawn, else let them be + len -= internal_vertices; + } + + if (len <= 0) { + return; + } + points.resize(len); - int len = points.size(); { PoolVector<Vector2>::Read polyr = polygon.read(); @@ -177,7 +210,8 @@ void Polygon2D::_notification(int p_what) { Transform2D texmat(tex_rot, tex_ofs); texmat.scale(tex_scale); Size2 tex_size = texture->get_size(); - uvs.resize(points.size()); + + uvs.resize(len); if (points.size() == uv.size()) { @@ -194,9 +228,9 @@ void Polygon2D::_notification(int p_what) { } } - if (!invert && bone_weights.size()) { + if (skeleton_node && !invert && bone_weights.size()) { //a skeleton is set! fill indices and weights - int vc = points.size(); + int vc = len; bones.resize(vc * 4); weights.resize(vc * 4); @@ -258,93 +292,247 @@ void Polygon2D::_notification(int p_what) { } Vector<Color> colors; - int color_len = vertex_colors.size(); - colors.resize(len); - { + if (vertex_colors.size() == points.size()) { + colors.resize(len); PoolVector<Color>::Read color_r = vertex_colors.read(); - for (int i = 0; i < color_len && i < len; i++) { + for (int i = 0; i < len; i++) { colors.write[i] = color_r[i]; } - for (int i = color_len; i < len; i++) { - colors.write[i] = color; - } + } else { + colors.push_back(color); } // Vector<int> indices = Geometry::triangulate_polygon(points); // VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, texture.is_valid() ? texture->get_rid() : RID()); - if (invert || splits.size() == 0) { + if (invert || polygons.size() == 0) { Vector<int> indices = Geometry::triangulate_polygon(points); - VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID()); + if (indices.size()) { + VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID()); + } } else { + //draw individual polygons + Vector<int> total_indices; + for (int i = 0; i < polygons.size(); i++) { + PoolVector<int> src_indices = polygons[i]; + int ic = src_indices.size(); + if (ic < 3) + continue; + PoolVector<int>::Read r = src_indices.read(); + + Vector<Vector2> tmp_points; + tmp_points.resize(ic); + + for (int j = 0; j < ic; j++) { + int idx = r[j]; + ERR_CONTINUE(idx < 0 || idx >= points.size()); + tmp_points.write[j] = points[r[j]]; + } + Vector<int> indices = Geometry::triangulate_polygon(tmp_points); + int ic2 = indices.size(); + const int *r2 = indices.ptr(); + + int bic = total_indices.size(); + total_indices.resize(bic + ic2); + int *w2 = total_indices.ptrw(); + + for (int j = 0; j < ic2; j++) { + w2[j + bic] = r[r2[j]]; + } + } + + if (total_indices.size()) { + VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), total_indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID()); + } + +#if 0 //use splits Vector<int> loop; int sc = splits.size(); PoolVector<int>::Read r = splits.read(); - int last = points.size(); + + print_line("has splits, amount " + itos(splits.size())); Vector<Vector<int> > loops; - for (int i = 0; i < last; i++) { + // find a point that can be used to begin, must not be in a split, and have to the left and right the same one + // like this one -> x---o + // \ / \ . + // o---o + int base_point = -1; + { + int current_point = -1; + int base_point_prev_split = -1; + + + for (int i = 0; i < points.size(); i++) { + + //find if this point is in a split + int split_index = -1; + bool has_prev_split = false; + int min_dist_to_end = 0x7FFFFFFF; + + for (int j = 0; j < sc; j += 2) { + + int split_pos = -1; + int split_end = -1; + + if (r[j + 0] == i) { //found split in first point + split_pos = r[j + 0]; + split_end = r[j + 1]; + } else if (r[j + 1] == i) { //found split in second point + split_pos = r[j + 1]; + split_end = r[j + 0]; + } + + if (split_pos == split_end) { + continue; //either nothing found or begin == end, this not a split in either case + } + + if (j == base_point_prev_split) { + has_prev_split = true; + } + + //compute distance from split pos to split end in current traversal direction + int dist_to_end = split_end > split_pos ? split_end - split_pos : (last - split_pos + split_end); + + if (dist_to_end < min_dist_to_end) { + //always keep the valid split with the least distance to the loop + min_dist_to_end = dist_to_end; + split_index = j; + } + } + + if (split_index == -1) { + current_point = i; //no split here, we are testing this point + } else if (has_prev_split) { + base_point = current_point; // there is a split and it contains the previous visited split, success + break; + } else { + //invalidate current point and keep split + current_point = -1; + base_point_prev_split = split_index; + } + } + } + + print_line("found base point: " + itos(base_point)); - int split; - int min_end = -1; + if (base_point != -1) { + int point = base_point; + int last = base_point; + //go through all the points, find splits do { - loop.push_back(i); + int split; + int last_dist_to_end = -1; //maximum valid distance to end - split = -1; - int end = -1; + do { - for (int j = 0; j < sc; j += 2) { - if (r[j + 1] >= last) - continue; //no longer valid - if (min_end != -1 && r[j + 1] >= min_end) - continue; - if (r[j] == i) { - if (split == -1 || r[j + 1] > end) { - split = r[j]; - end = r[j + 1]; + loop.push_back(point); //push current point + + split = -1; + int end = -1; + + int max_dist_to_end = 0; + + //find if this point is in a split + for (int j = 0; j < sc; j += 2) { + + int split_pos = -1; + int split_end = -1; + + if (r[j + 0] == point) { //match first split index + split_pos = r[j + 0]; + split_end = r[j + 1]; + } else if (r[j + 1] == point) { //match second split index + split_pos = r[j + 1]; + split_end = r[j + 0]; + } + + if (split_pos == split_end) { + continue; //either nothing found or begin == end, this not a split in either case + } + + //compute distance from split pos to split end + int dist_to_end = split_end > split_pos ? split_end - split_pos : (points.size() - split_pos + split_end); + + if (last_dist_to_end != -1 && dist_to_end >= last_dist_to_end) { + //distance must be shorter than in last iteration, means we've tested this before so ignore + continue; + } else if (dist_to_end > max_dist_to_end) { + //always keep the valid point with the most distance (as long as it's valid) + max_dist_to_end = dist_to_end; + split = split_pos; + end = split_end; } } - } - if (split != -1) { - for (int j = end; j < last; j++) { - loop.push_back(j); + if (split != -1) { + //found a split! + int from = end; + + //add points until last is reached + while (true) { + //find if point is in a split + loop.push_back(from); + + if (from == last) { + break; + } + + from++; + if (from >= points.size()) { //wrap if reached end + from = 0; + } + + if (from == loop[0]) { + break; //end because we reached split source + } + } + + loops.push_back(loop); //done with this loop + loop.clear(); + + last_dist_to_end = max_dist_to_end; + last = end; //algorithm can safely finish in this split point } - loops.push_back(loop); - last = end + 1; - loop.clear(); - min_end = end; //avoid this split from repeating - } - } while (split != -1); + } while (split != -1); + + } while (point != last); } - if (loop.size()) { + if (loop.size() >=2 ) { //points remained + //points remain + loop.push_back(last); //no splits found, use last loops.push_back(loop); } - Vector<int> indices; + print_line("total loops: " + itos(loops.size())); - for (int i = 0; i < loops.size(); i++) { - Vector<int> loop = loops[i]; - Vector<Vector2> vertices; - vertices.resize(loop.size()); - for (int j = 0; j < vertices.size(); j++) { - vertices.write[j] = points[loop[j]]; - } - Vector<int> sub_indices = Geometry::triangulate_polygon(vertices); - int from = indices.size(); - indices.resize(from + sub_indices.size()); - for (int j = 0; j < sub_indices.size(); j++) { - indices.write[from + j] = loop[sub_indices[j]]; + if (loops.size()) { //loops found + Vector<int> indices; + + for (int i = 0; i < loops.size(); i++) { + Vector<int> loop = loops[i]; + Vector<Vector2> vertices; + vertices.resize(loop.size()); + for (int j = 0; j < vertices.size(); j++) { + vertices.write[j] = points[loop[j]]; + } + Vector<int> sub_indices = Geometry::triangulate_polygon(vertices); + int from = indices.size(); + indices.resize(from + sub_indices.size()); + for (int j = 0; j < sub_indices.size(); j++) { + indices.write[from + j] = loop[sub_indices[j]]; + } } - } - VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID()); + VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID()); + } +#endif } } break; @@ -362,6 +550,15 @@ PoolVector<Vector2> Polygon2D::get_polygon() const { return polygon; } +void Polygon2D::set_internal_vertex_count(int p_count) { + + internal_vertices = p_count; +} + +int Polygon2D::get_internal_vertex_count() const { + return internal_vertices; +} + void Polygon2D::set_uv(const PoolVector<Vector2> &p_uv) { uv = p_uv; @@ -373,16 +570,15 @@ PoolVector<Vector2> Polygon2D::get_uv() const { return uv; } -void Polygon2D::set_splits(const PoolVector<int> &p_splits) { +void Polygon2D::set_polygons(const Array &p_polygons) { - ERR_FAIL_COND(p_splits.size() & 1); //splits should be multiple of 2 - splits = p_splits; + polygons = p_polygons; update(); } -PoolVector<int> Polygon2D::get_splits() const { +Array Polygon2D::get_polygons() const { - return splits; + return polygons; } void Polygon2D::set_color(const Color &p_color) { @@ -585,8 +781,8 @@ void Polygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color", "color"), &Polygon2D::set_color); ClassDB::bind_method(D_METHOD("get_color"), &Polygon2D::get_color); - ClassDB::bind_method(D_METHOD("set_splits", "splits"), &Polygon2D::set_splits); - ClassDB::bind_method(D_METHOD("get_splits"), &Polygon2D::get_splits); + ClassDB::bind_method(D_METHOD("set_polygons", "polygons"), &Polygon2D::set_polygons); + ClassDB::bind_method(D_METHOD("get_polygons"), &Polygon2D::get_polygons); ClassDB::bind_method(D_METHOD("set_vertex_colors", "vertex_colors"), &Polygon2D::set_vertex_colors); ClassDB::bind_method(D_METHOD("get_vertex_colors"), &Polygon2D::get_vertex_colors); @@ -630,14 +826,15 @@ void Polygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_skeleton", "skeleton"), &Polygon2D::set_skeleton); ClassDB::bind_method(D_METHOD("get_skeleton"), &Polygon2D::get_skeleton); + ClassDB::bind_method(D_METHOD("set_internal_vertex_count", "internal_vertex_count"), &Polygon2D::set_internal_vertex_count); + ClassDB::bind_method(D_METHOD("get_internal_vertex_count"), &Polygon2D::get_internal_vertex_count); + ClassDB::bind_method(D_METHOD("_set_bones", "bones"), &Polygon2D::_set_bones); ClassDB::bind_method(D_METHOD("_get_bones"), &Polygon2D::_get_bones); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "uv"), "set_uv", "get_uv"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "splits"), "set_splits", "get_splits"); + ClassDB::bind_method(D_METHOD("_skeleton_bone_setup_changed"), &Polygon2D::_skeleton_bone_setup_changed); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "vertex_colors"), "set_vertex_colors", "get_vertex_colors"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "get_antialiased"); ADD_GROUP("Texture", ""); @@ -654,7 +851,13 @@ void Polygon2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert_enable"), "set_invert", "get_invert"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "invert_border", PROPERTY_HINT_RANGE, "0.1,16384,0.1"), "set_invert_border", "get_invert_border"); + ADD_GROUP("Data", ""); + ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); + ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "uv"), "set_uv", "get_uv"); + ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "vertex_colors"), "set_vertex_colors", "get_vertex_colors"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons"), "set_polygons", "get_polygons"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bones", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_bones", "_get_bones"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "internal_vertex_count", PROPERTY_HINT_RANGE, "0,1000"), "set_internal_vertex_count", "get_internal_vertex_count"); } Polygon2D::Polygon2D() { @@ -667,4 +870,6 @@ Polygon2D::Polygon2D() { tex_scale = Vector2(1, 1); color = Color(1, 1, 1); rect_cache_dirty = true; + internal_vertices = 0; + current_skeleton_id = 0; } diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index 575f71d74a..f25b3885b0 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -40,7 +40,8 @@ class Polygon2D : public Node2D { PoolVector<Vector2> polygon; PoolVector<Vector2> uv; PoolVector<Color> vertex_colors; - PoolVector<int> splits; + Array polygons; + int internal_vertices; struct Bone { NodePath path; @@ -64,10 +65,13 @@ class Polygon2D : public Node2D { mutable Rect2 item_rect; NodePath skeleton; + ObjectID current_skeleton_id; Array _get_bones() const; void _set_bones(const Array &p_bones); + void _skeleton_bone_setup_changed(); + protected: void _notification(int p_what); static void _bind_methods(); @@ -87,11 +91,14 @@ public: void set_polygon(const PoolVector<Vector2> &p_polygon); PoolVector<Vector2> get_polygon() const; + void set_internal_vertex_count(int p_count); + int get_internal_vertex_count() const; + void set_uv(const PoolVector<Vector2> &p_uv); PoolVector<Vector2> get_uv() const; - void set_splits(const PoolVector<int> &p_uv); - PoolVector<int> get_splits() const; + void set_polygons(const Array &p_polygons); + Array get_polygons() const; void set_color(const Color &p_color); Color get_color() const; diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index 543314eefa..bed6f8a816 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/position_2d.h b/scene/2d/position_2d.h index bff474cccd..c95315fea3 100644 --- a/scene/2d/position_2d.h +++ b/scene/2d/position_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index f7c18a17df..57dfe5176d 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h index a438be87b6..f53f3ff07b 100644 --- a/scene/2d/ray_cast_2d.h +++ b/scene/2d/ray_cast_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp index f0274e5206..1c38a91877 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/remote_transform_2d.h b/scene/2d/remote_transform_2d.h index 3f395f820e..16a5417592 100644 --- a/scene/2d/remote_transform_2d.h +++ b/scene/2d/remote_transform_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 2c362f1b31..aa15255384 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -203,6 +203,7 @@ void Skeleton2D::_update_bone_setup() { transform_dirty = true; _update_transform(); + emit_signal("bone_setup_changed"); } void Skeleton2D::_make_transform_dirty() { @@ -291,6 +292,8 @@ void Skeleton2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_bone", "idx"), &Skeleton2D::get_bone); ClassDB::bind_method(D_METHOD("get_skeleton"), &Skeleton2D::get_skeleton); + + ADD_SIGNAL(MethodInfo("bone_setup_changed")); } Skeleton2D::Skeleton2D() { @@ -298,6 +301,7 @@ Skeleton2D::Skeleton2D() { transform_dirty = true; skeleton = VS::get_singleton()->skeleton_create(); + set_notify_transform(true); } Skeleton2D::~Skeleton2D() { diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h index 9d0a061457..cf9877e6f8 100644 --- a/scene/2d/skeleton_2d.h +++ b/scene/2d/skeleton_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index 04e199a21b..ba103a8bf0 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -435,22 +435,22 @@ void Sprite::_bind_methods() { ADD_SIGNAL(MethodInfo("frame_changed")); ADD_SIGNAL(MethodInfo("texture_changed")); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); ADD_GROUP("Offset", ""); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered"); - ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "flip_v"), "set_flip_v", "is_flipped_v"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_v"), "set_flip_v", "is_flipped_v"); ADD_GROUP("Animation", ""); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes"); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame"); ADD_GROUP("Region", "region_"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region", "is_region"); - ADD_PROPERTYNZ(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "region_filter_clip"), "set_region_filter_clip", "is_region_filter_clip_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region", "is_region"); + ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_filter_clip"), "set_region_filter_clip", "is_region_filter_clip_enabled"); } Sprite::Sprite() { diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h index ab444f89fc..e38db3a299 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 67e25ec508..ed0a9c4915 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -75,15 +75,15 @@ void TileMap::_notification(int p_what) { Quadrant &q = E->get(); if (navigation) { - for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) { + for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) { - navigation->navpoly_remove(E->get().id); + navigation->navpoly_remove(F->get().id); } q.navpoly_ids.clear(); } - for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) { - VS::get_singleton()->free(E->get().id); + for (Map<PosKey, Quadrant::Occluder>::Element *F = q.occluder_instances.front(); F; F = F->next()) { + VS::get_singleton()->free(F->get().id); } q.occluder_instances.clear(); } @@ -129,14 +129,14 @@ void TileMap::_update_quadrant_transform() { Physics2DServer::get_singleton()->body_set_state(q.body, Physics2DServer::BODY_STATE_TRANSFORM, xform); if (navigation) { - for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) { + for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) { - navigation->navpoly_set_transform(E->get().id, nav_rel * E->get().xform); + navigation->navpoly_set_transform(F->get().id, nav_rel * F->get().xform); } } - for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) { - VS::get_singleton()->canvas_light_occluder_set_transform(E->get().id, global_transform * E->get().xform); + for (Map<PosKey, Quadrant::Occluder>::Element *F = q.occluder_instances.front(); F; F = F->next()) { + VS::get_singleton()->canvas_light_occluder_set_transform(F->get().id, global_transform * F->get().xform); } } } @@ -327,6 +327,11 @@ void TileMap::update_dirty_quadrants() { Ref<ShaderMaterial> mat = tile_set->tile_get_material(c.id); int z_index = tile_set->tile_get_z_index(c.id); + if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE || + tile_set->tile_get_tile_mode(c.id) == TileSet::ATLAS_TILE) { + z_index += tile_set->autotile_get_z_index(c.id, Vector2(c.autotile_coord_x, c.autotile_coord_y)); + } + RID canvas_item; RID debug_canvas_item; @@ -372,13 +377,12 @@ void TileMap::update_dirty_quadrants() { r.size = tile_set->autotile_get_size(c.id); r.position += (r.size + Vector2(spacing, spacing)) * Vector2(c.autotile_coord_x, c.autotile_coord_y); } - Size2 s = tex->get_size(); + Size2 s; if (r == Rect2()) s = tex->get_size(); - else { + else s = r.size; - } Rect2 rect; rect.position = offset.floor(); @@ -458,27 +462,45 @@ void TileMap::update_dirty_quadrants() { Vector<TileSet::ShapeData> shapes = tile_set->tile_get_shapes(c.id); - for (int i = 0; i < shapes.size(); i++) { - Ref<Shape2D> shape = shapes[i].shape; + for (int j = 0; j < shapes.size(); j++) { + Ref<Shape2D> shape = shapes[j].shape; if (shape.is_valid()) { - if (tile_set->tile_get_tile_mode(c.id) == TileSet::SINGLE_TILE || (shapes[i].autotile_coord.x == c.autotile_coord_x && shapes[i].autotile_coord.y == c.autotile_coord_y)) { + if (tile_set->tile_get_tile_mode(c.id) == TileSet::SINGLE_TILE || (shapes[j].autotile_coord.x == c.autotile_coord_x && shapes[j].autotile_coord.y == c.autotile_coord_y)) { Transform2D xform; xform.set_origin(offset.floor()); - Vector2 shape_ofs = shapes[i].shape_transform.get_origin(); + Vector2 shape_ofs = shapes[j].shape_transform.get_origin(); _fix_cell_transform(xform, c, shape_ofs + center_ofs, s); - xform *= shapes[i].shape_transform.untranslated(); + xform *= shapes[j].shape_transform.untranslated(); if (debug_canvas_item.is_valid()) { vs->canvas_item_add_set_transform(debug_canvas_item, xform); shape->draw(debug_canvas_item, debug_collision_color); } - ps->body_add_shape(q.body, shape->get_rid(), xform); - ps->body_set_shape_metadata(q.body, shape_idx, Vector2(E->key().x, E->key().y)); - ps->body_set_shape_as_one_way_collision(q.body, shape_idx, shapes[i].one_way_collision); - shape_idx++; + + if (shape->has_meta("decomposed")) { + Array _shapes = shape->get_meta("decomposed"); + for (int k = 0; k < _shapes.size(); k++) { + Ref<ConvexPolygonShape2D> convex = _shapes[k]; + if (convex.is_valid()) { + ps->body_add_shape(q.body, convex->get_rid(), xform); + ps->body_set_shape_metadata(q.body, shape_idx, Vector2(E->key().x, E->key().y)); + ps->body_set_shape_as_one_way_collision(q.body, shape_idx, shapes[j].one_way_collision, shapes[j].one_way_collision_margin); + shape_idx++; +#ifdef DEBUG_ENABLED + } else { + print_error("The TileSet asigned to the TileMap " + get_name() + " has an invalid convex shape."); +#endif + } + } + } else { + ps->body_add_shape(q.body, shape->get_rid(), xform); + ps->body_set_shape_metadata(q.body, shape_idx, Vector2(E->key().x, E->key().y)); + ps->body_set_shape_as_one_way_collision(q.body, shape_idx, shapes[j].one_way_collision, shapes[j].one_way_collision_margin); + shape_idx++; + } } } } @@ -527,23 +549,23 @@ void TileMap::update_dirty_quadrants() { colors.resize(vsize); { PoolVector<Vector2>::Read vr = navigation_polygon_vertices.read(); - for (int i = 0; i < vsize; i++) { - vertices.write[i] = vr[i]; - colors.write[i] = debug_navigation_color; + for (int j = 0; j < vsize; j++) { + vertices.write[j] = vr[j]; + colors.write[j] = debug_navigation_color; } } Vector<int> indices; - for (int i = 0; i < navpoly->get_polygon_count(); i++) { - Vector<int> polygon = navpoly->get_polygon(i); + for (int j = 0; j < navpoly->get_polygon_count(); j++) { + Vector<int> polygon = navpoly->get_polygon(j); - for (int j = 2; j < polygon.size(); j++) { + for (int k = 2; k < polygon.size(); k++) { - int kofs[3] = { 0, j - 1, j }; - for (int k = 0; k < 3; k++) { + int kofs[3] = { 0, k - 1, k }; + for (int l = 0; l < 3; l++) { - int idx = polygon[kofs[k]]; + int idx = polygon[kofs[l]]; ERR_FAIL_INDEX(idx, vsize); indices.push_back(idx); } @@ -597,9 +619,9 @@ void TileMap::update_dirty_quadrants() { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { Quadrant &q = E->get(); - for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { + for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) { - VS::get_singleton()->canvas_item_set_draw_index(E->get(), index++); + VS::get_singleton()->canvas_item_set_draw_index(F->get(), index++); } } @@ -835,7 +857,7 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) { Map<PosKey, Cell>::Element *E = tile_map.find(p); if (E != NULL) { int id = get_cell(p_x, p_y); - if (tile_set->tile_get_tile_mode(id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(id) == TileSet::ATLAS_TILE) { + if (tile_set->tile_get_tile_mode(id) == TileSet::AUTO_TILE) { uint16_t mask = 0; if (tile_set->autotile_get_bitmask_mode(id) == TileSet::BITMASK_2X2) { if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) { @@ -899,7 +921,8 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) { PosKey qk(p_x / _get_quadrant_size(), p_y / _get_quadrant_size()); Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk); _make_quadrant_dirty(Q); - } else { + + } else if (tile_set->tile_get_tile_mode(id) == TileSet::SINGLE_TILE) { E->get().autotile_coord_x = 0; E->get().autotile_coord_y = 0; } @@ -1048,9 +1071,9 @@ void TileMap::_update_all_items_material_state() { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { Quadrant &q = E->get(); - for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { + for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) { - _update_item_material_state(E->get()); + _update_item_material_state(F->get()); } } } @@ -1114,6 +1137,8 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) { */ set_cell(x, y, v, flip_h, flip_v, transpose, Vector2(coord_x, coord_y)); } + + format = FORMAT_2; } PoolVector<int> TileMap::_get_tile_data() const { @@ -1403,7 +1428,7 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) { bool TileMap::_get(const StringName &p_name, Variant &r_ret) const { if (p_name == "format") { - r_ret = FORMAT_2; + r_ret = format; return true; } else if (p_name == "tile_data") { r_ret = _get_tile_data(); @@ -1445,6 +1470,11 @@ Vector2 TileMap::world_to_map(const Vector2 &p_pos) const { default: {} } + // Account for precision errors on the border (GH-23250). + // 0.00005 is 5*CMP_EPSILON, results would start being unpredictable if + // cell size is > 15,000, but we can hardly have more precision anyway with + // floating point. + ret += Vector2(0.00005, 0.00005); return ret.floor(); } @@ -1618,6 +1648,8 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("is_cell_y_flipped", "x", "y"), &TileMap::is_cell_y_flipped); ClassDB::bind_method(D_METHOD("is_cell_transposed", "x", "y"), &TileMap::is_cell_transposed); + ClassDB::bind_method(D_METHOD("get_cell_autotile_coord", "x", "y"), &TileMap::get_cell_autotile_coord); + ClassDB::bind_method(D_METHOD("fix_invalid_tiles"), &TileMap::fix_invalid_tiles); ClassDB::bind_method(D_METHOD("clear"), &TileMap::clear); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 499c79b180..e450e1e256 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,7 +33,7 @@ #include "core/self_list.h" #include "core/vset.h" -#include "scene/2d/navigation2d.h" +#include "scene/2d/navigation_2d.h" #include "scene/2d/node_2d.h" #include "scene/resources/tile_set.h" diff --git a/scene/2d/screen_button.cpp b/scene/2d/touch_screen_button.cpp index 44a41328e8..9a1a759e72 100644 --- a/scene/2d/screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -1,12 +1,12 @@ /*************************************************************************/ -/* screen_button.cpp */ +/* touch_screen_button.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "screen_button.h" +#include "touch_screen_button.h" + #include "core/input_map.h" #include "core/os/input.h" #include "core/os/os.h" diff --git a/scene/2d/screen_button.h b/scene/2d/touch_screen_button.h index 3e8adc2e5e..df54e5340b 100644 --- a/scene/2d/screen_button.h +++ b/scene/2d/touch_screen_button.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* screen_button.h */ +/* touch_screen_button.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCREEN_BUTTON_H -#define SCREEN_BUTTON_H +#ifndef TOUCH_SCREEN_BUTTON_H +#define TOUCH_SCREEN_BUTTON_H #include "scene/2d/node_2d.h" -#include "scene/resources/bit_mask.h" +#include "scene/resources/bit_map.h" #include "scene/resources/rectangle_shape_2d.h" #include "scene/resources/texture.h" @@ -112,4 +112,4 @@ public: VARIANT_ENUM_CAST(TouchScreenButton::VisibilityMode); -#endif // SCREEN_BUTTON_H +#endif // TOUCH_SCREEN_BUTTON_H diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index 7d7c47619a..1cf037daf2 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -190,7 +190,7 @@ void VisibilityEnabler2D::_find_nodes(Node *p_node) { if (enabler[ENABLER_FREEZE_BODIES]) { RigidBody2D *rb2d = Object::cast_to<RigidBody2D>(p_node); - if (rb2d && ((rb2d->get_mode() == RigidBody2D::MODE_CHARACTER || (rb2d->get_mode() == RigidBody2D::MODE_RIGID && !rb2d->is_able_to_sleep())))) { + if (rb2d && ((rb2d->get_mode() == RigidBody2D::MODE_CHARACTER || rb2d->get_mode() == RigidBody2D::MODE_RIGID))) { add = true; meta = rb2d->get_mode(); diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h index 04084b609a..259368455b 100644 --- a/scene/2d/visibility_notifier_2d.h +++ b/scene/2d/visibility_notifier_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/y_sort.cpp b/scene/2d/y_sort.cpp index d3997c13c3..d7e523e189 100644 --- a/scene/2d/y_sort.cpp +++ b/scene/2d/y_sort.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/2d/y_sort.h b/scene/2d/y_sort.h index 5ff12aa25a..1bf757720e 100644 --- a/scene/2d/y_sort.h +++ b/scene/2d/y_sort.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/SCsub b/scene/3d/SCsub index 35cc7479d8..200cf4316f 100644 --- a/scene/3d/SCsub +++ b/scene/3d/SCsub @@ -7,6 +7,6 @@ if env['disable_3d']: env.scene_sources.append("3d/skeleton.cpp") env.scene_sources.append("3d/particles.cpp") env.scene_sources.append("3d/visual_instance.cpp") - env.scene_sources.append("3d/scenario_fx.cpp") + env.scene_sources.append("3d/world_environment.cpp") else: env.add_source_files(env.scene_sources, "*.cpp") diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp index 40a1029201..e58e26d2d1 100644 --- a/scene/3d/area.cpp +++ b/scene/3d/area.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -157,7 +157,9 @@ void Area::_body_inout(int p_status, const RID &p_body, int p_instance, int p_bo Map<ObjectID, BodyState>::Element *E = body_map.find(objid); - ERR_FAIL_COND(!body_in && !E); + if (!body_in && !E) { + return; //likely removed from the tree + } locked = true; @@ -290,7 +292,7 @@ void Area::_notification(int p_what) { void Area::set_monitoring(bool p_enable) { if (locked) { - ERR_EXPLAIN("This function can't be used during the in/out signal."); + ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitoring\",true/false)"); } ERR_FAIL_COND(locked); @@ -437,10 +439,10 @@ Array Area::get_overlapping_bodies() const { void Area::set_monitorable(bool p_enable) { - if (locked) { - ERR_EXPLAIN("This function can't be used during the in/out signal."); + if (locked || (is_inside_tree() && PhysicsServer::get_singleton()->is_flushing_queries())) { + ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitorable\",true/false)"); + ERR_FAIL(); } - ERR_FAIL_COND(locked); if (p_enable == monitorable) return; @@ -751,6 +753,7 @@ Area::Area() : angular_damp = 1; priority = 0; monitoring = false; + monitorable = false; collision_mask = 1; collision_layer = 1; set_ray_pickable(false); diff --git a/scene/3d/area.h b/scene/3d/area.h index e1ff1079e3..043d651e04 100644 --- a/scene/3d/area.h +++ b/scene/3d/area.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp index 2dc500f7ab..17b698c1b8 100644 --- a/scene/3d/arvr_nodes.cpp +++ b/scene/3d/arvr_nodes.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -266,6 +266,7 @@ void ARVRController::set_controller_id(int p_controller_id) { // We don't check any bounds here, this controller may not yet be active and just be a place holder until it is. // Note that setting this to 0 means this node is not bound to a controller yet. controller_id = p_controller_id; + update_configuration_warning(); }; int ARVRController::get_controller_id(void) const { @@ -446,6 +447,7 @@ void ARVRAnchor::set_anchor_id(int p_anchor_id) { // We don't check any bounds here, this anchor may not yet be active and just be a place holder until it is. // Note that setting this to 0 means this node is not bound to an anchor yet. anchor_id = p_anchor_id; + update_configuration_warning(); }; int ARVRAnchor::get_anchor_id(void) const { diff --git a/scene/3d/arvr_nodes.h b/scene/3d/arvr_nodes.h index d6690676cc..523bc112c1 100644 --- a/scene/3d/arvr_nodes.h +++ b/scene/3d/arvr_nodes.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 3046cad624..4b3934c4ea 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,11 +32,13 @@ #include "core/engine.h" #include "scene/3d/area.h" #include "scene/3d/camera.h" +#include "scene/3d/listener.h" #include "scene/main/viewport.h" + void AudioStreamPlayer3D::_mix_audio() { if (!stream_playback.is_valid() || !active || - (stream_paused && !stream_paused_fade_out)) { + (stream_paused && !stream_fade_out)) { return; } @@ -51,7 +53,7 @@ void AudioStreamPlayer3D::_mix_audio() { AudioFrame *buffer = mix_buffer.ptrw(); int buffer_size = mix_buffer.size(); - if (stream_paused_fade_out) { + if (stream_fade_out) { // Short fadeout ramp buffer_size = MIN(buffer_size, 128); } @@ -107,13 +109,15 @@ void AudioStreamPlayer3D::_mix_audio() { int buffers = AudioServer::get_singleton()->get_channel_count(); for (int k = 0; k < buffers; 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 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 vol_inc = (target_volume - vol_prev) / float(buffer_size); - AudioFrame vol = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : current.vol[k]; + AudioFrame vol = stream_fade_in ? AudioFrame(0.f, 0.f) : current.vol[k]; - AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k); + if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, k)) + continue; //may have been deleted, will be updated on process + AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k); current.filter.set_mode(AudioFilterSW::HIGHSHELF); current.filter.set_sampling_rate(AudioServer::get_singleton()->get_mix_rate()); current.filter.set_cutoff(attenuation_filter_cutoff_hz); @@ -159,6 +163,9 @@ void AudioStreamPlayer3D::_mix_audio() { if (current.reverb_bus_index >= 0) { + if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.reverb_bus_index, k)) + continue; //may have been deleted, will be updated on process + AudioFrame *rtarget = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.reverb_bus_index, k); if (current.reverb_bus_index == prev_outputs[i].reverb_bus_index) { @@ -191,9 +198,15 @@ void AudioStreamPlayer3D::_mix_audio() { active = false; } + if (stream_stop) { + active = false; + set_physics_process_internal(false); + setplay = -1; + } + output_ready = false; - stream_paused_fade_in = false; - stream_paused_fade_out = false; + stream_fade_in = false; + stream_fade_out = false; } float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const { @@ -201,15 +214,15 @@ float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const { float att = 0; switch (attenuation_model) { case ATTENUATION_INVERSE_DISTANCE: { - att = Math::linear2db(1.0 / ((p_distance / unit_size) + 000001)); + att = Math::linear2db(1.0 / ((p_distance / unit_size) + CMP_EPSILON)); } break; case ATTENUATION_INVERSE_SQUARE_DISTANCE: { float d = (p_distance / unit_size); d *= d; - att = Math::linear2db(1.0 / (d + 0.00001)); + att = Math::linear2db(1.0 / (d + CMP_EPSILON)); } break; case ATTENUATION_LOGARITHMIC: { - att = -20 * Math::log(p_distance / unit_size + 000001); + att = -20 * Math::log(p_distance / unit_size + CMP_EPSILON); } break; default: { ERR_PRINT("Unknown attenuation type"); @@ -318,16 +331,25 @@ void AudioStreamPlayer3D::_notification(int p_what) { if (!vp->is_audio_listener()) continue; - Vector3 local_pos = camera->get_global_transform().orthonormalized().affine_inverse().xform(global_pos); + bool listener_is_camera = true; + Spatial *listener_node = camera; + + Listener *listener = vp->get_listener(); + if (listener) { + listener_node = listener; + listener_is_camera = false; + } + + Vector3 local_pos = listener_node->get_global_transform().orthonormalized().affine_inverse().xform(global_pos); float dist = local_pos.length(); Vector3 area_sound_pos; - Vector3 cam_area_pos; + Vector3 listener_area_pos; if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) { - area_sound_pos = space_state->get_closest_point_to_object_volume(area->get_rid(), camera->get_global_transform().origin); - cam_area_pos = camera->get_global_transform().affine_inverse().xform(area_sound_pos); + area_sound_pos = space_state->get_closest_point_to_object_volume(area->get_rid(), listener_node->get_global_transform().origin); + listener_area_pos = listener_node->get_global_transform().affine_inverse().xform(area_sound_pos); } if (max_distance > 0) { @@ -335,10 +357,10 @@ void AudioStreamPlayer3D::_notification(int p_what) { float total_max = max_distance; if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) { - total_max = MAX(total_max, cam_area_pos.length()); + total_max = MAX(total_max, listener_area_pos.length()); } if (total_max > max_distance) { - continue; //can't hear this sound in this camera + continue; //can't hear this sound in this listener } } @@ -355,8 +377,8 @@ void AudioStreamPlayer3D::_notification(int p_what) { float db_att = (1.0 - MIN(1.0, multiplier)) * attenuation_filter_db; if (emission_angle_enabled) { - Vector3 camtopos = global_pos - camera->get_global_transform().origin; - float c = camtopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative + Vector3 listenertopos = global_pos - listener_node->get_global_transform().origin; + float c = listenertopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative float angle = Math::rad2deg(Math::acos(c)); if (angle > emission_angle) db_att -= -emission_angle_filter_attenuation_db; @@ -376,8 +398,8 @@ void AudioStreamPlayer3D::_notification(int p_what) { output.vol[0].l = 1.0 - c; output.vol[0].r = c; } else { - Vector3 camtopos = global_pos - camera->get_global_transform().origin; - float c = camtopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative + Vector3 listenertopos = global_pos - listener_node->get_global_transform().origin; + float c = listenertopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative float angle = Math::rad2deg(Math::acos(c)); float av = angle * (flat_pos.x < 0 ? -1 : 1) / 180.0; @@ -400,20 +422,20 @@ void AudioStreamPlayer3D::_notification(int p_what) { if (cc >= 3) { // Side pair - float sl = Math::abs(1.0 - Math::abs(-0.4 - av)); - float sr = Math::abs(1.0 - Math::abs(0.4 - av)); + float sleft = Math::abs(1.0 - Math::abs(-0.4 - av)); + float sright = Math::abs(1.0 - Math::abs(0.4 - av)); - output.vol[2].l = sl; - output.vol[2].r = sr; + output.vol[2].l = sleft; + output.vol[2].r = sright; } if (cc >= 4) { // Rear pair - float rl = Math::abs(1.0 - Math::abs(-0.2 - av)); - float rr = Math::abs(1.0 - Math::abs(0.2 - av)); + float rleft = Math::abs(1.0 - Math::abs(-0.2 - av)); + float rright = Math::abs(1.0 - Math::abs(0.2 - av)); - output.vol[3].l = rl; - output.vol[3].r = rr; + output.vol[3].l = rleft; + output.vol[3].r = rright; } } @@ -443,7 +465,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { if (uniformity > 0.0) { - float distance = cam_area_pos.length(); + float distance = listener_area_pos.length(); float attenuation = Math::db2linear(_get_attenuation_db(distance)); //float dist_att_db = -20 * Math::log(dist + 0.00001); //logarithmic attenuation, like in real life @@ -453,7 +475,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { if (attenuation < 1.0) { //pan the uniform sound - Vector3 rev_pos = cam_area_pos; + Vector3 rev_pos = listener_area_pos; rev_pos.y = 0; rev_pos.normalize(); @@ -512,9 +534,13 @@ void AudioStreamPlayer3D::_notification(int p_what) { if (doppler_tracking != DOPPLER_TRACKING_DISABLED) { - Vector3 camera_velocity = camera->get_doppler_tracked_velocity(); + Vector3 listener_velocity; - Vector3 local_velocity = camera->get_global_transform().orthonormalized().basis.xform_inv(linear_velocity - camera_velocity); + if (listener_is_camera) { + listener_velocity = camera->get_doppler_tracked_velocity(); + } + + Vector3 local_velocity = listener_node->get_global_transform().orthonormalized().basis.xform_inv(linear_velocity - listener_velocity); if (local_velocity == Vector3()) { output.pitch_scale = 1.0; @@ -636,6 +662,8 @@ 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; set_physics_process_internal(true); @@ -652,9 +680,8 @@ void AudioStreamPlayer3D::seek(float p_seconds) { void AudioStreamPlayer3D::stop() { if (stream_playback.is_valid()) { - active = false; - set_physics_process_internal(false); - setplay = -1; + stream_stop = true; + stream_fade_out = true; } } @@ -833,7 +860,9 @@ void AudioStreamPlayer3D::set_doppler_tracking(DopplerTracking p_tracking) { if (doppler_tracking != DOPPLER_TRACKING_DISABLED) { set_notify_transform(true); velocity_tracker->set_track_physics_step(doppler_tracking == DOPPLER_TRACKING_PHYSICS_STEP); - velocity_tracker->reset(get_global_transform().origin); + if (is_inside_tree()) { + velocity_tracker->reset(get_global_transform().origin); + } } else { set_notify_transform(false); } @@ -848,8 +877,8 @@ void AudioStreamPlayer3D::set_stream_paused(bool p_pause) { if (p_pause != stream_paused) { stream_paused = p_pause; - stream_paused_fade_in = stream_paused ? false : true; - stream_paused_fade_out = stream_paused ? true : false; + stream_fade_in = stream_paused ? false : true; + stream_fade_out = stream_paused ? true : false; } } @@ -987,8 +1016,9 @@ AudioStreamPlayer3D::AudioStreamPlayer3D() { out_of_range_mode = OUT_OF_RANGE_MIX; doppler_tracking = DOPPLER_TRACKING_DISABLED; stream_paused = false; - stream_paused_fade_in = false; - stream_paused_fade_out = false; + stream_fade_in = false; + stream_fade_out = false; + stream_stop = 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 14413d0702..e467c170fb 100644 --- a/scene/3d/audio_stream_player_3d.h +++ b/scene/3d/audio_stream_player_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -109,8 +109,9 @@ private: float pitch_scale; bool autoplay; bool stream_paused; - bool stream_paused_fade_in; - bool stream_paused_fade_out; + bool stream_fade_in; + bool stream_fade_out; + bool stream_stop; StringName bus; void _mix_audio(); diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp index 62589bd67e..d66e6cc83d 100644 --- a/scene/3d/baked_lightmap.cpp +++ b/scene/3d/baked_lightmap.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/baked_lightmap.h b/scene/3d/baked_lightmap.h index 60b62f74eb..bb3f84719a 100644 --- a/scene/3d/baked_lightmap.h +++ b/scene/3d/baked_lightmap.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/bone_attachment.cpp b/scene/3d/bone_attachment.cpp index a875b65c22..0233029435 100644 --- a/scene/3d/bone_attachment.cpp +++ b/scene/3d/bone_attachment.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/bone_attachment.h b/scene/3d/bone_attachment.h index 81a225015e..051e2b4c56 100644 --- a/scene/3d/bone_attachment.h +++ b/scene/3d/bone_attachment.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 8ef64e2e80..368cebeeab 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -449,7 +449,9 @@ void Camera::set_doppler_tracking(DopplerTracking p_tracking) { doppler_tracking = p_tracking; if (p_tracking != DOPPLER_TRACKING_DISABLED) { velocity_tracker->set_track_physics_step(doppler_tracking == DOPPLER_TRACKING_PHYSICS_STEP); - velocity_tracker->reset(get_global_transform().origin); + if (is_inside_tree()) { + velocity_tracker->reset(get_global_transform().origin); + } } _update_camera_mode(); } @@ -495,6 +497,7 @@ void Camera::_bind_methods() { ClassDB::bind_method(D_METHOD("get_keep_aspect_mode"), &Camera::get_keep_aspect_mode); ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &Camera::set_doppler_tracking); ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &Camera::get_doppler_tracking); + ClassDB::bind_method(D_METHOD("get_frustum"), &Camera::get_frustum); ClassDB::bind_method(D_METHOD("set_cull_mask_bit", "layer", "enable"), &Camera::set_cull_mask_bit); ClassDB::bind_method(D_METHOD("get_cull_mask_bit", "layer"), &Camera::get_cull_mask_bit); diff --git a/scene/3d/camera.h b/scene/3d/camera.h index a35c9d6e7f..a531324a85 100644 --- a/scene/3d/camera.h +++ b/scene/3d/camera.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/collision_object.cpp b/scene/3d/collision_object.cpp index 99b8ce0567..d8c2042c88 100644 --- a/scene/3d/collision_object.cpp +++ b/scene/3d/collision_object.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/collision_object.h b/scene/3d/collision_object.h index f8ef04b78f..90f370b6d4 100644 --- a/scene/3d/collision_object.h +++ b/scene/3d/collision_object.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/collision_polygon.cpp b/scene/3d/collision_polygon.cpp index 379dd21c39..db07059b32 100644 --- a/scene/3d/collision_polygon.cpp +++ b/scene/3d/collision_polygon.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/collision_polygon.h b/scene/3d/collision_polygon.h index f1f137c9c5..04c00fc70f 100644 --- a/scene/3d/collision_polygon.h +++ b/scene/3d/collision_polygon.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/collision_shape.cpp b/scene/3d/collision_shape.cpp index 4fd68fb47d..ac33e2b714 100644 --- a/scene/3d/collision_shape.cpp +++ b/scene/3d/collision_shape.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -124,6 +124,10 @@ String CollisionShape::get_configuration_warning() const { return TTR("A shape must be provided for CollisionShape to function. Please create a shape resource for it!"); } + if (shape->is_class("PlaneShape")) { + return TTR("Plane shapes don't work well and will be removed in future versions. Please don't use them."); + } + return String(); } diff --git a/scene/3d/collision_shape.h b/scene/3d/collision_shape.h index 6ca8e80ea1..0c8e383a7f 100644 --- a/scene/3d/collision_shape.h +++ b/scene/3d/collision_shape.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index 35a2049bda..11dfbdb1f9 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -198,6 +198,35 @@ String CPUParticles::get_configuration_warning() const { String warnings; + bool mesh_found = false; + bool anim_material_found = false; + + if (get_mesh().is_valid()) { + mesh_found = true; + for (int j = 0; j < get_mesh()->get_surface_count(); j++) { + anim_material_found = Object::cast_to<ShaderMaterial>(get_mesh()->surface_get_material(j).ptr()) != NULL; + SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(get_mesh()->surface_get_material(j).ptr()); + anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES); + } + } + + anim_material_found = anim_material_found || Object::cast_to<ShaderMaterial>(get_material_override().ptr()) != NULL; + SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(get_material_override().ptr()); + anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES); + + if (!mesh_found) { + if (warnings != String()) + warnings += "\n"; + warnings += "- " + TTR("Nothing is visible because no mesh has been assigned."); + } + + if (!anim_material_found && (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 || + get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid())) { + if (warnings != String()) + warnings += "\n"; + warnings += "- " + TTR("CPUParticles animation requires the usage of a SpatialMaterial with \"Billboard Particles\" enabled."); + } + return warnings; } @@ -494,7 +523,7 @@ void CPUParticles::_particles_process(float p_delta) { Basis velocity_xform; if (!local_coords) { emission_xform = get_global_transform(); - velocity_xform = emission_xform.basis.inverse().transposed(); + velocity_xform = emission_xform.basis; } for (int i = 0; i < pcount; i++) { @@ -576,19 +605,14 @@ void CPUParticles::_particles_process(float p_delta) { p.hue_rot_rand = Math::randf(); p.anim_offset_rand = Math::randf(); - float angle1_rad; - float angle2_rad; - if (flags[FLAG_DISABLE_Z]) { - - angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; + float angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0); p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); - } else { //initiate velocity spread in 3D - angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; - angle2_rad = (Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * Math_PI * spread / 180.0; + float angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; + float angle2_rad = (Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * Math_PI * spread / 180.0; Vector3 direction_xz = Vector3(Math::sin(angle1_rad), 0, Math::cos(angle1_rad)); Vector3 direction_yz = Vector3(0, Math::sin(angle2_rad), Math::cos(angle2_rad)); @@ -662,7 +686,7 @@ void CPUParticles::_particles_process(float p_delta) { if (flags[FLAG_DISABLE_Z]) { p.velocity.z = 0.0; - p.velocity.z = 0.0; + p.transform.origin.z = 0.0; } } else if (!p.active) { @@ -728,15 +752,15 @@ void CPUParticles::_particles_process(float p_delta) { } Vector3 force = gravity; - Vector3 pos = p.transform.origin; + Vector3 position = p.transform.origin; if (flags[FLAG_DISABLE_Z]) { - pos.z = 0.0; + position.z = 0.0; } //apply linear acceleration force += p.velocity.length() > 0.0 ? p.velocity.normalized() * (parameters[PARAM_LINEAR_ACCEL] + tex_linear_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_LINEAR_ACCEL]) : Vector3(); //apply radial acceleration Vector3 org = emission_xform.origin; - Vector3 diff = pos - org; + Vector3 diff = position - org; force += diff.length() > 0.0 ? diff.normalized() * (parameters[PARAM_RADIAL_ACCEL] + tex_radial_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_RADIAL_ACCEL]) : Vector3(); //apply tangential acceleration; if (flags[FLAG_DISABLE_Z]) { @@ -781,12 +805,6 @@ void CPUParticles::_particles_process(float p_delta) { base_angle += p.custom[1] * lifetime * (parameters[PARAM_ANGULAR_VELOCITY] + tex_angular_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed) * 2.0f - 1.0f, randomness[PARAM_ANGULAR_VELOCITY]); p.custom[0] = Math::deg2rad(base_angle); //angle p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]) + p.custom[1] * (parameters[PARAM_ANIM_SPEED] + tex_anim_speed) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ANIM_SPEED]); //angle - if (flags[FLAG_ANIM_LOOP]) { - p.custom[2] = Math::fmod(p.custom[2], 1.0f); //loop - - } else { - p.custom[2] = CLAMP(p.custom[2], 0.0f, 1.0); //0 to 1 only - } } //apply color //apply hue rotation @@ -1151,7 +1169,6 @@ void CPUParticles::convert_from_particles(Node *p_particles) { set_particle_flag(FLAG_ALIGN_Y_TO_VELOCITY, material->get_flag(ParticlesMaterial::FLAG_ALIGN_Y_TO_VELOCITY)); set_particle_flag(FLAG_ROTATE_Y, material->get_flag(ParticlesMaterial::FLAG_ROTATE_Y)); set_particle_flag(FLAG_DISABLE_Z, material->get_flag(ParticlesMaterial::FLAG_DISABLE_Z)); - set_particle_flag(FLAG_ANIM_LOOP, material->get_flag(ParticlesMaterial::FLAG_ANIM_LOOP)); set_emission_shape(EmissionShape(material->get_emission_shape())); set_emission_sphere_radius(material->get_emission_sphere_radius()); @@ -1221,7 +1238,7 @@ void CPUParticles::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_EXP_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); @@ -1309,7 +1326,7 @@ void CPUParticles::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY); ADD_GROUP("Angular Velocity", "angular_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-360,360,0.01"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGULAR_VELOCITY); /* @@ -1339,15 +1356,15 @@ void CPUParticles::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGLE); ADD_GROUP("Scale", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_amount", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_amount_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_amount_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_SCALE); ADD_GROUP("Color", ""); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_color_ramp", "get_color_ramp"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp"); ADD_GROUP("Hue Variation", "hue_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.1"), "set_param", "get_param", PARAM_HUE_VARIATION); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_HUE_VARIATION); ADD_GROUP("Animation", "anim_"); @@ -1357,7 +1374,6 @@ void CPUParticles::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_OFFSET); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "anim_loop"), "set_particle_flag", "get_particle_flag", FLAG_ANIM_LOOP); BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY); BIND_ENUM_CONSTANT(PARAM_ANGULAR_VELOCITY); diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h index 77a144b70b..b50befe7be 100644 --- a/scene/3d/cpu_particles.h +++ b/scene/3d/cpu_particles.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -70,7 +70,6 @@ public: FLAG_ALIGN_Y_TO_VELOCITY, FLAG_ROTATE_Y, FLAG_DISABLE_Z, - FLAG_ANIM_LOOP, FLAG_MAX }; @@ -170,7 +169,6 @@ private: PoolVector<Color> emission_colors; int emission_point_count; - bool anim_loop; Vector3 gravity; void _particles_process(float p_delta); diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index 6276d02eff..c491275f00 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,6 +30,8 @@ #include "gi_probe.h" +#include "core/os/os.h" + #include "mesh_instance.h" #include "voxel_light_baker.h" @@ -490,6 +492,14 @@ PoolVector<Face3> GIProbe::get_faces(uint32_t p_usage_flags) const { return PoolVector<Face3>(); } +String GIProbe::get_configuration_warning() const { + + if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) { + return TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead."); + } + return String(); +} + void GIProbe::_bind_methods() { ClassDB::bind_method(D_METHOD("set_probe_data", "data"), &GIProbe::set_probe_data); diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h index af4b646590..4badabbadf 100644 --- a/scene/3d/gi_probe.h +++ b/scene/3d/gi_probe.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -168,6 +168,8 @@ public: virtual AABB get_aabb() const; virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + virtual String get_configuration_warning() const; + GIProbe(); ~GIProbe(); }; diff --git a/scene/3d/immediate_geometry.cpp b/scene/3d/immediate_geometry.cpp index 14a0b0505d..a555106bd8 100644 --- a/scene/3d/immediate_geometry.cpp +++ b/scene/3d/immediate_geometry.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/immediate_geometry.h b/scene/3d/immediate_geometry.h index f7201b4bba..3467663dff 100644 --- a/scene/3d/immediate_geometry.h +++ b/scene/3d/immediate_geometry.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/interpolated_camera.cpp b/scene/3d/interpolated_camera.cpp index 93832f8e00..d720dd117c 100644 --- a/scene/3d/interpolated_camera.cpp +++ b/scene/3d/interpolated_camera.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/interpolated_camera.h b/scene/3d/interpolated_camera.h index b025112295..97100c9501 100644 --- a/scene/3d/interpolated_camera.h +++ b/scene/3d/interpolated_camera.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 11d61315ba..cf1af918f7 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -210,6 +210,13 @@ bool Light::is_editor_only() const { return editor_only; } +void Light::_validate_property(PropertyInfo &property) const { + + if (VisualServer::get_singleton()->is_low_end() && property.name == "shadow_contact") { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + } +} + void Light::_bind_methods() { ClassDB::bind_method(D_METHOD("set_editor_only", "editor_only"), &Light::set_editor_only); diff --git a/scene/3d/light.h b/scene/3d/light.h index b35b397ced..ddd5bc6b3a 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -92,6 +92,7 @@ protected: static void _bind_methods(); void _notification(int p_what); + virtual void _validate_property(PropertyInfo &property) const; Light(VisualServer::LightType p_type); diff --git a/scene/3d/listener.cpp b/scene/3d/listener.cpp index 439c1f8c45..85e65e23f2 100644 --- a/scene/3d/listener.cpp +++ b/scene/3d/listener.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/listener.h b/scene/3d/listener.h index 8047971ebd..86451e7d99 100644 --- a/scene/3d/listener.h +++ b/scene/3d/listener.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -71,8 +71,6 @@ public: void set_visible_layers(uint32_t p_layers); uint32_t get_visible_layers() const; - Vector<Plane> get_frustum() const; - Listener(); ~Listener(); }; diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp index cf0317cd58..848889155b 100644 --- a/scene/3d/mesh_instance.cpp +++ b/scene/3d/mesh_instance.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -138,6 +138,8 @@ void MeshInstance::set_mesh(const Ref<Mesh> &p_mesh) { set_base(RID()); } + update_gizmo(); + _change_notify(); } Ref<Mesh> MeshInstance::get_mesh() const { diff --git a/scene/3d/mesh_instance.h b/scene/3d/mesh_instance.h index 0b5b4b9e7b..022ef15aad 100644 --- a/scene/3d/mesh_instance.h +++ b/scene/3d/mesh_instance.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/multimesh_instance.cpp b/scene/3d/multimesh_instance.cpp index 4cbd1df64a..d744a74859 100644 --- a/scene/3d/multimesh_instance.cpp +++ b/scene/3d/multimesh_instance.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/multimesh_instance.h b/scene/3d/multimesh_instance.h index 1cd077a0a5..8f41aa8fd2 100644 --- a/scene/3d/multimesh_instance.h +++ b/scene/3d/multimesh_instance.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp index 6e7b372647..5a3c8223ff 100644 --- a/scene/3d/navigation.cpp +++ b/scene/3d/navigation.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/navigation.h b/scene/3d/navigation.h index 8f200997cd..f920d1d7f6 100644 --- a/scene/3d/navigation.h +++ b/scene/3d/navigation.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/navigation_mesh.cpp b/scene/3d/navigation_mesh.cpp index 99680b7273..93731c4023 100644 --- a/scene/3d/navigation_mesh.cpp +++ b/scene/3d/navigation_mesh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -292,11 +292,11 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() { if (ek.from < ek.to) SWAP(ek.from, ek.to); - Map<_EdgeKey, bool>::Element *E = edge_map.find(ek); + Map<_EdgeKey, bool>::Element *F = edge_map.find(ek); - if (E) { + if (F) { - E->get() = false; + F->get() = false; } else { diff --git a/scene/3d/navigation_mesh.h b/scene/3d/navigation_mesh.h index 753ad76edc..74531e2423 100644 --- a/scene/3d/navigation_mesh.h +++ b/scene/3d/navigation_mesh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index 10b26778ef..57ab01f7be 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,6 +30,9 @@ #include "particles.h" +#include "core/os/os.h" +#include "scene/resources/particles_material.h" + #include "servers/visual_server.h" AABB Particles::get_aabb() const { @@ -223,18 +226,34 @@ bool Particles::get_fractional_delta() const { String Particles::get_configuration_warning() const { + if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) { + return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles node instead. You can use the \"Convert to CPUParticles\" option for this purpose."); + } + String warnings; bool meshes_found = false; + bool anim_material_found = false; for (int i = 0; i < draw_passes.size(); i++) { if (draw_passes[i].is_valid()) { meshes_found = true; - break; + for (int j = 0; j < draw_passes[i]->get_surface_count(); j++) { + anim_material_found = Object::cast_to<ShaderMaterial>(draw_passes[i]->surface_get_material(j).ptr()) != NULL; + SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(draw_passes[i]->surface_get_material(j).ptr()); + anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES); + } + if (meshes_found && anim_material_found) break; } } + anim_material_found = anim_material_found || Object::cast_to<ShaderMaterial>(get_material_override().ptr()) != NULL; + SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(get_material_override().ptr()); + anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES); + if (!meshes_found) { + if (warnings != String()) + warnings += "\n"; warnings += "- " + TTR("Nothing is visible because meshes have not been assigned to draw passes."); } @@ -242,6 +261,15 @@ String Particles::get_configuration_warning() const { if (warnings != String()) warnings += "\n"; warnings += "- " + TTR("A material to process the particles is not assigned, so no behavior is imprinted."); + } else { + const ParticlesMaterial *process = Object::cast_to<ParticlesMaterial>(process_material.ptr()); + if (!anim_material_found && process && + (process->get_param(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 || + process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) { + if (warnings != String()) + warnings += "\n"; + warnings += "- " + TTR("Particles animation requires the usage of a SpatialMaterial with \"Billboard Particles\" enabled."); + } } return warnings; @@ -326,7 +354,7 @@ void Particles::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_EXP_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); diff --git a/scene/3d/particles.h b/scene/3d/particles.h index 72241c5c89..42c68010db 100644 --- a/scene/3d/particles.h +++ b/scene/3d/particles.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/path.cpp b/scene/3d/path.cpp index 339a434a6e..190967d76c 100644 --- a/scene/3d/path.cpp +++ b/scene/3d/path.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -44,10 +44,11 @@ void Path::_curve_changed() { emit_signal("curve_changed"); } - // update the configuration warnings of all children of type OrientedPathFollows + // update the configuration warnings of all children of type PathFollow + // previously used for PathFollowOriented (now enforced orientation is done in PathFollow) if (is_inside_tree()) { for (int i = 0; i < get_child_count(); i++) { - OrientedPathFollow *child = Object::cast_to<OrientedPathFollow>(get_child(i)); + PathFollow *child = Object::cast_to<PathFollow>(get_child(i)); if (child) { child->update_configuration_warning(); } @@ -105,24 +106,66 @@ void PathFollow::_update_transform() { return; } + float bl = c->get_baked_length(); + if (bl == 0.0) { + return; + } + float bi = c->get_bake_interval(); float o = offset; + float o_next = offset + bi; if (loop) { - o = Math::fposmod(o, c->get_baked_length()); + o = Math::fposmod(o, bl); + o_next = Math::fposmod(o_next, bl); + } else if (rotation_mode == ROTATION_ORIENTED && o_next >= bl) { + o = bl - bi; + o_next = bl; } Vector3 pos = c->interpolate_baked(o, cubic); Transform t = get_transform(); + // Vector3 pos_offset = Vector3(h_offset, v_offset, 0); not used in all cases + // will be replaced by "Vector3(h_offset, v_offset, 0)" where it was formerly used + + if (rotation_mode == ROTATION_ORIENTED) { + + Vector3 forward = c->interpolate_baked(o_next, cubic) - pos; + + if (forward.length_squared() < CMP_EPSILON2) + forward = Vector3(0, 0, 1); + else + forward.normalize(); - t.origin = pos; - Vector3 pos_offset = Vector3(h_offset, v_offset, 0); + Vector3 up = c->interpolate_baked_up_vector(o, true); - if (rotation_mode != ROTATION_NONE) { + if (o_next < o) { + Vector3 up1 = c->interpolate_baked_up_vector(o_next, true); + Vector3 axis = up.cross(up1); + + if (axis.length_squared() < CMP_EPSILON2) + axis = forward; + else + axis.normalize(); + + up.rotate(axis, up.angle_to(up1) * 0.5f); + } + + Vector3 scale = t.basis.get_scale(); + Vector3 sideways = up.cross(forward).normalized(); + up = forward.cross(sideways).normalized(); + + t.basis.set(sideways, up, forward); + t.basis.scale_local(scale); + + t.origin = pos + sideways * h_offset + up * v_offset; + } else if (rotation_mode != ROTATION_NONE) { // perform parallel transport // // see C. Dougan, The Parallel Transport Frame, Game Programming Gems 2 for example // for a discussion about why not Frenet frame. + t.origin = pos; + Vector3 t_prev = (pos - c->interpolate_baked(o - delta_offset, cubic)).normalized(); Vector3 t_cur = (c->interpolate_baked(o + delta_offset, cubic) - pos).normalized(); @@ -165,9 +208,9 @@ void PathFollow::_update_transform() { } } - t.translate(pos_offset); + t.translate(Vector3(h_offset, v_offset, 0)); } else { - t.origin += pos_offset; + t.origin = pos + Vector3(h_offset, v_offset, 0); } set_transform(t); @@ -213,7 +256,7 @@ void PathFollow::_validate_property(PropertyInfo &property) const { if (path && path->get_curve().is_valid()) max = path->get_curve()->get_baked_length(); - property.hint_string = "0," + rtos(max) + ",0.01"; + property.hint_string = "0," + rtos(max) + ",0.01,or_greater"; } } @@ -224,6 +267,11 @@ String PathFollow::get_configuration_warning() const { if (!Object::cast_to<Path>(get_parent())) { return TTR("PathFollow only works when set as a child of a Path node."); + } else { + Path *path = Object::cast_to<Path>(get_parent()); + if (path->get_curve().is_valid() && !path->get_curve()->is_up_vector_enabled() && rotation_mode == ROTATION_ORIENTED) { + return TTR("PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent Path's Curve resource."); + } } return String(); @@ -252,11 +300,11 @@ void PathFollow::_bind_methods() { ClassDB::bind_method(D_METHOD("set_loop", "loop"), &PathFollow::set_loop); ClassDB::bind_method(D_METHOD("has_loop"), &PathFollow::has_loop); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_EXP_RANGE, "0,10000,0.01,or_greater"), "set_offset", "get_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_greater"), "set_offset", "get_offset"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); 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, "rotation_mode", PROPERTY_HINT_ENUM, "None,Y,XY,XYZ"), "set_rotation_mode", "get_rotation_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_mode", PROPERTY_HINT_ENUM, "None,Y,XY,XYZ,Oriented"), "set_rotation_mode", "get_rotation_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cubic_interp"), "set_cubic_interpolation", "get_cubic_interpolation"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); @@ -264,6 +312,7 @@ void PathFollow::_bind_methods() { BIND_ENUM_CONSTANT(ROTATION_Y); BIND_ENUM_CONSTANT(ROTATION_XY); BIND_ENUM_CONSTANT(ROTATION_XYZ); + BIND_ENUM_CONSTANT(ROTATION_ORIENTED); } void PathFollow::set_offset(float p_offset) { @@ -322,6 +371,8 @@ float PathFollow::get_unit_offset() const { void PathFollow::set_rotation_mode(RotationMode p_rotation_mode) { rotation_mode = p_rotation_mode; + + update_configuration_warning(); _update_transform(); } @@ -351,236 +402,3 @@ PathFollow::PathFollow() { cubic = true; loop = true; } - -////////////// - -void OrientedPathFollow::_update_transform() { - - if (!path) - return; - - Ref<Curve3D> c = path->get_curve(); - if (!c.is_valid()) - return; - - int count = c->get_point_count(); - if (count < 2) - return; - - if (delta_offset == 0) { - return; - } - - float offset = get_offset(); - float bl = c->get_baked_length(); - float bi = c->get_bake_interval(); - float o = offset; - float o_next = offset + bi; - - if (has_loop()) { - o = Math::fposmod(o, bl); - o_next = Math::fposmod(o_next, bl); - } else if (o_next >= bl) { - o = bl - bi; - o_next = bl; - } - - bool cubic = get_cubic_interpolation(); - Vector3 pos = c->interpolate_baked(o, cubic); - Vector3 forward = c->interpolate_baked(o_next, cubic) - pos; - - if (forward.length_squared() < CMP_EPSILON2) - forward = Vector3(0, 0, 1); - else - forward.normalize(); - - Vector3 up = c->interpolate_baked_up_vector(o, true); - - if (o_next < o) { - Vector3 up1 = c->interpolate_baked_up_vector(o_next, true); - Vector3 axis = up.cross(up1); - - if (axis.length_squared() < CMP_EPSILON2) - axis = forward; - else - axis.normalize(); - - up.rotate(axis, up.angle_to(up1) * 0.5f); - } - - Transform t = get_transform(); - Vector3 scale = t.basis.get_scale(); - - Vector3 sideways = up.cross(forward).normalized(); - up = forward.cross(sideways).normalized(); - - t.basis.set(sideways, up, forward); - t.basis.scale_local(scale); - - t.origin = pos + sideways * get_h_offset() + up * get_v_offset(); - - set_transform(t); -} - -void OrientedPathFollow::_notification(int p_what) { - - switch (p_what) { - - case NOTIFICATION_ENTER_TREE: { - - Node *parent = get_parent(); - if (parent) { - path = Object::cast_to<Path>(parent); - if (path) { - _update_transform(); - } - } - - } break; - case NOTIFICATION_EXIT_TREE: { - - path = NULL; - } break; - } -} - -void OrientedPathFollow::set_cubic_interpolation(bool p_enable) { - - cubic = p_enable; -} - -bool OrientedPathFollow::get_cubic_interpolation() const { - - return cubic; -} - -void OrientedPathFollow::_validate_property(PropertyInfo &property) const { - - if (property.name == "offset") { - - float max = 10000; - if (path && path->get_curve().is_valid()) - max = path->get_curve()->get_baked_length(); - - property.hint_string = "0," + rtos(max) + ",0.01"; - } -} - -String OrientedPathFollow::get_configuration_warning() const { - - if (!is_visible_in_tree() || !is_inside_tree()) - return String(); - - if (!Object::cast_to<Path>(get_parent())) { - return TTR("OrientedPathFollow only works when set as a child of a Path node."); - } else { - Path *path = Object::cast_to<Path>(get_parent()); - if (path->get_curve().is_valid() && !path->get_curve()->is_up_vector_enabled()) { - return TTR("OrientedPathFollow requires up vectors enabled in its parent Path."); - } - } - - return String(); -} - -void OrientedPathFollow::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_offset", "offset"), &OrientedPathFollow::set_offset); - ClassDB::bind_method(D_METHOD("get_offset"), &OrientedPathFollow::get_offset); - - ClassDB::bind_method(D_METHOD("set_h_offset", "h_offset"), &OrientedPathFollow::set_h_offset); - ClassDB::bind_method(D_METHOD("get_h_offset"), &OrientedPathFollow::get_h_offset); - - ClassDB::bind_method(D_METHOD("set_v_offset", "v_offset"), &OrientedPathFollow::set_v_offset); - ClassDB::bind_method(D_METHOD("get_v_offset"), &OrientedPathFollow::get_v_offset); - - ClassDB::bind_method(D_METHOD("set_unit_offset", "unit_offset"), &OrientedPathFollow::set_unit_offset); - ClassDB::bind_method(D_METHOD("get_unit_offset"), &OrientedPathFollow::get_unit_offset); - - ClassDB::bind_method(D_METHOD("set_cubic_interpolation", "enable"), &OrientedPathFollow::set_cubic_interpolation); - ClassDB::bind_method(D_METHOD("get_cubic_interpolation"), &OrientedPathFollow::get_cubic_interpolation); - - ClassDB::bind_method(D_METHOD("set_loop", "loop"), &OrientedPathFollow::set_loop); - ClassDB::bind_method(D_METHOD("has_loop"), &OrientedPathFollow::has_loop); - - ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01"), "set_offset", "get_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); - 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::BOOL, "cubic_interp"), "set_cubic_interpolation", "get_cubic_interpolation"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); -} - -void OrientedPathFollow::set_offset(float p_offset) { - delta_offset = p_offset - offset; - offset = p_offset; - - if (path) - _update_transform(); - _change_notify("offset"); - _change_notify("unit_offset"); -} - -void OrientedPathFollow::set_h_offset(float p_h_offset) { - - h_offset = p_h_offset; - if (path) - _update_transform(); -} - -float OrientedPathFollow::get_h_offset() const { - - return h_offset; -} - -void OrientedPathFollow::set_v_offset(float p_v_offset) { - - v_offset = p_v_offset; - if (path) - _update_transform(); -} - -float OrientedPathFollow::get_v_offset() const { - - return v_offset; -} - -float OrientedPathFollow::get_offset() const { - - return offset; -} - -void OrientedPathFollow::set_unit_offset(float p_unit_offset) { - - if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) - set_offset(p_unit_offset * path->get_curve()->get_baked_length()); -} - -float OrientedPathFollow::get_unit_offset() const { - - if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) - return get_offset() / path->get_curve()->get_baked_length(); - else - return 0; -} - -void OrientedPathFollow::set_loop(bool p_loop) { - - loop = p_loop; -} - -bool OrientedPathFollow::has_loop() const { - - return loop; -} - -OrientedPathFollow::OrientedPathFollow() { - - offset = 0; - delta_offset = 0; - h_offset = 0; - v_offset = 0; - path = NULL; - cubic = true; - loop = true; -} diff --git a/scene/3d/path.h b/scene/3d/path.h index beb37d9714..2a12c4a826 100644 --- a/scene/3d/path.h +++ b/scene/3d/path.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -63,7 +63,8 @@ public: ROTATION_NONE, ROTATION_Y, ROTATION_XY, - ROTATION_XYZ + ROTATION_XYZ, + ROTATION_ORIENTED }; private: @@ -113,49 +114,4 @@ public: VARIANT_ENUM_CAST(PathFollow::RotationMode); -class OrientedPathFollow : public Spatial { - - GDCLASS(OrientedPathFollow, Spatial); - -private: - Path *path; - real_t delta_offset; // change in offset since last _update_transform - real_t offset; - real_t h_offset; - real_t v_offset; - bool cubic; - bool loop; - - void _update_transform(); - -protected: - virtual void _validate_property(PropertyInfo &property) const; - - void _notification(int p_what); - static void _bind_methods(); - -public: - void set_offset(float p_offset); - float get_offset() const; - - void set_h_offset(float p_h_offset); - float get_h_offset() const; - - void set_v_offset(float p_v_offset); - float get_v_offset() const; - - void set_unit_offset(float p_unit_offset); - float get_unit_offset() const; - - void set_loop(bool p_loop); - bool has_loop() const; - - void set_cubic_interpolation(bool p_enable); - bool get_cubic_interpolation() const; - - String get_configuration_warning() const; - - OrientedPathFollow(); -}; - #endif // PATH_H diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 0fb0869979..05214ed669 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,7 +32,10 @@ #include "core/core_string_names.h" #include "core/engine.h" +#include "core/list.h" #include "core/method_bind_ext.gen.inc" +#include "core/object.h" +#include "core/rid.h" #include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED @@ -108,6 +111,20 @@ bool PhysicsBody::get_collision_layer_bit(int p_bit) const { return get_collision_layer() & (1 << p_bit); } +Array PhysicsBody::get_collision_exceptions() { + List<RID> exceptions; + PhysicsServer::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); + Array ret; + for (List<RID>::Element *E = exceptions.front(); E; E = E->next()) { + RID body = E->get(); + ObjectID instance_id = PhysicsServer::get_singleton()->body_get_object_instance_id(body); + Object *obj = ObjectDB::get_instance(instance_id); + PhysicsBody *physics_body = Object::cast_to<PhysicsBody>(obj); + ret.append(physics_body); + } + return ret; +} + void PhysicsBody::add_collision_exception_with(Node *p_node) { ERR_FAIL_NULL(p_node); @@ -171,7 +188,7 @@ PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) : #ifndef DISABLE_DEPRECATED void StaticBody::set_friction(real_t p_friction) { - if (p_friction == 1.0) { // default value, don't create an override for that + if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that return; } @@ -201,7 +218,7 @@ real_t StaticBody::get_friction() const { void StaticBody::set_bounce(real_t p_bounce) { - if (p_bounce == 0.0) { // default value, don't create an override for that + if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that return; } @@ -289,14 +306,15 @@ void StaticBody::_bind_methods() { ClassDB::bind_method(D_METHOD("_reload_physics_characteristics"), &StaticBody::_reload_physics_characteristics); + ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody::get_collision_exceptions); ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody::add_collision_exception_with); ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody::remove_collision_exception_with); #ifndef DISABLE_DEPRECATED - ADD_PROPERTYNO(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); #endif // DISABLE_DEPRECATED - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity"); } @@ -614,7 +632,7 @@ real_t RigidBody::get_weight() const { #ifndef DISABLE_DEPRECATED void RigidBody::set_friction(real_t p_friction) { - if (p_friction == 1.0) { // default value, don't create an override for that + if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that return; } @@ -643,7 +661,7 @@ real_t RigidBody::get_friction() const { void RigidBody::set_bounce(real_t p_bounce) { - if (p_bounce == 0.0) { // default value, don't create an override for that + if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that return; } @@ -1006,10 +1024,10 @@ void RigidBody::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight"); #ifndef DISABLE_DEPRECATED - ADD_PROPERTYNO(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); #endif // DISABLE_DEPRECATED - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "continuous_cd"), "set_use_continuous_collision_detection", "is_using_continuous_collision_detection"); @@ -1086,10 +1104,10 @@ void RigidBody::_reload_physics_characteristics() { ////////////////////////////////////////////////////// ////////////////////////// -Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_test_only) { +Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) { Collision col; - if (move_and_collide(p_motion, p_infinite_inertia, col, p_test_only)) { + if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) { if (motion_cache.is_null()) { motion_cache.instance(); motion_cache->owner = this; @@ -1103,11 +1121,11 @@ Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_inf return Ref<KinematicCollision>(); } -bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_test_only) { +bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) { Transform gt = get_global_transform(); PhysicsServer::MotionResult result; - bool colliding = PhysicsServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, &result); + bool colliding = PhysicsServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, &result, p_exclude_raycast_shapes); if (colliding) { r_collision.collider_metadata = result.collider_metadata; @@ -1149,7 +1167,8 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve } } - Vector3 motion = (floor_velocity + lv) * get_physics_process_delta_time(); + // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky + Vector3 motion = (floor_velocity + lv) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); on_floor = false; on_ceiling = false; @@ -1203,7 +1222,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve floor_velocity = collision.collider_vel; if (p_stop_on_slope) { - if (Vector3() == lv_n + p_floor_direction) { + if ((lv_n + p_floor_direction).length() < 0.01) { Transform gt = get_global_transform(); gt.origin -= collision.travel; set_global_transform(gt); @@ -1224,6 +1243,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve motion = motion.slide(p_floor_direction); lv = lv.slide(p_floor_direction); } else { + Vector3 n = collision.normal; motion = motion.slide(n); lv = lv.slide(n); @@ -1248,7 +1268,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve return lv; } -Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_floor_direction, bool p_infinite_inertia, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle) { +Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { bool was_on_floor = on_floor; @@ -1260,14 +1280,27 @@ Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity Collision col; Transform gt = get_global_transform(); - if (move_and_collide(p_snap, p_infinite_inertia, col, true)) { - gt.origin += col.travel; - if (p_floor_direction != Vector3() && Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) { - on_floor = true; - on_floor_body = col.collider_rid; - floor_velocity = col.collider_vel; + if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { + + bool apply = true; + if (p_floor_direction != Vector3()) { + if (Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) { + on_floor = true; + on_floor_body = col.collider_rid; + floor_velocity = col.collider_vel; + if (p_stop_on_slope) { + // move and collide may stray the object a bit because of pre un-stucking, + // so only ensure that motion happens on floor direction in this case. + col.travel = p_floor_direction * p_floor_direction.dot(col.travel); + } + } else { + apply = false; //snapped with floor direction, but did not snap to a floor, do not snap. + } + } + if (apply) { + gt.origin += col.travel; + set_global_transform(gt); } - set_global_transform(gt); } return ret; @@ -1382,11 +1415,11 @@ Ref<KinematicCollision> KinematicBody::_get_slide_collision(int p_bounce) { void KinematicBody::_bind_methods() { - ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "infinite_inertia", "stop_on_slope", "max_bounces", "floor_max_angle"), &KinematicBody::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(true), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45))); + ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody::test_move); + ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody::test_move, DEFVAL(true)); ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody::is_on_floor); ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody::is_on_ceiling); @@ -1888,6 +1921,26 @@ bool PhysicalBone::SixDOFJointData::_set(const StringName &p_name, const Variant if (j.is_valid()) PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS, axis_data[axis].linear_limit_softness); + } else if ("linear_spring_enabled" == var_name) { + axis_data[axis].linear_spring_enabled = p_value; + if (j.is_valid()) + PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING, axis_data[axis].linear_spring_enabled); + + } else if ("linear_spring_stiffness" == var_name) { + axis_data[axis].linear_spring_stiffness = p_value; + if (j.is_valid()) + PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS, axis_data[axis].linear_spring_stiffness); + + } else if ("linear_spring_damping" == var_name) { + axis_data[axis].linear_spring_damping = p_value; + if (j.is_valid()) + PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_DAMPING, axis_data[axis].linear_spring_damping); + + } else if ("linear_equilibrium_point" == var_name) { + axis_data[axis].linear_equilibrium_point = p_value; + if (j.is_valid()) + PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT, axis_data[axis].linear_equilibrium_point); + } else if ("linear_restitution" == var_name) { axis_data[axis].linear_restitution = p_value; if (j.is_valid()) @@ -1933,6 +1986,26 @@ bool PhysicalBone::SixDOFJointData::_set(const StringName &p_name, const Variant if (j.is_valid()) PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_ANGULAR_ERP, axis_data[axis].erp); + } else if ("angular_spring_enabled" == var_name) { + axis_data[axis].angular_spring_enabled = p_value; + if (j.is_valid()) + PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING, axis_data[axis].angular_spring_enabled); + + } else if ("angular_spring_stiffness" == var_name) { + axis_data[axis].angular_spring_stiffness = p_value; + if (j.is_valid()) + PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS, axis_data[axis].angular_spring_stiffness); + + } else if ("angular_spring_damping" == var_name) { + axis_data[axis].angular_spring_damping = p_value; + if (j.is_valid()) + PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_DAMPING, axis_data[axis].angular_spring_damping); + + } else if ("angular_equilibrium_point" == var_name) { + axis_data[axis].angular_equilibrium_point = p_value; + if (j.is_valid()) + PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT, axis_data[axis].angular_equilibrium_point); + } else { return false; } @@ -1971,6 +2044,14 @@ bool PhysicalBone::SixDOFJointData::_get(const StringName &p_name, Variant &r_re r_ret = axis_data[axis].linear_limit_lower; } else if ("linear_limit_softness" == var_name) { r_ret = axis_data[axis].linear_limit_softness; + } else if ("linear_spring_enabled" == var_name) { + r_ret = axis_data[axis].linear_spring_enabled; + } else if ("linear_spring_stiffness" == var_name) { + r_ret = axis_data[axis].linear_spring_stiffness; + } else if ("linear_spring_damping" == var_name) { + r_ret = axis_data[axis].linear_spring_damping; + } else if ("linear_equilibrium_point" == var_name) { + r_ret = axis_data[axis].linear_equilibrium_point; } else if ("linear_restitution" == var_name) { r_ret = axis_data[axis].linear_restitution; } else if ("linear_damping" == var_name) { @@ -1989,6 +2070,14 @@ bool PhysicalBone::SixDOFJointData::_get(const StringName &p_name, Variant &r_re r_ret = axis_data[axis].angular_damping; } else if ("erp" == var_name) { r_ret = axis_data[axis].erp; + } else if ("angular_spring_enabled" == var_name) { + r_ret = axis_data[axis].angular_spring_enabled; + } else if ("angular_spring_stiffness" == var_name) { + r_ret = axis_data[axis].angular_spring_stiffness; + } else if ("angular_spring_damping" == var_name) { + r_ret = axis_data[axis].angular_spring_damping; + } else if ("angular_equilibrium_point" == var_name) { + r_ret = axis_data[axis].angular_equilibrium_point; } else { return false; } @@ -2003,6 +2092,10 @@ void PhysicalBone::SixDOFJointData::_get_property_list(List<PropertyInfo> *p_lis p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_limit_upper")); p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_limit_lower")); p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_limit_softness", PROPERTY_HINT_RANGE, "0.01,16,0.01")); + p_list->push_back(PropertyInfo(Variant::BOOL, "joint_constraints/" + axis_names[i] + "/linear_spring_enabled")); + p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_spring_stiffness")); + p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_spring_damping")); + p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_equilibrium_point")); p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01")); p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_damping", PROPERTY_HINT_RANGE, "0.01,16,0.01")); p_list->push_back(PropertyInfo(Variant::BOOL, "joint_constraints/" + axis_names[i] + "/angular_limit_enabled")); @@ -2012,6 +2105,10 @@ void PhysicalBone::SixDOFJointData::_get_property_list(List<PropertyInfo> *p_lis p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01")); p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_damping", PROPERTY_HINT_RANGE, "0.01,16,0.01")); p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/erp")); + p_list->push_back(PropertyInfo(Variant::BOOL, "joint_constraints/" + axis_names[i] + "/angular_spring_enabled")); + p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_spring_stiffness")); + p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_spring_damping")); + p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_equilibrium_point")); } } @@ -2275,6 +2372,10 @@ void PhysicalBone::_reload_joint() { PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_UPPER_LIMIT, g6dofjd->axis_data[axis].linear_limit_upper); PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_LOWER_LIMIT, g6dofjd->axis_data[axis].linear_limit_lower); PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS, g6dofjd->axis_data[axis].linear_limit_softness); + PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING, g6dofjd->axis_data[axis].linear_spring_enabled); + PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS, g6dofjd->axis_data[axis].linear_spring_stiffness); + PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_DAMPING, g6dofjd->axis_data[axis].linear_spring_damping); + PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT, g6dofjd->axis_data[axis].linear_equilibrium_point); PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_RESTITUTION, g6dofjd->axis_data[axis].linear_restitution); PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_DAMPING, g6dofjd->axis_data[axis].linear_damping); PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT, g6dofjd->axis_data[axis].angular_limit_enabled); @@ -2284,6 +2385,10 @@ void PhysicalBone::_reload_joint() { PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_RESTITUTION, g6dofjd->axis_data[axis].angular_restitution); PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_DAMPING, g6dofjd->axis_data[axis].angular_damping); PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_ERP, g6dofjd->axis_data[axis].erp); + PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING, g6dofjd->axis_data[axis].angular_spring_enabled); + PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS, g6dofjd->axis_data[axis].angular_spring_stiffness); + PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_DAMPING, g6dofjd->axis_data[axis].angular_spring_damping); + PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT, g6dofjd->axis_data[axis].angular_equilibrium_point); } } break; @@ -2326,7 +2431,8 @@ void PhysicalBone::set_joint_type(JointType p_joint_type) { if (p_joint_type == get_joint_type()) return; - memdelete(joint_data); + if (joint_data) + memdelete(joint_data); joint_data = NULL; switch (p_joint_type) { case JOINT_TYPE_PIN: @@ -2526,7 +2632,8 @@ PhysicalBone::PhysicalBone() : } PhysicalBone::~PhysicalBone() { - memdelete(joint_data); + if (joint_data) + memdelete(joint_data); } void PhysicalBone::update_bone_id() { diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index ed9f41197b..589af98062 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -69,6 +69,7 @@ public: void set_collision_mask_bit(int p_bit, bool p_value); bool get_collision_mask_bit(int p_bit) const; + Array get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); @@ -309,14 +310,14 @@ private: _FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const; - Ref<KinematicCollision> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_test_only = false); + Ref<KinematicCollision> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false); Ref<KinematicCollision> _get_slide_collision(int p_bounce); protected: static void _bind_methods(); public: - bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collisionz, bool p_test_only = false); + bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collisionz, bool p_exclude_raycast_shapes = true, bool p_test_only = false); bool test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia); bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision); @@ -328,7 +329,7 @@ public: float get_safe_margin() const; Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); - Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_floor_direction = Vector3(0, 0, 0), bool p_infinite_inertia = true, bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45)); + Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_floor_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; @@ -493,6 +494,10 @@ public: real_t linear_limit_softness; real_t linear_restitution; real_t linear_damping; + bool linear_spring_enabled; + real_t linear_spring_stiffness; + real_t linear_spring_damping; + real_t linear_equilibrium_point; bool angular_limit_enabled; real_t angular_limit_upper; real_t angular_limit_lower; @@ -500,6 +505,10 @@ public: real_t angular_restitution; real_t angular_damping; real_t erp; + bool angular_spring_enabled; + real_t angular_spring_stiffness; + real_t angular_spring_damping; + real_t angular_equilibrium_point; SixDOFAxisData() : linear_limit_enabled(true), @@ -508,13 +517,21 @@ public: linear_limit_softness(0.7), linear_restitution(0.5), linear_damping(1.), + linear_spring_enabled(false), + linear_spring_stiffness(0), + linear_spring_damping(0), + linear_equilibrium_point(0), angular_limit_enabled(true), angular_limit_upper(0), angular_limit_lower(0), angular_limit_softness(0.5), angular_restitution(0), angular_damping(1.), - erp(0.5) {} + erp(0.5), + angular_spring_enabled(false), + angular_spring_stiffness(0), + angular_spring_damping(0.), + angular_equilibrium_point(0) {} }; virtual JointType get_joint_type() { return JOINT_TYPE_6DOF; } diff --git a/scene/3d/physics_joint.cpp b/scene/3d/physics_joint.cpp index a30fc0ac3e..c261ed3aeb 100644 --- a/scene/3d/physics_joint.cpp +++ b/scene/3d/physics_joint.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -707,6 +707,9 @@ void Generic6DOFJoint::_bind_methods() { ClassDB::bind_method(D_METHOD("set_flag_z", "flag", "value"), &Generic6DOFJoint::set_flag_z); ClassDB::bind_method(D_METHOD("get_flag_z", "flag"), &Generic6DOFJoint::get_flag_z); + ClassDB::bind_method(D_METHOD("set_precision", "precision"), &Generic6DOFJoint::set_precision); + ClassDB::bind_method(D_METHOD("get_precision"), &Generic6DOFJoint::get_precision); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_x/upper_distance"), "set_param_x", "get_param_x", PARAM_LINEAR_UPPER_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_x/lower_distance"), "set_param_x", "get_param_x", PARAM_LINEAR_LOWER_LIMIT); @@ -716,6 +719,11 @@ void Generic6DOFJoint::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_MOTOR); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motor_x/target_velocity"), "set_param_x", "get_param_x", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_LINEAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_x/damping"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_ANGULAR_LIMIT); ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit_x/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_x", "_get_angular_hi_limit_x"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit_x/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_x", "_get_angular_lo_limit_x"); @@ -727,6 +735,10 @@ void Generic6DOFJoint::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_MOTOR); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motor_x/target_velocity"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_ANGULAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_x/damping"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_y/upper_distance"), "set_param_y", "get_param_y", PARAM_LINEAR_UPPER_LIMIT); @@ -737,6 +749,10 @@ void Generic6DOFJoint::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_MOTOR); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motor_y/target_velocity"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_y/damping"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_ANGULAR_LIMIT); ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit_y/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_y", "_get_angular_hi_limit_y"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit_y/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_y", "_get_angular_lo_limit_y"); @@ -748,6 +764,10 @@ void Generic6DOFJoint::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_MOTOR); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motor_y/target_velocity"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_ANGULAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_y/damping"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_z/upper_distance"), "set_param_z", "get_param_z", PARAM_LINEAR_UPPER_LIMIT); @@ -758,6 +778,10 @@ void Generic6DOFJoint::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_MOTOR); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motor_z/target_velocity"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_z/damping"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_z/equilibrium_point"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_ANGULAR_LIMIT); ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit_z/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_z", "_get_angular_hi_limit_z"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit_z/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_z", "_get_angular_lo_limit_z"); @@ -769,6 +793,12 @@ void Generic6DOFJoint::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_MOTOR); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motor_z/target_velocity"), "set_param_z", "get_param_z", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_ANGULAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_z/damping"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_z/equilibrium_point"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "precision", PROPERTY_HINT_RANGE, "1,99999,1"), "set_precision", "get_precision"); BIND_ENUM_CONSTANT(PARAM_LINEAR_LOWER_LIMIT); BIND_ENUM_CONSTANT(PARAM_LINEAR_UPPER_LIMIT); @@ -790,6 +820,8 @@ void Generic6DOFJoint::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_ENABLE_LINEAR_LIMIT); BIND_ENUM_CONSTANT(FLAG_ENABLE_ANGULAR_LIMIT); + BIND_ENUM_CONSTANT(FLAG_ENABLE_LINEAR_SPRING); + BIND_ENUM_CONSTANT(FLAG_ENABLE_ANGULAR_SPRING); BIND_ENUM_CONSTANT(FLAG_ENABLE_MOTOR); BIND_ENUM_CONSTANT(FLAG_ENABLE_LINEAR_MOTOR); BIND_ENUM_CONSTANT(FLAG_MAX); @@ -880,6 +912,14 @@ bool Generic6DOFJoint::get_flag_z(Flag p_flag) const { return flags_z[p_flag]; } +void Generic6DOFJoint::set_precision(int p_precision) { + precision = p_precision; + + PhysicsServer::get_singleton()->generic_6dof_joint_set_precision( + get_joint(), + precision); +} + RID Generic6DOFJoint::_configure_joint(PhysicsBody *body_a, PhysicsBody *body_b) { Transform gt = get_global_transform(); @@ -914,7 +954,8 @@ RID Generic6DOFJoint::_configure_joint(PhysicsBody *body_a, PhysicsBody *body_b) return j; } -Generic6DOFJoint::Generic6DOFJoint() { +Generic6DOFJoint::Generic6DOFJoint() : + precision(1) { set_param_x(PARAM_LINEAR_LOWER_LIMIT, 0); set_param_x(PARAM_LINEAR_UPPER_LIMIT, 0); @@ -923,6 +964,9 @@ Generic6DOFJoint::Generic6DOFJoint() { set_param_x(PARAM_LINEAR_DAMPING, 1.0); set_param_x(PARAM_LINEAR_MOTOR_TARGET_VELOCITY, 0); set_param_x(PARAM_LINEAR_MOTOR_FORCE_LIMIT, 0); + set_param_x(PARAM_LINEAR_SPRING_STIFFNESS, 0.01); + set_param_x(PARAM_LINEAR_SPRING_DAMPING, 0.01); + set_param_x(PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT, 0.0); set_param_x(PARAM_ANGULAR_LOWER_LIMIT, 0); set_param_x(PARAM_ANGULAR_UPPER_LIMIT, 0); set_param_x(PARAM_ANGULAR_LIMIT_SOFTNESS, 0.5f); @@ -932,9 +976,14 @@ Generic6DOFJoint::Generic6DOFJoint() { set_param_x(PARAM_ANGULAR_ERP, 0.5); set_param_x(PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, 0); set_param_x(PARAM_ANGULAR_MOTOR_FORCE_LIMIT, 300); + set_param_x(PARAM_ANGULAR_SPRING_STIFFNESS, 0); + set_param_x(PARAM_ANGULAR_SPRING_DAMPING, 0); + set_param_x(PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT, 0); set_flag_x(FLAG_ENABLE_ANGULAR_LIMIT, true); set_flag_x(FLAG_ENABLE_LINEAR_LIMIT, true); + set_flag_x(FLAG_ENABLE_ANGULAR_SPRING, false); + set_flag_x(FLAG_ENABLE_LINEAR_SPRING, false); set_flag_x(FLAG_ENABLE_MOTOR, false); set_flag_x(FLAG_ENABLE_LINEAR_MOTOR, false); @@ -945,6 +994,9 @@ Generic6DOFJoint::Generic6DOFJoint() { set_param_y(PARAM_LINEAR_DAMPING, 1.0); set_param_y(PARAM_LINEAR_MOTOR_TARGET_VELOCITY, 0); set_param_y(PARAM_LINEAR_MOTOR_FORCE_LIMIT, 0); + set_param_y(PARAM_LINEAR_SPRING_STIFFNESS, 0.01); + set_param_y(PARAM_LINEAR_SPRING_DAMPING, 0.01); + set_param_y(PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT, 0.0); set_param_y(PARAM_ANGULAR_LOWER_LIMIT, 0); set_param_y(PARAM_ANGULAR_UPPER_LIMIT, 0); set_param_y(PARAM_ANGULAR_LIMIT_SOFTNESS, 0.5f); @@ -954,9 +1006,14 @@ Generic6DOFJoint::Generic6DOFJoint() { set_param_y(PARAM_ANGULAR_ERP, 0.5); set_param_y(PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, 0); set_param_y(PARAM_ANGULAR_MOTOR_FORCE_LIMIT, 300); + set_param_y(PARAM_ANGULAR_SPRING_STIFFNESS, 0); + set_param_y(PARAM_ANGULAR_SPRING_DAMPING, 0); + set_param_y(PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT, 0); set_flag_y(FLAG_ENABLE_ANGULAR_LIMIT, true); set_flag_y(FLAG_ENABLE_LINEAR_LIMIT, true); + set_flag_y(FLAG_ENABLE_ANGULAR_SPRING, false); + set_flag_y(FLAG_ENABLE_LINEAR_SPRING, false); set_flag_y(FLAG_ENABLE_MOTOR, false); set_flag_y(FLAG_ENABLE_LINEAR_MOTOR, false); @@ -967,6 +1024,9 @@ Generic6DOFJoint::Generic6DOFJoint() { set_param_z(PARAM_LINEAR_DAMPING, 1.0); set_param_z(PARAM_LINEAR_MOTOR_TARGET_VELOCITY, 0); set_param_z(PARAM_LINEAR_MOTOR_FORCE_LIMIT, 0); + set_param_z(PARAM_LINEAR_SPRING_STIFFNESS, 0.01); + set_param_z(PARAM_LINEAR_SPRING_DAMPING, 0.01); + set_param_z(PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT, 0.0); set_param_z(PARAM_ANGULAR_LOWER_LIMIT, 0); set_param_z(PARAM_ANGULAR_UPPER_LIMIT, 0); set_param_z(PARAM_ANGULAR_LIMIT_SOFTNESS, 0.5f); @@ -976,9 +1036,14 @@ Generic6DOFJoint::Generic6DOFJoint() { set_param_z(PARAM_ANGULAR_ERP, 0.5); set_param_z(PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, 0); set_param_z(PARAM_ANGULAR_MOTOR_FORCE_LIMIT, 300); + set_param_z(PARAM_ANGULAR_SPRING_STIFFNESS, 0); + set_param_z(PARAM_ANGULAR_SPRING_DAMPING, 0); + set_param_z(PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT, 0); set_flag_z(FLAG_ENABLE_ANGULAR_LIMIT, true); set_flag_z(FLAG_ENABLE_LINEAR_LIMIT, true); + set_flag_z(FLAG_ENABLE_ANGULAR_SPRING, false); + set_flag_z(FLAG_ENABLE_LINEAR_SPRING, false); set_flag_z(FLAG_ENABLE_MOTOR, false); set_flag_z(FLAG_ENABLE_LINEAR_MOTOR, false); } diff --git a/scene/3d/physics_joint.h b/scene/3d/physics_joint.h index 37870d6f30..f6df920314 100644 --- a/scene/3d/physics_joint.h +++ b/scene/3d/physics_joint.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -251,6 +251,9 @@ public: PARAM_LINEAR_DAMPING = PhysicsServer::G6DOF_JOINT_LINEAR_DAMPING, PARAM_LINEAR_MOTOR_TARGET_VELOCITY = PhysicsServer::G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY, PARAM_LINEAR_MOTOR_FORCE_LIMIT = PhysicsServer::G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT, + PARAM_LINEAR_SPRING_STIFFNESS = PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS, + PARAM_LINEAR_SPRING_DAMPING = PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_DAMPING, + PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT = PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT, PARAM_ANGULAR_LOWER_LIMIT = PhysicsServer::G6DOF_JOINT_ANGULAR_LOWER_LIMIT, PARAM_ANGULAR_UPPER_LIMIT = PhysicsServer::G6DOF_JOINT_ANGULAR_UPPER_LIMIT, PARAM_ANGULAR_LIMIT_SOFTNESS = PhysicsServer::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS, @@ -260,12 +263,17 @@ public: PARAM_ANGULAR_ERP = PhysicsServer::G6DOF_JOINT_ANGULAR_ERP, PARAM_ANGULAR_MOTOR_TARGET_VELOCITY = PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY, PARAM_ANGULAR_MOTOR_FORCE_LIMIT = PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT, + PARAM_ANGULAR_SPRING_STIFFNESS = PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS, + PARAM_ANGULAR_SPRING_DAMPING = PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_DAMPING, + PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT = PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT, PARAM_MAX = PhysicsServer::G6DOF_JOINT_MAX, }; enum Flag { FLAG_ENABLE_LINEAR_LIMIT = PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, FLAG_ENABLE_ANGULAR_LIMIT = PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT, + FLAG_ENABLE_LINEAR_SPRING = PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING, + FLAG_ENABLE_ANGULAR_SPRING = PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING, FLAG_ENABLE_MOTOR = PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_MOTOR, FLAG_ENABLE_LINEAR_MOTOR = PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR, FLAG_MAX = PhysicsServer::G6DOF_JOINT_FLAG_MAX @@ -297,6 +305,8 @@ protected: float params_z[PARAM_MAX]; bool flags_z[FLAG_MAX]; + int precision; + virtual RID _configure_joint(PhysicsBody *body_a, PhysicsBody *body_b); static void _bind_methods(); @@ -319,6 +329,11 @@ public: void set_flag_z(Flag p_flag, bool p_enabled); bool get_flag_z(Flag p_flag) const; + void set_precision(int p_precision); + int get_precision() const { + return precision; + } + Generic6DOFJoint(); }; diff --git a/scene/3d/portal.cpp b/scene/3d/portal.cpp index 137338d79e..f5163dfcdd 100644 --- a/scene/3d/portal.cpp +++ b/scene/3d/portal.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/portal.h b/scene/3d/portal.h index cb3f208072..f053867917 100644 --- a/scene/3d/portal.h +++ b/scene/3d/portal.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/position_3d.cpp b/scene/3d/position_3d.cpp index 3ae04f491f..18de105eee 100644 --- a/scene/3d/position_3d.cpp +++ b/scene/3d/position_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/position_3d.h b/scene/3d/position_3d.h index 2bc69eff9b..21361592d1 100644 --- a/scene/3d/position_3d.h +++ b/scene/3d/position_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/proximity_group.cpp b/scene/3d/proximity_group.cpp index f56f728d99..12eab2e4e8 100644 --- a/scene/3d/proximity_group.cpp +++ b/scene/3d/proximity_group.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/proximity_group.h b/scene/3d/proximity_group.h index 448f30bf80..bd11e31031 100644 --- a/scene/3d/proximity_group.h +++ b/scene/3d/proximity_group.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp index 17f069bbc8..10f92058e0 100644 --- a/scene/3d/ray_cast.cpp +++ b/scene/3d/ray_cast.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/ray_cast.h b/scene/3d/ray_cast.h index e95382e1fe..43d55adb98 100644 --- a/scene/3d/ray_cast.h +++ b/scene/3d/ray_cast.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp index fe522bbe97..c34771d9f1 100644 --- a/scene/3d/reflection_probe.cpp +++ b/scene/3d/reflection_probe.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h index 13ae1c81f6..48d65b79f7 100644 --- a/scene/3d/reflection_probe.h +++ b/scene/3d/reflection_probe.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,7 +32,7 @@ #define REFLECTIONPROBE_H #include "scene/3d/visual_instance.h" -#include "scene/resources/sky_box.h" +#include "scene/resources/sky.h" #include "scene/resources/texture.h" #include "servers/visual_server.h" diff --git a/scene/3d/remote_transform.cpp b/scene/3d/remote_transform.cpp index c12e49fb47..add77e0272 100644 --- a/scene/3d/remote_transform.cpp +++ b/scene/3d/remote_transform.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -63,38 +63,40 @@ void RemoteTransform::_update_remote() { if (update_remote_position && update_remote_rotation && update_remote_scale) { n->set_global_transform(get_global_transform()); } else { - Transform n_trans = n->get_global_transform(); Transform our_trans = get_global_transform(); - if (!update_remote_position) - our_trans.set_origin(n_trans.get_origin()); + if (update_remote_rotation) + n->set_rotation(our_trans.basis.get_rotation()); - n->set_global_transform(our_trans); + if (update_remote_scale) + n->set_scale(our_trans.basis.get_scale()); - if (!update_remote_rotation) - n->set_rotation(n_trans.basis.get_rotation()); + if (update_remote_position) { + Transform n_trans = n->get_global_transform(); - if (!update_remote_scale) - n->set_scale(n_trans.basis.get_scale()); + n_trans.set_origin(our_trans.get_origin()); + n->set_global_transform(n_trans); + } } } else { if (update_remote_position && update_remote_rotation && update_remote_scale) { - n->set_global_transform(get_global_transform()); + n->set_transform(get_transform()); } else { - Transform n_trans = n->get_transform(); Transform our_trans = get_transform(); - if (!update_remote_position) - our_trans.set_origin(n_trans.get_origin()); + if (update_remote_rotation) + n->set_rotation(our_trans.basis.get_rotation()); - n->set_transform(our_trans); + if (update_remote_scale) + n->set_scale(our_trans.basis.get_scale()); - if (!update_remote_rotation) - n->set_rotation(n_trans.basis.get_rotation()); + if (update_remote_position) { + Transform n_trans = n->get_transform(); - if (!update_remote_scale) - n->set_scale(n_trans.basis.get_scale()); + n_trans.set_origin(our_trans.get_origin()); + n->set_transform(n_trans); + } } } } diff --git a/scene/3d/remote_transform.h b/scene/3d/remote_transform.h index 6b788a2d75..b737a4f858 100644 --- a/scene/3d/remote_transform.h +++ b/scene/3d/remote_transform.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/room_instance.cpp b/scene/3d/room_instance.cpp index 3914d7190e..073fe4f1da 100644 --- a/scene/3d/room_instance.cpp +++ b/scene/3d/room_instance.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/room_instance.h b/scene/3d/room_instance.h index ff388e606c..9ee140d522 100644 --- a/scene/3d/room_instance.h +++ b/scene/3d/room_instance.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp index db82ef2a5c..b7279e4d4f 100644 --- a/scene/3d/skeleton.cpp +++ b/scene/3d/skeleton.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -70,9 +70,9 @@ bool Skeleton::_set(const StringName &p_path, const Variant &p_value) { for (int i = 0; i < children.size(); i++) { - NodePath path = children[i]; - ERR_CONTINUE(path.operator String() == ""); - Node *node = get_node(path); + NodePath npath = children[i]; + ERR_CONTINUE(npath.operator String() == ""); + Node *node = get_node(npath); ERR_CONTINUE(!node); bind_child_node_to_bone(which, node); } @@ -115,8 +115,8 @@ bool Skeleton::_get(const StringName &p_path, Variant &r_ret) const { ERR_CONTINUE(!obj); Node *node = Object::cast_to<Node>(obj); ERR_CONTINUE(!node); - NodePath path = get_path_to(node); - children.push_back(path); + NodePath npath = get_path_to(node); + children.push_back(npath); } r_ret = children; @@ -198,11 +198,7 @@ void Skeleton::_notification(int p_what) { case NOTIFICATION_ENTER_WORLD: { - if (dirty) { - - dirty = false; - _make_dirty(); // property make it dirty - } + VS::get_singleton()->skeleton_set_world_transform(skeleton, use_bones_in_world_transform, get_global_transform()); } break; case NOTIFICATION_EXIT_WORLD: { @@ -210,21 +206,7 @@ void Skeleton::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - if (dirty) - break; //will be eventually updated - - //if moved, just update transforms - VisualServer *vs = VisualServer::get_singleton(); - const Bone *bonesptr = bones.ptr(); - int len = bones.size(); - Transform global_transform = get_global_transform(); - Transform global_transform_inverse = global_transform.affine_inverse(); - - for (int i = 0; i < len; i++) { - - const Bone &b = bonesptr[i]; - vs->skeleton_bone_set_transform(skeleton, i, global_transform * (b.transform_final * global_transform_inverse)); - } + VS::get_singleton()->skeleton_set_world_transform(skeleton, use_bones_in_world_transform, get_global_transform()); } break; case NOTIFICATION_UPDATE_SKELETON: { @@ -232,7 +214,7 @@ void Skeleton::_notification(int p_what) { Bone *bonesptr = bones.ptrw(); int len = bones.size(); - vs->skeleton_allocate(skeleton, len); // if same size, nothin really happens + vs->skeleton_allocate(skeleton, len); // if same size, nothing really happens _update_process_order(); @@ -257,9 +239,6 @@ void Skeleton::_notification(int p_what) { rest_global_inverse_dirty = false; } - Transform global_transform = get_global_transform(); - Transform global_transform_inverse = global_transform.affine_inverse(); - for (int i = 0; i < len; i++) { Bone &b = bonesptr[order[i]]; @@ -320,7 +299,7 @@ void Skeleton::_notification(int p_what) { } b.transform_final = b.pose_global * b.rest_global_inverse; - vs->skeleton_bone_set_transform(skeleton, i, global_transform * (b.transform_final * global_transform_inverse)); + vs->skeleton_bone_set_transform(skeleton, order[i], b.transform_final); for (List<uint32_t>::Element *E = b.nodes_bound.front(); E; E = E->next()) { @@ -594,10 +573,6 @@ void Skeleton::_make_dirty() { if (dirty) return; - if (!is_inside_tree()) { - dirty = true; - return; - } MessageQueue::get_singleton()->push_notification(this, NOTIFICATION_UPDATE_SKELETON); dirty = true; } @@ -771,6 +746,16 @@ void Skeleton::physical_bones_remove_collision_exception(RID p_exception) { #endif // _3D_DISABLED +void Skeleton::set_use_bones_in_world_transform(bool p_enable) { + use_bones_in_world_transform = p_enable; + if (is_inside_tree()) { + VS::get_singleton()->skeleton_set_world_transform(skeleton, use_bones_in_world_transform, get_global_transform()); + } +} +bool Skeleton::is_using_bones_in_world_transform() const { + return use_bones_in_world_transform; +} + void Skeleton::_bind_methods() { ClassDB::bind_method(D_METHOD("add_bone", "name"), &Skeleton::add_bone); @@ -807,6 +792,9 @@ void Skeleton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_bone_transform", "bone_idx"), &Skeleton::get_bone_transform); + ClassDB::bind_method(D_METHOD("set_use_bones_in_world_transform", "enable"), &Skeleton::set_use_bones_in_world_transform); + ClassDB::bind_method(D_METHOD("is_using_bones_in_world_transform"), &Skeleton::is_using_bones_in_world_transform); + #ifndef _3D_DISABLED ClassDB::bind_method(D_METHOD("physical_bones_stop_simulation"), &Skeleton::physical_bones_stop_simulation); @@ -818,6 +806,7 @@ void Skeleton::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bone_ignore_animation", "bone", "ignore"), &Skeleton::set_bone_ignore_animation); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bones_in_world_transform"), "set_use_bones_in_world_transform", "is_using_bones_in_world_transform"); BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON); } @@ -828,6 +817,7 @@ Skeleton::Skeleton() { process_order_dirty = true; skeleton = VisualServer::get_singleton()->skeleton_create(); set_notify_transform(true); + use_bones_in_world_transform = false; } Skeleton::~Skeleton() { diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h index 07abdc1fe7..5f43b3c6c3 100644 --- a/scene/3d/skeleton.h +++ b/scene/3d/skeleton.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -100,6 +100,7 @@ class Skeleton : public Spatial { void _make_dirty(); bool dirty; + bool use_bones_in_world_transform; // bind helpers Array _get_bound_child_nodes_to_bone(int p_bone) const { @@ -179,6 +180,9 @@ public: void localize_rests(); // used for loaders and tools int get_process_order(int p_idx); + void set_use_bones_in_world_transform(bool p_enable); + bool is_using_bones_in_world_transform() const; + #ifndef _3D_DISABLED // Physical bone API diff --git a/scene/3d/soft_body.cpp b/scene/3d/soft_body.cpp index 4ebc941ebc..ac20609c21 100644 --- a/scene/3d/soft_body.cpp +++ b/scene/3d/soft_body.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,8 +29,12 @@ /*************************************************************************/ #include "soft_body.h" +#include "core/list.h" +#include "core/object.h" #include "core/os/os.h" +#include "core/rid.h" #include "scene/3d/collision_object.h" +#include "scene/3d/physics_body.h" #include "scene/3d/skeleton.h" #include "servers/physics_server.h" @@ -335,6 +339,7 @@ void SoftBody::_bind_methods() { ClassDB::bind_method(D_METHOD("set_parent_collision_ignore", "parent_collision_ignore"), &SoftBody::set_parent_collision_ignore); ClassDB::bind_method(D_METHOD("get_parent_collision_ignore"), &SoftBody::get_parent_collision_ignore); + ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &SoftBody::get_collision_exceptions); ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &SoftBody::add_collision_exception_with); ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &SoftBody::remove_collision_exception_with); @@ -396,7 +401,7 @@ String SoftBody::get_configuration_warning() const { } Transform t = get_transform(); - if ((ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(0).length() - 1.0) > 0.05)) { + if ((ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) { if (!warning.empty()) warning += "\n\n"; @@ -547,6 +552,20 @@ PoolVector<SoftBody::PinnedPoint> SoftBody::get_pinned_points_indices() { return pinned_points; } +Array SoftBody::get_collision_exceptions() { + List<RID> exceptions; + PhysicsServer::get_singleton()->soft_body_get_collision_exceptions(physics_rid, &exceptions); + Array ret; + for (List<RID>::Element *E = exceptions.front(); E; E = E->next()) { + RID body = E->get(); + ObjectID instance_id = PhysicsServer::get_singleton()->body_get_object_instance_id(body); + Object *obj = ObjectDB::get_instance(instance_id); + PhysicsBody *physics_body = Object::cast_to<PhysicsBody>(obj); + ret.append(physics_body); + } + return ret; +} + void SoftBody::add_collision_exception_with(Node *p_node) { ERR_FAIL_NULL(p_node); CollisionObject *collision_object = Object::cast_to<CollisionObject>(p_node); diff --git a/scene/3d/soft_body.h b/scene/3d/soft_body.h index ee3d8d87cf..2516d39552 100644 --- a/scene/3d/soft_body.h +++ b/scene/3d/soft_body.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -166,6 +166,7 @@ public: void set_drag_coefficient(real_t p_drag_coefficient); real_t get_drag_coefficient(); + Array get_collision_exceptions(); void add_collision_exception_with(Node *p_node); void remove_collision_exception_with(Node *p_node); diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp index fcc908cdc6..d6544c39da 100644 --- a/scene/3d/spatial.cpp +++ b/scene/3d/spatial.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,6 +32,7 @@ #include "core/engine.h" #include "core/message_queue.h" +#include "scene/main/scene_tree.h" #include "scene/main/viewport.h" #include "scene/scene_string_names.h" @@ -401,6 +402,8 @@ void Spatial::update_gizmo() { if (!is_inside_world()) return; if (!data.gizmo.is_valid()) + get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this); + if (!data.gizmo.is_valid()) return; if (data.gizmo_dirty) return; @@ -800,15 +803,15 @@ void Spatial::_bind_methods() { //ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), "set_global_transform", "get_global_transform") ; ADD_GROUP("Transform", ""); - ADD_PROPERTYNZ(PropertyInfo(Variant::TRANSFORM, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "translation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_translation", "get_translation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_NONE, "", 0), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_scale", "get_scale"); ADD_GROUP("Matrix", ""); - ADD_PROPERTYNZ(PropertyInfo(Variant::TRANSFORM, "transform", PROPERTY_HINT_NONE, ""), "set_transform", "get_transform"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform", PROPERTY_HINT_NONE, ""), "set_transform", "get_transform"); ADD_GROUP("Visibility", ""); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "SpatialGizmo", 0), "set_gizmo", "get_gizmo"); ADD_SIGNAL(MethodInfo("visibility_changed")); diff --git a/scene/3d/spatial.h b/scene/3d/spatial.h index 815ca16bc5..18a4a5b54d 100644 --- a/scene/3d/spatial.h +++ b/scene/3d/spatial.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/spatial_velocity_tracker.cpp b/scene/3d/spatial_velocity_tracker.cpp index 3850a0c7e6..97517be53b 100644 --- a/scene/3d/spatial_velocity_tracker.cpp +++ b/scene/3d/spatial_velocity_tracker.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/spatial_velocity_tracker.h b/scene/3d/spatial_velocity_tracker.h index a8278a4fb5..795f56091f 100644 --- a/scene/3d/spatial_velocity_tracker.h +++ b/scene/3d/spatial_velocity_tracker.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/spring_arm.cpp b/scene/3d/spring_arm.cpp index f74784c2f9..f3665d251b 100644 --- a/scene/3d/spring_arm.cpp +++ b/scene/3d/spring_arm.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/spring_arm.h b/scene/3d/spring_arm.h index e0c3f2992d..35df56f06e 100644 --- a/scene/3d/spring_arm.h +++ b/scene/3d/spring_arm.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 774ee49af2..6b70eef662 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -382,36 +382,30 @@ void Sprite3D::_draw() { VS::get_singleton()->immediate_clear(immediate); if (!texture.is_valid()) - return; //no texuture no life + return; Vector2 tsize = texture->get_size(); if (tsize.x == 0 || tsize.y == 0) return; - Size2i s; - Rect2i src_rect; - - if (region) { - - s = region_rect.size; - src_rect = region_rect; - } else { - s = texture->get_size(); - s = s / Size2i(hframes, vframes); + Rect2 base_rect; + if (region) + base_rect = region_rect; + else + base_rect = Rect2(0, 0, texture->get_width(), texture->get_height()); - src_rect.size = s; - src_rect.position.x += (frame % hframes) * s.x; - src_rect.position.y += (frame / hframes) * s.y; - } + Size2 frame_size = base_rect.size / Size2(hframes, vframes); + Point2 frame_offset = Point2(frame % hframes, frame / hframes); + frame_offset *= frame_size; - Point2i ofs = get_offset(); + Point2 dest_offset = get_offset(); if (is_centered()) - ofs -= s / 2; - - Rect2i dst_rect(ofs, s); + dest_offset -= frame_size / 2; + Rect2 src_rect(base_rect.position + frame_offset, frame_size); + Rect2 final_dst_rect(dest_offset, frame_size); Rect2 final_rect; Rect2 final_src_rect; - if (!texture->get_rect_region(dst_rect, src_rect, final_rect, final_src_rect)) + if (!texture->get_rect_region(final_dst_rect, src_rect, final_rect, final_src_rect)) return; if (final_rect.size.x == 0 || final_rect.size.y == 0) @@ -461,6 +455,13 @@ void Sprite3D::_draw() { int axis = get_axis(); normal[axis] = 1.0; + Plane tangent; + if (axis == Vector3::AXIS_X) { + tangent = Plane(0, 0, -1, 1); + } else { + tangent = Plane(1, 0, 0, 1); + } + RID mat = SpatialMaterial::get_material_rid_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); VS::get_singleton()->immediate_set_material(immediate, mat); @@ -487,6 +488,7 @@ void Sprite3D::_draw() { for (int i = 0; i < 4; i++) { VS::get_singleton()->immediate_normal(immediate, normal); + VS::get_singleton()->immediate_tangent(immediate, tangent); VS::get_singleton()->immediate_color(immediate, color); VS::get_singleton()->immediate_uv(immediate, uvs[i]); @@ -612,7 +614,7 @@ Rect2 Sprite3D::get_item_rect() const { s = s / Point2(hframes, vframes); } - Point2i ofs = get_offset(); + Point2 ofs = get_offset(); if (is_centered()) ofs -= s / 2; @@ -699,15 +701,15 @@ void AnimatedSprite3D::_draw() { return; Size2i s = tsize; - Rect2i src_rect; + Rect2 src_rect; src_rect.size = s; - Point2i ofs = get_offset(); + Point2 ofs = get_offset(); if (is_centered()) ofs -= s / 2; - Rect2i dst_rect(ofs, s); + Rect2 dst_rect(ofs, s); Rect2 final_rect; Rect2 final_src_rect; @@ -761,6 +763,13 @@ void AnimatedSprite3D::_draw() { int axis = get_axis(); normal[axis] = 1.0; + Plane tangent; + if (axis == Vector3::AXIS_X) { + tangent = Plane(0, 0, -1, -1); + } else { + tangent = Plane(1, 0, 0, -1); + } + RID mat = SpatialMaterial::get_material_rid_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); VS::get_singleton()->immediate_set_material(immediate, mat); @@ -788,6 +797,7 @@ void AnimatedSprite3D::_draw() { for (int i = 0; i < 4; i++) { VS::get_singleton()->immediate_normal(immediate, normal); + VS::get_singleton()->immediate_tangent(immediate, tangent); VS::get_singleton()->immediate_color(immediate, color); VS::get_singleton()->immediate_uv(immediate, uvs[i]); @@ -1078,10 +1088,10 @@ void AnimatedSprite3D::_bind_methods() { ADD_SIGNAL(MethodInfo("frame_changed")); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames"); + 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_PROPERTYNZ(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame"); + 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 a4705a8970..0e086ef31e 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp index 56a86b6a17..c7f7b14a8f 100644 --- a/scene/3d/vehicle_body.cpp +++ b/scene/3d/vehicle_body.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/vehicle_body.h b/scene/3d/vehicle_body.h index 68fbf8d873..7e7571df4d 100644 --- a/scene/3d/vehicle_body.h +++ b/scene/3d/vehicle_body.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/visibility_notifier.cpp b/scene/3d/visibility_notifier.cpp index c69387d082..3014432d59 100644 --- a/scene/3d/visibility_notifier.cpp +++ b/scene/3d/visibility_notifier.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -153,7 +153,7 @@ void VisibilityEnabler::_find_nodes(Node *p_node) { if (enabler[ENABLER_FREEZE_BODIES]) { RigidBody *rb = Object::cast_to<RigidBody>(p_node); - if (rb && ((rb->get_mode() == RigidBody::MODE_CHARACTER || (rb->get_mode() == RigidBody::MODE_RIGID && !rb->is_able_to_sleep())))) { + if (rb && ((rb->get_mode() == RigidBody::MODE_CHARACTER || rb->get_mode() == RigidBody::MODE_RIGID))) { add = true; meta = rb->get_mode(); diff --git a/scene/3d/visibility_notifier.h b/scene/3d/visibility_notifier.h index 2cf685a92c..ff4424300c 100644 --- a/scene/3d/visibility_notifier.h +++ b/scene/3d/visibility_notifier.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp index 6dc821c3f5..1bbf1b7bc7 100644 --- a/scene/3d/visual_instance.cpp +++ b/scene/3d/visual_instance.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h index 784f2a358a..3b6fccf65f 100644 --- a/scene/3d/visual_instance.h +++ b/scene/3d/visual_instance.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp index 0eccbbc8f9..750ed97ae6 100644 --- a/scene/3d/voxel_light_baker.cpp +++ b/scene/3d/voxel_light_baker.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -342,8 +342,8 @@ void VoxelLightBaker::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p if (lnormal == Vector3()) //just in case normal as nor provided lnormal = normal; - int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1); - int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1); + int uv_x = CLAMP(int(Math::fposmod(uv.x, 1.0f) * bake_texture_size), 0, bake_texture_size - 1); + int uv_y = CLAMP(int(Math::fposmod(uv.y, 1.0f) * bake_texture_size), 0, bake_texture_size - 1); int ofs = uv_y * bake_texture_size + uv_x; albedo_accum.r += p_material.albedo[ofs].r; @@ -887,7 +887,7 @@ void VoxelLightBaker::plot_light_directional(const Vector3 &p_direction, const C distance -= distance_adv; } - if (result == idx) { + if (result == (uint32_t)idx) { //cell hit itself! hooray! Vector3 normal(cells[idx].normal[0], cells[idx].normal[1], cells[idx].normal[2]); @@ -1018,7 +1018,7 @@ void VoxelLightBaker::plot_light_omni(const Vector3 &p_pos, const Color &p_color distance -= distance_adv; } - if (result == idx) { + if (result == (uint32_t)idx) { //cell hit itself! hooray! if (normal == Vector3()) { @@ -1152,7 +1152,7 @@ void VoxelLightBaker::plot_light_spot(const Vector3 &p_pos, const Vector3 &p_axi distance -= distance_adv; } - if (result == idx) { + if (result == (uint32_t)idx) { //cell hit itself! hooray! if (normal == Vector3()) { @@ -1730,7 +1730,7 @@ Vector3 VoxelLightBaker::_compute_ray_trace_at_pos(const Vector3 &p_pos, const V //int level_limit = max_level; cell = 0; //start from root - for (int i = 0; i < max_level; i++) { + for (int j = 0; j < max_level; j++) { const Cell *bc = &cells[cell]; @@ -1759,14 +1759,14 @@ Vector3 VoxelLightBaker::_compute_ray_trace_at_pos(const Vector3 &p_pos, const V } if (unlikely(cell != CHILD_EMPTY)) { - for (int i = 0; i < 6; i++) { + for (int j = 0; j < 6; j++) { //anisotropic read light - float amount = direction.dot(aniso_normal[i]); + float amount = direction.dot(aniso_normal[j]); if (amount <= 0) continue; - accum.x += light[cell].accum[i][0] * amount; - accum.y += light[cell].accum[i][1] * amount; - accum.z += light[cell].accum[i][2] * amount; + accum.x += light[cell].accum[j][0] * amount; + accum.y += light[cell].accum[j][1] * amount; + accum.z += light[cell].accum[j][2] * amount; } accum.x += cells[cell].emission[0]; accum.y += cells[cell].emission[1]; @@ -1833,16 +1833,16 @@ Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh } int faces = ic ? ic / 3 : vc / 3; - for (int i = 0; i < faces; i++) { + for (int j = 0; j < faces; j++) { Vector3 vertex[3]; Vector3 normal[3]; Vector2 uv[3]; - for (int j = 0; j < 3; j++) { - int idx = ic ? ir[i * 3 + j] : i * 3 + j; - vertex[j] = xform.xform(vr[idx]); - normal[j] = xform.basis.xform(nr[idx]).normalized(); - uv[j] = u2r[idx]; + for (int k = 0; k < 3; k++) { + int idx = ic ? ir[j * 3 + k] : j * 3 + k; + vertex[k] = xform.xform(vr[idx]); + normal[k] = xform.basis.xform(nr[idx]).normalized(); + uv[k] = u2r[idx]; } _plot_triangle(uv, vertex, normal, lightmap.ptrw(), width, height); @@ -1931,7 +1931,6 @@ Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh //add directional light (do this after blur) { - LightMap *lightmap_ptr = lightmap.ptrw(); const Cell *cells = bake_cells.ptr(); const Light *light = bake_light.ptr(); #ifdef _OPENMP @@ -2209,7 +2208,7 @@ PoolVector<int> VoxelLightBaker::create_gi_probe_data() { } { - uint16_t alpha = CLAMP(uint32_t(bake_cells[i].alpha * 65535.0), 0, 65535); + uint16_t alpha = MIN(uint32_t(bake_cells[i].alpha * 65535.0), 65535); uint16_t level = bake_cells[i].level; w32[ofs++] = (uint32_t(level) << 16) | uint32_t(alpha); @@ -2253,7 +2252,7 @@ void VoxelLightBaker::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Re uint32_t child = bake_cells[p_idx].children[i]; - if (child == CHILD_EMPTY || child >= max_original_cells) + if (child == CHILD_EMPTY || child >= (uint32_t)max_original_cells) continue; AABB aabb = p_aabb; diff --git a/scene/3d/voxel_light_baker.h b/scene/3d/voxel_light_baker.h index 3d55c053f3..295e099d47 100644 --- a/scene/3d/voxel_light_baker.h +++ b/scene/3d/voxel_light_baker.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/3d/scenario_fx.cpp b/scene/3d/world_environment.cpp index 26cbfc0b11..3cd43cbf5b 100644 --- a/scene/3d/scenario_fx.cpp +++ b/scene/3d/world_environment.cpp @@ -1,12 +1,12 @@ /*************************************************************************/ -/* scenario_fx.cpp */ +/* world_environment.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "scenario_fx.h" +#include "world_environment.h" #include "scene/main/viewport.h" void WorldEnvironment::_notification(int p_what) { diff --git a/scene/3d/scenario_fx.h b/scene/3d/world_environment.h index 7a8e2b548f..bf36a0a532 100644 --- a/scene/3d/scenario_fx.h +++ b/scene/3d/world_environment.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* scenario_fx.h */ +/* world_environment.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp index 76de39c3e6..dded44b990 100644 --- a/scene/animation/animation_blend_space_1d.cpp +++ b/scene/animation/animation_blend_space_1d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -110,7 +110,7 @@ void AnimationNodeBlendSpace1D::add_blend_point(const Ref<AnimationRootNode> &p_ if (p_at_index == -1 || p_at_index == blend_points_used) { p_at_index = blend_points_used; } else { - for (int i = blend_points_used - 1; i > p_at_index; i++) { + for (int i = blend_points_used - 1; i > p_at_index; i--) { blend_points[i] = blend_points[i - 1]; } } diff --git a/scene/animation/animation_blend_space_1d.h b/scene/animation/animation_blend_space_1d.h index a83a813744..dfac88b712 100644 --- a/scene/animation/animation_blend_space_1d.h +++ b/scene/animation/animation_blend_space_1d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp index 9321133d5f..95d4644004 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,9 +33,17 @@ void AnimationNodeBlendSpace2D::get_parameter_list(List<PropertyInfo> *r_list) const { r_list->push_back(PropertyInfo(Variant::VECTOR2, blend_position)); + r_list->push_back(PropertyInfo(Variant::INT, closest, PROPERTY_HINT_NONE, "", 0)); + r_list->push_back(PropertyInfo(Variant::REAL, length_internal, PROPERTY_HINT_NONE, "", 0)); } Variant AnimationNodeBlendSpace2D::get_parameter_default_value(const StringName &p_parameter) const { - return Vector2(); + if (p_parameter == closest) { + return -1; + } else if (p_parameter == length_internal) { + return 0; + } else { + return Vector2(); + } } void AnimationNodeBlendSpace2D::get_child_nodes(List<ChildNode> *r_child_nodes) { @@ -72,18 +80,15 @@ void AnimationNodeBlendSpace2D::add_blend_point(const Ref<AnimationRootNode> &p_ blend_points[p_at_index].node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED); blend_points_used++; - if (auto_triangles) { - trianges_dirty = true; - } + _queue_auto_triangles(); + emit_signal("tree_changed"); } void AnimationNodeBlendSpace2D::set_blend_point_position(int p_point, const Vector2 &p_position) { ERR_FAIL_INDEX(p_point, blend_points_used); blend_points[p_point].position = p_position; - if (auto_triangles) { - trianges_dirty = true; - } + _queue_auto_triangles(); } void AnimationNodeBlendSpace2D::set_blend_point_node(int p_point, const Ref<AnimationRootNode> &p_node) { ERR_FAIL_INDEX(p_point, blend_points_used); @@ -301,6 +306,15 @@ Vector<int> AnimationNodeBlendSpace2D::_get_triangles() const { return t; } +void AnimationNodeBlendSpace2D::_queue_auto_triangles() { + if (!auto_triangles || trianges_dirty) { + return; + } + + trianges_dirty = true; + call_deferred("_update_triangles"); +} + void AnimationNodeBlendSpace2D::_update_triangles() { if (!auto_triangles || !trianges_dirty) @@ -308,8 +322,10 @@ void AnimationNodeBlendSpace2D::_update_triangles() { trianges_dirty = false; triangles.clear(); - if (blend_points_used < 3) + if (blend_points_used < 3) { + emit_signal("triangles_updated"); return; + } Vector<Vector2> points; points.resize(blend_points_used); @@ -322,6 +338,7 @@ void AnimationNodeBlendSpace2D::_update_triangles() { for (int i = 0; i < triangles.size(); i++) { add_triangle(triangles[i].points[0], triangles[i].points[1], triangles[i].points[2]); } + emit_signal("triangles_updated"); } Vector2 AnimationNodeBlendSpace2D::get_closest_point(const Vector2 &p_point) { @@ -412,84 +429,124 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) { _update_triangles(); Vector2 blend_pos = get_parameter(blend_position); + int closest = get_parameter(this->closest); + float length_internal = get_parameter(this->length_internal); + float mind = 0; //time of min distance point - if (triangles.size() == 0) - return 0; + if (blend_mode == BLEND_MODE_INTERPOLATED) { - Vector2 best_point; - bool first = true; - int blend_triangle = -1; - float blend_weights[3] = { 0, 0, 0 }; + if (triangles.size() == 0) + return 0; - for (int i = 0; i < triangles.size(); i++) { - Vector2 points[3]; - for (int j = 0; j < 3; j++) { - points[j] = get_blend_point_position(get_triangle_point(i, j)); - } + Vector2 best_point; + bool first = true; + int blend_triangle = -1; + float blend_weights[3] = { 0, 0, 0 }; - if (Geometry::is_point_in_triangle(blend_pos, points[0], points[1], points[2])) { + for (int i = 0; i < triangles.size(); i++) { + Vector2 points[3]; + for (int j = 0; j < 3; j++) { + points[j] = get_blend_point_position(get_triangle_point(i, j)); + } - blend_triangle = i; - _blend_triangle(blend_pos, points, blend_weights); - break; - } + if (Geometry::is_point_in_triangle(blend_pos, points[0], points[1], points[2])) { - for (int j = 0; j < 3; j++) { - Vector2 s[2] = { - points[j], - points[(j + 1) % 3] - }; - Vector2 closest = Geometry::get_closest_point_to_segment_2d(blend_pos, s); - if (first || closest.distance_to(blend_pos) < best_point.distance_to(blend_pos)) { - best_point = closest; blend_triangle = i; - first = false; - float d = s[0].distance_to(s[1]); - if (d == 0.0) { - blend_weights[j] = 1.0; - blend_weights[(j + 1) % 3] = 0.0; - blend_weights[(j + 2) % 3] = 0.0; - } else { - float c = s[0].distance_to(closest) / d; - - blend_weights[j] = 1.0 - c; - blend_weights[(j + 1) % 3] = c; - blend_weights[(j + 2) % 3] = 0.0; + _blend_triangle(blend_pos, points, blend_weights); + break; + } + + for (int j = 0; j < 3; j++) { + Vector2 s[2] = { + points[j], + points[(j + 1) % 3] + }; + Vector2 closest2 = Geometry::get_closest_point_to_segment_2d(blend_pos, s); + if (first || closest2.distance_to(blend_pos) < best_point.distance_to(blend_pos)) { + best_point = closest2; + blend_triangle = i; + first = false; + float d = s[0].distance_to(s[1]); + if (d == 0.0) { + blend_weights[j] = 1.0; + blend_weights[(j + 1) % 3] = 0.0; + blend_weights[(j + 2) % 3] = 0.0; + } else { + float c = s[0].distance_to(closest2) / d; + + blend_weights[j] = 1.0 - c; + blend_weights[(j + 1) % 3] = c; + blend_weights[(j + 2) % 3] = 0.0; + } } } } - } - ERR_FAIL_COND_V(blend_triangle == -1, 0); //should never reach here + ERR_FAIL_COND_V(blend_triangle == -1, 0); //should never reach here - int triangle_points[3]; - for (int j = 0; j < 3; j++) { - triangle_points[j] = get_triangle_point(blend_triangle, j); - } + int triangle_points[3]; + for (int j = 0; j < 3; j++) { + triangle_points[j] = get_triangle_point(blend_triangle, j); + } - first = true; - float mind = 0; - for (int i = 0; i < blend_points_used; i++) { + first = true; - bool found = false; - for (int j = 0; j < 3; j++) { - if (i == triangle_points[j]) { - //blend with the given weight - float t = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, blend_weights[j], FILTER_IGNORE, false); - if (first || t < mind) { - mind = t; - first = false; + for (int i = 0; i < blend_points_used; i++) { + + bool found = false; + for (int j = 0; j < 3; j++) { + if (i == triangle_points[j]) { + //blend with the given weight + float t = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, blend_weights[j], FILTER_IGNORE, false); + if (first || t < mind) { + mind = t; + first = false; + } + found = true; + break; } - found = true; - break; + } + + if (!found) { + //ignore + blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, 0, FILTER_IGNORE, false); } } + } else { + + int new_closest = -1; + float new_closest_dist = 1e20; + + for (int i = 0; i < blend_points_used; i++) { - if (!found) { - //ignore - blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, 0, FILTER_IGNORE, false); + float d = blend_points[i].position.distance_squared_to(blend_pos); + if (d < new_closest_dist) { + + new_closest = i; + new_closest_dist = d; + } + } + + if (new_closest != closest) { + + float from = 0; + if (blend_mode == BLEND_MODE_DISCRETE_CARRY && closest != -1) { + //see how much animation remains + from = blend_node(blend_points[closest].name, blend_points[closest].node, p_time, true, 0.0, FILTER_IGNORE, false) - length_internal; + } + + mind = blend_node(blend_points[new_closest].name, blend_points[new_closest].node, from, true, 1.0, FILTER_IGNORE, false) + from; + length_internal = from + mind; + + closest = new_closest; + + } else { + mind = blend_node(blend_points[closest].name, blend_points[closest].node, p_time, p_seek, 1.0, FILTER_IGNORE, false); } } + + set_parameter(this->closest, closest); + set_parameter(this->length_internal, length_internal); return mind; } @@ -498,6 +555,10 @@ String AnimationNodeBlendSpace2D::get_caption() const { } void AnimationNodeBlendSpace2D::_validate_property(PropertyInfo &property) const { + + if (auto_triangles && property.name == "triangles") { + property.usage = 0; + } if (property.name.begins_with("blend_point_")) { String left = property.name.get_slicec('/', 0); int idx = left.get_slicec('_', 2).to_int(); @@ -509,10 +570,12 @@ void AnimationNodeBlendSpace2D::_validate_property(PropertyInfo &property) const } void AnimationNodeBlendSpace2D::set_auto_triangles(bool p_enable) { - auto_triangles = p_enable; - if (auto_triangles) { - trianges_dirty = true; + if (auto_triangles == p_enable) { + return; } + + auto_triangles = p_enable; + _queue_auto_triangles(); } bool AnimationNodeBlendSpace2D::get_auto_triangles() const { @@ -527,6 +590,14 @@ void AnimationNodeBlendSpace2D::_tree_changed() { emit_signal("tree_changed"); } +void AnimationNodeBlendSpace2D::set_blend_mode(BlendMode p_blend_mode) { + blend_mode = p_blend_mode; +} + +AnimationNodeBlendSpace2D::BlendMode AnimationNodeBlendSpace2D::get_blend_mode() const { + return blend_mode; +} + void AnimationNodeBlendSpace2D::_bind_methods() { ClassDB::bind_method(D_METHOD("add_blend_point", "node", "pos", "at_index"), &AnimationNodeBlendSpace2D::add_blend_point, DEFVAL(-1)); @@ -565,7 +636,11 @@ void AnimationNodeBlendSpace2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_auto_triangles", "enable"), &AnimationNodeBlendSpace2D::set_auto_triangles); ClassDB::bind_method(D_METHOD("get_auto_triangles"), &AnimationNodeBlendSpace2D::get_auto_triangles); + ClassDB::bind_method(D_METHOD("set_blend_mode", "mode"), &AnimationNodeBlendSpace2D::set_blend_mode); + ClassDB::bind_method(D_METHOD("get_blend_mode"), &AnimationNodeBlendSpace2D::get_blend_mode); + ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationNodeBlendSpace2D::_tree_changed); + ClassDB::bind_method(D_METHOD("_update_triangles"), &AnimationNodeBlendSpace2D::_update_triangles); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_triangles", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_auto_triangles", "get_auto_triangles"); @@ -581,6 +656,12 @@ void AnimationNodeBlendSpace2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "snap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_snap", "get_snap"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "x_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_x_label", "get_x_label"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "y_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_y_label", "get_y_label"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Interpolated,Discrete,Carry", PROPERTY_USAGE_NOEDITOR), "set_blend_mode", "get_blend_mode"); + + ADD_SIGNAL(MethodInfo("triangles_updated")); + BIND_ENUM_CONSTANT(BLEND_MODE_INTERPOLATED); + BIND_ENUM_CONSTANT(BLEND_MODE_DISCRETE); + BIND_ENUM_CONSTANT(BLEND_MODE_DISCRETE_CARRY); } AnimationNodeBlendSpace2D::AnimationNodeBlendSpace2D() { @@ -597,6 +678,9 @@ AnimationNodeBlendSpace2D::AnimationNodeBlendSpace2D() { y_label = "y"; trianges_dirty = false; blend_position = "blend_position"; + closest = "closest"; + length_internal = "length_internal"; + blend_mode = BLEND_MODE_INTERPOLATED; } AnimationNodeBlendSpace2D::~AnimationNodeBlendSpace2D() { diff --git a/scene/animation/animation_blend_space_2d.h b/scene/animation/animation_blend_space_2d.h index 2c684687de..c21360beb9 100644 --- a/scene/animation/animation_blend_space_2d.h +++ b/scene/animation/animation_blend_space_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,7 +35,14 @@ class AnimationNodeBlendSpace2D : public AnimationRootNode { GDCLASS(AnimationNodeBlendSpace2D, AnimationRootNode) +public: + enum BlendMode { + BLEND_MODE_INTERPOLATED, + BLEND_MODE_DISCRETE, + BLEND_MODE_DISCRETE_CARRY, + }; +protected: enum { MAX_BLEND_POINTS = 64 }; @@ -56,11 +63,14 @@ class AnimationNodeBlendSpace2D : public AnimationRootNode { Vector<BlendTriangle> triangles; StringName blend_position; + StringName closest; + StringName length_internal; Vector2 max_space; Vector2 min_space; Vector2 snap; String x_label; String y_label; + BlendMode blend_mode; void _add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node); void _set_triangles(const Vector<int> &p_triangles); @@ -72,6 +82,7 @@ class AnimationNodeBlendSpace2D : public AnimationRootNode { bool trianges_dirty; void _update_triangles(); + void _queue_auto_triangles(); void _tree_changed(); @@ -122,10 +133,15 @@ public: void set_auto_triangles(bool p_enable); bool get_auto_triangles() const; + void set_blend_mode(BlendMode p_blend_mode); + BlendMode get_blend_mode() const; + virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name); AnimationNodeBlendSpace2D(); ~AnimationNodeBlendSpace2D(); }; +VARIANT_ENUM_CAST(AnimationNodeBlendSpace2D::BlendMode) + #endif // ANIMATION_BLEND_SPACE_2D_H diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index b85d4e541e..0daa574f72 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -40,12 +40,11 @@ StringName AnimationNodeAnimation::get_animation() const { return animation; } -float AnimationNodeAnimation::get_playback_time() const { - return time; -} - Vector<String> (*AnimationNodeAnimation::get_editable_animation_list)() = NULL; +void AnimationNodeAnimation::get_parameter_list(List<PropertyInfo> *r_list) const { + r_list->push_back(PropertyInfo(Variant::REAL, time, PROPERTY_HINT_NONE, "", 0)); +} void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const { if (property.name == "animation" && get_editable_animation_list) { @@ -70,6 +69,8 @@ float AnimationNodeAnimation::process(float p_time, bool p_seek) { AnimationPlayer *ap = state->player; ERR_FAIL_COND_V(!ap, 0); + float time = get_parameter(this->time); + if (!ap->has_animation(animation)) { AnimationNodeBlendTree *tree = Object::cast_to<AnimationNodeBlendTree>(parent); @@ -86,6 +87,8 @@ float AnimationNodeAnimation::process(float p_time, bool p_seek) { Ref<Animation> anim = ap->get_animation(animation); + float step; + if (p_seek) { time = p_time; step = 0; @@ -109,6 +112,8 @@ float AnimationNodeAnimation::process(float p_time, bool p_seek) { blend_animation(animation, time, step, p_seek, 1.0); + set_parameter(this->time, time); + return anim_size - time; } @@ -120,16 +125,13 @@ void AnimationNodeAnimation::_bind_methods() { ClassDB::bind_method(D_METHOD("set_animation", "name"), &AnimationNodeAnimation::set_animation); ClassDB::bind_method(D_METHOD("get_animation"), &AnimationNodeAnimation::get_animation); - ClassDB::bind_method(D_METHOD("get_playback_time"), &AnimationNodeAnimation::get_playback_time); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation"); } AnimationNodeAnimation::AnimationNodeAnimation() { last_version = 0; skip = false; - time = 0; - step = 0; + time = "time"; } //////////////////////////////////////////////////////// @@ -139,10 +141,14 @@ void AnimationNodeOneShot::get_parameter_list(List<PropertyInfo> *r_list) const r_list->push_back(PropertyInfo(Variant::BOOL, prev_active, PROPERTY_HINT_NONE, "", 0)); r_list->push_back(PropertyInfo(Variant::REAL, time, PROPERTY_HINT_NONE, "", 0)); r_list->push_back(PropertyInfo(Variant::REAL, remaining, PROPERTY_HINT_NONE, "", 0)); + r_list->push_back(PropertyInfo(Variant::REAL, time_to_restart, PROPERTY_HINT_NONE, "", 0)); } + Variant AnimationNodeOneShot::get_parameter_default_value(const StringName &p_parameter) const { if (p_parameter == active || p_parameter == prev_active) { return false; + } else if (p_parameter == time_to_restart) { + return -1; } else { return 0.0; } @@ -216,13 +222,26 @@ float AnimationNodeOneShot::process(float p_time, bool p_seek) { bool prev_active = get_parameter(this->prev_active); float time = get_parameter(this->time); float remaining = get_parameter(this->remaining); + float time_to_restart = get_parameter(this->time_to_restart); if (!active) { //make it as if this node doesn't exist, pass input 0 by. if (prev_active) { set_parameter(this->prev_active, false); } - return blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync); + if (time_to_restart >= 0.0 && !p_seek) { + time_to_restart -= p_time; + if (time_to_restart < 0) { + //restart + set_parameter(this->active, true); + active = true; + } + set_parameter(this->time_to_restart, time_to_restart); + } + + if (!active) { + return blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync); + } } bool os_seek = p_seek; @@ -266,7 +285,6 @@ float AnimationNodeOneShot::process(float p_time, bool p_seek) { if (do_start) { remaining = os_rem; - do_start = false; } if (!p_seek) { @@ -275,6 +293,10 @@ float AnimationNodeOneShot::process(float p_time, bool p_seek) { if (remaining <= 0) { set_parameter(this->active, false); set_parameter(this->prev_active, false); + if (autorestart) { + float restart_sec = autorestart_delay + Math::randf() * autorestart_random_delay; + set_parameter(this->time_to_restart, restart_sec); + } } } @@ -349,6 +371,7 @@ AnimationNodeOneShot::AnimationNodeOneShot() { prev_active = "prev_active"; time = "time"; remaining = "remaining"; + time_to_restart = "time_to_restart"; } //////////////////////////////////////////////// @@ -699,7 +722,7 @@ String AnimationNodeTransition::get_input_caption(int p_input) const { if (tree.is_valid() && current >= 0) { prev = current; - prev_xfading = xfade; + prev_xfading = xfade; time = 0; current = p_current; switched = true; @@ -770,8 +793,6 @@ float AnimationNodeTransition::process(float p_time, bool p_seek) { rem = blend_input(current, p_time, p_seek, 1.0 - blend, FILTER_IGNORE, false); } - switched = false; - if (p_seek) { // don't seek prev animation blend_input(prev, 0, false, blend, FILTER_IGNORE, false); time = p_time; @@ -836,12 +857,11 @@ AnimationNodeTransition::AnimationNodeTransition() { time = "time"; current = "current"; prev_current = "prev_current"; - ; enabled_inputs = 0; for (int i = 0; i < MAX_INPUTS; i++) { inputs[i].auto_advance = false; - inputs[i].name = itos(i + 1); + inputs[i].name = "state " + itos(i); } } diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index 4ca11e464b..c16dcb1b8c 100644 --- a/scene/animation/animation_blend_tree.h +++ b/scene/animation/animation_blend_tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -38,10 +38,9 @@ class AnimationNodeAnimation : public AnimationRootNode { GDCLASS(AnimationNodeAnimation, AnimationRootNode); StringName animation; + StringName time; uint64_t last_version; - float time; - float step; bool skip; protected: @@ -50,6 +49,8 @@ protected: static void _bind_methods(); public: + void get_parameter_list(List<PropertyInfo> *r_list) const; + static Vector<String> (*get_editable_animation_list)(); virtual String get_caption() const; @@ -58,8 +59,6 @@ public: void set_animation(const StringName &p_name); StringName get_animation() const; - float get_playback_time() const; - AnimationNodeAnimation(); }; @@ -92,6 +91,7 @@ private: StringName prev_active; StringName time; StringName remaining; + StringName time_to_restart; protected: static void _bind_methods(); diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp index 756907c41c..feefe3ddd4 100644 --- a/scene/animation/animation_cache.cpp +++ b/scene/animation/animation_cache.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -133,19 +133,19 @@ void AnimationCache::_update_cache() { } else { if (np.get_subname_count() > 0) { - RES res; + RES res2; Vector<StringName> leftover_subpath; // We don't want to cache the last resource unless it is a method call bool is_method = animation->track_get_type(i) == Animation::TYPE_METHOD; - root->get_node_and_resource(np, res, leftover_subpath, is_method); + root->get_node_and_resource(np, res2, leftover_subpath, is_method); - if (res.is_valid()) { - path.resource = res; + if (res2.is_valid()) { + path.resource = res2; } else { path.node = node; } - path.object = res.is_valid() ? res.ptr() : (Object *)node; + path.object = res2.is_valid() ? res2.ptr() : (Object *)node; path.subpath = leftover_subpath; } else { diff --git a/scene/animation/animation_cache.h b/scene/animation/animation_cache.h index cf28236376..ac668b7796 100644 --- a/scene/animation/animation_cache.h +++ b/scene/animation/animation_cache.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 5923ad7657..5df3da93e1 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -345,7 +345,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *sm, len_current = sm->blend_node(current, sm->states[current].node, 0, true, 1.0, AnimationNode::FILTER_IGNORE, false); pos_current = 0; loops_current = 0; - play_start = false; } if (!sm->states.has(current)) { @@ -374,7 +373,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *sm, if (fading_from != StringName()) { - sm->blend_node(current, sm->states[fading_from].node, p_time, p_seek, 1.0 - fade_blend, AnimationNode::FILTER_IGNORE, false); + sm->blend_node(fading_from, sm->states[fading_from].node, p_time, p_seek, 1.0 - fade_blend, AnimationNode::FILTER_IGNORE, false); } //guess playback position @@ -422,7 +421,8 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *sm, if (sm->transitions[i].from == current && auto_advance) { - if (sm->transitions[i].transition->get_priority() < priority_best) { + if (sm->transitions[i].transition->get_priority() <= priority_best) { + priority_best = sm->transitions[i].transition->get_priority(); auto_advance_to = i; } } @@ -481,10 +481,9 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *sm, } //compute time left for transitions by using the end node - if (sm->end_node != StringName() && sm->end_node != current) { - rem = sm->blend_node(current, sm->states[sm->end_node].node, 0, true, 0, AnimationNode::FILTER_IGNORE, false); + rem = sm->blend_node(sm->end_node, sm->states[sm->end_node].node, 0, true, 0, AnimationNode::FILTER_IGNORE, false); } return rem; diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index a88b3eb482..e47b940c35 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 102f05a146..016db15b73 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -287,7 +287,6 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) { // broken track (nonexistent bone) p_anim->node_cache[i]->skeleton = NULL; p_anim->node_cache[i]->spatial = NULL; - printf("bone is %ls\n", String(bone_name).c_str()); ERR_CONTINUE(p_anim->node_cache[i]->bone_idx < 0); } } else { @@ -344,10 +343,16 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float for (int i = 0; i < a->get_track_count(); i++) { + // If an animation changes this animation (or it animates itself) + // we need to recreate our animation cache + if (p_anim->node_cache.size() != a->get_track_count()) { + _ensure_node_caches(p_anim); + } + TrackNodeCache *nc = p_anim->node_cache[i]; - if (!nc) // no node cache for this track, skip it - continue; + if (!nc) + continue; // no node cache for this track, skip it if (!a->track_is_enabled(i)) continue; // do nothing if the track is disabled @@ -985,25 +990,12 @@ void AnimationPlayer::remove_animation(const StringName &p_name) { void AnimationPlayer::_ref_anim(const Ref<Animation> &p_anim) { - if (used_anims.has(p_anim)) - used_anims[p_anim]++; - else { - used_anims[p_anim] = 1; - Ref<Animation>(p_anim)->connect("changed", this, "_animation_changed"); - } + Ref<Animation>(p_anim)->connect(SceneStringNames::get_singleton()->tracks_changed, this, "_animation_changed", varray(), CONNECT_REFERENCE_COUNTED); } void AnimationPlayer::_unref_anim(const Ref<Animation> &p_anim) { - ERR_FAIL_COND(!used_anims.has(p_anim)); - - int &n = used_anims[p_anim]; - n--; - if (n == 0) { - - Ref<Animation>(p_anim)->disconnect("changed", this, "_animation_changed"); - used_anims.erase(p_anim); - } + Ref<Animation>(p_anim)->disconnect(SceneStringNames::get_singleton()->tracks_changed, this, "_animation_changed"); } void AnimationPlayer::rename_animation(const StringName &p_name, const StringName &p_new_name) { @@ -1120,6 +1112,15 @@ void AnimationPlayer::queue(const StringName &p_name) { queued.push_back(p_name); } +PoolVector<String> AnimationPlayer::get_queue() { + PoolVector<String> ret; + for (List<StringName>::Element *E = queued.front(); E; E = E->next()) { + ret.push_back(E->get()); + } + + return ret; +} + void AnimationPlayer::clear_queue() { queued.clear(); } @@ -1131,8 +1132,6 @@ void AnimationPlayer::play_backwards(const StringName &p_name, float p_custom_bl void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float p_custom_scale, bool p_from_end) { - //printf("animation is %ls\n", String(p_name).c_str()); - //ERR_FAIL_COND(!is_inside_scene()); StringName name = p_name; if (String(name) == "") @@ -1190,9 +1189,21 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float _stop_playing_caches(); c.current.from = &animation_set[name]; - c.current.pos = p_from_end ? c.current.from->animation->get_length() : 0; + + if (c.assigned != name) { // reset + c.current.pos = p_from_end ? c.current.from->animation->get_length() : 0; + } else { + if (p_from_end && c.current.pos == 0) { + // Animation reset BUT played backwards, set position to the end + c.current.pos = c.current.from->animation->get_length(); + } else if (!p_from_end && c.current.pos == c.current.from->animation->get_length()) { + // Animation resumed but already ended, set position to the beggining + c.current.pos = 0; + } + } + c.current.speed_scale = p_custom_scale; - c.assigned = p_name; + c.assigned = name; c.seeked = false; c.started = true; @@ -1271,6 +1282,7 @@ void AnimationPlayer::stop(bool p_reset) { if (p_reset) { c.current.from = NULL; c.current.speed_scale = 1; + c.current.pos = 0; } _set_process(false); queued.clear(); @@ -1348,6 +1360,9 @@ void AnimationPlayer::_animation_changed() { clear_caches(); emit_signal("caches_cleared"); + if (is_playing()) { + playback.seeked = true; //need to restart stuff, like audio + } } void AnimationPlayer::_stop_playing_caches() { @@ -1415,6 +1430,8 @@ StringName AnimationPlayer::find_animation(const Ref<Animation> &p_animation) co } void AnimationPlayer::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."); autoplay = p_name; } @@ -1600,6 +1617,7 @@ void AnimationPlayer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_assigned_animation", "anim"), &AnimationPlayer::set_assigned_animation); ClassDB::bind_method(D_METHOD("get_assigned_animation"), &AnimationPlayer::get_assigned_animation); ClassDB::bind_method(D_METHOD("queue", "name"), &AnimationPlayer::queue); + ClassDB::bind_method(D_METHOD("get_queue"), &AnimationPlayer::get_queue); ClassDB::bind_method(D_METHOD("clear_queue"), &AnimationPlayer::clear_queue); ClassDB::bind_method(D_METHOD("set_active", "active"), &AnimationPlayer::set_active); diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index f50b2454ec..fea4819821 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -114,10 +114,12 @@ private: Variant value_accum; uint64_t accum_pass; Variant capture; - PropertyAnim() { - accum_pass = 0; - object = NULL; - } + + PropertyAnim() : + owner(NULL), + special(SP_NONE), + object(NULL), + accum_pass(0) {} }; Map<StringName, PropertyAnim> property_anim; @@ -129,25 +131,28 @@ private: float bezier_accum; Object *object; uint64_t accum_pass; - BezierAnim() { - accum_pass = 0; - bezier_accum = 0; - object = NULL; - } + + BezierAnim() : + owner(NULL), + bezier_accum(0.0), + object(NULL), + accum_pass(0) {} }; Map<StringName, BezierAnim> bezier_anim; - TrackNodeCache() { - skeleton = NULL; - spatial = NULL; - node = NULL; - accum_pass = 0; - bone_idx = -1; - node_2d = NULL; - audio_playing = false; - animation_playing = false; - } + TrackNodeCache() : + id(0), + node(NULL), + spatial(NULL), + node_2d(NULL), + skeleton(NULL), + bone_idx(-1), + accum_pass(0), + audio_playing(false), + audio_start(0.0), + audio_len(0.0), + animation_playing(false) {} }; struct TrackNodeCacheKey { @@ -176,8 +181,6 @@ private: int cache_update_bezier_size; Set<TrackNodeCache *> playing_caches; - Map<Ref<Animation>, int> used_anims; - uint64_t accum_pass; float speed_scale; float default_blend_time; @@ -312,6 +315,7 @@ public: void play(const StringName &p_name = StringName(), float p_custom_blend = -1, float p_custom_scale = 1.0, bool p_from_end = false); void play_backwards(const StringName &p_name = StringName(), float p_custom_blend = -1); void queue(const StringName &p_name); + PoolVector<String> get_queue(); void clear_queue(); void stop(bool p_reset = true); bool is_playing() const; diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index eb00f91bb3..0b6fa26bfc 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -37,9 +37,20 @@ #include "servers/audio/audio_stream.h" void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const { + if (get_script_instance()) { + Array parameters = get_script_instance()->call("get_parameter_list"); + for (int i = 0; i < parameters.size(); i++) { + Dictionary d = parameters[i]; + ERR_CONTINUE(d.empty()); + r_list->push_back(PropertyInfo::from_dict(d)); + } + } } Variant AnimationNode::get_parameter_default_value(const StringName &p_parameter) const { + if (get_script_instance()) { + return get_script_instance()->call("get_parameter_default_value"); + } return Variant(); } @@ -62,6 +73,18 @@ Variant AnimationNode::get_parameter(const StringName &p_name) const { } void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) { + + if (get_script_instance()) { + Dictionary cn = get_script_instance()->call("get_child_nodes"); + List<Variant> keys; + cn.get_key_list(&keys); + for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + ChildNode child; + child.name = E->get(); + child.node = cn[E->get()]; + r_child_nodes->push_back(child); + } + } } void AnimationNode::blend_animation(const StringName &p_animation, float p_time, float p_delta, bool p_seeked, float p_blend) { @@ -373,6 +396,9 @@ void AnimationNode::_validate_property(PropertyInfo &property) const { } Ref<AnimationNode> AnimationNode::get_child_by_name(const StringName &p_name) { + if (get_script_instance()) { + return get_script_instance()->call("get_child_by_name"); + } return Ref<AnimationNode>(); } @@ -403,6 +429,14 @@ void AnimationNode::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_filter_enabled", "is_filter_enabled"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "filters", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_filters", "_get_filters"); + BIND_VMETHOD(MethodInfo(Variant::DICTIONARY, "get_child_nodes")); + BIND_VMETHOD(MethodInfo(Variant::ARRAY, "get_parameter_list")); + BIND_VMETHOD(MethodInfo(Variant::OBJECT, "get_child_by_name", PropertyInfo(Variant::STRING, "name"))); + { + MethodInfo mi = MethodInfo(Variant::NIL, "get_parameter_default_value", PropertyInfo(Variant::STRING, "name")); + mi.return_val.usage = PROPERTY_USAGE_NIL_IS_VARIANT; + BIND_VMETHOD(mi); + } BIND_VMETHOD(MethodInfo("process", PropertyInfo(Variant::REAL, "time"), PropertyInfo(Variant::BOOL, "seek"))); BIND_VMETHOD(MethodInfo(Variant::STRING, "get_caption")); BIND_VMETHOD(MethodInfo(Variant::STRING, "has_filter")); @@ -651,6 +685,10 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { track = track_animation; } break; + default: { + ERR_PRINT("Animation corrupted (invalid track type)"); + continue; + } } track_cache[path] = track; @@ -819,6 +857,9 @@ void AnimationTree::_process_graph(float p_delta) { for (int i = 0; i < a->get_track_count(); i++) { NodePath path = a->track_get_path(i); + + ERR_CONTINUE(!track_cache.has(path)); + TrackCache *track = track_cache[path]; if (track->type != a->track_get_type(i)) { continue; //may happen should not @@ -968,10 +1009,10 @@ void AnimationTree::_process_graph(float p_delta) { a->method_track_get_key_indices(i, time, delta, &indices); - for (List<int>::Element *E = indices.front(); E; E = E->next()) { + for (List<int>::Element *F = indices.front(); F; F = F->next()) { - StringName method = a->method_track_get_name(i, E->get()); - Vector<Variant> params = a->method_track_get_params(i, E->get()); + StringName method = a->method_track_get_name(i, F->get()); + Vector<Variant> params = a->method_track_get_params(i, F->get()); int s = params.size(); @@ -1110,9 +1151,9 @@ void AnimationTree::_process_graph(float p_delta) { TrackCacheAnimation *t = static_cast<TrackCacheAnimation *>(track); - AnimationPlayer *player = Object::cast_to<AnimationPlayer>(t->object); + AnimationPlayer *player2 = Object::cast_to<AnimationPlayer>(t->object); - if (!player) + if (!player2) continue; if (delta == 0 || seeked) { @@ -1124,10 +1165,10 @@ void AnimationTree::_process_graph(float p_delta) { float pos = a->track_get_key_time(i, idx); StringName anim_name = a->animation_track_get_key_animation(i, idx); - if (String(anim_name) == "[stop]" || !player->has_animation(anim_name)) + if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name)) continue; - Ref<Animation> anim = player->get_animation(anim_name); + Ref<Animation> anim = player2->get_animation(anim_name); float at_anim_pos; @@ -1137,14 +1178,14 @@ void AnimationTree::_process_graph(float p_delta) { at_anim_pos = MAX(anim->get_length(), time - pos); //seek to end } - if (player->is_playing() || seeked) { - player->play(anim_name); - player->seek(at_anim_pos); + if (player2->is_playing() || seeked) { + player2->play(anim_name); + player2->seek(at_anim_pos); t->playing = true; playing_caches.insert(t); } else { - player->set_assigned_animation(anim_name); - player->seek(at_anim_pos, true); + player2->set_assigned_animation(anim_name); + player2->seek(at_anim_pos, true); } } else { //find stuff to play @@ -1154,15 +1195,15 @@ void AnimationTree::_process_graph(float p_delta) { int idx = to_play.back()->get(); StringName anim_name = a->animation_track_get_key_animation(i, idx); - if (String(anim_name) == "[stop]" || !player->has_animation(anim_name)) { + if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name)) { if (playing_caches.has(t)) { playing_caches.erase(t); - player->stop(); + player2->stop(); t->playing = false; } } else { - player->play(anim_name); + player2->play(anim_name); t->playing = true; playing_caches.insert(t); } diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index cda7f8ae74..4c65b2a92c 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index 524784df53..3420b48ae3 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -136,9 +136,9 @@ bool AnimationTreePlayer::_set(const StringName &p_name, const Variant &p_value) else animation_node_set_animation(id, node.get_valid("animation")); Array filters = node.get_valid("filter"); - for (int i = 0; i < filters.size(); i++) { + for (int j = 0; j < filters.size(); j++) { - animation_node_set_filter_path(id, filters[i], true); + animation_node_set_filter_path(id, filters[j], true); } } break; case NODE_ONESHOT: { @@ -150,9 +150,9 @@ bool AnimationTreePlayer::_set(const StringName &p_name, const Variant &p_value) oneshot_node_set_autorestart_delay(id, node.get_valid("autorestart_delay")); oneshot_node_set_autorestart_random_delay(id, node.get_valid("autorestart_random_delay")); Array filters = node.get_valid("filter"); - for (int i = 0; i < filters.size(); i++) { + for (int j = 0; j < filters.size(); j++) { - oneshot_node_set_filter_path(id, filters[i], true); + oneshot_node_set_filter_path(id, filters[j], true); } } break; @@ -162,9 +162,9 @@ bool AnimationTreePlayer::_set(const StringName &p_name, const Variant &p_value) case NODE_BLEND2: { blend2_node_set_amount(id, node.get_valid("blend")); Array filters = node.get_valid("filter"); - for (int i = 0; i < filters.size(); i++) { + for (int j = 0; j < filters.size(); j++) { - blend2_node_set_filter_path(id, filters[i], true); + blend2_node_set_filter_path(id, filters[j], true); } } break; case NODE_BLEND3: { @@ -278,8 +278,8 @@ bool AnimationTreePlayer::_get(const StringName &p_name, Variant &r_ret) const { an->filter.get_key_list(&keys); k.resize(keys.size()); int i = 0; - for (List<NodePath>::Element *E = keys.front(); E; E = E->next()) { - k[i++] = E->get(); + for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) { + k[i++] = F->get(); } node["filter"] = k; } break; @@ -297,8 +297,8 @@ bool AnimationTreePlayer::_get(const StringName &p_name, Variant &r_ret) const { osn->filter.get_key_list(&keys); k.resize(keys.size()); int i = 0; - for (List<NodePath>::Element *E = keys.front(); E; E = E->next()) { - k[i++] = E->get(); + for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) { + k[i++] = F->get(); } node["filter"] = k; @@ -315,8 +315,8 @@ bool AnimationTreePlayer::_get(const StringName &p_name, Variant &r_ret) const { bn->filter.get_key_list(&keys); k.resize(keys.size()); int i = 0; - for (List<NodePath>::Element *E = keys.front(); E; E = E->next()) { - k[i++] = E->get(); + for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) { + k[i++] = F->get(); } node["filter"] = k; @@ -401,6 +401,9 @@ void AnimationTreePlayer::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { + ERR_EXPLAIN("AnimationTreePlayer has been deprecated. Use AnimationTree instead."); + WARN_DEPRECATED + if (!processing) { //make sure that a previous process state was not saved //only process if "processing" is set @@ -409,12 +412,14 @@ void AnimationTreePlayer::_notification(int p_what) { } } break; case NOTIFICATION_READY: { + dirty_caches = true; if (master != NodePath()) { _update_sources(); } } break; case NOTIFICATION_INTERNAL_PROCESS: { + if (animation_process_mode == ANIMATION_PROCESS_PHYSICS) break; @@ -869,10 +874,10 @@ void AnimationTreePlayer::_process_animation(float p_delta) { List<int> indices; a->method_track_get_key_indices(tr.local_track, anim_list->time, anim_list->step, &indices); - for (List<int>::Element *E = indices.front(); E; E = E->next()) { + for (List<int>::Element *F = indices.front(); F; F = F->next()) { - StringName method = a->method_track_get_name(tr.local_track, E->get()); - Vector<Variant> args = a->method_track_get_params(tr.local_track, E->get()); + StringName method = a->method_track_get_name(tr.local_track, F->get()); + Vector<Variant> args = a->method_track_get_params(tr.local_track, F->get()); args.resize(VARIANT_ARG_MAX); tr.track->object->call(method, args[0], args[1], args[2], args[3], args[4]); } @@ -1715,6 +1720,11 @@ Error AnimationTreePlayer::node_rename(const StringName &p_node, const StringNam return OK; } +String AnimationTreePlayer::get_configuration_warning() const { + + return TTR("This node has been deprecated. Use AnimationTree instead."); +} + void AnimationTreePlayer::_bind_methods() { ClassDB::bind_method(D_METHOD("add_node", "type", "id"), &AnimationTreePlayer::add_node); diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h index d2d7b1c9ec..9ec6325969 100644 --- a/scene/animation/animation_tree_player.h +++ b/scene/animation/animation_tree_player.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -109,6 +109,14 @@ private: Variant value; bool skip; + + Track() : + id(0), + object(NULL), + spatial(NULL), + skeleton(NULL), + bone_idx(-1), + skip(false) {} }; typedef Map<TrackKey, Track> TrackMap; @@ -343,6 +351,8 @@ public: int node_get_input_count(const StringName &p_node) const; StringName node_get_input_source(const StringName &p_node, int p_input) const; + String get_configuration_warning() const; + /* ANIMATION NODE */ void animation_node_set_animation(const StringName &p_node, const Ref<Animation> &p_animation); Ref<Animation> animation_node_get_animation(const StringName &p_node) const; diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp index 01a10dbc2b..646a39d063 100644 --- a/scene/animation/root_motion_view.cpp +++ b/scene/animation/root_motion_view.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/animation/root_motion_view.h b/scene/animation/root_motion_view.h index 5198ab21aa..bca265b1f0 100644 --- a/scene/animation/root_motion_view.h +++ b/scene/animation/root_motion_view.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/animation/skeleton_ik.cpp b/scene/animation/skeleton_ik.cpp index 83f45afac8..88fb2d5bfc 100644 --- a/scene/animation/skeleton_ik.cpp +++ b/scene/animation/skeleton_ik.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -280,7 +280,7 @@ void FabrikInverseKinematic::make_goal(Task *p_task, const Transform &p_inverse_ } } -void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool p_use_magnet, const Vector3 &p_magnet_position) { +void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position) { if (blending_delta <= 0.01f) { return; // Skip solving @@ -314,7 +314,10 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool p_u } } else { // Set target orientation to tip - new_bone_pose.basis = p_task->chain.tips[0].end_effector->goal_transform.basis; + if (override_tip_basis) + new_bone_pose.basis = p_task->chain.tips[0].end_effector->goal_transform.basis; + else + new_bone_pose.basis = new_bone_pose.basis * p_task->chain.tips[0].end_effector->goal_transform.basis; } p_task->skeleton->set_bone_global_pose(ci->bone, new_bone_pose); @@ -366,6 +369,9 @@ void SkeletonIK::_bind_methods() { ClassDB::bind_method(D_METHOD("set_target_node", "node"), &SkeletonIK::set_target_node); ClassDB::bind_method(D_METHOD("get_target_node"), &SkeletonIK::get_target_node); + ClassDB::bind_method(D_METHOD("set_override_tip_basis", "override"), &SkeletonIK::set_override_tip_basis); + ClassDB::bind_method(D_METHOD("is_override_tip_basis"), &SkeletonIK::is_override_tip_basis); + ClassDB::bind_method(D_METHOD("set_use_magnet", "use"), &SkeletonIK::set_use_magnet); ClassDB::bind_method(D_METHOD("is_using_magnet"), &SkeletonIK::is_using_magnet); @@ -388,6 +394,7 @@ void SkeletonIK::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "tip_bone"), "set_tip_bone", "get_tip_bone"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "interpolation", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_interpolation", "get_interpolation"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "target"), "set_target_transform", "get_target_transform"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_tip_basis"), "set_override_tip_basis", "is_override_tip_basis"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_magnet"), "set_use_magnet", "is_using_magnet"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "magnet"), "set_magnet_position", "get_magnet_position"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_node"), "set_target_node", "get_target_node"); @@ -418,6 +425,7 @@ void SkeletonIK::_notification(int p_what) { SkeletonIK::SkeletonIK() : Node(), interpolation(1), + override_tip_basis(true), use_magnet(false), min_distance(0.01), max_iterations(10), @@ -478,6 +486,14 @@ NodePath SkeletonIK::get_target_node() { return target_node_path_override; } +void SkeletonIK::set_override_tip_basis(bool p_override) { + override_tip_basis = p_override; +} + +bool SkeletonIK::is_override_tip_basis() const { + return override_tip_basis; +} + void SkeletonIK::set_use_magnet(bool p_use) { use_magnet = p_use; } @@ -555,7 +571,7 @@ void SkeletonIK::reload_goal() { void SkeletonIK::_solve_chain() { if (!task) return; - FabrikInverseKinematic::solve(task, interpolation, use_magnet, magnet_position); + FabrikInverseKinematic::solve(task, interpolation, override_tip_basis, use_magnet, magnet_position); } #endif // _3D_DISABLED diff --git a/scene/animation/skeleton_ik.h b/scene/animation/skeleton_ik.h index 202d6959bb..228184a2df 100644 --- a/scene/animation/skeleton_ik.h +++ b/scene/animation/skeleton_ik.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -138,7 +138,7 @@ public: // The goal of chain should be always in local space static void set_goal(Task *p_task, const Transform &p_goal); static void make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta); - static void solve(Task *p_task, real_t blending_delta, bool p_use_magnet, const Vector3 &p_magnet_position); + static void solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position); }; class SkeletonIK : public Node { @@ -149,6 +149,7 @@ class SkeletonIK : public Node { real_t interpolation; Transform target; NodePath target_node_path_override; + bool override_tip_basis; bool use_magnet; Vector3 magnet_position; @@ -185,6 +186,9 @@ public: void set_target_node(const NodePath &p_node); NodePath get_target_node(); + void set_override_tip_basis(bool p_override); + bool is_override_tip_basis() const; + void set_use_magnet(bool p_use); bool is_using_magnet() const; diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 3521782417..6a5d7839f4 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/animation/tween.h b/scene/animation/tween.h index aa47c00717..6fe3bffdbe 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/audio/audio_player.cpp b/scene/audio/audio_stream_player.cpp index 64af7efb16..2688041d18 100644 --- a/scene/audio/audio_player.cpp +++ b/scene/audio/audio_stream_player.cpp @@ -1,12 +1,12 @@ /*************************************************************************/ -/* audio_player.cpp */ +/* audio_stream_player.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "audio_player.h" +#include "audio_stream_player.h" #include "core/engine.h" @@ -91,13 +91,19 @@ void AudioStreamPlayer::_mix_internal(bool p_fadeout) { void AudioStreamPlayer::_mix_audio() { - if (!stream_playback.is_valid() || !active) + if (!stream_playback.is_valid() || !active || + (stream_paused && !stream_fade)) { return; + } - if (stream_paused) { - if (stream_paused_fade) { - _mix_internal(true); - stream_paused_fade = false; + if (stream_fade) { + _mix_internal(true); + stream_fade = false; + + if (stream_stop) { + stream_playback->stop(); + active = false; + set_process_internal(false); } return; } @@ -203,6 +209,7 @@ 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; active = true; set_process_internal(true); @@ -219,8 +226,8 @@ void AudioStreamPlayer::seek(float p_seconds) { void AudioStreamPlayer::stop() { if (stream_playback.is_valid()) { - active = false; - set_process_internal(false); + stream_stop = true; + stream_fade = true; } } @@ -294,7 +301,7 @@ void AudioStreamPlayer::set_stream_paused(bool p_pause) { if (p_pause != stream_paused) { stream_paused = p_pause; - stream_paused_fade = p_pause ? true : false; + stream_fade = p_pause ? true : false; } } @@ -384,7 +391,8 @@ AudioStreamPlayer::AudioStreamPlayer() { setseek = -1; active = false; stream_paused = false; - stream_paused_fade = false; + stream_fade = false; + stream_stop = false; mix_target = MIX_TARGET_STEREO; AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); diff --git a/scene/audio/audio_player.h b/scene/audio/audio_stream_player.h index 591c00ed18..fba8ce7dd3 100644 --- a/scene/audio/audio_player.h +++ b/scene/audio/audio_stream_player.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* audio_player.h */ +/* audio_stream_player.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOPLAYER_H -#define AUDIOPLAYER_H +#ifndef AUDIO_STREAM_PLAYER_H +#define AUDIO_STREAM_PLAYER_H #include "scene/main/node.h" #include "servers/audio/audio_stream.h" @@ -58,7 +58,8 @@ private: float volume_db; bool autoplay; bool stream_paused; - bool stream_paused_fade; + bool stream_fade; + bool stream_stop; StringName bus; MixTarget mix_target; @@ -110,4 +111,5 @@ public: }; VARIANT_ENUM_CAST(AudioStreamPlayer::MixTarget) -#endif // AUDIOPLAYER_H + +#endif // AUDIO_STREAM_PLAYER_H diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 6dfaacc776..806c8afa5b 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -82,16 +82,16 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) { get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce); } - emit_signal("pressed"); _unpress_group(); + emit_signal("pressed"); } else { status.pressed = !status.pressed; pressed(); - emit_signal("pressed"); _unpress_group(); + emit_signal("pressed"); toggled(status.pressed); if (get_script_instance()) { @@ -135,6 +135,7 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) { get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce); } + _unpress_group(); emit_signal("pressed"); } else { @@ -142,6 +143,7 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) { status.pressed = !status.pressed; pressed(); + _unpress_group(); emit_signal("pressed"); toggled(status.pressed); @@ -150,8 +152,6 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) { } emit_signal("toggled", status.pressed); } - - _unpress_group(); } status.press_attempt = false; @@ -215,12 +215,14 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) { get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce); } + _unpress_group(); emit_signal("pressed"); } else { status.pressed = !status.pressed; pressed(); + _unpress_group(); emit_signal("pressed"); toggled(status.pressed); @@ -229,8 +231,6 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) { } emit_signal("toggled", status.pressed); } - - _unpress_group(); } accept_event(); @@ -406,6 +406,16 @@ bool BaseButton::is_toggle_mode() const { return toggle_mode; } +void BaseButton::set_shortcut_in_tooltip(bool p_on) { + + shortcut_in_tooltip = p_on; +} + +bool BaseButton::is_shortcut_in_tooltip_enabled() const { + + return shortcut_in_tooltip; +} + void BaseButton::set_action_mode(ActionMode p_mode) { action_mode = p_mode; @@ -471,7 +481,7 @@ void BaseButton::_unhandled_input(Ref<InputEvent> p_event) { String BaseButton::get_tooltip(const Point2 &p_pos) const { String tooltip = Control::get_tooltip(p_pos); - if (shortcut.is_valid() && shortcut->is_valid()) { + if (shortcut_in_tooltip && shortcut.is_valid() && shortcut->is_valid()) { String text = shortcut->get_name() + " (" + shortcut->get_as_text() + ")"; if (shortcut->get_name().nocasecmp_to(tooltip) != 0) { text += "\n" + tooltip; @@ -510,6 +520,8 @@ void BaseButton::_bind_methods() { ClassDB::bind_method(D_METHOD("is_hovered"), &BaseButton::is_hovered); ClassDB::bind_method(D_METHOD("set_toggle_mode", "enabled"), &BaseButton::set_toggle_mode); ClassDB::bind_method(D_METHOD("is_toggle_mode"), &BaseButton::is_toggle_mode); + ClassDB::bind_method(D_METHOD("set_shortcut_in_tooltip", "enabled"), &BaseButton::set_shortcut_in_tooltip); + ClassDB::bind_method(D_METHOD("is_shortcut_in_tooltip_enabled"), &BaseButton::is_shortcut_in_tooltip_enabled); ClassDB::bind_method(D_METHOD("set_disabled", "disabled"), &BaseButton::set_disabled); ClassDB::bind_method(D_METHOD("is_disabled"), &BaseButton::is_disabled); ClassDB::bind_method(D_METHOD("set_action_mode", "mode"), &BaseButton::set_action_mode); @@ -533,11 +545,12 @@ void BaseButton::_bind_methods() { ADD_SIGNAL(MethodInfo("button_up")); ADD_SIGNAL(MethodInfo("button_down")); ADD_SIGNAL(MethodInfo("toggled", PropertyInfo(Variant::BOOL, "button_pressed"))); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "toggle_mode"), "set_toggle_mode", "is_toggle_mode"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed"); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "action_mode", PROPERTY_HINT_ENUM, "Button Press,Button Release"), "set_action_mode", "get_action_mode"); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "button_mask", PROPERTY_HINT_FLAGS, "Mouse Left, Mouse Right, Mouse Middle"), "set_button_mask", "get_button_mask"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_in_tooltip"), "set_shortcut_in_tooltip", "is_shortcut_in_tooltip_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "action_mode", PROPERTY_HINT_ENUM, "Button Press,Button Release"), "set_action_mode", "get_action_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "button_mask", PROPERTY_HINT_FLAGS, "Mouse Left, Mouse Right, Mouse Middle"), "set_button_mask", "get_button_mask"); ADD_PROPERTY(PropertyInfo(Variant::INT, "enabled_focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_enabled_focus_mode", "get_enabled_focus_mode"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "ShortCut"), "set_shortcut", "get_shortcut"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "group", PROPERTY_HINT_RESOURCE_TYPE, "ButtonGroup"), "set_button_group", "get_button_group"); @@ -555,6 +568,7 @@ void BaseButton::_bind_methods() { BaseButton::BaseButton() { toggle_mode = false; + shortcut_in_tooltip = true; status.pressed = false; status.press_attempt = false; status.hovering = false; @@ -581,6 +595,16 @@ void ButtonGroup::get_buttons(List<BaseButton *> *r_buttons) { } } +Array ButtonGroup::_get_buttons() { + + Array btns; + for (Set<BaseButton *>::Element *E = buttons.front(); E; E = E->next()) { + btns.push_back(E->get()); + } + + return btns; +} + BaseButton *ButtonGroup::get_pressed_button() { for (Set<BaseButton *>::Element *E = buttons.front(); E; E = E->next()) { @@ -594,6 +618,7 @@ BaseButton *ButtonGroup::get_pressed_button() { void ButtonGroup::_bind_methods() { ClassDB::bind_method(D_METHOD("get_pressed_button"), &ButtonGroup::get_pressed_button); + ClassDB::bind_method(D_METHOD("get_buttons"), &ButtonGroup::_get_buttons); } ButtonGroup::ButtonGroup() { diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index 176d9fc213..9a00cc79f2 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -51,6 +51,7 @@ public: private: int button_mask; bool toggle_mode; + bool shortcut_in_tooltip; FocusMode enabled_focus_mode; Ref<ShortCut> shortcut; @@ -100,6 +101,9 @@ public: void set_toggle_mode(bool p_on); bool is_toggle_mode() const; + void set_shortcut_in_tooltip(bool p_on); + bool is_shortcut_in_tooltip_enabled() const; + void set_disabled(bool p_disabled); bool is_disabled() const; @@ -139,6 +143,7 @@ protected: public: BaseButton *get_pressed_button(); void get_buttons(List<BaseButton *> *r_buttons); + Array _get_buttons(); ButtonGroup(); }; diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp index 12b9fe7c03..cc37d4cf7d 100644 --- a/scene/gui/box_container.cpp +++ b/scene/gui/box_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -255,6 +255,10 @@ void BoxContainer::_notification(int p_what) { _resort(); } break; + case NOTIFICATION_THEME_CHANGED: { + + minimum_size_changed(); + } break; } } diff --git a/scene/gui/box_container.h b/scene/gui/box_container.h index abc228f804..89924f7fcb 100644 --- a/scene/gui/box_container.h +++ b/scene/gui/box_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 2d17fb1391..c734136895 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -140,8 +140,8 @@ void Button::_notification(int p_what) { if (has_focus()) { - Ref<StyleBox> style = get_stylebox("focus"); - style->draw(ci, Rect2(Point2(), size)); + Ref<StyleBox> style2 = get_stylebox("focus"); + style2->draw(ci, Rect2(Point2(), size)); } Ref<Font> font = get_font("font"); @@ -274,10 +274,10 @@ void Button::_bind_methods() { BIND_ENUM_CONSTANT(ALIGN_CENTER); BIND_ENUM_CONSTANT(ALIGN_RIGHT); - ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_button_icon", "get_button_icon"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_button_icon", "get_button_icon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "get_clip_text"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "get_clip_text"); ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_text_align", "get_text_align"); } diff --git a/scene/gui/button.h b/scene/gui/button.h index 0b41b14f02..6ba3475e5a 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/center_container.cpp b/scene/gui/center_container.cpp index cf71f89830..7c842999d1 100644 --- a/scene/gui/center_container.cpp +++ b/scene/gui/center_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/center_container.h b/scene/gui/center_container.h index 519e1493ec..9c9f61388c 100644 --- a/scene/gui/center_container.h +++ b/scene/gui/center_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp index 0790f87ea7..1d8b74d9db 100644 --- a/scene/gui/check_box.cpp +++ b/scene/gui/check_box.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/check_box.h b/scene/gui/check_box.h index 8375b46ca0..adfb12e7a1 100644 --- a/scene/gui/check_box.h +++ b/scene/gui/check_box.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp index fa9538da28..35e3119473 100644 --- a/scene/gui/check_button.cpp +++ b/scene/gui/check_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/check_button.h b/scene/gui/check_button.h index a11749e3f6..13b0dbc194 100644 --- a/scene/gui/check_button.h +++ b/scene/gui/check_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index c5d3def4c1..7aca6acd00 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,6 +35,7 @@ #include "core/os/os.h" #ifdef TOOLS_ENABLED +#include "editor_scale.h" #include "editor_settings.h" #endif @@ -81,11 +82,8 @@ void ColorPicker::_notification(int p_what) { } break; case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: { - if (screen != NULL) { - if (screen->is_visible()) { - screen->hide(); - } - } + if (screen != NULL && screen->is_visible()) + screen->hide(); } break; } } @@ -156,7 +154,7 @@ void ColorPicker::_value_changed(double) { void ColorPicker::_html_entered(const String &p_html) { - if (updating) + if (updating || text_is_constructor || !c_text->is_visible()) return; float last_alpha = color.a; @@ -176,14 +174,15 @@ void ColorPicker::_update_color() { updating = true; for (int i = 0; i < 4; i++) { - scroll[i]->set_step(0.01); if (raw_mode_enabled) { + scroll[i]->set_step(0.01); scroll[i]->set_max(100); if (i == 3) scroll[i]->set_max(1); scroll[i]->set_value(color.components[i]); } else { - const int byte_value = color.components[i] * 255; + scroll[i]->set_step(1); + const float byte_value = color.components[i] * 255.0; scroll[i]->set_max(next_power_of_2(MAX(255, byte_value)) - 1); scroll[i]->set_value(byte_value); } @@ -204,34 +203,24 @@ void ColorPicker::_update_presets() { preset->draw_texture_rect(get_icon("preset_bg", "ColorPicker"), Rect2(Point2(), preset_size), true); -#ifdef TOOLS_ENABLED - if (Engine::get_singleton()->is_editor_hint()) { - PoolColorArray arr_to_save = PoolColorArray(); - - for (int i = 0; i < presets.size(); i++) { - preset->draw_rect(Rect2(Point2(size.width * i, 0), size), presets[i]); - arr_to_save.insert(i, presets[i]); - } - - EditorSettings::get_singleton()->set_project_metadata("color_picker", "presets", arr_to_save); - } -#else for (int i = 0; i < presets.size(); i++) { preset->draw_rect(Rect2(Point2(size.width * i, 0), size), presets[i]); } -#endif } void ColorPicker::_text_type_toggled() { - if (!Engine::get_singleton()->is_editor_hint()) - return; + text_is_constructor = !text_is_constructor; if (text_is_constructor) { text_type->set_text(""); text_type->set_icon(get_icon("Script", "EditorIcons")); + + c_text->set_editable(false); } else { text_type->set_text("#"); text_type->set_icon(NULL); + + c_text->set_editable(true); } _update_color(); } @@ -251,6 +240,38 @@ void ColorPicker::add_preset(const Color &p_color) { preset->update(); if (presets.size() == 10) bt_add_preset->hide(); + +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + PoolColorArray arr_to_save = get_presets(); + EditorSettings::get_singleton()->set_project_metadata("color_picker", "presets", arr_to_save); + } +#endif +} + +void ColorPicker::erase_preset(const Color &p_color) { + + if (presets.find(p_color)) { + presets.erase(presets.find(p_color)); + preset->update(); + +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + PoolColorArray arr_to_save = get_presets(); + EditorSettings::get_singleton()->set_project_metadata("color_picker", "presets", arr_to_save); + } +#endif + } +} + +PoolColorArray ColorPicker::get_presets() const { + + PoolColorArray arr; + arr.resize(presets.size()); + for (int i = 0; i < presets.size(); i++) { + arr.set(i, presets[i]); + } + return arr; } void ColorPicker::set_raw_mode(bool p_enabled) { @@ -284,19 +305,21 @@ bool ColorPicker::is_deferred_mode() const { void ColorPicker::_update_text_value() { bool visible = true; if (text_is_constructor) { - String t = "Color(" + String::num(color.r) + "," + String::num(color.g) + "," + String::num(color.b); + String t = "Color(" + String::num(color.r) + ", " + String::num(color.g) + ", " + String::num(color.b); if (edit_alpha && color.a < 1) - t += ("," + String::num(color.a) + ")"); + t += ", " + String::num(color.a) + ")"; else t += ")"; c_text->set_text(t); - } else { - if (color.r > 1 || color.g > 1 || color.b > 1 || color.r < 0 || color.g < 0 || color.b < 0) { - visible = false; - } else { - c_text->set_text(color.to_html(edit_alpha && color.a < 1)); - } } + + if (color.r > 1 || color.g > 1 || color.b > 1 || color.r < 0 || color.g < 0 || color.b < 0) { + visible = false; + } else if (!text_is_constructor) { + c_text->set_text(color.to_html(edit_alpha && color.a < 1)); + } + + text_type->set_visible(visible); c_text->set_visible(visible); } @@ -444,14 +467,15 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) { if (bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) { int index = bev->get_position().x / (preset->get_size().x / presets.size()); set_pick_color(presets[index]); + _update_color(); + emit_signal("color_changed", color); } else if (bev->is_pressed() && bev->get_button_index() == BUTTON_RIGHT) { int index = bev->get_position().x / (preset->get_size().x / presets.size()); - presets.erase(presets[index]); - preset->update(); + Color clicked_preset = presets[index]; + erase_preset(clicked_preset); + emit_signal("preset_removed", clicked_preset); bt_add_preset->show(); } - _update_color(); - emit_signal("color_changed", color); } Ref<InputEventMouseMotion> mev = p_event; @@ -473,21 +497,17 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) { void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> bev = p_event; - - if (bev.is_valid()) { - - if (bev->get_button_index() == BUTTON_LEFT && !bev->is_pressed()) { - emit_signal("color_changed", color); - screen->hide(); - } + if (bev.is_valid() && bev->get_button_index() == BUTTON_LEFT && !bev->is_pressed()) { + emit_signal("color_changed", color); + screen->hide(); } Ref<InputEventMouseMotion> mev = p_event; - if (mev.is_valid()) { Viewport *r = get_tree()->get_root(); if (!r->get_visible_rect().has_point(Point2(mev->get_global_position().x, mev->get_global_position().y))) return; + Ref<Image> img = r->get_texture()->get_data(); if (img.is_valid() && !img->empty()) { img->lock(); @@ -501,6 +521,7 @@ void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) { void ColorPicker::_add_preset_pressed() { add_preset(color); + emit_signal("preset_added", color); } void ColorPicker::_screen_pick_pressed() { @@ -512,6 +533,8 @@ void ColorPicker::_screen_pick_pressed() { screen->set_anchors_and_margins_preset(Control::PRESET_WIDE); screen->set_default_cursor_shape(CURSOR_POINTING_HAND); screen->connect("gui_input", this, "_screen_input"); + // It immediately toggles off in the first press otherwise. + screen->call_deferred("connect", "hide", btn_pick, "set_pressed", varray(false)); } screen->raise(); screen->show_modal(); @@ -553,6 +576,8 @@ void ColorPicker::_bind_methods() { ClassDB::bind_method(D_METHOD("set_edit_alpha", "show"), &ColorPicker::set_edit_alpha); ClassDB::bind_method(D_METHOD("is_editing_alpha"), &ColorPicker::is_editing_alpha); ClassDB::bind_method(D_METHOD("add_preset", "color"), &ColorPicker::add_preset); + ClassDB::bind_method(D_METHOD("erase_preset", "color"), &ColorPicker::erase_preset); + ClassDB::bind_method(D_METHOD("get_presets"), &ColorPicker::get_presets); ClassDB::bind_method(D_METHOD("_value_changed"), &ColorPicker::_value_changed); ClassDB::bind_method(D_METHOD("_html_entered"), &ColorPicker::_html_entered); ClassDB::bind_method(D_METHOD("_text_type_toggled"), &ColorPicker::_text_type_toggled); @@ -575,6 +600,8 @@ void ColorPicker::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deferred_mode"), "set_deferred_mode", "is_deferred_mode"); ADD_SIGNAL(MethodInfo("color_changed", PropertyInfo(Variant::COLOR, "color"))); + ADD_SIGNAL(MethodInfo("preset_added", PropertyInfo(Variant::COLOR, "color"))); + ADD_SIGNAL(MethodInfo("preset_removed", PropertyInfo(Variant::COLOR, "color"))); } ColorPicker::ColorPicker() : @@ -589,22 +616,25 @@ ColorPicker::ColorPicker() : screen = NULL; HBoxContainer *hb_smpl = memnew(HBoxContainer); - btn_pick = memnew(ToolButton); - btn_pick->connect("pressed", this, "_screen_pick_pressed"); + add_child(hb_smpl); sample = memnew(TextureRect); + hb_smpl->add_child(sample); sample->set_h_size_flags(SIZE_EXPAND_FILL); sample->connect("draw", this, "_sample_draw"); - hb_smpl->add_child(sample); + btn_pick = memnew(ToolButton); hb_smpl->add_child(btn_pick); - add_child(hb_smpl); + btn_pick->set_toggle_mode(true); + btn_pick->set_tooltip(TTR("Pick a color from the screen.")); + btn_pick->connect("pressed", this, "_screen_pick_pressed"); HBoxContainer *hb_edit = memnew(HBoxContainer); + add_child(hb_edit); hb_edit->set_v_size_flags(SIZE_EXPAND_FILL); uv_edit = memnew(Control); - + hb_edit->add_child(uv_edit); uv_edit->connect("gui_input", this, "_uv_input"); uv_edit->set_mouse_filter(MOUSE_FILTER_PASS); uv_edit->set_h_size_flags(SIZE_EXPAND_FILL); @@ -612,19 +642,14 @@ ColorPicker::ColorPicker() : uv_edit->set_custom_minimum_size(Size2(get_constant("sv_width"), get_constant("sv_height"))); uv_edit->connect("draw", this, "_hsv_draw", make_binds(0, uv_edit)); - add_child(hb_edit); - w_edit = memnew(Control); + hb_edit->add_child(w_edit); w_edit->set_custom_minimum_size(Size2(get_constant("h_width"), 0)); w_edit->set_h_size_flags(SIZE_FILL); w_edit->set_v_size_flags(SIZE_EXPAND_FILL); w_edit->connect("gui_input", this, "_w_input"); w_edit->connect("draw", this, "_hsv_draw", make_binds(1, w_edit)); - hb_edit->add_child(uv_edit); - hb_edit->add_child(memnew(VSeparator)); - hb_edit->add_child(w_edit); - VBoxContainer *vbl = memnew(VBoxContainer); add_child(vbl); @@ -665,31 +690,43 @@ ColorPicker::ColorPicker() : } HBoxContainer *hhb = memnew(HBoxContainer); + vbr->add_child(hhb); btn_mode = memnew(CheckButton); + hhb->add_child(btn_mode); btn_mode->set_text(TTR("Raw Mode")); btn_mode->connect("toggled", this, "set_raw_mode"); - hhb->add_child(btn_mode); - vbr->add_child(hhb); + text_type = memnew(Button); - text_type->set_flat(true); - text_type->connect("pressed", this, "_text_type_toggled"); hhb->add_child(text_type); + text_type->set_text("#"); + text_type->set_tooltip(TTR("Switch between hexadecimal and code values.")); + if (Engine::get_singleton()->is_editor_hint()) { + +#ifdef TOOLS_ENABLED + text_type->set_custom_minimum_size(Size2(28 * EDSCALE, 0)); // Adjust for the width of the "Script" icon. +#endif + text_type->connect("pressed", this, "_text_type_toggled"); + } else { + + text_type->set_flat(true); + text_type->set_mouse_filter(MOUSE_FILTER_IGNORE); + } c_text = memnew(LineEdit); hhb->add_child(c_text); + c_text->set_h_size_flags(SIZE_EXPAND_FILL); c_text->connect("text_entered", this, "_html_entered"); c_text->connect("focus_entered", this, "_focus_enter"); c_text->connect("focus_exited", this, "_html_focus_exit"); - text_type->set_text("#"); - c_text->set_h_size_flags(SIZE_EXPAND_FILL); - _update_controls(); updating = false; set_pick_color(Color(1, 1, 1)); + add_child(memnew(HSeparator)); + HBoxContainer *bbc = memnew(HBoxContainer); add_child(bbc); @@ -699,9 +736,9 @@ ColorPicker::ColorPicker() : preset->connect("draw", this, "_update_presets"); bt_add_preset = memnew(Button); - bt_add_preset->set_tooltip(TTR("Add current color as a preset")); - bt_add_preset->connect("pressed", this, "_add_preset_pressed"); bbc->add_child(bt_add_preset); + bt_add_preset->set_tooltip(TTR("Add current color as a preset.")); + bt_add_preset->connect("pressed", this, "_add_preset_pressed"); } ///////////////// @@ -812,9 +849,9 @@ void ColorPickerButton::_bind_methods() { ColorPickerButton::ColorPickerButton() { - //Initialization is now done deferred - //this improves performance in the inspector as the color picker - //can be expensive to initialize + // Initialization is now done deferred, + // this improves performance in the inspector as the color picker + // can be expensive to initialize. picker = NULL; popup = NULL; edit_alpha = true; diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 0166da7118..b78844839a 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -105,6 +105,9 @@ public: Color get_pick_color() const; void add_preset(const Color &p_color); + void erase_preset(const Color &p_color); + PoolColorArray get_presets() const; + void set_raw_mode(bool p_enabled); bool is_raw_mode() const; diff --git a/scene/gui/color_rect.cpp b/scene/gui/color_rect.cpp index 463f3911dc..df9b4e8498 100644 --- a/scene/gui/color_rect.cpp +++ b/scene/gui/color_rect.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/color_rect.h b/scene/gui/color_rect.h index a841008f76..d7f9ef275d 100644 --- a/scene/gui/color_rect.h +++ b/scene/gui/color_rect.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index d606629041..7f1ca58d58 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -95,6 +95,7 @@ void Container::_sort_children() { void Container::fit_child_in_rect(Control *p_child, const Rect2 &p_rect) { + ERR_FAIL_COND(!p_child); ERR_FAIL_COND(p_child->get_parent() != this); Size2 minsize = p_child->get_combined_minimum_size(); @@ -168,6 +169,19 @@ void Container::_notification(int p_what) { } } +String Container::get_configuration_warning() const { + + String warning = Control::get_configuration_warning(); + + if (get_class() == "Container" && get_script().is_null()) { + if (warning != String()) { + warning += "\n"; + } + warning += TTR("Container by itself serves no purpose unless a script configures it's children placement behavior.\nIf you dont't intend to add a script, then please use a plain 'Control' node instead."); + } + return warning; +} + void Container::_bind_methods() { ClassDB::bind_method(D_METHOD("_sort_children"), &Container::_sort_children); diff --git a/scene/gui/container.h b/scene/gui/container.h index c472162f58..80d3f6ee5d 100644 --- a/scene/gui/container.h +++ b/scene/gui/container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -57,6 +57,8 @@ public: void fit_child_in_rect(Control *p_child, const Rect2 &p_rect); + virtual String get_configuration_warning() const; + Container(); }; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index e155d0ef86..86894ce070 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -206,65 +206,62 @@ bool Control::_set(const StringName &p_name, const Variant &p_value) { if (name.begins_with("custom_icons/")) { String dname = name.get_slicec('/', 1); + if (data.icon_override.has(dname)) { + data.icon_override[dname]->disconnect("changed", this, "_override_changed"); + } data.icon_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - update(); } else if (name.begins_with("custom_shaders/")) { String dname = name.get_slicec('/', 1); + if (data.shader_override.has(dname)) { + data.shader_override[dname]->disconnect("changed", this, "_override_changed"); + } data.shader_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - update(); } else if (name.begins_with("custom_styles/")) { String dname = name.get_slicec('/', 1); + if (data.style_override.has(dname)) { + data.style_override[dname]->disconnect("changed", this, "_override_changed"); + } data.style_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - update(); } else if (name.begins_with("custom_fonts/")) { String dname = name.get_slicec('/', 1); if (data.font_override.has(dname)) { - _unref_font(data.font_override[dname]); + data.font_override[dname]->disconnect("changed", this, "_override_changed"); } data.font_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - update(); } else if (name.begins_with("custom_colors/")) { String dname = name.get_slicec('/', 1); data.color_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - update(); } else if (name.begins_with("custom_constants/")) { String dname = name.get_slicec('/', 1); data.constant_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - update(); } else return false; } else { if (name.begins_with("custom_icons/")) { String dname = name.get_slicec('/', 1); - notification(NOTIFICATION_THEME_CHANGED); add_icon_override(dname, p_value); } else if (name.begins_with("custom_shaders/")) { String dname = name.get_slicec('/', 1); add_shader_override(dname, p_value); - notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("custom_styles/")) { String dname = name.get_slicec('/', 1); add_style_override(dname, p_value); - notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("custom_fonts/")) { String dname = name.get_slicec('/', 1); add_font_override(dname, p_value); - notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("custom_colors/")) { String dname = name.get_slicec('/', 1); add_color_override(dname, p_value); - notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("custom_constants/")) { String dname = name.get_slicec('/', 1); add_constant_override(dname, p_value); - notification(NOTIFICATION_THEME_CHANGED); } else return false; } @@ -328,13 +325,15 @@ bool Control::_get(const StringName &p_name, Variant &r_ret) const { } void Control::_get_property_list(List<PropertyInfo> *p_list) const { - Ref<Theme> theme; + Ref<Theme> theme = Theme::get_default(); + /* Using the default theme since the properties below are meant for editor only if (data.theme.is_valid()) { theme = data.theme; } else { theme = Theme::get_default(); - } + + }*/ { List<StringName> names; @@ -449,6 +448,11 @@ void Control::_update_canvas_item_transform() { Transform2D xform = _get_internal_transform(); xform[2] += get_position(); + // We use a little workaround to avoid flickering when moving the pivot with _edit_set_pivot() + if (is_inside_tree() && Math::abs(Math::sin(data.rotation * 4.0f)) < 0.00001f && get_viewport()->is_snap_controls_to_pixels_enabled()) { + xform[2] = xform[2].round(); + } + VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), xform); } @@ -1334,11 +1338,6 @@ void Control::_size_changed() { new_size_cache.height = minimum_size.height; } - // We use a little workaround to avoid flickering when moving the pivot with _edit_set_pivot() - if (is_inside_tree() && Math::abs(Math::sin(data.rotation * 4.0f)) < 0.00001f && get_viewport()->is_snap_controls_to_pixels_enabled()) { - new_size_cache = new_size_cache.round(); - new_pos_cache = new_pos_cache.round(); - } bool pos_changed = new_pos_cache != data.pos_cache; bool size_changed = new_size_cache != data.size_cache; @@ -1738,10 +1737,10 @@ Rect2 Control::_compute_child_rect(const float p_anchors[4], const float p_margi void Control::_compute_margins(Rect2 p_rect, const float p_anchors[4], float (&r_margins)[4]) { Size2 parent_rect_size = get_parent_anchorable_rect().size; - r_margins[0] = Math::floor(p_rect.position.x - (p_anchors[0] * parent_rect_size.x)); - r_margins[1] = Math::floor(p_rect.position.y - (p_anchors[1] * parent_rect_size.y)); - r_margins[2] = Math::floor(p_rect.position.x + p_rect.size.x - (p_anchors[2] * parent_rect_size.x)); - r_margins[3] = Math::floor(p_rect.position.y + p_rect.size.y - (p_anchors[3] * parent_rect_size.y)); + r_margins[0] = p_rect.position.x - (p_anchors[0] * parent_rect_size.x); + r_margins[1] = p_rect.position.y - (p_anchors[1] * parent_rect_size.y); + r_margins[2] = p_rect.position.x + p_rect.size.x - (p_anchors[2] * parent_rect_size.x); + r_margins[3] = p_rect.position.y + p_rect.size.y - (p_anchors[3] * parent_rect_size.y); } void Control::set_position(const Size2 &p_point) { @@ -1798,51 +1797,63 @@ Rect2 Control::get_anchorable_rect() const { void Control::add_icon_override(const StringName &p_name, const Ref<Texture> &p_icon) { ERR_FAIL_COND(p_icon.is_null()); + if (data.icon_override.has(p_name)) { + data.icon_override[p_name]->disconnect("changed", this, "_override_changed"); + } data.icon_override[p_name] = p_icon; + if (data.icon_override[p_name].is_valid()) { + data.icon_override[p_name]->connect("changed", this, "_override_changed", Vector<Variant>(), CONNECT_REFERENCE_COUNTED); + } notification(NOTIFICATION_THEME_CHANGED); - update(); } void Control::add_shader_override(const StringName &p_name, const Ref<Shader> &p_shader) { ERR_FAIL_COND(p_shader.is_null()); + if (data.shader_override.has(p_name)) { + data.shader_override[p_name]->disconnect("changed", this, "_override_changed"); + } data.shader_override[p_name] = p_shader; + if (data.shader_override[p_name].is_valid()) { + data.shader_override[p_name]->connect("changed", this, "_override_changed", Vector<Variant>(), CONNECT_REFERENCE_COUNTED); + } notification(NOTIFICATION_THEME_CHANGED); - update(); } void Control::add_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) { ERR_FAIL_COND(p_style.is_null()); + if (data.style_override.has(p_name)) { + data.style_override[p_name]->disconnect("changed", this, "_override_changed"); + } data.style_override[p_name] = p_style; + if (data.style_override[p_name].is_valid()) { + data.style_override[p_name]->connect("changed", this, "_override_changed", Vector<Variant>(), CONNECT_REFERENCE_COUNTED); + } + notification(NOTIFICATION_THEME_CHANGED); - update(); } void Control::add_font_override(const StringName &p_name, const Ref<Font> &p_font) { ERR_FAIL_COND(p_font.is_null()); if (data.font_override.has(p_name)) { - _unref_font(data.font_override[p_name]); + data.font_override[p_name]->disconnect("changed", this, "_override_changed"); } data.font_override[p_name] = p_font; - - if (p_font.is_valid()) { - _ref_font(p_font); + if (data.font_override[p_name].is_valid()) { + data.font_override[p_name]->connect("changed", this, "_override_changed", Vector<Variant>(), CONNECT_REFERENCE_COUNTED); } notification(NOTIFICATION_THEME_CHANGED); - update(); } void Control::add_color_override(const StringName &p_name, const Color &p_color) { data.color_override[p_name] = p_color; notification(NOTIFICATION_THEME_CHANGED); - update(); } void Control::add_constant_override(const StringName &p_name, int p_constant) { data.constant_override[p_name] = p_constant; notification(NOTIFICATION_THEME_CHANGED); - update(); } void Control::set_focus_mode(FocusMode p_focus_mode) { @@ -2141,7 +2152,6 @@ void Control::_propagate_theme_changed(CanvasItem *p_at, Control *p_owner, bool c->data.theme_owner = p_owner; } c->notification(NOTIFICATION_THEME_CHANGED); - c->update(); } } @@ -2548,32 +2558,10 @@ float Control::get_rotation_degrees() const { return Math::rad2deg(get_rotation()); } -//needed to update the control if the font changes.. -void Control::_ref_font(Ref<Font> p_sc) { - - if (!data.font_refcount.has(p_sc)) { - data.font_refcount[p_sc] = 1; - p_sc->connect("changed", this, "_font_changed"); - } else { - data.font_refcount[p_sc] += 1; - } -} - -void Control::_unref_font(Ref<Font> p_sc) { - - ERR_FAIL_COND(!data.font_refcount.has(p_sc)); - data.font_refcount[p_sc]--; - if (data.font_refcount[p_sc] == 0) { - p_sc->disconnect("changed", this, "_font_changed"); - data.font_refcount.erase(p_sc); - } -} - -void Control::_font_changed() { +void Control::_override_changed() { - update(); notification(NOTIFICATION_THEME_CHANGED); - minimum_size_changed(); //fonts affect minimum size pretty much almost always + minimum_size_changed(); // overrides are likely to affect minimum size } void Control::set_pivot_offset(const Vector2 &p_pivot) { @@ -2733,7 +2721,7 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("get_scale"), &Control::get_scale); ClassDB::bind_method(D_METHOD("get_pivot_offset"), &Control::get_pivot_offset); ClassDB::bind_method(D_METHOD("get_custom_minimum_size"), &Control::get_custom_minimum_size); - ClassDB::bind_method(D_METHOD("get_parent_area_size"), &Control::get_size); + ClassDB::bind_method(D_METHOD("get_parent_area_size"), &Control::get_parent_area_size); ClassDB::bind_method(D_METHOD("get_global_position"), &Control::get_global_position); ClassDB::bind_method(D_METHOD("get_rect"), &Control::get_rect); ClassDB::bind_method(D_METHOD("get_global_rect"), &Control::get_global_rect); @@ -2827,7 +2815,7 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("_theme_changed"), &Control::_theme_changed); - ClassDB::bind_method(D_METHOD("_font_changed"), &Control::_font_changed); + ClassDB::bind_method(D_METHOD("_override_changed"), &Control::_override_changed); BIND_VMETHOD(MethodInfo("_gui_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); BIND_VMETHOD(MethodInfo(Variant::VECTOR2, "_get_minimum_size")); @@ -2844,36 +2832,36 @@ void Control::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_bottom", PROPERTY_HINT_RANGE, "0,1,0.01"), "_set_anchor", "get_anchor", MARGIN_BOTTOM); ADD_GROUP("Margin", "margin_"); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "margin_left", PROPERTY_HINT_RANGE, "-4096,4096"), "set_margin", "get_margin", MARGIN_LEFT); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "margin_top", PROPERTY_HINT_RANGE, "-4096,4096"), "set_margin", "get_margin", MARGIN_TOP); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "margin_right", PROPERTY_HINT_RANGE, "-4096,4096"), "set_margin", "get_margin", MARGIN_RIGHT); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "margin_bottom", PROPERTY_HINT_RANGE, "-4096,4096"), "set_margin", "get_margin", MARGIN_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "margin_left", PROPERTY_HINT_RANGE, "-4096,4096"), "set_margin", "get_margin", MARGIN_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "margin_top", PROPERTY_HINT_RANGE, "-4096,4096"), "set_margin", "get_margin", MARGIN_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "margin_right", PROPERTY_HINT_RANGE, "-4096,4096"), "set_margin", "get_margin", MARGIN_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "margin_bottom", PROPERTY_HINT_RANGE, "-4096,4096"), "set_margin", "get_margin", MARGIN_BOTTOM); ADD_GROUP("Grow Direction", "grow_"); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "grow_horizontal", PROPERTY_HINT_ENUM, "Begin,End,Both"), "set_h_grow_direction", "get_h_grow_direction"); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "grow_vertical", PROPERTY_HINT_ENUM, "Begin,End,Both"), "set_v_grow_direction", "get_v_grow_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "grow_horizontal", PROPERTY_HINT_ENUM, "Begin,End,Both"), "set_h_grow_direction", "get_h_grow_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "grow_vertical", PROPERTY_HINT_ENUM, "Begin,End,Both"), "set_v_grow_direction", "get_v_grow_direction"); ADD_GROUP("Rect", "rect_"); - ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "rect_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_position", "get_position"); - ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "rect_global_position", PROPERTY_HINT_NONE, "", 0), "set_global_position", "get_global_position"); - ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "rect_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_size", "get_size"); - ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "rect_min_size"), "set_custom_minimum_size", "get_custom_minimum_size"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "rect_rotation", PROPERTY_HINT_RANGE, "-1080,1080,0.01"), "set_rotation_degrees", "get_rotation_degrees"); - ADD_PROPERTYNO(PropertyInfo(Variant::VECTOR2, "rect_scale"), "set_scale", "get_scale"); - ADD_PROPERTYNO(PropertyInfo(Variant::VECTOR2, "rect_pivot_offset"), "set_pivot_offset", "get_pivot_offset"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_position", "get_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_global_position", PROPERTY_HINT_NONE, "", 0), "set_global_position", "get_global_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_min_size"), "set_custom_minimum_size", "get_custom_minimum_size"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "rect_rotation", PROPERTY_HINT_RANGE, "-1080,1080,0.01"), "set_rotation_degrees", "get_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_scale"), "set_scale", "get_scale"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_pivot_offset"), "set_pivot_offset", "get_pivot_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rect_clip_content"), "set_clip_contents", "is_clipping_contents"); ADD_GROUP("Hint", "hint_"); - ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "hint_tooltip", PROPERTY_HINT_MULTILINE_TEXT), "set_tooltip", "_get_tooltip"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "hint_tooltip", PROPERTY_HINT_MULTILINE_TEXT), "set_tooltip", "_get_tooltip"); ADD_GROUP("Focus", "focus_"); - ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_left", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_LEFT); - ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_top", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_TOP); - ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_right", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_RIGHT); - ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_bottom", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_BOTTOM); - ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_next", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_next", "get_focus_next"); - ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_previous", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_previous", "get_focus_previous"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_focus_mode", "get_focus_mode"); + ADD_PROPERTYI(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_left", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_top", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_right", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_bottom", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_BOTTOM); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "focus_next", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_next", "get_focus_next"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "focus_previous", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_previous", "get_focus_previous"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_focus_mode", "get_focus_mode"); ADD_GROUP("Mouse", "mouse_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_filter", PROPERTY_HINT_ENUM, "Stop,Pass,Ignore"), "set_mouse_filter", "get_mouse_filter"); @@ -2882,9 +2870,9 @@ void Control::_bind_methods() { ADD_GROUP("Size Flags", "size_flags_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_horizontal", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_h_size_flags", "get_h_size_flags"); ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_vertical", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_v_size_flags", "get_v_size_flags"); - ADD_PROPERTYNO(PropertyInfo(Variant::REAL, "size_flags_stretch_ratio", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_stretch_ratio", "get_stretch_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "size_flags_stretch_ratio", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_stretch_ratio", "get_stretch_ratio"); ADD_GROUP("Theme", ""); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme"); ADD_GROUP("", ""); BIND_ENUM_CONSTANT(FOCUS_NONE); diff --git a/scene/gui/control.h b/scene/gui/control.h index eb39d9ca0f..5e33f6ba43 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -207,7 +207,6 @@ private: HashMap<StringName, Ref<Font> > font_override; HashMap<StringName, Color> color_override; HashMap<StringName, int> constant_override; - Map<Ref<Font>, int> font_refcount; } data; @@ -234,9 +233,7 @@ private: void _size_changed(); String _get_tooltip() const; - void _ref_font(Ref<Font> p_sc); - void _unref_font(Ref<Font> p_sc); - void _font_changed(); + void _override_changed(); void _update_canvas_item_transform(); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index e3a21eb10d..89f3d509d0 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -535,7 +535,7 @@ void AcceptDialog::_bind_methods() { ADD_SIGNAL(MethodInfo("custom_action", PropertyInfo(Variant::STRING, "action"))); ADD_GROUP("Dialog", "dialog"); - ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "dialog_text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "dialog_text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dialog_hide_on_ok"), "set_hide_on_ok", "get_hide_on_ok"); } diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index feb080dd06..4b89ac54c5 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 1e9f4df4a3..059e59ea21 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,6 +29,7 @@ /*************************************************************************/ #include "file_dialog.h" + #include "core/os/keyboard.h" #include "core/print_string.h" #include "scene/gui/label.h" @@ -596,7 +597,7 @@ void FileDialog::set_current_file(const String &p_file) { int lp = p_file.find_last("."); if (lp != -1) { file->select(0, lp); - if (file->is_inside_tree()) + if (file->is_inside_tree() && !get_tree()->is_node_being_edited(file)) file->grab_focus(); } } @@ -860,7 +861,7 @@ FileDialog::FileDialog() { HBoxContainer *hbc = memnew(HBoxContainer); dir_up = memnew(ToolButton); - dir_up->set_tooltip(RTR("Go to parent folder")); + dir_up->set_tooltip(RTR("Go to parent folder.")); hbc->add_child(dir_up); dir_up->connect("pressed", this, "_go_up"); @@ -870,6 +871,7 @@ FileDialog::FileDialog() { dir->set_h_size_flags(SIZE_EXPAND_FILL); refresh = memnew(ToolButton); + refresh->set_tooltip(RTR("Refresh")); refresh->connect("pressed", this, "_update_file_list"); hbc->add_child(refresh); diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 8bd15080d3..85edac0b12 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index c13964d196..cfbc9d6d18 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h index f6927ad0b7..662278a17b 100644 --- a/scene/gui/gradient_edit.h +++ b/scene/gui/gradient_edit.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,8 +33,8 @@ #include "scene/gui/color_picker.h" #include "scene/gui/popup.h" -#include "scene/resources/color_ramp.h" #include "scene/resources/default_theme/theme_data.h" +#include "scene/resources/gradient.h" #define POINT_WIDTH (8 * EDSCALE) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index b3bebc88ec..68e734502b 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,6 +34,10 @@ #include "core/os/keyboard.h" #include "scene/gui/box_container.h" +#ifdef TOOLS_ENABLED +#include "editor/editor_scale.h" +#endif + #define ZOOM_SCALE 1.2 #define MIN_ZOOM (((1 / ZOOM_SCALE) / ZOOM_SCALE) / ZOOM_SCALE) @@ -217,8 +221,8 @@ void GraphEdit::_graph_node_raised(Node *p_gn) { } int first_not_comment = 0; for (int i = 0; i < get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); - if (gn && !gn->is_comment()) { + GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); + if (gn2 && !gn2->is_comment()) { first_not_comment = i; break; } @@ -257,8 +261,9 @@ void GraphEdit::add_child_notify(Node *p_child) { void GraphEdit::remove_child_notify(Node *p_child) { Control::remove_child_notify(p_child); - - top_layer->call_deferred("raise"); //top layer always on top! + if (is_inside_tree()) { + top_layer->call_deferred("raise"); //top layer always on top! + } GraphNode *gn = Object::cast_to<GraphNode>(p_child); if (gn) { gn->disconnect("offset_changed", this, "_graph_node_moved"); @@ -665,11 +670,15 @@ void GraphEdit::_draw_cos_line(CanvasItem *p_where, const Vector2 &p_from, const Vector<Color> colors; points.push_back(p_from); colors.push_back(p_color); - _bake_segment2d(points, colors, 0, 1, p_from, c1, p_to, c2, 0, 3, 9, 8, p_color, p_to_color, lines); + _bake_segment2d(points, colors, 0, 1, p_from, c1, p_to, c2, 0, 3, 9, 3, p_color, p_to_color, lines); points.push_back(p_to); colors.push_back(p_to_color); +#ifdef TOOLS_ENABLED + p_where->draw_polyline_colors(points, colors, Math::floor(2 * EDSCALE), true); +#else p_where->draw_polyline_colors(points, colors, 2, true); +#endif } void GraphEdit::_connections_layer_draw() { @@ -950,33 +959,33 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { - GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); - if (!gn || !gn->is_selected()) + GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); + if (!gn2 || !gn2->is_selected()) continue; - previus_selected.push_back(gn); + previus_selected.push_back(gn2); } } else if (b->get_shift()) { box_selection_mode_aditive = false; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { - GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); - if (!gn || !gn->is_selected()) + GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); + if (!gn2 || !gn2->is_selected()) continue; - previus_selected.push_back(gn); + previus_selected.push_back(gn2); } } else { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { - GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); - if (!gn) + GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); + if (!gn2) continue; - gn->set_selected(false); + gn2->set_selected(false); } } } @@ -1277,7 +1286,7 @@ void GraphEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("connection_request", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::STRING, "to"), PropertyInfo(Variant::INT, "to_slot"))); ADD_SIGNAL(MethodInfo("disconnection_request", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::STRING, "to"), PropertyInfo(Variant::INT, "to_slot"))); - ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2, "p_position"))); + ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2, "position"))); ADD_SIGNAL(MethodInfo("duplicate_nodes_request")); ADD_SIGNAL(MethodInfo("node_selected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::VECTOR2, "release_position"))); @@ -1339,21 +1348,25 @@ GraphEdit::GraphEdit() { zoom_minus = memnew(ToolButton); zoom_hb->add_child(zoom_minus); + zoom_minus->set_tooltip(RTR("Zoom Out")); zoom_minus->connect("pressed", this, "_zoom_minus"); zoom_minus->set_focus_mode(FOCUS_NONE); zoom_reset = memnew(ToolButton); zoom_hb->add_child(zoom_reset); + zoom_reset->set_tooltip(RTR("Zoom Reset")); zoom_reset->connect("pressed", this, "_zoom_reset"); zoom_reset->set_focus_mode(FOCUS_NONE); zoom_plus = memnew(ToolButton); zoom_hb->add_child(zoom_plus); + zoom_plus->set_tooltip(RTR("Zoom In")); zoom_plus->connect("pressed", this, "_zoom_plus"); zoom_plus->set_focus_mode(FOCUS_NONE); snap_button = memnew(ToolButton); snap_button->set_toggle_mode(true); + snap_button->set_tooltip(RTR("Enable snap and show grid.")); snap_button->connect("pressed", this, "_snap_toggled"); snap_button->set_pressed(true); snap_button->set_focus_mode(FOCUS_NONE); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 71165e3dc9..de826bf505 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index b189afd30b..8c588109d6 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -192,97 +192,104 @@ bool GraphNode::has_point(const Point2 &p_point) const { void GraphNode::_notification(int p_what) { - if (p_what == NOTIFICATION_DRAW) { + switch (p_what) { + case NOTIFICATION_DRAW: { - Ref<StyleBox> sb; + Ref<StyleBox> sb; - if (comment) { - sb = get_stylebox(selected ? "commentfocus" : "comment"); + if (comment) { + sb = get_stylebox(selected ? "commentfocus" : "comment"); - } else { + } else { - sb = get_stylebox(selected ? "selectedframe" : "frame"); - } + sb = get_stylebox(selected ? "selectedframe" : "frame"); + } - //sb=sb->duplicate(); - //sb->call("set_modulate",modulate); - Ref<Texture> port = get_icon("port"); - Ref<Texture> close = get_icon("close"); - Ref<Texture> resizer = get_icon("resizer"); - int close_offset = get_constant("close_offset"); - int close_h_offset = get_constant("close_h_offset"); - Color close_color = get_color("close_color"); - Ref<Font> title_font = get_font("title_font"); - int title_offset = get_constant("title_offset"); - int title_h_offset = get_constant("title_h_offset"); - Color title_color = get_color("title_color"); - Point2i icofs = -port->get_size() * 0.5; - int edgeofs = get_constant("port_offset"); - icofs.y += sb->get_margin(MARGIN_TOP); - - draw_style_box(sb, Rect2(Point2(), get_size())); - - switch (overlay) { - case OVERLAY_DISABLED: { - - } break; - case OVERLAY_BREAKPOINT: { - - draw_style_box(get_stylebox("breakpoint"), Rect2(Point2(), get_size())); - } break; - case OVERLAY_POSITION: { - draw_style_box(get_stylebox("position"), Rect2(Point2(), get_size())); - - } break; - } + //sb=sb->duplicate(); + //sb->call("set_modulate",modulate); + Ref<Texture> port = get_icon("port"); + Ref<Texture> close = get_icon("close"); + Ref<Texture> resizer = get_icon("resizer"); + int close_offset = get_constant("close_offset"); + int close_h_offset = get_constant("close_h_offset"); + Color close_color = get_color("close_color"); + Ref<Font> title_font = get_font("title_font"); + int title_offset = get_constant("title_offset"); + int title_h_offset = get_constant("title_h_offset"); + Color title_color = get_color("title_color"); + Point2i icofs = -port->get_size() * 0.5; + int edgeofs = get_constant("port_offset"); + icofs.y += sb->get_margin(MARGIN_TOP); + + draw_style_box(sb, Rect2(Point2(), get_size())); + + switch (overlay) { + case OVERLAY_DISABLED: { + + } break; + case OVERLAY_BREAKPOINT: { + + draw_style_box(get_stylebox("breakpoint"), Rect2(Point2(), get_size())); + } break; + case OVERLAY_POSITION: { + draw_style_box(get_stylebox("position"), Rect2(Point2(), get_size())); + + } break; + } - int w = get_size().width - sb->get_minimum_size().x; + int w = get_size().width - sb->get_minimum_size().x; - if (show_close) - w -= close->get_width(); + if (show_close) + w -= close->get_width(); - draw_string(title_font, Point2(sb->get_margin(MARGIN_LEFT) + title_h_offset, -title_font->get_height() + title_font->get_ascent() + title_offset), title, title_color, w); - if (show_close) { - Vector2 cpos = Point2(w + sb->get_margin(MARGIN_LEFT) + close_h_offset, -close->get_height() + close_offset); - draw_texture(close, cpos, close_color); - close_rect.position = cpos; - close_rect.size = close->get_size(); - } else { - close_rect = Rect2(); - } + draw_string(title_font, Point2(sb->get_margin(MARGIN_LEFT) + title_h_offset, -title_font->get_height() + title_font->get_ascent() + title_offset), title, title_color, w); + if (show_close) { + Vector2 cpos = Point2(w + sb->get_margin(MARGIN_LEFT) + close_h_offset, -close->get_height() + close_offset); + draw_texture(close, cpos, close_color); + close_rect.position = cpos; + close_rect.size = close->get_size(); + } else { + close_rect = Rect2(); + } - for (Map<int, Slot>::Element *E = slot_info.front(); E; E = E->next()) { - - if (E->key() < 0 || E->key() >= cache_y.size()) - continue; - if (!slot_info.has(E->key())) - continue; - const Slot &s = slot_info[E->key()]; - //left - if (s.enable_left) { - Ref<Texture> p = port; - if (s.custom_slot_left.is_valid()) { - p = s.custom_slot_left; + for (Map<int, Slot>::Element *E = slot_info.front(); E; E = E->next()) { + + if (E->key() < 0 || E->key() >= cache_y.size()) + continue; + if (!slot_info.has(E->key())) + continue; + const Slot &s = slot_info[E->key()]; + //left + if (s.enable_left) { + Ref<Texture> p = port; + if (s.custom_slot_left.is_valid()) { + p = s.custom_slot_left; + } + p->draw(get_canvas_item(), icofs + Point2(edgeofs, cache_y[E->key()]), s.color_left); } - p->draw(get_canvas_item(), icofs + Point2(edgeofs, cache_y[E->key()]), s.color_left); - } - if (s.enable_right) { - Ref<Texture> p = port; - if (s.custom_slot_right.is_valid()) { - p = s.custom_slot_right; + if (s.enable_right) { + Ref<Texture> p = port; + if (s.custom_slot_right.is_valid()) { + p = s.custom_slot_right; + } + p->draw(get_canvas_item(), icofs + Point2(get_size().x - edgeofs, cache_y[E->key()]), s.color_right); } - p->draw(get_canvas_item(), icofs + Point2(get_size().x - edgeofs, cache_y[E->key()]), s.color_right); } - } - if (resizable) { - draw_texture(resizer, get_size() - resizer->get_size()); - } - } + if (resizable) { + draw_texture(resizer, get_size() - resizer->get_size()); + } + } break; + + case NOTIFICATION_SORT_CHILDREN: { + + _resort(); + } break; - if (p_what == NOTIFICATION_SORT_CHILDREN) { + case NOTIFICATION_THEME_CHANGED: { - _resort(); + minimum_size_changed(); + } break; } } diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 20d25a69b0..2179904cc4 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index bb1d1d7695..d0e2edc7b5 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -164,6 +164,10 @@ void GridContainer::_notification(int p_what) { } } break; + case NOTIFICATION_THEME_CHANGED: { + + minimum_size_changed(); + } break; } } diff --git a/scene/gui/grid_container.h b/scene/gui/grid_container.h index 243d06f034..3196046378 100644 --- a/scene/gui/grid_container.h +++ b/scene/gui/grid_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 0d5fbee9ee..026374ded1 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,6 +36,7 @@ void ItemList::add_item(const String &p_item, const Ref<Texture> &p_texture, boo Item item; item.icon = p_texture; + item.icon_transposed = false; item.icon_region = Rect2i(); item.icon_modulate = Color(1, 1, 1, 1); item.text = p_item; @@ -54,6 +55,7 @@ void ItemList::add_icon_item(const Ref<Texture> &p_item, bool p_selectable) { Item item; item.icon = p_item; + item.icon_transposed = false; item.icon_region = Rect2i(); item.icon_modulate = Color(1, 1, 1, 1); //item.text=p_item; @@ -124,6 +126,22 @@ Ref<Texture> ItemList::get_item_icon(int p_idx) const { return items[p_idx].icon; } +void ItemList::set_item_icon_transposed(int p_idx, const bool p_transposed) { + + ERR_FAIL_INDEX(p_idx, items.size()); + + items.write[p_idx].icon_transposed = p_transposed; + update(); + shape_changed = true; +} + +bool ItemList::is_item_icon_transposed(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx, items.size(), false); + + return items[p_idx].icon_transposed; +} + void ItemList::set_item_icon_region(int p_idx, const Rect2 &p_region) { ERR_FAIL_INDEX(p_idx, items.size()); @@ -416,6 +434,7 @@ void ItemList::set_icon_mode(IconMode p_mode) { update(); shape_changed = true; } + ItemList::IconMode ItemList::get_icon_mode() const { return icon_mode; @@ -435,10 +454,18 @@ Size2 ItemList::Item::get_icon_size() const { if (icon.is_null()) return Size2(); - if (icon_region.has_no_area()) - return icon->get_size(); - return icon_region.size; + Size2 size_result = Size2(icon_region.size).abs(); + if (icon_region.size.x == 0 || icon_region.size.y == 0) + size_result = icon->get_size(); + + if (icon_transposed) { + Size2 size_tmp = size_result; + size_result.x = size_tmp.y; + size_result.y = size_tmp.x; + } + + return size_result; } void ItemList::_gui_input(const Ref<InputEvent> &p_event) { @@ -688,9 +715,9 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) { } } else if (p_event->is_action("ui_cancel")) { search_string = ""; - } else if (p_event->is_action("ui_select")) { + } else if (p_event->is_action("ui_select") && select_mode == SELECT_MULTI) { - if (select_mode == SELECT_MULTI && current >= 0 && current < items.size()) { + if (current >= 0 && current < items.size()) { if (items[current].selectable && !items[current].disabled && !items[current].selected) { select(current, false); emit_signal("multi_selected", current, true); @@ -1067,10 +1094,15 @@ void ItemList::_notification(int p_what) { if (items[i].disabled) modulate.a *= 0.5; - if (items[i].icon_region.has_no_area()) - draw_texture_rect(items[i].icon, draw_rect, false, modulate); - else - draw_texture_rect_region(items[i].icon, draw_rect, items[i].icon_region, modulate); + // If the icon is transposed, we have to switch the size so that it is drawn correctly + if (items[i].icon_transposed) { + Size2 size_tmp = draw_rect.size; + draw_rect.size.x = size_tmp.y; + draw_rect.size.y = size_tmp.x; + } + + Rect2 region = (items[i].icon_region.size.x == 0 || items[i].icon_region.size.y == 0) ? Rect2(Vector2(), items[i].icon->get_size()) : Rect2(items[i].icon_region); + draw_texture_rect_region(items[i].icon, draw_rect, region, modulate, items[i].icon_transposed); } if (items[i].tag_icon.is_valid()) { @@ -1082,13 +1114,13 @@ void ItemList::_notification(int p_what) { int max_len = -1; - Vector2 size = font->get_string_size(items[i].text); + Vector2 size2 = font->get_string_size(items[i].text); if (fixed_column_width) max_len = fixed_column_width; else if (same_column_width) max_len = items[i].rect_cache.size.x; else - max_len = size.x; + max_len = size2.x; Color modulate = items[i].selected ? font_color_selected : (items[i].custom_fg != Color() ? items[i].custom_fg : font_color); if (items[i].disabled) @@ -1138,12 +1170,12 @@ void ItemList::_notification(int p_what) { } else { if (fixed_column_width > 0) - size.x = MIN(size.x, fixed_column_width); + size2.x = MIN(size2.x, fixed_column_width); if (icon_mode == ICON_MODE_TOP) { - text_ofs.x += (items[i].rect_cache.size.width - size.x) / 2; + text_ofs.x += (items[i].rect_cache.size.width - size2.x) / 2; } else { - text_ofs.y += (items[i].rect_cache.size.height - size.y) / 2; + text_ofs.y += (items[i].rect_cache.size.height - size2.y) / 2; } text_ofs.y += font->get_ascent(); @@ -1405,6 +1437,9 @@ void ItemList::_bind_methods() { ClassDB::bind_method(D_METHOD("set_item_icon", "idx", "icon"), &ItemList::set_item_icon); ClassDB::bind_method(D_METHOD("get_item_icon", "idx"), &ItemList::get_item_icon); + ClassDB::bind_method(D_METHOD("set_item_icon_transposed", "idx", "rect"), &ItemList::set_item_icon_transposed); + ClassDB::bind_method(D_METHOD("is_item_icon_transposed", "idx"), &ItemList::is_item_icon_transposed); + ClassDB::bind_method(D_METHOD("set_item_icon_region", "idx", "rect"), &ItemList::set_item_icon_region); ClassDB::bind_method(D_METHOD("get_item_icon_region", "idx"), &ItemList::get_item_icon_region); @@ -1498,17 +1533,17 @@ void ItemList::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "select_mode", PROPERTY_HINT_ENUM, "Single,Multi"), "set_select_mode", "get_select_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_reselect"), "set_allow_reselect", "get_allow_reselect"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "allow_rmb_select"), "set_allow_rmb_select", "get_allow_rmb_select"); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "max_text_lines"), "set_max_text_lines", "get_max_text_lines"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "auto_height"), "set_auto_height", "has_auto_height"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_rmb_select"), "set_allow_rmb_select", "get_allow_rmb_select"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_text_lines"), "set_max_text_lines", "get_max_text_lines"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_height"), "set_auto_height", "has_auto_height"); ADD_GROUP("Columns", ""); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "max_columns"), "set_max_columns", "get_max_columns"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "same_column_width"), "set_same_column_width", "is_same_column_width"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "fixed_column_width"), "set_fixed_column_width", "get_fixed_column_width"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_columns"), "set_max_columns", "get_max_columns"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "same_column_width"), "set_same_column_width", "is_same_column_width"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_column_width"), "set_fixed_column_width", "get_fixed_column_width"); ADD_GROUP("Icon", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "icon_mode", PROPERTY_HINT_ENUM, "Top,Left"), "set_icon_mode", "get_icon_mode"); - ADD_PROPERTYNO(PropertyInfo(Variant::REAL, "icon_scale"), "set_icon_scale", "get_icon_scale"); - ADD_PROPERTYNO(PropertyInfo(Variant::VECTOR2, "fixed_icon_size"), "set_fixed_icon_size", "get_fixed_icon_size"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "icon_scale"), "set_icon_scale", "get_icon_scale"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "fixed_icon_size"), "set_fixed_icon_size", "get_fixed_icon_size"); BIND_ENUM_CONSTANT(ICON_MODE_TOP); BIND_ENUM_CONSTANT(ICON_MODE_LEFT); @@ -1524,6 +1559,7 @@ void ItemList::_bind_methods() { ADD_SIGNAL(MethodInfo("nothing_selected")); GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000); + ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/incremental_search_max_interval_msec", PropertyInfo(Variant::INT, "gui/timers/incremental_search_max_interval_msec", PROPERTY_HINT_RANGE, "0,10000,1,or_greater")); // No negative numbers } ItemList::ItemList() { diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index 58771c1777..3a7cc65ab4 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -53,6 +53,7 @@ private: struct Item { Ref<Texture> icon; + bool icon_transposed; Rect2i icon_region; Color icon_modulate; Ref<Texture> tag_icon; @@ -133,6 +134,9 @@ public: void set_item_icon(int p_idx, const Ref<Texture> &p_icon); Ref<Texture> get_item_icon(int p_idx) const; + void set_item_icon_transposed(int p_idx, const bool transposed); + bool is_item_icon_transposed(int p_idx) const; + void set_item_icon_region(int p_idx, const Rect2 &p_region); Rect2 get_item_icon_region(int p_idx) const; diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 6ff2d232f0..e3e9368a12 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -244,7 +244,7 @@ void Label::_notification(int p_what) { CharType n = xl_text[i + pos + 1]; if (uppercase) { c = String::char_uppercase(c); - n = String::char_uppercase(c); + n = String::char_uppercase(n); } float move = font->draw_char(ci, Point2(x_ofs_shadow, y_ofs) + shadow_ofs, c, n, font_color_shadow, false); @@ -265,7 +265,7 @@ void Label::_notification(int p_what) { CharType n = xl_text[i + pos + 1]; if (uppercase) { c = String::char_uppercase(c); - n = String::char_uppercase(c); + n = String::char_uppercase(n); } x_ofs += drawer.draw_char(ci, Point2(x_ofs, y_ofs), c, n, font_color); @@ -393,9 +393,9 @@ void Label::regenerate_word_cache() { WordCache *last = NULL; - for (int i = 0; i < xl_text.size() + 1; i++) { + for (int i = 0; i <= xl_text.length(); i++) { - CharType current = i < xl_text.length() ? xl_text[i] : ' '; //always a space at the end, so the algo works + CharType current = i < xl_text.length() ? xl_text[i] : L' '; //always a space at the end, so the algo works if (uppercase) current = String::char_uppercase(current); @@ -429,12 +429,11 @@ void Label::regenerate_word_cache() { if (current == '\n') { insert_newline = true; - } else { + } else if (current != ' ') { total_char_cache++; } if (i < xl_text.length() && xl_text[i] == ' ') { - total_char_cache--; // do not count spaces if (line_width > 0 || last == NULL || last->char_pos != WordCache::CHAR_WRAPLINE) { space_count++; line_width += space_width; @@ -665,12 +664,12 @@ void Label::_bind_methods() { BIND_ENUM_CONSTANT(VALIGN_BOTTOM); BIND_ENUM_CONSTANT(VALIGN_FILL); - ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "valign", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_valign", "get_valign"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "autowrap"), "set_autowrap", "has_autowrap"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "is_clipping_text"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "uppercase"), "set_uppercase", "is_uppercase"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "valign", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_valign", "get_valign"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autowrap"), "set_autowrap", "has_autowrap"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "is_clipping_text"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uppercase"), "set_uppercase", "is_uppercase"); ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1", PROPERTY_USAGE_EDITOR), "set_visible_characters", "get_visible_characters"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible"); ADD_PROPERTY(PropertyInfo(Variant::INT, "lines_skipped", PROPERTY_HINT_RANGE, "0,999,1"), "set_lines_skipped", "get_lines_skipped"); diff --git a/scene/gui/label.h b/scene/gui/label.h index d5e0b60773..561c42ef9e 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index c4373876b1..bf6833e512 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -248,7 +248,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { set_cursor_position(text.length()); } break; #endif - default: { handled = false; } + default: { + handled = false; + } } if (handled) { @@ -831,7 +833,6 @@ void LineEdit::_notification(int p_what) { OS::get_singleton()->set_ime_active(true); OS::get_singleton()->set_ime_position(get_global_position() + Point2(using_placeholder ? 0 : x_ofs, y_ofs + caret_height)); - OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this); } } break; case NOTIFICATION_FOCUS_ENTER: { @@ -843,7 +844,6 @@ void LineEdit::_notification(int p_what) { OS::get_singleton()->set_ime_active(true); Point2 cursor_pos = Point2(get_cursor_position(), 1) * get_minimum_size().height; OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos); - OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this); if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->show_virtual_keyboard(text, get_global_rect()); @@ -852,7 +852,6 @@ void LineEdit::_notification(int p_what) { case NOTIFICATION_FOCUS_EXIT: { OS::get_singleton()->set_ime_position(Point2()); - OS::get_singleton()->set_ime_intermediate_text_callback(NULL, NULL); OS::get_singleton()->set_ime_active(false); ime_text = ""; ime_selection = Point2(); @@ -861,6 +860,14 @@ void LineEdit::_notification(int p_what) { OS::get_singleton()->hide_virtual_keyboard(); } break; + case MainLoop::NOTIFICATION_OS_IME_UPDATE: { + + if (has_focus()) { + ime_text = OS::get_singleton()->get_ime_text(); + ime_selection = OS::get_singleton()->get_ime_selection(); + update(); + } + } break; } } @@ -1147,9 +1154,7 @@ void LineEdit::set_cursor_position(int p_pos) { if (cursor_pos <= window_pos) { /* Adjust window if cursor goes too much to the left */ - if (window_pos > 0) - set_window_pos(window_pos - 1); - + set_window_pos(MAX(0, cursor_pos - 1)); } else if (cursor_pos > window_pos) { /* Adjust window if cursor goes too much to the right */ int window_width = get_size().width - style->get_minimum_size().width; @@ -1283,13 +1288,11 @@ int LineEdit::get_max_length() const { void LineEdit::selection_fill_at_cursor() { - int aux; - selection.begin = cursor_pos; selection.end = selection.cursor_start; if (selection.end < selection.begin) { - aux = selection.end; + int aux = selection.end; selection.end = selection.begin; selection.begin = aux; } @@ -1461,13 +1464,6 @@ void LineEdit::set_right_icon(const Ref<Texture> &p_icon) { update(); } -void LineEdit::_ime_text_callback(void *p_self, String p_text, Point2 p_selection) { - LineEdit *self = (LineEdit *)p_self; - self->ime_text = p_text; - self->ime_selection = p_selection; - self->update(); -} - void LineEdit::_text_changed() { if (expand_to_text_length) @@ -1573,22 +1569,22 @@ void LineEdit::_bind_methods() { BIND_ENUM_CONSTANT(MENU_REDO); BIND_ENUM_CONSTANT(MENU_MAX); - ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "max_length"), "set_max_length", "get_max_length"); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "secret"), "set_secret", "is_secret"); - ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "secret_character"), "set_secret_character", "get_secret_character"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "expand_to_text_length"), "set_expand_to_text_length", "get_expand_to_text_length"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_length"), "set_max_length", "get_max_length"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "secret"), "set_secret", "is_secret"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "secret_character"), "set_secret_character", "get_secret_character"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand_to_text_length"), "set_expand_to_text_length", "get_expand_to_text_length"); ADD_PROPERTY(PropertyInfo(Variant::INT, "focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_focus_mode", "get_focus_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clear_button_enabled"), "set_clear_button_enabled", "is_clear_button_enabled"); ADD_GROUP("Placeholder", "placeholder_"); - ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "placeholder_alpha", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_placeholder_alpha", "get_placeholder_alpha"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "placeholder_alpha", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_placeholder_alpha", "get_placeholder_alpha"); ADD_GROUP("Caret", "caret_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "cursor_set_blink_enabled", "cursor_get_blink_enabled"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "cursor_set_blink_speed", "cursor_get_blink_speed"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "cursor_set_blink_speed", "cursor_get_blink_speed"); ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_position"), "set_cursor_position", "get_cursor_position"); } diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 5294d99da0..3b29780dc0 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -122,7 +122,6 @@ private: Timer *caret_blink_timer; - static void _ime_text_callback(void *p_self, String p_text, Point2 p_selection); void _text_changed(); void _emit_text_change(); bool expand_to_text_length; diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp index d38a067fef..21527e9bfc 100644 --- a/scene/gui/link_button.cpp +++ b/scene/gui/link_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -75,6 +75,7 @@ void LinkButton::_notification(int p_what) { color = get_color("font_color"); do_underline = underline_mode == UNDERLINE_MODE_ALWAYS; } break; + case DRAW_HOVER_PRESSED: case DRAW_PRESSED: { if (has_color("font_color_pressed")) @@ -91,7 +92,6 @@ void LinkButton::_notification(int p_what) { do_underline = underline_mode != UNDERLINE_MODE_NEVER; } break; - case DRAW_HOVER_PRESSED: break; // Not used in this class case DRAW_DISABLED: { color = get_color("font_color_disabled"); @@ -134,8 +134,8 @@ void LinkButton::_bind_methods() { BIND_ENUM_CONSTANT(UNDERLINE_MODE_ON_HOVER); BIND_ENUM_CONSTANT(UNDERLINE_MODE_NEVER); - ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "underline", PROPERTY_HINT_ENUM, "Always,On Hover,Never"), "set_underline_mode", "get_underline_mode"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "underline", PROPERTY_HINT_ENUM, "Always,On Hover,Never"), "set_underline_mode", "get_underline_mode"); } LinkButton::LinkButton() { diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h index 0821ad9c0d..17c4bca67b 100644 --- a/scene/gui/link_button.h +++ b/scene/gui/link_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,7 +32,7 @@ #define LINKBUTTON_H #include "scene/gui/base_button.h" -#include "scene/resources/bit_mask.h" +#include "scene/resources/bit_map.h" class LinkButton : public BaseButton { diff --git a/scene/gui/margin_container.cpp b/scene/gui/margin_container.cpp index 5e1d53fe1d..62ba45c484 100644 --- a/scene/gui/margin_container.cpp +++ b/scene/gui/margin_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -64,27 +64,33 @@ Size2 MarginContainer::get_minimum_size() const { void MarginContainer::_notification(int p_what) { - if (p_what == NOTIFICATION_SORT_CHILDREN) { + switch (p_what) { + case NOTIFICATION_SORT_CHILDREN: { - int margin_left = get_constant("margin_left"); - int margin_top = get_constant("margin_top"); - int margin_right = get_constant("margin_right"); - int margin_bottom = get_constant("margin_bottom"); + int margin_left = get_constant("margin_left"); + int margin_top = get_constant("margin_top"); + int margin_right = get_constant("margin_right"); + int margin_bottom = get_constant("margin_bottom"); - Size2 s = get_size(); + Size2 s = get_size(); - for (int i = 0; i < get_child_count(); i++) { + for (int i = 0; i < get_child_count(); i++) { - Control *c = Object::cast_to<Control>(get_child(i)); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; + Control *c = Object::cast_to<Control>(get_child(i)); + if (!c) + continue; + if (c->is_set_as_toplevel()) + continue; - int w = s.width - margin_left - margin_right; - int h = s.height - margin_top - margin_bottom; - fit_child_in_rect(c, Rect2(margin_left, margin_top, w, h)); - } + int w = s.width - margin_left - margin_right; + int h = s.height - margin_top - margin_bottom; + fit_child_in_rect(c, Rect2(margin_left, margin_top, w, h)); + } + } break; + case NOTIFICATION_THEME_CHANGED: { + + minimum_size_changed(); + } break; } } diff --git a/scene/gui/margin_container.h b/scene/gui/margin_container.h index ea75109248..336b68665f 100644 --- a/scene/gui/margin_container.h +++ b/scene/gui/margin_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 95ec618c3b..b67d8c00d6 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -71,13 +71,24 @@ PopupMenu *MenuButton::get_popup() const { return popup; } +void MenuButton::_set_items(const Array &p_items) { + + popup->set("items", p_items); +} + Array MenuButton::_get_items() const { return popup->get("items"); } -void MenuButton::_set_items(const Array &p_items) { - popup->set("items", p_items); +void MenuButton::set_switch_on_hover(bool p_enabled) { + + switch_on_hover = p_enabled; +} + +bool MenuButton::is_switch_on_hover() { + + return switch_on_hover; } void MenuButton::_bind_methods() { @@ -86,9 +97,12 @@ void MenuButton::_bind_methods() { ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &MenuButton::_unhandled_key_input); ClassDB::bind_method(D_METHOD("_set_items"), &MenuButton::_set_items); ClassDB::bind_method(D_METHOD("_get_items"), &MenuButton::_get_items); + ClassDB::bind_method(D_METHOD("set_switch_on_hover", "enable"), &MenuButton::set_switch_on_hover); + ClassDB::bind_method(D_METHOD("is_switch_on_hover"), &MenuButton::is_switch_on_hover); ClassDB::bind_method(D_METHOD("set_disable_shortcuts", "disabled"), &MenuButton::set_disable_shortcuts); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "items", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_items", "_get_items"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "switch_on_hover"), "set_switch_on_hover", "is_switch_on_hover"); ADD_SIGNAL(MethodInfo("about_to_show")); } @@ -100,6 +114,7 @@ void MenuButton::set_disable_shortcuts(bool p_disabled) { MenuButton::MenuButton() { + switch_on_hover = false; set_flat(true); set_disable_shortcuts(false); set_enabled_focus_mode(FOCUS_NONE); diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h index 0636accfee..794840035e 100644 --- a/scene/gui/menu_button.h +++ b/scene/gui/menu_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -41,6 +41,7 @@ class MenuButton : public Button { GDCLASS(MenuButton, Button); bool clicked; + bool switch_on_hover; bool disable_shortcuts; PopupMenu *popup; @@ -57,6 +58,8 @@ public: virtual void pressed(); PopupMenu *get_popup() const; + void set_switch_on_hover(bool p_enabled); + bool is_switch_on_hover(); void set_disable_shortcuts(bool p_disabled); MenuButton(); diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp index c6a34921c7..23e0ea876d 100644 --- a/scene/gui/nine_patch_rect.cpp +++ b/scene/gui/nine_patch_rect.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -70,18 +70,18 @@ void NinePatchRect::_bind_methods() { ADD_SIGNAL(MethodInfo("texture_changed")); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled"); - ADD_PROPERTYNZ(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); ADD_GROUP("Patch Margin", "patch_margin_"); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "patch_margin_left", PROPERTY_HINT_RANGE, "0,16384,1"), "set_patch_margin", "get_patch_margin", MARGIN_LEFT); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "patch_margin_top", PROPERTY_HINT_RANGE, "0,16384,1"), "set_patch_margin", "get_patch_margin", MARGIN_TOP); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "patch_margin_right", PROPERTY_HINT_RANGE, "0,16384,1"), "set_patch_margin", "get_patch_margin", MARGIN_RIGHT); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "patch_margin_bottom", PROPERTY_HINT_RANGE, "0,16384,1"), "set_patch_margin", "get_patch_margin", MARGIN_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "patch_margin_left", PROPERTY_HINT_RANGE, "0,16384,1"), "set_patch_margin", "get_patch_margin", MARGIN_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "patch_margin_top", PROPERTY_HINT_RANGE, "0,16384,1"), "set_patch_margin", "get_patch_margin", MARGIN_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "patch_margin_right", PROPERTY_HINT_RANGE, "0,16384,1"), "set_patch_margin", "get_patch_margin", MARGIN_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "patch_margin_bottom", PROPERTY_HINT_RANGE, "0,16384,1"), "set_patch_margin", "get_patch_margin", MARGIN_BOTTOM); ADD_GROUP("Axis Stretch", "axis_stretch_"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "axis_stretch_horizontal", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_h_axis_stretch_mode", "get_h_axis_stretch_mode"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "axis_stretch_vertical", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_v_axis_stretch_mode", "get_v_axis_stretch_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "axis_stretch_horizontal", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_h_axis_stretch_mode", "get_h_axis_stretch_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "axis_stretch_vertical", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_v_axis_stretch_mode", "get_v_axis_stretch_mode"); BIND_ENUM_CONSTANT(AXIS_STRETCH_MODE_STRETCH); BIND_ENUM_CONSTANT(AXIS_STRETCH_MODE_TILE); diff --git a/scene/gui/nine_patch_rect.h b/scene/gui/nine_patch_rect.h index b4b4602a7d..ac17e52fc1 100644 --- a/scene/gui/nine_patch_rect.h +++ b/scene/gui/nine_patch_rect.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 6b847c6483..b9b270ce0c 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -160,6 +160,12 @@ int OptionButton::get_item_id(int p_idx) const { return popup->get_item_id(p_idx); } + +int OptionButton::get_item_index(int p_id) const { + + return popup->get_item_index(p_id); +} + Variant OptionButton::get_item_metadata(int p_idx) const { return popup->get_item_metadata(p_idx); @@ -306,6 +312,7 @@ void OptionButton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_text", "idx"), &OptionButton::get_item_text); ClassDB::bind_method(D_METHOD("get_item_icon", "idx"), &OptionButton::get_item_icon); ClassDB::bind_method(D_METHOD("get_item_id", "idx"), &OptionButton::get_item_id); + ClassDB::bind_method(D_METHOD("get_item_index", "id"), &OptionButton::get_item_index); ClassDB::bind_method(D_METHOD("get_item_metadata", "idx"), &OptionButton::get_item_metadata); ClassDB::bind_method(D_METHOD("is_item_disabled", "idx"), &OptionButton::is_item_disabled); ClassDB::bind_method(D_METHOD("get_item_count"), &OptionButton::get_item_count); diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index d5f866d806..63b451377a 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -71,6 +71,7 @@ public: String get_item_text(int p_idx) const; Ref<Texture> get_item_icon(int p_idx) const; int get_item_id(int p_idx) const; + int get_item_index(int p_id) const; Variant get_item_metadata(int p_idx) const; bool is_item_disabled(int p_idx) const; diff --git a/scene/gui/panel.cpp b/scene/gui/panel.cpp index d3b7b72ee1..c26bd09f50 100644 --- a/scene/gui/panel.cpp +++ b/scene/gui/panel.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/panel.h b/scene/gui/panel.h index db8b35372e..f8d15e4261 100644 --- a/scene/gui/panel.h +++ b/scene/gui/panel.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/panel_container.cpp b/scene/gui/panel_container.cpp index a778d62659..b1fced87fc 100644 --- a/scene/gui/panel_container.cpp +++ b/scene/gui/panel_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/panel_container.h b/scene/gui/panel_container.h index 267e2b921f..15661d3e35 100644 --- a/scene/gui/panel_container.h +++ b/scene/gui/panel_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index bfbe62e1c7..80ec7049fc 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -52,9 +52,13 @@ void Popup::_notification(int p_what) { //small helper to make editing of these easier in editor #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) { + //edited on editor set_as_toplevel(false); - } + } else #endif + if (is_visible()) { + hide(); + } } } @@ -120,49 +124,22 @@ void Popup::popup_centered_minsize(const Size2 &p_minsize) { void Popup::popup_centered(const Size2 &p_size) { - Point2 window_size = get_viewport_rect().size; - - emit_signal("about_to_show"); Rect2 rect; + Size2 window_size = get_viewport_rect().size; rect.size = p_size == Size2() ? get_size() : p_size; - rect.position = ((window_size - rect.size) / 2.0).floor(); - set_position(rect.position); - set_size(rect.size); - show_modal(exclusive); - _fix_size(); - - Control *focusable = find_next_valid_focus(); - if (focusable) - focusable->grab_focus(); - - _post_popup(); - notification(NOTIFICATION_POST_POPUP); - popped_up = true; + popup(rect); } void Popup::popup_centered_ratio(float p_screen_ratio) { - emit_signal("about_to_show"); - Rect2 rect; - Point2 window_size = get_viewport_rect().size; + Size2 window_size = get_viewport_rect().size; rect.size = (window_size * p_screen_ratio).floor(); rect.position = ((window_size - rect.size) / 2.0).floor(); - set_position(rect.position); - set_size(rect.size); - - show_modal(exclusive); - _fix_size(); - Control *focusable = find_next_valid_focus(); - if (focusable) - focusable->grab_focus(); - - _post_popup(); - notification(NOTIFICATION_POST_POPUP); - popped_up = true; + popup(rect); } void Popup::popup(const Rect2 &p_bounds) { diff --git a/scene/gui/popup.h b/scene/gui/popup.h index 5b1ef7d6ca..7ccefe1d75 100644 --- a/scene/gui/popup.h +++ b/scene/gui/popup.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 3239641c2f..28b124d143 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -453,7 +453,6 @@ void PopupMenu::_notification(int p_what) { Color icon_color(1, 1, 1, items[i].disabled ? 0.5 : 1); - item_ofs.x += items[i].h_ofs; if (!items[i].icon.is_null()) { icon_size = items[i].icon->get_size(); @@ -470,6 +469,7 @@ void PopupMenu::_notification(int p_what) { String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].xl_text; + item_ofs.x += items[i].h_ofs; if (items[i].separator) { int sep_h = separator->get_center_size().height + separator->get_minimum_size().height; @@ -519,9 +519,9 @@ void PopupMenu::_notification(int p_what) { if (items[i].accel || (items[i].shortcut.is_valid() && items[i].shortcut->is_valid())) { //accelerator - String text = _get_accel_text(i); - item_ofs.x = size.width - style->get_margin(MARGIN_RIGHT) - font->get_string_size(text).width; - font->draw(ci, item_ofs + Point2(0, Math::floor((h - font_h) / 2.0)), text, i == mouse_over ? font_color_hover : font_color_accel); + String text2 = _get_accel_text(i); + item_ofs.x = size.width - style->get_margin(MARGIN_RIGHT) - font->get_string_size(text2).width; + font->draw(ci, item_ofs + Point2(0, Math::floor((h - font_h) / 2.0)), text2, i == mouse_over ? font_color_hover : font_color_accel); } items.write[i]._ofs_cache = ofs.y; @@ -557,6 +557,21 @@ void PopupMenu::_notification(int p_what) { mouse_over = -1; update(); } + + for (int i = 0; i < items.size(); i++) { + if (items[i].submenu == "") + continue; + + Node *n = get_node(items[i].submenu); + if (!n) + continue; + + PopupMenu *pm = Object::cast_to<PopupMenu>(n); + if (!pm || !pm->is_visible()) + continue; + + pm->hide(); + } } break; } } @@ -1012,8 +1027,7 @@ bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_fo code |= KEY_MASK_SHIFT; } - int il = items.size(); - for (int i = 0; i < il; i++) { + for (int i = 0; i < items.size(); i++) { if (is_item_disabled(i) || items[i].shortcut_is_disabled) continue; @@ -1381,9 +1395,9 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("_submenu_timeout"), &PopupMenu::_submenu_timeout); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "items", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_items", "_get_items"); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "hide_on_item_selection"), "set_hide_on_item_selection", "is_hide_on_item_selection"); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "hide_on_checkable_item_selection"), "set_hide_on_checkable_item_selection", "is_hide_on_checkable_item_selection"); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "hide_on_state_item_selection"), "set_hide_on_state_item_selection", "is_hide_on_state_item_selection"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_on_item_selection"), "set_hide_on_item_selection", "is_hide_on_item_selection"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_on_checkable_item_selection"), "set_hide_on_checkable_item_selection", "is_hide_on_checkable_item_selection"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_on_state_item_selection"), "set_hide_on_state_item_selection", "is_hide_on_state_item_selection"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "submenu_popup_delay"), "set_submenu_popup_delay", "get_submenu_popup_delay"); ADD_SIGNAL(MethodInfo("id_pressed", PropertyInfo(Variant::INT, "ID"))); @@ -1411,6 +1425,7 @@ PopupMenu::PopupMenu() { set_hide_on_item_selection(true); set_hide_on_checkable_item_selection(true); set_hide_on_multistate_item_selection(false); + set_hide_on_window_lose_focus(true); submenu_timer = memnew(Timer); submenu_timer->set_wait_time(0.3); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index a06a17c9fe..767ff568fe 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp index fc5d56237a..264eda4035 100644 --- a/scene/gui/progress_bar.cpp +++ b/scene/gui/progress_bar.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,9 +39,12 @@ Size2 ProgressBar::get_minimum_size() const { Size2 minimum_size = bg->get_minimum_size(); minimum_size.height = MAX(minimum_size.height, fg->get_minimum_size().height); minimum_size.width = MAX(minimum_size.width, fg->get_minimum_size().width); - //if (percent_visible) { this is needed, else the progressbar will collapse - minimum_size.height = MAX(minimum_size.height, bg->get_minimum_size().height + font->get_height()); - //} + if (percent_visible) { + minimum_size.height = MAX(minimum_size.height, bg->get_minimum_size().height + font->get_height()); + } else { // this is needed, else the progressbar will collapse + minimum_size.width = MAX(minimum_size.width, 1); + minimum_size.height = MAX(minimum_size.height, 1); + } return minimum_size; } @@ -92,5 +95,6 @@ void ProgressBar::_bind_methods() { ProgressBar::ProgressBar() { set_v_size_flags(0); + set_step(0.01); percent_visible = true; } diff --git a/scene/gui/progress_bar.h b/scene/gui/progress_bar.h index d091c983b1..6157183e0f 100644 --- a/scene/gui/progress_bar.h +++ b/scene/gui/progress_bar.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp index e862743934..c24e62c8cb 100644 --- a/scene/gui/range.cpp +++ b/scene/gui/range.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/range.h b/scene/gui/range.h index 58f15c8aa8..cf0add8c89 100644 --- a/scene/gui/range.h +++ b/scene/gui/range.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/reference_rect.cpp b/scene/gui/reference_rect.cpp index e96e5afb2a..553e133946 100644 --- a/scene/gui/reference_rect.cpp +++ b/scene/gui/reference_rect.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/reference_rect.h b/scene/gui/reference_rect.h index 9fad1a06b0..de3ccaeeca 100644 --- a/scene/gui/reference_rect.h +++ b/scene/gui/reference_rect.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index bb36852cf9..9bcf10d5e7 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -220,13 +220,14 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & case ALIGN_LEFT: l.offset_caches.push_back(0); break; \ case ALIGN_CENTER: l.offset_caches.push_back(((p_width - margin) - used) / 2); break; \ case ALIGN_RIGHT: l.offset_caches.push_back(((p_width - margin) - used)); break; \ - case ALIGN_FILL: l.offset_caches.push_back((p_width - margin) - used /*+spaces_size*/); break; \ + case ALIGN_FILL: l.offset_caches.push_back(line_wrapped ? ((p_width - margin) - used) : 0); break; \ } \ l.height_caches.push_back(line_height); \ l.ascent_caches.push_back(line_ascent); \ l.descent_caches.push_back(line_descent); \ l.space_caches.push_back(spaces); \ } \ + line_wrapped = false; \ y += line_height + get_constant(SceneStringNames::get_singleton()->line_separation); \ line_height = 0; \ line_ascent = 0; \ @@ -254,6 +255,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & l.minimum_width = MAX(l.minimum_width, m_width); \ } \ if (wofs + m_width > p_width) { \ + line_wrapped = true; \ if (p_mode == PROCESS_CACHE) { \ if (spaces > 0) \ spaces -= 1; \ @@ -298,6 +300,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & int rchar = 0; int lh = 0; bool line_is_blank = true; + bool line_wrapped = false; int fh = 0; while (it) { @@ -541,7 +544,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & Vector2 draw_ofs = Point2(wofs, y); Color font_color_shadow = get_color("font_color_shadow"); bool use_outline = get_constant("shadow_as_outline"); - Point2 shadow_ofs(get_constant("shadow_offset_x"), get_constant("shadow_offset_y")); + Point2 shadow_ofs2(get_constant("shadow_offset_x"), get_constant("shadow_offset_y")); if (p_mode == PROCESS_CACHE) { @@ -565,7 +568,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & for (int i = 0; i < frame->lines.size(); i++) { - _process_line(frame, Point2(), ly, available_width, i, PROCESS_CACHE, cfont, Color(), font_color_shadow, use_outline, shadow_ofs); + _process_line(frame, Point2(), ly, available_width, i, PROCESS_CACHE, cfont, Color(), font_color_shadow, use_outline, shadow_ofs2); table->columns.write[column].min_width = MAX(table->columns[column].min_width, frame->lines[i].minimum_width); table->columns.write[column].max_width = MAX(table->columns[column].max_width, frame->lines[i].maximum_width); } @@ -638,7 +641,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & for (int i = 0; i < frame->lines.size(); i++) { int ly = 0; - _process_line(frame, Point2(), ly, table->columns[column].width, i, PROCESS_CACHE, cfont, Color(), font_color_shadow, use_outline, shadow_ofs); + _process_line(frame, Point2(), ly, table->columns[column].width, i, PROCESS_CACHE, cfont, Color(), font_color_shadow, use_outline, shadow_ofs2); frame->lines.write[i].height_cache = ly; //actual height frame->lines.write[i].height_accum_cache = ly; //actual height } @@ -671,9 +674,9 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & if (visible) { if (p_mode == PROCESS_DRAW) { - nonblank_line_count += _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_DRAW, cfont, ccolor, font_color_shadow, use_outline, shadow_ofs); + nonblank_line_count += _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_DRAW, cfont, ccolor, font_color_shadow, use_outline, shadow_ofs2); } else if (p_mode == PROCESS_POINTER) { - _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_POINTER, cfont, ccolor, font_color_shadow, use_outline, shadow_ofs, p_click_pos, r_click_item, r_click_char, r_outside); + _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_POINTER, cfont, ccolor, font_color_shadow, use_outline, shadow_ofs2, p_click_pos, r_click_item, r_click_char, r_outside); if (r_click_item && *r_click_item) { RETURN; // exit early } @@ -762,20 +765,19 @@ void RichTextLabel::_update_scroll() { if (exceeds) { scroll_visible = true; - main->first_invalid_line = 0; scroll_w = vscroll->get_combined_minimum_size().width; vscroll->show(); vscroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -scroll_w); - _validate_line_caches(main); - } else { - scroll_visible = false; - vscroll->hide(); scroll_w = 0; - _validate_line_caches(main); + vscroll->hide(); } + + main->first_invalid_line = 0; //invalidate ALL + _validate_line_caches(main); } + scroll_updated = true; } void RichTextLabel::_notification(int p_what) { @@ -928,6 +930,7 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) { if (true) { if (b->is_pressed() && !b->is_doubleclick()) { + scroll_updated = false; int line = 0; Item *item = NULL; @@ -936,12 +939,7 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) { if (item) { - Variant meta; - if (!outside && _find_meta(item, &meta)) { - //meta clicked - - emit_signal("meta_clicked", meta); - } else if (selection.enabled) { + if (selection.enabled) { selection.click = item; selection.click_char = line; @@ -990,6 +988,24 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) { } else if (!b->is_pressed()) { selection.click = NULL; + + if (!b->is_doubleclick() && !scroll_updated) { + int line = 0; + Item *item = NULL; + + bool outside; + _find_click(main, b->get_position(), &item, &line, &outside); + + if (item) { + + Variant meta; + if (!outside && _find_meta(item, &meta)) { + //meta clicked + + emit_signal("meta_clicked", meta); + } + } + } } } } @@ -1117,12 +1133,13 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) { } Variant meta; - if (item && !outside && _find_meta(item, &meta)) { - if (meta_hovering != item) { + ItemMeta *item_meta; + if (item && !outside && _find_meta(item, &meta, &item_meta)) { + if (meta_hovering != item_meta) { if (meta_hovering) { emit_signal("meta_hover_ended", current_meta); } - meta_hovering = static_cast<ItemMeta *>(item); + meta_hovering = item_meta; current_meta = meta; emit_signal("meta_hover_started", meta); } @@ -1253,7 +1270,7 @@ bool RichTextLabel::_find_strikethrough(Item *p_item) { return false; } -bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta) { +bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) { Item *item = p_item; @@ -1264,6 +1281,8 @@ bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta) { ItemMeta *meta = static_cast<ItemMeta *>(item); if (r_meta) *r_meta = meta->meta; + if (r_item) + *r_item = meta; return true; } @@ -2323,6 +2342,7 @@ RichTextLabel::RichTextLabel() { updating_scroll = false; scroll_active = true; scroll_w = 0; + scroll_updated = false; vscroll = memnew(VScrollBar); add_child(vscroll); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index c2e5712b9d..114c6103e2 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -225,6 +225,7 @@ private: bool scroll_following; bool scroll_active; int scroll_w; + bool scroll_updated; bool updating_scroll; int current_idx; int visible_line_count; @@ -284,7 +285,7 @@ private: Color _find_color(Item *p_item, const Color &p_default_color); bool _find_underline(Item *p_item); bool _find_strikethrough(Item *p_item); - bool _find_meta(Item *p_item, Variant *r_meta); + bool _find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item = NULL); void _update_scroll(); void _scroll_changed(double); diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index 07380f45cc..2938654ed9 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -330,6 +330,8 @@ void ScrollBar::_notification(int p_what) { if (Math::abs(vel) >= dist) { set_value(target_scroll); + scrolling = false; + set_physics_process_internal(false); } else { set_value(get_value() + vel); } diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h index cde4120cdb..5ceabfc06b 100644 --- a/scene/gui/scroll_bar.h +++ b/scene/gui/scroll_bar.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 26da16569a..28292309b9 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -246,7 +246,7 @@ void ScrollContainer::_notification(int p_what) { size.y -= h_scroll->get_minimum_size().y; if (v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) //scrolls may have been moved out for reasons - size.x -= h_scroll->get_minimum_size().x; + size.x -= v_scroll->get_minimum_size().x; for (int i = 0; i < get_child_count(); i++) { @@ -271,7 +271,6 @@ void ScrollContainer::_notification(int p_what) { } if (!scroll_v || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) { r.position.y = 0; - r.size.height = size.height; if (c->get_v_size_flags() & SIZE_EXPAND) r.size.height = MAX(size.height, minsize.height); else diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h index abef80294a..2ab169f4d0 100644 --- a/scene/gui/scroll_container.h +++ b/scene/gui/scroll_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/separator.cpp b/scene/gui/separator.cpp index cd0b06da81..a717420b9b 100644 --- a/scene/gui/separator.cpp +++ b/scene/gui/separator.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/separator.h b/scene/gui/separator.h index 7949c7ca9b..54ad9b5bb5 100644 --- a/scene/gui/separator.h +++ b/scene/gui/separator.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/shortcut.cpp b/scene/gui/shortcut.cpp index 6fcf96f611..400fdca082 100644 --- a/scene/gui/shortcut.cpp +++ b/scene/gui/shortcut.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/shortcut.h b/scene/gui/shortcut.h index 7613a24e43..df0623ed50 100644 --- a/scene/gui/shortcut.h +++ b/scene/gui/shortcut.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp index 147c0518ec..eb04b85931 100644 --- a/scene/gui/slider.cpp +++ b/scene/gui/slider.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/slider.h b/scene/gui/slider.h index 4d02348159..d0ab7baecf 100644 --- a/scene/gui/slider.h +++ b/scene/gui/slider.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index f766c0722d..d21143739c 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -110,6 +110,9 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) { range_click_timer->start(); line_edit->grab_focus(); + + drag.allowed = true; + drag.capture_pos = mb->get_position(); } break; case BUTTON_RIGHT: { @@ -133,14 +136,7 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) { } } - if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == 1) { - - //set_default_cursor_shape(CURSOR_VSIZE); - Vector2 cpos = Vector2(mb->get_position().x, mb->get_position().y); - drag.mouse_pos = cpos; - } - - if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == 1) { + if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { //set_default_cursor_shape(CURSOR_ARROW); range_click_timer->stop(); @@ -150,32 +146,24 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) { Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); warp_mouse(drag.capture_pos); } + drag.allowed = false; } Ref<InputEventMouseMotion> mm = p_event; - if (mm.is_valid() && mm->get_button_mask() & 1) { - - Vector2 cpos = mm->get_position(); + if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) { if (drag.enabled) { - float diff_y = drag.mouse_pos.y - cpos.y; - diff_y = Math::pow(ABS(diff_y), 1.8f) * SGN(diff_y); - diff_y *= 0.1; - - drag.mouse_pos = cpos; - drag.base_val = CLAMP(drag.base_val + get_step() * diff_y, get_min(), get_max()); - - set_value(drag.base_val); - - } else if (drag.mouse_pos.distance_to(cpos) > 2) { + drag.diff_y += mm->get_relative().y; + float diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8f) * SGN(drag.diff_y); + set_value(CLAMP(drag.base_val + get_step() * diff_y, get_min(), get_max())); + } else if (drag.allowed && drag.capture_pos.distance_to(mm->get_position()) > 2) { Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); drag.enabled = true; drag.base_val = get_value(); - drag.mouse_pos = cpos; - drag.capture_pos = cpos; + drag.diff_y = 0; } } } @@ -276,7 +264,7 @@ void SpinBox::_bind_methods() { ClassDB::bind_method(D_METHOD("_line_edit_input"), &SpinBox::_line_edit_input); ClassDB::bind_method(D_METHOD("_range_click_timeout"), &SpinBox::_range_click_timeout); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "prefix"), "set_prefix", "get_prefix"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "suffix"), "set_suffix", "get_suffix"); diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index f1ee26d9f3..49dc6d950c 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -54,10 +54,10 @@ class SpinBox : public Range { struct Drag { float base_val; + bool allowed; bool enabled; - Vector2 from; - Vector2 mouse_pos; Vector2 capture_pos; + float diff_y; } drag; void _line_edit_focus_exit(); diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index c38c411333..e5d1844d39 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -62,39 +62,28 @@ void SplitContainer::_resort() { // If we have only one element if (!first || !second) { if (first) { - fit_child_in_rect(_getch(0), Rect2(Point2(), get_size())); + fit_child_in_rect(first, Rect2(Point2(), get_size())); } else if (second) { - fit_child_in_rect(_getch(1), Rect2(Point2(), get_size())); + fit_child_in_rect(second, Rect2(Point2(), get_size())); } return; } // Determine expanded children - bool first_expanded = false; - bool second_expanded = false; - if (vertical) { - first_expanded = first->get_v_size_flags() & SIZE_EXPAND; - second_expanded = second->get_v_size_flags() & SIZE_EXPAND; - } else { - first_expanded = first->get_h_size_flags() & SIZE_EXPAND; - second_expanded = second->get_h_size_flags() & SIZE_EXPAND; - } + bool first_expanded = (vertical ? first->get_v_size_flags() : first->get_h_size_flags()) & SIZE_EXPAND; + bool second_expanded = (vertical ? second->get_v_size_flags() : second->get_h_size_flags()) & SIZE_EXPAND; // Determine the separation between items Ref<Texture> g = get_icon("grabber"); int sep = get_constant("separation"); - if (dragger_visibility == DRAGGER_HIDDEN_COLLAPSED) { - sep = 0; - } else { - sep = MAX(sep, vertical ? g->get_height() : g->get_width()); - } + sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(sep, vertical ? g->get_height() : g->get_width()) : 0; // Compute the minimum size Size2 ms_first = first->get_combined_minimum_size(); Size2 ms_second = second->get_combined_minimum_size(); + // Compute the separator position without the split offset float ratio = first->get_stretch_ratio() / (first->get_stretch_ratio() + second->get_stretch_ratio()); - int no_offset_middle_sep = 0; if (first_expanded && second_expanded) { no_offset_middle_sep = get_size()[axis] * ratio - sep / 2; @@ -104,12 +93,16 @@ void SplitContainer::_resort() { no_offset_middle_sep = ms_first[axis]; } + // Compute the final middle separation middle_sep = no_offset_middle_sep; - middle_sep += (collapsed) ? 0 : split_offset; - middle_sep = MIN(middle_sep, get_size()[axis] - ms_second[axis] - sep); - middle_sep = MAX(middle_sep, ms_first[axis]); if (!collapsed) { - split_offset = middle_sep - no_offset_middle_sep; + int clamped_split_offset = CLAMP(split_offset, ms_first[axis] - no_offset_middle_sep, (get_size()[axis] - ms_second[axis] - sep) - no_offset_middle_sep); + middle_sep += clamped_split_offset; + if (should_clamp_split_offset) { + split_offset = clamped_split_offset; + _change_notify("split_offset"); + should_clamp_split_offset = false; + } } if (vertical) { @@ -123,7 +116,6 @@ void SplitContainer::_resort() { } update(); - _change_notify("split_offset"); } Size2 SplitContainer::get_minimum_size() const { @@ -131,8 +123,8 @@ Size2 SplitContainer::get_minimum_size() const { /* Calculate MINIMUM SIZE */ Size2i minimum; - int sep = get_constant("separation"); Ref<Texture> g = get_icon("grabber"); + int sep = get_constant("separation"); sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(sep, vertical ? g->get_height() : g->get_width()) : 0; for (int i = 0; i < 2; i++) { @@ -172,34 +164,35 @@ void SplitContainer::_notification(int p_what) { _resort(); } break; - case NOTIFICATION_MOUSE_ENTER: { - - mouse_inside = true; - update(); - } break; case NOTIFICATION_MOUSE_EXIT: { mouse_inside = false; - update(); + if (get_constant("autohide")) + update(); } break; case NOTIFICATION_DRAW: { if (!_getch(0) || !_getch(1)) return; - if (collapsed || (!mouse_inside && get_constant("autohide"))) + if (collapsed || (!dragging && !mouse_inside && get_constant("autohide"))) + return; + + if (dragger_visibility != DRAGGER_VISIBLE) return; int sep = dragger_visibility != DRAGGER_HIDDEN_COLLAPSED ? get_constant("separation") : 0; Ref<Texture> tex = get_icon("grabber"); Size2 size = get_size(); - if (dragger_visibility == DRAGGER_VISIBLE) { - if (vertical) - draw_texture(tex, Point2i((size.x - tex->get_width()) / 2, middle_sep + (sep - tex->get_height()) / 2)); - else - draw_texture(tex, Point2i(middle_sep + (sep - tex->get_width()) / 2, (size.y - tex->get_height()) / 2)); - } + if (vertical) + draw_texture(tex, Point2i((size.x - tex->get_width()) / 2, middle_sep + (sep - tex->get_height()) / 2)); + else + draw_texture(tex, Point2i(middle_sep + (sep - tex->get_width()) / 2, (size.y - tex->get_height()) / 2)); + } break; + case NOTIFICATION_THEME_CHANGED: { + + minimum_size_changed(); } break; } } @@ -245,9 +238,26 @@ void SplitContainer::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> mm = p_event; - if (mm.is_valid() && dragging) { + if (mm.is_valid()) { + + bool mouse_inside_state = false; + if (vertical) + mouse_inside_state = mm->get_position().y > middle_sep && mm->get_position().y < middle_sep + get_constant("separation"); + else + mouse_inside_state = mm->get_position().x > middle_sep && mm->get_position().x < middle_sep + get_constant("separation"); + + if (mouse_inside != mouse_inside_state) { + + mouse_inside = mouse_inside_state; + if (get_constant("autohide")) + update(); + } + + if (!dragging) + return; split_offset = drag_ofs + ((vertical ? mm->get_position().y : mm->get_position().x) - drag_from); + should_clamp_split_offset = true; queue_sort(); emit_signal("dragged", get_split_offset()); } @@ -282,6 +292,7 @@ void SplitContainer::set_split_offset(int p_offset) { return; split_offset = p_offset; + queue_sort(); } @@ -290,6 +301,12 @@ int SplitContainer::get_split_offset() const { return split_offset; } +void SplitContainer::clamp_split_offset() { + should_clamp_split_offset = true; + + queue_sort(); +} + void SplitContainer::set_collapsed(bool p_collapsed) { if (collapsed == p_collapsed) @@ -319,8 +336,10 @@ bool SplitContainer::is_collapsed() const { void SplitContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &SplitContainer::_gui_input); + ClassDB::bind_method(D_METHOD("set_split_offset", "offset"), &SplitContainer::set_split_offset); ClassDB::bind_method(D_METHOD("get_split_offset"), &SplitContainer::get_split_offset); + ClassDB::bind_method(D_METHOD("clamp_split_offset"), &SplitContainer::clamp_split_offset); ClassDB::bind_method(D_METHOD("set_collapsed", "collapsed"), &SplitContainer::set_collapsed); ClassDB::bind_method(D_METHOD("is_collapsed"), &SplitContainer::is_collapsed); @@ -343,6 +362,7 @@ SplitContainer::SplitContainer(bool p_vertical) { mouse_inside = false; split_offset = 0; + should_clamp_split_offset = false; middle_sep = 0; vertical = p_vertical; dragging = false; diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h index 321f7fd3b7..3c1ca09a9f 100644 --- a/scene/gui/split_container.h +++ b/scene/gui/split_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -45,9 +45,10 @@ public: }; private: - bool vertical; + bool should_clamp_split_offset; int split_offset; int middle_sep; + bool vertical; bool dragging; int drag_from; int drag_ofs; @@ -67,6 +68,7 @@ protected: public: void set_split_offset(int p_offset); int get_split_offset() const; + void clamp_split_offset(); void set_collapsed(bool p_collapsed); bool is_collapsed() const; diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 4c354768fe..212efa4976 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -338,6 +338,7 @@ void TabContainer::_notification(int p_what) { } } break; case NOTIFICATION_THEME_CHANGED: { + minimum_size_changed(); call_deferred("_on_theme_changed"); //wait until all changed theme } break; } diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h index 8a3c9d2bb2..c110f041d0 100644 --- a/scene/gui/tab_container.h +++ b/scene/gui/tab_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index b7f8c74046..ac643c1320 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -53,7 +53,7 @@ Size2 Tabs::get_minimum_size() const { ms.width += get_constant("hseparation"); } - ms.width += font->get_string_size(tabs[i].text).width; + ms.width += Math::ceil(font->get_string_size(tabs[i].text).width); if (tabs[i].disabled) ms.width += tab_disabled->get_minimum_size().width; @@ -547,7 +547,7 @@ void Tabs::_update_cache() { for (int i = 0; i < tabs.size(); i++) { tabs.write[i].ofs_cache = mw; tabs.write[i].size_cache = get_tab_width(i); - tabs.write[i].size_text = font->get_string_size(tabs[i].text).width; + tabs.write[i].size_text = Math::ceil(font->get_string_size(tabs[i].text).width); mw += tabs[i].size_cache; if (tabs[i].size_cache <= min_width || i == current) { size_fixed += tabs[i].size_cache; @@ -803,7 +803,7 @@ int Tabs::get_tab_width(int p_idx) const { x += get_constant("hseparation"); } - x += font->get_string_size(tabs[p_idx].text).width; + x += Math::ceil(font->get_string_size(tabs[p_idx].text).width); if (tabs[p_idx].disabled) x += tab_disabled->get_minimum_size().width; @@ -983,7 +983,7 @@ void Tabs::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab"); ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_align", "get_tab_align"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "tab_close_display_policy", PROPERTY_HINT_ENUM, "Show Never,Show Active Only,Show Always"), "set_tab_close_display_policy", "get_tab_close_display_policy"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_close_display_policy", PROPERTY_HINT_ENUM, "Show Never,Show Active Only,Show Always"), "set_tab_close_display_policy", "get_tab_close_display_policy"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scrolling_enabled"), "set_scrolling_enabled", "get_scrolling_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled"); diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index a98744b804..7c54f1acf2 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index f8a5c4cea3..2bf2364873 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -549,16 +549,17 @@ void TextEdit::_notification(int p_what) { MessageQueue::get_singleton()->push_call(this, "_cursor_changed_emit"); if (text_changed_dirty) MessageQueue::get_singleton()->push_call(this, "_text_changed_emit"); - update_wrap_at(); + _update_wrap_at(); } break; case NOTIFICATION_RESIZED: { _update_scrollbars(); - update_wrap_at(); + call_deferred("_update_wrap_at"); } break; case NOTIFICATION_THEME_CHANGED: { _update_caches(); + _update_wrap_at(); } break; case MainLoop::NOTIFICATION_WM_FOCUS_IN: { window_has_focus = true; @@ -665,7 +666,7 @@ void TextEdit::_notification(int p_what) { bool brace_close_matching = false; bool brace_close_mismatch = false; - if (brace_matching_enabled) { + if (brace_matching_enabled && cursor.line >= 0 && cursor.line < text.size() && cursor.column >= 0) { if (cursor.column < text[cursor.line].length()) { //check for open @@ -802,6 +803,7 @@ void TextEdit::_notification(int p_what) { } Point2 cursor_pos; + int cursor_insert_offset_y = 0; // get the highlighted words String highlighted_text = get_selection_text(); @@ -846,9 +848,9 @@ void TextEdit::_notification(int p_what) { bool underlined = false; + Vector<String> wrap_rows = get_wrap_rows_text(line); int line_wrap_amount = times_line_wraps(line); int last_wrap_column = 0; - Vector<String> wrap_rows = get_wrap_rows_text(line); for (int line_wrap_index = 0; line_wrap_index < line_wrap_amount + 1; line_wrap_index++) { if (line_wrap_index != 0) { @@ -859,6 +861,9 @@ void TextEdit::_notification(int p_what) { const String &str = wrap_rows[line_wrap_index]; int indent_px = line_wrap_index != 0 ? get_indent_level(line) * cache.font->get_char_size(' ').width : 0; + if (indent_px >= wrap_at) { + indent_px = 0; + } if (line_wrap_index > 0) last_wrap_column += wrap_rows[line_wrap_index - 1].length(); @@ -1108,9 +1113,11 @@ void TextEdit::_notification(int p_what) { if (cursor.column == last_wrap_column + j && cursor.line == line && cursor_wrap_index == line_wrap_index) { cursor_pos = Point2i(char_ofs + char_margin + ofs_x, ofs_y); + cursor_pos.y += (get_row_height() - cache.font->get_height()) / 2; if (insert_mode) { - cursor_pos.y += (get_row_height() - 3); + cursor_insert_offset_y = (cache.font->get_height() - 3); + cursor_pos.y += cursor_insert_offset_y; } int caret_w = (str[j] == '\t') ? cache.font->get_char_size(' ').width : char_w; @@ -1155,7 +1162,8 @@ void TextEdit::_notification(int p_what) { #else caret_w = (block_caret) ? caret_w : 2; #endif - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, get_row_height())), cache.caret_color); + + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, cache.font->get_height())), cache.caret_color); } } } @@ -1198,9 +1206,11 @@ void TextEdit::_notification(int p_what) { if (cursor.column == last_wrap_column + str.length() && cursor.line == line && cursor_wrap_index == line_wrap_index && (char_ofs + char_margin) >= xmargin_beg) { cursor_pos = Point2i(char_ofs + char_margin + ofs_x, ofs_y); + cursor_pos.y += (get_row_height() - cache.font->get_height()) / 2; if (insert_mode) { - cursor_pos.y += (get_row_height() - 3); + cursor_insert_offset_y = cache.font->get_height() - 3; + cursor_pos.y += cursor_insert_offset_y; } if (ime_text.length() > 0) { int ofs = 0; @@ -1245,7 +1255,8 @@ void TextEdit::_notification(int p_what) { #else int caret_w = (block_caret) ? char_w : 2; #endif - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, get_row_height())), cache.caret_color); + + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, cache.font->get_height())), cache.caret_color); } } } @@ -1287,9 +1298,9 @@ void TextEdit::_notification(int p_what) { int th = h + csb->get_minimum_size().y; if (cursor_pos.y + get_row_height() + th > get_size().height) { - completion_rect.position.y = cursor_pos.y - th; + completion_rect.position.y = cursor_pos.y - th - (cache.line_spacing / 2.0f) - cursor_insert_offset_y; } else { - completion_rect.position.y = cursor_pos.y + get_row_height() + csb->get_offset().y; + completion_rect.position.y = cursor_pos.y + cache.font->get_height() + (cache.line_spacing / 2.0f) + csb->get_offset().y - cursor_insert_offset_y; completion_below = true; } @@ -1323,7 +1334,8 @@ void TextEdit::_notification(int p_what) { text_color = color_regions[j].color; } } - draw_string(cache.font, Point2(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent()), completion_options[l], text_color, completion_rect.size.width); + int yofs = (get_row_height() - cache.font->get_height()) / 2; + draw_string(cache.font, Point2(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent() + yofs), completion_options[l], text_color, completion_rect.size.width); } if (scrollw) { @@ -1372,8 +1384,8 @@ void TextEdit::_notification(int p_what) { } } - Size2 size = Size2(max_w, sc * font->get_height() + spacing); - Size2 minsize = size + sb->get_minimum_size(); + Size2 size2 = Size2(max_w, sc * font->get_height() + spacing); + Size2 minsize = size2 + sb->get_minimum_size(); if (completion_hint_offset == -0xFFFF) { completion_hint_offset = cursor_pos.x - offset; @@ -1412,7 +1424,6 @@ void TextEdit::_notification(int p_what) { if (has_focus()) { OS::get_singleton()->set_ime_active(true); OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos + Point2(0, get_row_height())); - OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this); } } break; @@ -1425,38 +1436,31 @@ void TextEdit::_notification(int p_what) { OS::get_singleton()->set_ime_active(true); Point2 cursor_pos = Point2(cursor_get_column(), cursor_get_line()) * get_row_height(); OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos); - OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this); if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->show_virtual_keyboard(get_text(), get_global_rect()); - if (raised_from_completion) { - VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 1); - } } break; case NOTIFICATION_FOCUS_EXIT: { OS::get_singleton()->set_ime_position(Point2()); - OS::get_singleton()->set_ime_intermediate_text_callback(NULL, NULL); OS::get_singleton()->set_ime_active(false); ime_text = ""; ime_selection = Point2(); if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->hide_virtual_keyboard(); - if (raised_from_completion) { - VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 0); + } break; + case MainLoop::NOTIFICATION_OS_IME_UPDATE: { + + if (has_focus()) { + ime_text = OS::get_singleton()->get_ime_text(); + ime_selection = OS::get_singleton()->get_ime_selection(); + update(); } } break; } } -void TextEdit::_ime_text_callback(void *p_self, String p_text, Point2 p_selection) { - TextEdit *self = (TextEdit *)p_self; - self->ime_text = p_text; - self->ime_selection = p_selection; - self->update(); -} - void TextEdit::_consume_pair_symbol(CharType ch) { int cursor_position_to_move = cursor_get_column() + 1; @@ -1713,10 +1717,10 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co col = get_char_pos_for_line(colx, row, wrap_index); if (is_wrap_enabled() && wrap_index < times_line_wraps(row)) { // move back one if we are at the end of the row - Vector<String> rows = get_wrap_rows_text(row); + Vector<String> rows2 = get_wrap_rows_text(row); int row_end_col = 0; for (int i = 0; i < wrap_index + 1; i++) { - row_end_col += rows[i].length(); + row_end_col += rows2[i].length(); } if (col >= row_end_col) col -= 1; @@ -2201,10 +2205,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { bool had_selection = selection.active; // stuff to do when selection is active.. - if (selection.active) { - - if (readonly) - return; + if (!readonly && selection.active) { bool clear = false; bool unselect = false; @@ -2644,24 +2645,26 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } case KEY_UP: { - if (k->get_shift()) - _pre_shift_selection(); if (k->get_alt()) { scancode_handled = false; break; } #ifndef APPLE_STYLE_KEYS if (k->get_command()) { - _scroll_lines_up(); - break; - } #else if (k->get_command() && k->get_alt()) { +#endif _scroll_lines_up(); break; } + if (k->get_shift()) { + _pre_shift_selection(); + } + +#ifdef APPLE_STYLE_KEYS if (k->get_command()) { + cursor_set_line(0); } else #endif @@ -2695,24 +2698,24 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } case KEY_DOWN: { - if (k->get_shift()) - _pre_shift_selection(); if (k->get_alt()) { scancode_handled = false; break; } #ifndef APPLE_STYLE_KEYS if (k->get_command()) { - _scroll_lines_down(); - break; - } - #else if (k->get_command() && k->get_alt()) { +#endif _scroll_lines_down(); break; } + if (k->get_shift()) { + _pre_shift_selection(); + } + +#ifdef APPLE_STYLE_KEYS if (k->get_command()) { cursor_set_line(get_last_unhidden_line(), true, false, 9999); } else @@ -3260,7 +3263,6 @@ void TextEdit::_scroll_down(real_t p_delta) { int max_v_scroll = round(v_scroll->get_max() - v_scroll->get_page()); if (target_v_scroll > max_v_scroll) { target_v_scroll = max_v_scroll; - v_scroll->set_value(target_v_scroll); } if (Math::abs(target_v_scroll - v_scroll->get_value()) < 1.0) { v_scroll->set_value(target_v_scroll); @@ -3373,20 +3375,20 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i String preinsert_text = text[p_line].substr(0, p_char); String postinsert_text = text[p_line].substr(p_char, text[p_line].size()); - for (int i = 0; i < substrings.size(); i++) { + for (int j = 0; j < substrings.size(); j++) { //insert the substrings - if (i == 0) { + if (j == 0) { - text.set(p_line, preinsert_text + substrings[i]); + text.set(p_line, preinsert_text + substrings[j]); } else { - text.insert(p_line + i, substrings[i]); + text.insert(p_line + j, substrings[j]); } - if (i == substrings.size() - 1) { + if (j == substrings.size() - 1) { - text.set(p_line + i, text[p_line + i] + postinsert_text); + text.set(p_line + j, text[p_line + j] + postinsert_text); } } @@ -3645,7 +3647,7 @@ int TextEdit::get_total_visible_rows() const { return total_rows; } -void TextEdit::update_wrap_at() { +void TextEdit::_update_wrap_at() { wrap_at = get_size().width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width - wrap_right_offset; update_cursor_wrap_offset(); @@ -3789,6 +3791,9 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const { int cur_wrap_index = 0; int tab_offset_px = get_indent_level(p_line) * cache.font->get_char_size(' ').width; + if (tab_offset_px >= wrap_at) { + tab_offset_px = 0; + } while (col < line_text.length()) { CharType c = line_text[col]; @@ -3796,36 +3801,46 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const { int indent_ofs = (cur_wrap_index != 0 ? tab_offset_px : 0); - word_str += c; - word_px += w; - if (c == ' ') { - // end of a word; add this word to the substring + if (indent_ofs + word_px + w > wrap_at) { + // not enough space to add this char; start next line wrap_substring += word_str; - px += word_px; - word_str = ""; - word_px = 0; - } + lines.push_back(wrap_substring); + cur_wrap_index++; + wrap_substring = ""; + px = 0; - if ((indent_ofs + px + word_px) > wrap_at) { - // do not want to add this word - if (indent_ofs + word_px > wrap_at) { - // not enough space; add it anyway + word_str = ""; + word_str += c; + word_px = w; + } else { + word_str += c; + word_px += w; + if (c == ' ') { + // end of a word; add this word to the substring wrap_substring += word_str; px += word_px; word_str = ""; word_px = 0; } - lines.push_back(wrap_substring); - // reset for next wrap - cur_wrap_index++; - wrap_substring = ""; - px = 0; + + if (indent_ofs + px + word_px > wrap_at) { + // this word will be moved to the next line + lines.push_back(wrap_substring); + // reset for next wrap + cur_wrap_index++; + wrap_substring = ""; + px = 0; + } } col++; } // line ends before hit wrap_at; add this word to the substring wrap_substring += word_str; lines.push_back(wrap_substring); + + // update cache + text.set_line_wrap_amount(p_line, lines.size() - 1); + return lines; } @@ -4028,6 +4043,9 @@ int TextEdit::get_char_pos_for_line(int p_px, int p_line, int p_wrap_index) cons int line_wrap_amount = times_line_wraps(p_line); int wrap_offset_px = get_indent_level(p_line) * cache.font->get_char_size(' ').width; + if (wrap_offset_px >= wrap_at) { + wrap_offset_px = 0; + } if (p_wrap_index > line_wrap_amount) p_wrap_index = line_wrap_amount; if (p_wrap_index > 0) @@ -4069,6 +4087,9 @@ int TextEdit::get_column_x_offset_for_line(int p_char, int p_line) const { int px = get_column_x_offset(n_char, rows[wrap_index]); int wrap_offset_px = get_indent_level(p_line) * cache.font->get_char_size(' ').width; + if (wrap_offset_px >= wrap_at) { + wrap_offset_px = 0; + } if (wrap_index != 0) px += wrap_offset_px; @@ -4270,6 +4291,7 @@ void TextEdit::_clear() { cursor.line_ofs = 0; cursor.wrap_ofs = 0; cursor.last_fit_x = 0; + selection.active = false; } void TextEdit::clear() { @@ -5666,16 +5688,12 @@ void TextEdit::_confirm_completion() { void TextEdit::_cancel_code_hint() { - VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 0); - raised_from_completion = false; completion_hint = ""; update(); } void TextEdit::_cancel_completion() { - VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 0); - raised_from_completion = false; if (!completion_active) return; @@ -5767,6 +5785,7 @@ void TextEdit::_update_completion_candidates() { completion_base = s; Vector<float> sim_cache; bool single_quote = s.begins_with("'"); + Vector<String> completion_options_casei; for (int i = 0; i < completion_strings.size(); i++) { if (single_quote && completion_strings[i].is_quoted()) { @@ -5775,9 +5794,13 @@ void TextEdit::_update_completion_candidates() { if (completion_strings[i].begins_with(s)) { completion_options.push_back(completion_strings[i]); + } else if (completion_strings[i].to_lower().begins_with(s.to_lower())) { + completion_options_casei.push_back(completion_strings[i]); } } + completion_options.append_array(completion_options_casei); + if (completion_options.size() == 0) { for (int i = 0; i < completion_strings.size(); i++) { if (s.is_subsequence_of(completion_strings[i])) { @@ -5833,8 +5856,6 @@ void TextEdit::query_code_comple() { void TextEdit::set_code_hint(const String &p_hint) { - VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 1); - raised_from_completion = true; completion_hint = p_hint; completion_hint_offset = -0xFFFF; update(); @@ -5842,8 +5863,6 @@ void TextEdit::set_code_hint(const String &p_hint) { void TextEdit::code_complete(const Vector<String> &p_strings, bool p_forced) { - VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 1); - raised_from_completion = true; completion_strings = p_strings; completion_active = true; completion_forced = p_forced; @@ -6053,7 +6072,10 @@ void TextEdit::menu_option(int p_option) { case MENU_UNDO: { undo(); } break; - }; + case MENU_REDO: { + redo(); + } + } } void TextEdit::set_select_identifiers_on_hover(bool p_enable) { @@ -6088,6 +6110,7 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("_click_selection_held"), &TextEdit::_click_selection_held); ClassDB::bind_method(D_METHOD("_toggle_draw_caret"), &TextEdit::_toggle_draw_caret); ClassDB::bind_method(D_METHOD("_v_scroll_input"), &TextEdit::_v_scroll_input); + ClassDB::bind_method(D_METHOD("_update_wrap_at"), &TextEdit::_update_wrap_at); BIND_ENUM_CONSTANT(SEARCH_MATCH_CASE); BIND_ENUM_CONSTANT(SEARCH_WHOLE_WORDS); @@ -6214,7 +6237,7 @@ void TextEdit::_bind_methods() { ADD_GROUP("Caret", "caret_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_block_mode"), "cursor_set_block_mode", "cursor_is_block_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "cursor_set_blink_enabled", "cursor_get_blink_enabled"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "cursor_set_blink_speed", "cursor_get_blink_speed"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "cursor_set_blink_speed", "cursor_get_blink_speed"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_moving_by_right_click"), "set_right_click_moves_caret", "is_right_click_moving_caret"); ADD_SIGNAL(MethodInfo("cursor_changed")); @@ -6229,9 +6252,11 @@ void TextEdit::_bind_methods() { BIND_ENUM_CONSTANT(MENU_CLEAR); BIND_ENUM_CONSTANT(MENU_SELECT_ALL); BIND_ENUM_CONSTANT(MENU_UNDO); + BIND_ENUM_CONSTANT(MENU_REDO); BIND_ENUM_CONSTANT(MENU_MAX); GLOBAL_DEF("gui/timers/text_edit_idle_detect_sec", 3); + ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/text_edit_idle_detect_sec", PropertyInfo(Variant::REAL, "gui/timers/text_edit_idle_detect_sec", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); // No negative numbers } TextEdit::TextEdit() { @@ -6345,8 +6370,6 @@ TextEdit::TextEdit() { target_v_scroll = 0; v_scroll_speed = 80; - raised_from_completion = false; - context_menu_enabled = true; menu = memnew(PopupMenu); add_child(menu); @@ -6358,6 +6381,7 @@ TextEdit::TextEdit() { menu->add_item(RTR("Clear"), MENU_CLEAR); menu->add_separator(); menu->add_item(RTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z); + menu->add_item(RTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z); menu->connect("id_pressed", this, "menu_option"); } diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index f0c18ad047..95f1fbbee5 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -306,8 +306,6 @@ private: float target_v_scroll; float v_scroll_speed; - bool raised_from_completion; - String highlighted_word; uint64_t last_dblclk; @@ -338,7 +336,7 @@ private: int get_total_visible_rows() const; void update_cursor_wrap_offset(); - void update_wrap_at(); + void _update_wrap_at(); bool line_wraps(int line) const; int times_line_wraps(int line) const; Vector<String> get_wrap_rows_text(int p_line) const; @@ -382,8 +380,6 @@ private: void _scroll_lines_up(); void _scroll_lines_down(); - static void _ime_text_callback(void *p_self, String p_text, Point2 p_selection); - //void mouse_motion(const Point& p_pos, const Point& p_rel, int p_button_mask); Size2 get_minimum_size() const; @@ -446,6 +442,7 @@ public: MENU_CLEAR, MENU_SELECT_ALL, MENU_UNDO, + MENU_REDO, MENU_MAX }; diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index 413f9dbbe6..19bef9fdf5 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -64,7 +64,9 @@ bool TextureButton::has_point(const Point2 &p_point) const { Rect2 rect = Rect2(); Size2 mask_size = click_mask->get_size(); - if (_tile) { + if (_position_rect.no_area()) { + rect.size = mask_size; + } else if (_tile) { // if the stretch mode is tile we offset the point to keep it inside the mask size rect.size = mask_size; if (_position_rect.has_point(point)) { @@ -128,6 +130,7 @@ void TextureButton::_notification(int p_what) { if (normal.is_valid()) texdraw = normal; } break; + case DRAW_HOVER_PRESSED: case DRAW_PRESSED: { if (pressed.is_null()) { @@ -150,7 +153,6 @@ void TextureButton::_notification(int p_what) { } else texdraw = hover; } break; - case DRAW_HOVER_PRESSED: break; // Not used in this class case DRAW_DISABLED: { if (disabled.is_null()) { @@ -206,8 +208,8 @@ void TextureButton::_notification(int p_what) { Size2 scaleSize(size.width / tex_size.width, size.height / tex_size.height); float scale = scaleSize.width > scaleSize.height ? scaleSize.width : scaleSize.height; Size2 scaledTexSize = tex_size * scale; - Point2 ofs = ((scaledTexSize - size) / scale).abs() / 2.0f; - _texture_region = Rect2(ofs, size / scale); + Point2 ofs2 = ((scaledTexSize - size) / scale).abs() / 2.0f; + _texture_region = Rect2(ofs2, size / scale); } break; } } @@ -216,6 +218,8 @@ void TextureButton::_notification(int p_what) { draw_texture_rect(texdraw, _position_rect, _tile); else draw_texture_rect_region(texdraw, _position_rect, _texture_region); + } else { + _position_rect = Rect2(); } if (has_focus() && focused.is_valid()) { @@ -247,14 +251,14 @@ void TextureButton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_stretch_mode"), &TextureButton::get_stretch_mode); ADD_GROUP("Textures", "texture_"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_texture", "get_normal_texture"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture_pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_pressed_texture", "get_pressed_texture"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture_hover", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_hover_texture", "get_hover_texture"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture_disabled", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_disabled_texture", "get_disabled_texture"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture_focused", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_focused_texture", "get_focused_texture"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture_click_mask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_click_mask", "get_click_mask"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "expand", PROPERTY_HINT_RESOURCE_TYPE, "bool"), "set_expand", "get_expand"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_texture", "get_normal_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_pressed_texture", "get_pressed_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_hover", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_hover_texture", "get_hover_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_disabled", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_disabled_texture", "get_disabled_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_focused", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_focused_texture", "get_focused_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_click_mask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_click_mask", "get_click_mask"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand", PROPERTY_HINT_RESOURCE_TYPE, "bool"), "set_expand", "get_expand"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode"); BIND_ENUM_CONSTANT(STRETCH_SCALE); BIND_ENUM_CONSTANT(STRETCH_TILE); diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h index d42df390e8..d9224de686 100644 --- a/scene/gui/texture_button.h +++ b/scene/gui/texture_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,7 +32,7 @@ #define TEXTURE_BUTTON_H #include "scene/gui/base_button.h" -#include "scene/resources/bit_mask.h" +#include "scene/resources/bit_map.h" class TextureButton : public BaseButton { GDCLASS(TextureButton, BaseButton); diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp index 75f88dc4e6..c534df5cbe 100644 --- a/scene/gui/texture_progress.cpp +++ b/scene/gui/texture_progress.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -160,23 +160,27 @@ Point2 TextureProgress::unit_val_to_uv(float val) { if (edge == 0) { if (dir.x > 0) continue; - cp = -dir.x; cq = -(edgeLeft - p.x); + dir.x *= 2.0 * cq; + cp = -dir.x; } else if (edge == 1) { if (dir.x < 0) continue; - cp = dir.x; cq = (edgeRight - p.x); + dir.x *= 2.0 * cq; + cp = dir.x; } else if (edge == 2) { if (dir.y > 0) continue; - cp = -dir.y; cq = -(edgeBottom - p.y); + dir.y *= 2.0 * cq; + cp = -dir.y; } else if (edge == 3) { if (dir.y < 0) continue; - cp = dir.y; cq = (edgeTop - p.y); + dir.y *= 2.0 * cq; + cp = dir.y; } cr = cq / cp; if (cr >= 0 && cr < t1) @@ -247,12 +251,14 @@ void TextureProgress::draw_nine_patch_stretched(const Ref<Texture> &p_texture, F middle_section_size *= MIN(1.0, (MAX(0.0, width_filled - first_section_size) / MAX(1.0, width_total - first_section_size - last_section_size))); last_section_size = MAX(0.0, last_section_size - (width_total - width_filled)); + first_section_size = MIN(first_section_size, width_filled); width_texture = MIN(width_texture, first_section_size + middle_section_size + last_section_size); switch (mode) { case FILL_LEFT_TO_RIGHT: { src_rect.size.x = width_texture; dst_rect.size.x = width_filled; + topleft.x = first_section_size; bottomright.x = last_section_size; } break; case FILL_RIGHT_TO_LEFT: { @@ -261,11 +267,13 @@ void TextureProgress::draw_nine_patch_stretched(const Ref<Texture> &p_texture, F dst_rect.position.x += width_total - width_filled; dst_rect.size.x = width_filled; topleft.x = last_section_size; + bottomright.x = first_section_size; } break; case FILL_TOP_TO_BOTTOM: { src_rect.size.y = width_texture; dst_rect.size.y = width_filled; bottomright.y = last_section_size; + topleft.y = first_section_size; } break; case FILL_BOTTOM_TO_TOP: { src_rect.position.y += src_rect.size.y - width_texture; @@ -273,6 +281,7 @@ void TextureProgress::draw_nine_patch_stretched(const Ref<Texture> &p_texture, F dst_rect.position.y += width_total - width_filled; dst_rect.size.y = width_filled; topleft.y = last_section_size; + bottomright.y = first_section_size; } break; case FILL_BILINEAR_LEFT_AND_RIGHT: { // TODO: Implement @@ -486,21 +495,21 @@ void TextureProgress::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_under", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_under_texture", "get_under_texture"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_over", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_over_texture", "get_over_texture"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_progress", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_progress_texture", "get_progress_texture"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "fill_mode", PROPERTY_HINT_ENUM, "Left to Right,Right to Left,Top to Bottom,Bottom to Top,Clockwise,Counter Clockwise,Bilinear (Left and Right),Bilinear (Top and Bottom), Clockwise and Counter Clockwise"), "set_fill_mode", "get_fill_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "fill_mode", PROPERTY_HINT_ENUM, "Left to Right,Right to Left,Top to Bottom,Bottom to Top,Clockwise,Counter Clockwise,Bilinear (Left and Right),Bilinear (Top and Bottom), Clockwise and Counter Clockwise"), "set_fill_mode", "get_fill_mode"); ADD_GROUP("Tint", "tint_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_under"), "set_tint_under", "get_tint_under"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_over"), "set_tint_over", "get_tint_over"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_progress"), "set_tint_progress", "get_tint_progress"); ADD_GROUP("Radial Fill", "radial_"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "radial_initial_angle", PROPERTY_HINT_RANGE, "0.0,360.0,0.1,slider"), "set_radial_initial_angle", "get_radial_initial_angle"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "radial_fill_degrees", PROPERTY_HINT_RANGE, "0.0,360.0,0.1,slider"), "set_fill_degrees", "get_fill_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "radial_initial_angle", PROPERTY_HINT_RANGE, "0.0,360.0,0.1,slider"), "set_radial_initial_angle", "get_radial_initial_angle"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "radial_fill_degrees", PROPERTY_HINT_RANGE, "0.0,360.0,0.1,slider"), "set_fill_degrees", "get_fill_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "radial_center_offset"), "set_radial_center_offset", "get_radial_center_offset"); ADD_GROUP("Stretch", "stretch_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "nine_patch_stretch"), "set_nine_patch_stretch", "get_nine_patch_stretch"); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "stretch_margin_left", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", MARGIN_LEFT); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "stretch_margin_top", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", MARGIN_TOP); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "stretch_margin_right", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", MARGIN_RIGHT); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "stretch_margin_bottom", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", MARGIN_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "stretch_margin_left", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", MARGIN_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "stretch_margin_top", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", MARGIN_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "stretch_margin_right", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", MARGIN_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "stretch_margin_bottom", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", MARGIN_BOTTOM); BIND_ENUM_CONSTANT(FILL_LEFT_TO_RIGHT); BIND_ENUM_CONSTANT(FILL_RIGHT_TO_LEFT); diff --git a/scene/gui/texture_progress.h b/scene/gui/texture_progress.h index a11e55234a..008bf5b038 100644 --- a/scene/gui/texture_progress.h +++ b/scene/gui/texture_progress.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp index f4285525f6..caae48336b 100644 --- a/scene/gui/texture_rect.cpp +++ b/scene/gui/texture_rect.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -109,9 +109,9 @@ void TextureRect::_bind_methods() { ClassDB::bind_method(D_METHOD("set_stretch_mode", "stretch_mode"), &TextureRect::set_stretch_mode); ClassDB::bind_method(D_METHOD("get_stretch_mode"), &TextureRect::get_stretch_mode); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "expand"), "set_expand", "has_expand"); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale On Expand (Compat),Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand"), "set_expand", "has_expand"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale On Expand (Compat),Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode"); BIND_ENUM_CONSTANT(STRETCH_SCALE_ON_EXPAND); BIND_ENUM_CONSTANT(STRETCH_SCALE); diff --git a/scene/gui/texture_rect.h b/scene/gui/texture_rect.h index b684ac816c..ddd101573b 100644 --- a/scene/gui/texture_rect.h +++ b/scene/gui/texture_rect.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/tool_button.cpp b/scene/gui/tool_button.cpp index 4220a6b5ce..a81cc34efa 100644 --- a/scene/gui/tool_button.cpp +++ b/scene/gui/tool_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/tool_button.h b/scene/gui/tool_button.h index b8be18e560..8f729cd4df 100644 --- a/scene/gui/tool_button.h +++ b/scene/gui/tool_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 0c11181f98..236c4dbe63 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -901,6 +901,7 @@ void Tree::update_cache() { cache.item_margin = get_constant("item_margin"); cache.button_margin = get_constant("button_margin"); cache.guide_width = get_constant("guide_width"); + cache.draw_guides = get_constant("draw_guides"); cache.draw_relationship_lines = get_constant("draw_relationship_lines"); cache.relationship_line_color = get_color("relationship_line_color"); cache.scroll_border = get_constant("scroll_border"); @@ -1070,11 +1071,11 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 int font_ascent = font->get_ascent(); int ofs = p_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); - int skip = 0; + int skip2 = 0; for (int i = 0; i < columns.size(); i++) { - if (skip) { - skip--; + if (skip2) { + skip2--; continue; } @@ -1101,7 +1102,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 while (i + plus < columns.size() && !p_item->cells[i + plus].editable && p_item->cells[i + plus].mode == TreeItem::CELL_MODE_STRING && p_item->cells[i + plus].text == "" && p_item->cells[i + plus].icon.is_null()) { w += get_column_width(i + plus); plus++; - skip++; + skip2++; } } @@ -1132,7 +1133,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 cell_rect.size.x += cache.hseparation; } - VisualServer::get_singleton()->canvas_item_add_line(ci, Point2i(cell_rect.position.x, cell_rect.position.y + cell_rect.size.height), cell_rect.position + cell_rect.size, cache.guide_color, 1); + if (cache.draw_guides) { + VisualServer::get_singleton()->canvas_item_add_line(ci, Point2i(cell_rect.position.x, cell_rect.position.y + cell_rect.size.height), cell_rect.position + cell_rect.size, cache.guide_color, 1); + } if (i == 0) { @@ -1155,16 +1158,15 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 r.position.x += icon_width; r.size.x -= icon_width; } - //r.grow(cache.selected->get_margin(MARGIN_LEFT)); + p_item->set_meta("__focus_rect", Rect2(r.position, r.size)); if (has_focus()) { cache.selected_focus->draw(ci, r); - p_item->set_meta("__focus_rect", Rect2(r.position, r.size)); } else { cache.selected->draw(ci, r); } if (text_editor->is_visible_in_tree()) { - Vector2 ofs(0, (text_editor->get_size().height - r.size.height) / 2); - text_editor->set_position(get_global_position() + r.position - ofs); + Vector2 ofs2(0, (text_editor->get_size().height - r.size.height) / 2); + text_editor->set_position(get_global_position() + r.position - ofs2); } } @@ -1416,7 +1418,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 while (c) { - if (cache.draw_relationship_lines == 1 && (c->get_parent() != root || !hide_root)) { + if (cache.draw_relationship_lines > 0 && (!hide_root || c->parent != root)) { int root_ofs = children_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); int parent_ofs = p_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); Point2i root_pos = Point2i(root_ofs, children_pos.y + label_h / 2) - cache.offset + p_draw_ofs; @@ -1599,6 +1601,7 @@ void Tree::_range_click_timeout() { mb.instance(); ; + propagate_mouse_activated = false; // done from outside, so signal handler can't clear the tree in the middle of emit (which is a common case) blocked++; propagate_mouse_event(pos + cache.offset, 0, 0, false, root, BUTTON_LEFT, mb); blocked--; @@ -1612,6 +1615,11 @@ void Tree::_range_click_timeout() { if (!click_handled) range_click_timer->stop(); + if (propagate_mouse_activated) { + emit_signal("item_activated"); + propagate_mouse_activated = false; + } + } else { range_click_timer->stop(); } @@ -1720,7 +1728,8 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool if (p_doubleclick && (!c.editable || c.mode == TreeItem::CELL_MODE_CUSTOM || c.mode == TreeItem::CELL_MODE_ICON /*|| c.mode==TreeItem::CELL_MODE_CHECK*/)) { //it's confusing for check - emit_signal("item_activated"); + propagate_mouse_activated = true; + incr_search.clear(); return -1; } @@ -2519,7 +2528,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { pressing_for_editor = false; } - if (cache.click_type == Cache::CLICK_BUTTON) { + if (cache.click_type == Cache::CLICK_BUTTON && cache.click_item != NULL) { // make sure in case of wrong reference after reconstructing whole TreeItems cache.click_item = get_item_at_position(cache.click_pos); emit_signal("button_pressed", cache.click_item, cache.click_column, cache.click_id); @@ -2588,6 +2597,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { click_handled = false; pressing_for_editor = false; + propagate_mouse_activated = false; blocked++; propagate_mouse_event(pos + cache.offset, 0, 0, b->is_doubleclick(), root, b->get_button_index(), b); @@ -2625,6 +2635,11 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { } } + if (propagate_mouse_activated) { + emit_signal("item_activated"); + propagate_mouse_activated = false; + } + } break; case BUTTON_WHEEL_UP: { @@ -2683,8 +2698,8 @@ bool Tree::edit_selected() { popup_menu->clear(); for (int i = 0; i < c.text.get_slice_count(","); i++) { - String s = c.text.get_slicec(',', i); - popup_menu->add_item(s.get_slicec(':', 0), s.get_slicec(':', 1).empty() ? i : s.get_slicec(':', 1).to_int()); + String s2 = c.text.get_slicec(',', i); + popup_menu->add_item(s2.get_slicec(':', 0), s2.get_slicec(':', 1).empty() ? i : s2.get_slicec(':', 1).to_int()); } popup_menu->set_size(Size2(rect.size.width, 0)); @@ -2698,6 +2713,7 @@ bool Tree::edit_selected() { Vector2 ofs(0, (text_editor->get_size().height - rect.size.height) / 2); Point2i textedpos = get_global_position() + rect.position - ofs; + cache.text_editor_position = textedpos; text_editor->set_position(textedpos); text_editor->set_size(rect.size); text_editor->clear(); @@ -2935,14 +2951,14 @@ void Tree::_notification(int p_what) { if (show_column_titles) { //title buttons - int ofs = cache.bg->get_margin(MARGIN_LEFT); + int ofs2 = cache.bg->get_margin(MARGIN_LEFT); for (int i = 0; i < columns.size(); i++) { Ref<StyleBox> sb = (cache.click_type == Cache::CLICK_TITLE && cache.click_index == i) ? cache.title_button_pressed : ((cache.hover_type == Cache::CLICK_TITLE && cache.hover_index == i) ? cache.title_button_hover : cache.title_button); Ref<Font> f = cache.tb_font; - Rect2 tbrect = Rect2(ofs - cache.offset.x, bg->get_margin(MARGIN_TOP), get_column_width(i), tbh); + Rect2 tbrect = Rect2(ofs2 - cache.offset.x, bg->get_margin(MARGIN_TOP), get_column_width(i), tbh); sb->draw(ci, tbrect); - ofs += tbrect.size.width; + ofs2 += tbrect.size.width; //text int clip_w = tbrect.size.width - sb->get_minimum_size().width; f->draw_halign(ci, tbrect.position + Point2i(sb->get_offset().x, (tbrect.size.height - f->get_height()) / 2 + f->get_ascent()), HALIGN_CENTER, clip_w, columns[i].title, cache.title_button_color); @@ -2953,6 +2969,21 @@ void Tree::_notification(int p_what) { if (p_what == NOTIFICATION_THEME_CHANGED) { update_cache(); } + + if (p_what == NOTIFICATION_RESIZED || p_what == NOTIFICATION_TRANSFORM_CHANGED) { + + if (popup_edited_item != NULL) { + Rect2 rect = popup_edited_item->get_meta("__focus_rect"); + Vector2 ofs(0, (text_editor->get_size().height - rect.size.height) / 2); + Point2i textedpos = get_global_position() + rect.position - ofs; + + if (cache.text_editor_position != textedpos) { + cache.text_editor_position = textedpos; + text_editor->set_position(textedpos); + value_editor->set_position(textedpos + Point2i(0, text_editor->get_size().height)); + } + } + } } Size2 Tree::get_minimum_size() const { @@ -3881,6 +3912,7 @@ Tree::Tree() { value_editor->set_as_toplevel(true); text_editor->set_as_toplevel(true); + set_notify_transform(true); updating_value_editor = false; pressed_button = -1; @@ -3925,6 +3957,7 @@ Tree::Tree() { cache.hover_cell = -1; allow_reselect = false; + propagate_mouse_activated = false; } Tree::~Tree() { diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 34138acb85..26d64baafb 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -329,6 +329,8 @@ private: bool range_drag_enabled; Vector2 range_drag_capture_pos; + bool propagate_mouse_activated; + //TreeItem *cursor_item; //int cursor_column; @@ -434,6 +436,7 @@ private: int button_margin; Point2 offset; int draw_relationship_lines; + int draw_guides; int scroll_border; int scroll_speed; @@ -456,6 +459,8 @@ private: TreeItem *hover_item; int hover_cell; + Point2i text_editor_position; + } cache; int _get_title_button_height() const; diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp index 39e7c73390..5768f58977 100644 --- a/scene/gui/video_player.cpp +++ b/scene/gui/video_player.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -90,53 +90,32 @@ void VideoPlayer::_mix_audio() { AudioFrame vol = AudioFrame(volume, volume); - // Copy to server's audio buffer - switch (AudioServer::get_singleton()->get_speaker_mode()) { + int cc = AudioServer::get_singleton()->get_channel_count(); - case AudioServer::SPEAKER_MODE_STEREO: { - AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 0); + if (cc == 1) { + AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 0); + ERR_FAIL_COND(!target); - for (int j = 0; j < buffer_size; j++) { + for (int j = 0; j < buffer_size; j++) { - target[j] += buffer[j] * vol; - } - - } break; - case AudioServer::SPEAKER_SURROUND_31: { - - // FIXME: Implement - } break; - case AudioServer::SPEAKER_SURROUND_51: { - - AudioFrame *targets[2] = { - AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 1), - AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 2), - }; - - for (int j = 0; j < buffer_size; j++) { + target[j] += buffer[j] * vol; + } - AudioFrame frame = buffer[j] * vol; - targets[0][j] = frame; - targets[1][j] = frame; - } - } break; - case AudioServer::SPEAKER_SURROUND_71: { + } else { + AudioFrame *targets[4]; - AudioFrame *targets[3] = { - AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 1), - AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 2), - AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 3) - }; + for (int k = 0; k < cc; k++) { + targets[k] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, k); + ERR_FAIL_COND(!targets[k]); + } - for (int j = 0; j < buffer_size; j++) { + for (int j = 0; j < buffer_size; j++) { - AudioFrame frame = buffer[j] * vol; - targets[0][j] += frame; - targets[1][j] += frame; - targets[2][j] += frame; + AudioFrame frame = buffer[j] * vol; + for (int k = 0; k < cc; k++) { + targets[k][j] += frame; } - - } break; + } } } diff --git a/scene/gui/video_player.h b/scene/gui/video_player.h index 5c379b5620..62fb7838b6 100644 --- a/scene/gui/video_player.h +++ b/scene/gui/video_player.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/viewport_container.cpp b/scene/gui/viewport_container.cpp index ac5e6020eb..3f7a110c1b 100644 --- a/scene/gui/viewport_container.cpp +++ b/scene/gui/viewport_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -121,6 +121,8 @@ void ViewportContainer::_notification(int p_what) { c->set_update_mode(Viewport::UPDATE_ALWAYS); else c->set_update_mode(Viewport::UPDATE_DISABLED); + + c->set_handle_input_locally(false); //do not handle input locally here } } @@ -165,8 +167,34 @@ void ViewportContainer::_input(const Ref<InputEvent> &p_event) { } } +void ViewportContainer::_unhandled_input(const Ref<InputEvent> &p_event) { + + if (Engine::get_singleton()->is_editor_hint()) + return; + + Transform2D xform = get_global_transform(); + + if (stretch) { + Transform2D scale_xf; + scale_xf.scale(Vector2(shrink, shrink)); + xform *= scale_xf; + } + + Ref<InputEvent> ev = p_event->xformed_by(xform.affine_inverse()); + + for (int i = 0; i < get_child_count(); i++) { + + Viewport *c = Object::cast_to<Viewport>(get_child(i)); + if (!c || c->is_input_disabled()) + continue; + + c->unhandled_input(ev); + } +} + void ViewportContainer::_bind_methods() { + ClassDB::bind_method(D_METHOD("_unhandled_input", "event"), &ViewportContainer::_unhandled_input); ClassDB::bind_method(D_METHOD("_input", "event"), &ViewportContainer::_input); ClassDB::bind_method(D_METHOD("set_stretch", "enable"), &ViewportContainer::set_stretch); ClassDB::bind_method(D_METHOD("is_stretch_enabled"), &ViewportContainer::is_stretch_enabled); diff --git a/scene/gui/viewport_container.h b/scene/gui/viewport_container.h index 45c4cd03a1..b4ecc583ba 100644 --- a/scene/gui/viewport_container.h +++ b/scene/gui/viewport_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -49,6 +49,7 @@ public: bool is_stretch_enabled() const; void _input(const Ref<InputEvent> &p_event); + void _unhandled_input(const Ref<InputEvent> &p_event); void set_stretch_shrink(int p_shrink); int get_stretch_shrink() const; diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index a2e890e7a7..2b1991ebb0 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,7 +35,7 @@ void CanvasLayer::set_layer(int p_xform) { layer = p_xform; if (viewport.is_valid()) - VisualServer::get_singleton()->viewport_set_canvas_layer(viewport, canvas, layer); + VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent()); } int CanvasLayer::get_layer() const { @@ -146,19 +146,28 @@ void CanvasLayer::_notification(int p_what) { vp = Node::get_viewport(); } ERR_FAIL_COND(!vp); + + vp->_canvas_layer_add(this); viewport = vp->get_viewport_rid(); VisualServer::get_singleton()->viewport_attach_canvas(viewport, canvas); - VisualServer::get_singleton()->viewport_set_canvas_layer(viewport, canvas, layer); + VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent()); VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform); } break; case NOTIFICATION_EXIT_TREE: { + vp->_canvas_layer_remove(this); VisualServer::get_singleton()->viewport_remove_canvas(viewport, canvas); viewport = RID(); } break; + case NOTIFICATION_MOVED_IN_PARENT: { + + if (is_inside_tree()) + VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent()); + + } break; } } @@ -179,6 +188,7 @@ RID CanvasLayer::get_viewport() const { void CanvasLayer::set_custom_viewport(Node *p_viewport) { ERR_FAIL_NULL(p_viewport); if (is_inside_tree()) { + vp->_canvas_layer_remove(this); VisualServer::get_singleton()->viewport_remove_canvas(viewport, canvas); viewport = RID(); } @@ -198,10 +208,11 @@ void CanvasLayer::set_custom_viewport(Node *p_viewport) { else vp = Node::get_viewport(); + vp->_canvas_layer_add(this); viewport = vp->get_viewport_rid(); VisualServer::get_singleton()->viewport_attach_canvas(viewport, canvas); - VisualServer::get_singleton()->viewport_set_canvas_layer(viewport, canvas, layer); + VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent()); VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform); } } diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h index aae23fbb12..5d67245102 100644 --- a/scene/main/canvas_layer.h +++ b/scene/main/canvas_layer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index a9b7fba9c7..8b68b3215c 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -220,13 +220,12 @@ bool HTTPRequest::_handle_response(bool *ret_value) { Error err; if (new_request.begins_with("http")) { // New url, request all again - err = _parse_url(new_request); + _parse_url(new_request); } else { request_string = new_request; } err = _request(); - if (err == OK) { request_sent = false; got_response = false; diff --git a/scene/main/http_request.h b/scene/main/http_request.h index de09d2afda..baabda4010 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/instance_placeholder.cpp b/scene/main/instance_placeholder.cpp index 0ee5648de2..71addd6fea 100644 --- a/scene/main/instance_placeholder.cpp +++ b/scene/main/instance_placeholder.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/instance_placeholder.h b/scene/main/instance_placeholder.h index 2158257c93..3d0e879b2b 100644 --- a/scene/main/instance_placeholder.h +++ b/scene/main/instance_placeholder.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 50e94e6db5..04d7107fa4 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -157,7 +157,7 @@ void Node::_notification(int p_notification) { // kill children as cleanly as possible while (data.children.size()) { - Node *child = data.children[0]; + Node *child = data.children[data.children.size() - 1]; //begin from the end because its faster and more consistent with creation remove_child(child); memdelete(child); } @@ -959,7 +959,9 @@ void Node::set_human_readable_collision_renaming(bool p_enabled) { #ifdef TOOLS_ENABLED String Node::validate_child_name(Node *p_child) { - return _generate_serial_child_name(p_child); + StringName name = p_child->data.name; + _generate_serial_child_name(p_child, name); + return name; } #endif @@ -972,7 +974,9 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) { //this approach to autoset node names is human readable but very slow //it's turned on while running in the editor - p_child->data.name = _generate_serial_child_name(p_child); + StringName name = p_child->data.name; + _generate_serial_child_name(p_child, name); + p_child->data.name = name; } else { @@ -1008,74 +1012,120 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) { } } -String Node::_generate_serial_child_name(Node *p_child) { +// Return s + 1 as if it were an integer +String increase_numeric_string(const String &s) { - String name = p_child->data.name; + String res = s; + bool carry = res.length() > 0; - if (name == "") { + for (int i = res.length() - 1; i >= 0; i--) { + if (!carry) { + break; + } + CharType n = s[i]; + if (n == '9') { // keep carry as true: 9 + 1 + res[i] = '0'; + } else { + res[i] = s[i] + 1; + carry = false; + } + } + + if (carry) { + res = "1" + res; + } + + return res; +} + +void Node::_generate_serial_child_name(const Node *p_child, StringName &name) const { + + if (name == StringName()) { + //no name and a new nade is needed, create one. name = p_child->get_class(); // Adjust casing according to project setting. The current type name is expected to be in PascalCase. switch (ProjectSettings::get_singleton()->get("node/name_casing").operator int()) { case NAME_CASING_PASCAL_CASE: break; - case NAME_CASING_CAMEL_CASE: - name[0] = name.to_lower()[0]; - break; + case NAME_CASING_CAMEL_CASE: { + String n = name; + n[0] = n.to_lower()[0]; + name = n; + } break; case NAME_CASING_SNAKE_CASE: - name = name.camelcase_to_underscore(true); + name = String(name).camelcase_to_underscore(true); break; } } + //quickly test if proposed name exists + int cc = data.children.size(); //children count + const Node *const *children_ptr = data.children.ptr(); + + { + + bool exists = false; + + for (int i = 0; i < cc; i++) { + if (children_ptr[i] == p_child) { //exclude self in renaming if its already a child + continue; + } + if (children_ptr[i]->data.name == name) { + exists = true; + } + } + + if (!exists) { + return; //if it does not exist, it does not need validation + } + } + // Extract trailing number + String name_string = name; String nums; - for (int i = name.length() - 1; i >= 0; i--) { - CharType n = name[i]; + for (int i = name_string.length() - 1; i >= 0; i--) { + CharType n = name_string[i]; if (n >= '0' && n <= '9') { - nums = String::chr(name[i]) + nums; + nums = String::chr(name_string[i]) + nums; } else { break; } } String nnsep = _get_name_num_separator(); - int num = 0; - bool explicit_zero = false; - if (nums.length() > 0 && name.substr(name.length() - nnsep.length() - nums.length(), nnsep.length()) == nnsep) { - // Base name + Separator + Number - num = nums.to_int(); - name = name.substr(0, name.length() - nnsep.length() - nums.length()); // Keep base name - if (num == 0) { - explicit_zero = true; - } + int name_last_index = name_string.length() - nnsep.length() - nums.length(); + + // Assign the base name + separator to name if we have numbers preceded by a separator + if (nums.length() > 0 && name_string.substr(name_last_index, nnsep.length()) == nnsep) { + name_string = name_string.substr(0, name_last_index + nnsep.length()); + } else { + nums = ""; } - int num_places = nums.length(); for (;;) { - String attempt = (name + (num > 0 || explicit_zero ? nnsep + itos(num).pad_zeros(num_places) : "")).strip_edges(); - bool found = false; - for (int i = 0; i < data.children.size(); i++) { - if (data.children[i] == p_child) + StringName attempt = name_string + nums; + bool exists = false; + + for (int i = 0; i < cc; i++) { + if (children_ptr[i] == p_child) { continue; - if (data.children[i]->data.name == attempt) { - found = true; - break; + } + if (children_ptr[i]->data.name == attempt) { + exists = true; } } - if (!found) { - return attempt; + + if (!exists) { + name = attempt; + return; } else { - if (num == 0) { - if (explicit_zero) { - // Name ended in separator + 0; user expects to get to separator + 1 - num = 1; - } else { - // Name was undecorated so skip to 2 for a more natural result - num = 2; - } + if (nums.length() == 0) { + // Name was undecorated so skip to 2 for a more natural result + nums = "2"; + name_string += nnsep; // Add separator because nums.length() > 0 was false } else { - num++; + nums = increase_numeric_string(nums); } } } @@ -1182,13 +1232,24 @@ void Node::remove_child(Node *p_child) { ERR_FAIL_COND(data.blocked > 0); } + int child_count = data.children.size(); + Node **children = data.children.ptrw(); int idx = -1; - for (int i = 0; i < data.children.size(); i++) { - if (data.children[i] == p_child) { + if (p_child->data.pos >= 0 && p_child->data.pos < child_count) { + if (children[p_child->data.pos] == p_child) { + idx = p_child->data.pos; + } + } + + if (idx == -1) { //maybe removed while unparenting or something and index was not updated, so just in case the above fails, try this. + for (int i = 0; i < child_count; i++) { - idx = i; - break; + if (children[i] == p_child) { + + idx = i; + break; + } } } @@ -1205,9 +1266,14 @@ void Node::remove_child(Node *p_child) { data.children.remove(idx); - for (int i = idx; i < data.children.size(); i++) { + //update pointer and size + child_count = data.children.size(); + children = data.children.ptrw(); - data.children[i]->data.pos = i; + for (int i = idx; i < child_count; i++) { + + children[i]->data.pos = i; + children[i]->notification(NOTIFICATION_MOVED_IN_PARENT); } p_child->data.parent = NULL; @@ -1245,7 +1311,7 @@ Node *Node::_get_child_by_name(const StringName &p_name) const { return NULL; } -Node *Node::_get_node(const NodePath &p_path) const { +Node *Node::get_node_or_null(const NodePath &p_path) const { if (!data.inside_tree && p_path.is_absolute()) { ERR_EXPLAIN("Can't use get_node() with absolute paths from outside the active scene tree."); @@ -1310,7 +1376,7 @@ Node *Node::_get_node(const NodePath &p_path) const { Node *Node::get_node(const NodePath &p_path) const { - Node *node = _get_node(p_path); + Node *node = get_node_or_null(p_path); if (!node) { ERR_EXPLAIN("Node not found: " + p_path); ERR_FAIL_COND_V(!node, NULL); @@ -1320,7 +1386,7 @@ Node *Node::get_node(const NodePath &p_path) const { bool Node::has_node(const NodePath &p_path) const { - return _get_node(p_path) != NULL; + return get_node_or_null(p_path) != NULL; } Node *Node::find_node(const String &p_mask, bool p_recursive, bool p_owned) const { @@ -1835,7 +1901,7 @@ void Node::set_editable_instance(Node *p_node, bool p_editable) { } } -bool Node::is_editable_instance(Node *p_node) const { +bool Node::is_editable_instance(const Node *p_node) const { if (!p_node) return false; //easier, null is never editable :) @@ -2643,6 +2709,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("get_child", "idx"), &Node::get_child); ClassDB::bind_method(D_METHOD("has_node", "path"), &Node::has_node); ClassDB::bind_method(D_METHOD("get_node", "path"), &Node::get_node); + ClassDB::bind_method(D_METHOD("get_node_or_null", "path"), &Node::get_node_or_null); ClassDB::bind_method(D_METHOD("get_parent"), &Node::get_parent); ClassDB::bind_method(D_METHOD("find_node", "mask", "recursive", "owned"), &Node::find_node, DEFVAL(true), DEFVAL(true)); ClassDB::bind_method(D_METHOD("find_parent", "mask"), &Node::find_parent); @@ -2724,7 +2791,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_import_path", "import_path"), &Node::set_import_path); ClassDB::bind_method(D_METHOD("_get_import_path"), &Node::get_import_path); - ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "_import_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_import_path", "_get_import_path"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "_import_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_import_path", "_get_import_path"); { MethodInfo mi; @@ -2782,18 +2849,18 @@ void Node::_bind_methods() { ADD_SIGNAL(MethodInfo("tree_exiting")); ADD_SIGNAL(MethodInfo("tree_exited")); - //ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "process/process" ),"set_process","is_processing") ; - //ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "process/physics_process" ), "set_physics_process","is_physics_processing") ; - //ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "process/input" ), "set_process_input","is_processing_input" ) ; - //ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "process/unhandled_input" ), "set_process_unhandled_input","is_processing_unhandled_input" ) ; + //ADD_PROPERTY( PropertyInfo( Variant::BOOL, "process/process" ),"set_process","is_processing") ; + //ADD_PROPERTY( PropertyInfo( Variant::BOOL, "process/physics_process" ), "set_physics_process","is_physics_processing") ; + //ADD_PROPERTY( PropertyInfo( Variant::BOOL, "process/input" ), "set_process_input","is_processing_input" ) ; + //ADD_PROPERTY( PropertyInfo( Variant::BOOL, "process/unhandled_input" ), "set_process_unhandled_input","is_processing_unhandled_input" ) ; ADD_GROUP("Pause", "pause_"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "pause_mode", PROPERTY_HINT_ENUM, "Inherit,Stop,Process"), "set_pause_mode", "get_pause_mode"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "editor/display_folded", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_display_folded", "is_displayed_folded"); - ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "name", PROPERTY_HINT_NONE, "", 0), "set_name", "get_name"); - ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "filename", PROPERTY_HINT_NONE, "", 0), "set_filename", "get_filename"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_owner", "get_owner"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "", "get_multiplayer"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "set_custom_multiplayer", "get_custom_multiplayer"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "pause_mode", PROPERTY_HINT_ENUM, "Inherit,Stop,Process"), "set_pause_mode", "get_pause_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor/display_folded", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_display_folded", "is_displayed_folded"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "name", PROPERTY_HINT_NONE, "", 0), "set_name", "get_name"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "filename", PROPERTY_HINT_NONE, "", 0), "set_filename", "get_filename"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_owner", "get_owner"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "", "get_multiplayer"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "set_custom_multiplayer", "get_custom_multiplayer"); BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::REAL, "delta"))); BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::REAL, "delta"))); diff --git a/scene/main/node.h b/scene/main/node.h index a7baebc9c2..e6189389cb 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -153,13 +153,12 @@ private: void _print_tree_pretty(const String prefix, const bool last); void _print_tree(const Node *p_node); - Node *_get_node(const NodePath &p_path) const; Node *_get_child_by_name(const StringName &p_name) const; void _replace_connections_target(Node *p_new_target); void _validate_child_name(Node *p_child, bool p_force_human_readable = false); - String _generate_serial_child_name(Node *p_child); + void _generate_serial_child_name(const Node *p_child, StringName &name) const; void _propagate_reverse_notification(int p_notification); void _propagate_deferred_notification(int p_notification, bool p_reverse); @@ -252,6 +251,7 @@ public: Node *get_child(int p_index) const; bool has_node(const NodePath &p_path) const; Node *get_node(const NodePath &p_path) const; + Node *get_node_or_null(const NodePath &p_path) const; Node *find_node(const String &p_mask, bool p_recursive = true, bool p_owned = true) const; bool has_node_and_resource(const NodePath &p_path) const; Node *get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property = true) const; @@ -303,7 +303,7 @@ public: String get_filename() const; void set_editable_instance(Node *p_node, bool p_editable); - bool is_editable_instance(Node *p_node) const; + bool is_editable_instance(const Node *p_node) const; void set_editable_instances(const HashMap<NodePath, int> &p_editable_instances); HashMap<NodePath, int> get_editable_instances() const; diff --git a/scene/main/resource_preloader.cpp b/scene/main/resource_preloader.cpp index dbe7daa604..cb1168b73e 100644 --- a/scene/main/resource_preloader.cpp +++ b/scene/main/resource_preloader.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/resource_preloader.h b/scene/main/resource_preloader.h index 98c7b21f37..3e3be4ac82 100644 --- a/scene/main/resource_preloader.h +++ b/scene/main/resource_preloader.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index fdbe3b57f0..689f18a09d 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -484,6 +484,14 @@ bool SceneTree::iteration(float p_time) { return _quit; } +void SceneTree::_update_font_oversampling(float p_ratio) { + + if (use_font_oversampling) { + DynamicFontAtSize::font_oversampling = p_ratio; + DynamicFont::update_oversampling(); + } +} + bool SceneTree::idle(float p_time) { //print_line("ram: "+itos(OS::get_singleton()->get_static_memory_usage())+" sram: "+itos(OS::get_singleton()->get_dynamic_memory_usage())); @@ -515,12 +523,6 @@ bool SceneTree::idle(float p_time) { last_screen_size = win_size; _update_root_rect(); - - if (use_font_oversampling) { - DynamicFontAtSize::font_oversampling = OS::get_singleton()->get_window_size().width / root->get_visible_rect().size.width; - DynamicFont::update_oversampling(); - } - emit_signal("screen_resized"); } @@ -535,10 +537,15 @@ bool SceneTree::idle(float p_time) { //go through timers + List<Ref<SceneTreeTimer> >::Element *L = timers.back(); //last element + for (List<Ref<SceneTreeTimer> >::Element *E = timers.front(); E;) { List<Ref<SceneTreeTimer> >::Element *N = E->next(); if (pause && !E->get()->is_pause_mode_process()) { + if (E == L) { + break; //break on last, so if new timers were added during list traversal, ignore them. + } E = N; continue; } @@ -550,6 +557,9 @@ bool SceneTree::idle(float p_time) { E->get()->emit_signal("timeout"); timers.erase(E); } + if (E == L) { + break; //break on last, so if new timers were added during list traversal, ignore them. + } E = N; } @@ -631,6 +641,7 @@ void SceneTree::_notification(int p_notification) { } } break; case NOTIFICATION_OS_MEMORY_WARNING: + case NOTIFICATION_OS_IME_UPDATE: case NOTIFICATION_WM_MOUSE_ENTER: case NOTIFICATION_WM_MOUSE_EXIT: case NOTIFICATION_WM_FOCUS_IN: @@ -1124,10 +1135,12 @@ void SceneTree::_update_root_rect() { if (stretch_mode == STRETCH_MODE_DISABLED) { + _update_font_oversampling(1.0); root->set_size((last_screen_size / stretch_shrink).floor()); root->set_attach_to_screen_rect(Rect2(Point2(), last_screen_size)); root->set_size_override_stretch(false); root->set_size_override(false, Size2()); + root->update_canvas_items(); return; //user will take care } @@ -1141,6 +1154,10 @@ void SceneTree::_update_root_rect() { float viewport_aspect = desired_res.aspect(); float video_mode_aspect = video_mode.aspect(); + if (use_font_oversampling && stretch_aspect == STRETCH_ASPECT_IGNORE) { + 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) { //same aspect or ignore aspect viewport_size = desired_res; @@ -1199,21 +1216,30 @@ void SceneTree::_update_root_rect() { switch (stretch_mode) { case STRETCH_MODE_DISABLED: { // Already handled above + _update_font_oversampling(1.0); } break; case STRETCH_MODE_2D: { + _update_font_oversampling(screen_size.x / viewport_size.x); //screen / viewport radio drives oversampling root->set_size((screen_size / stretch_shrink).floor()); root->set_attach_to_screen_rect(Rect2(margin, screen_size)); root->set_size_override_stretch(true); root->set_size_override(true, (viewport_size / stretch_shrink).floor()); + root->update_canvas_items(); //force them to update just in case } break; case STRETCH_MODE_VIEWPORT: { + _update_font_oversampling(1.0); root->set_size((viewport_size / stretch_shrink).floor()); root->set_attach_to_screen_rect(Rect2(margin, screen_size)); root->set_size_override_stretch(false); root->set_size_override(false, Size2()); + root->update_canvas_items(); //force them to update just in case + + if (use_font_oversampling) { + WARN_PRINT("Font oversampling does not work in 'Viewport' stretch mode, only '2D'.") + } } break; } @@ -1916,12 +1942,11 @@ void SceneTree::add_idle_callback(IdleCallback p_callback) { void SceneTree::set_use_font_oversampling(bool p_oversampling) { + if (use_font_oversampling == p_oversampling) + return; + use_font_oversampling = p_oversampling; - if (use_font_oversampling) { - DynamicFontAtSize::font_oversampling = OS::get_singleton()->get_window_size().width / root->get_visible_rect().size.width; - } else { - DynamicFontAtSize::font_oversampling = 1.0; - } + _update_root_rect(); } bool SceneTree::is_using_font_oversampling() const { @@ -1935,6 +1960,7 @@ SceneTree::SceneTree() { accept_quit = true; quit_on_go_back = true; initialized = false; + use_font_oversampling = false; #ifdef DEBUG_ENABLED debug_collisions_hint = false; debug_navigation_hint = false; @@ -1944,6 +1970,7 @@ SceneTree::SceneTree() { debug_navigation_color = GLOBAL_DEF("debug/shapes/navigation/geometry_color", Color(0.1, 1.0, 0.7, 0.4)); debug_navigation_disabled_color = GLOBAL_DEF("debug/shapes/navigation/disabled_geometry_color", Color(1.0, 0.7, 0.1, 0.4)); collision_debug_contacts = GLOBAL_DEF("debug/shapes/collision/max_contacts_displayed", 10000); + ProjectSettings::get_singleton()->set_custom_property_info("debug/shapes/collision/max_contacts_displayed", PropertyInfo(Variant::INT, "debug/shapes/collision/max_contacts_displayed", PROPERTY_HINT_RANGE, "0,20000,1")); // No negative tree_version = 1; physics_process_time = 1; @@ -1964,6 +1991,7 @@ SceneTree::SceneTree() { root = memnew(Viewport); root->set_name("root"); + root->set_handle_input_locally(false); if (!root->get_world().is_valid()) root->set_world(Ref<World>(memnew(World))); @@ -1977,7 +2005,9 @@ SceneTree::SceneTree() { current_scene = NULL; int ref_atlas_size = GLOBAL_DEF("rendering/quality/reflections/atlas_size", 2048); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/reflections/atlas_size", PropertyInfo(Variant::INT, "rendering/quality/reflections/atlas_size", PROPERTY_HINT_RANGE, "0,8192,or_greater")); //next_power_of_2 will return a 0 as min value int ref_atlas_subdiv = GLOBAL_DEF("rendering/quality/reflections/atlas_subdiv", 8); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/reflections/atlas_subdiv", PropertyInfo(Variant::INT, "rendering/quality/reflections/atlas_subdiv", PROPERTY_HINT_RANGE, "0,32,or_greater")); //next_power_of_2 will return a 0 as min value int msaa_mode = GLOBAL_DEF("rendering/quality/filters/msaa", 0); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x")); root->set_msaa(Viewport::MSAA(msaa_mode)); @@ -2066,8 +2096,6 @@ SceneTree::SceneTree() { live_edit_root = NodePath("/root"); #endif - - use_font_oversampling = false; } SceneTree::~SceneTree() { diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index d59cbe05fb..e15a64604d 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -43,7 +43,6 @@ @author Juan Linietsky <reduzio@gmail.com> */ -class SceneTree; class PackedScene; class Node; class Viewport; @@ -153,6 +152,7 @@ private: Size2i stretch_min; real_t stretch_shrink; + void _update_font_oversampling(float p_ratio); void _update_root_rect(); List<ObjectID> delete_queue; diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index 227840531e..2ae950dad5 100755 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/timer.h b/scene/main/timer.h index 2f42252a7e..c492c6b61c 100755 --- a/scene/main/timer.h +++ b/scene/main/timer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index bb379ff4af..d86c241ec6 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -37,14 +37,15 @@ #include "scene/3d/camera.h" #include "scene/3d/collision_object.h" #include "scene/3d/listener.h" -#include "scene/3d/scenario_fx.h" #include "scene/3d/spatial.h" +#include "scene/3d/world_environment.h" #include "scene/gui/control.h" #include "scene/gui/label.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" #include "scene/gui/panel_container.h" #include "scene/gui/popup_menu.h" +#include "scene/main/canvas_layer.h" #include "scene/main/timer.h" #include "scene/resources/mesh.h" #include "scene/scene_string_names.h" @@ -147,7 +148,7 @@ void ViewportTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_viewport_path_in_scene", "path"), &ViewportTexture::set_viewport_path_in_scene); ClassDB::bind_method(D_METHOD("get_viewport_path_in_scene"), &ViewportTexture::get_viewport_path_in_scene); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "viewport_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Viewport"), "set_viewport_path_in_scene", "get_viewport_path_in_scene"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "viewport_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Viewport", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT), "set_viewport_path_in_scene", "get_viewport_path_in_scene"); } ViewportTexture::ViewportTexture() { @@ -188,7 +189,7 @@ Viewport::GUI::GUI() { dragging = false; mouse_focus = NULL; mouse_click_grabber = NULL; - mouse_focus_button = -1; + mouse_focus_mask = 0; key_focus = NULL; mouse_over = NULL; @@ -231,6 +232,25 @@ void Viewport::update_worlds() { find_world()->_update(get_tree()->get_frame()); } +void Viewport::_collision_object_input_event(CollisionObject *p_object, Camera *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape, bool p_discard_empty_motion) { + + Transform object_transform = p_object->get_global_transform(); + Transform camera_transform = p_camera->get_global_transform(); + ObjectID id = p_object->get_instance_id(); + + if (p_discard_empty_motion) { + //avoid sending the event unnecessarily if nothing really changed in the context + Ref<InputEventMouseMotion> mm = p_input_event; + if (mm.is_valid() && object_transform == physics_last_object_transform && camera_transform == physics_last_camera_transform && physics_last_id == id) { + return; //discarded + } + } + p_object->_input_event(camera, p_input_event, p_pos, p_normal, p_shape); + physics_last_object_transform = object_transform; + physics_last_camera_transform = camera_transform; + physics_last_id = id; +} + void Viewport::_test_new_mouseover(ObjectID new_collider) { #ifndef _3D_DISABLED if (new_collider != physics_object_over) { @@ -402,6 +422,34 @@ void Viewport::_notification(int p_what) { PhysicsDirectSpaceState::RayResult result; Physics2DDirectSpaceState *ss2d = Physics2DServer::get_singleton()->space_get_direct_state(find_world_2d()->get_space()); + bool discard_empty_motion = false; + + { // if no motion event exists, create a new one. This is necessary because objects or camera may have moved. + // while this extra event is sent, it is checked if both camera and last object and last ID did not move. If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame + bool has_mouse_motion = false; + for (List<Ref<InputEvent> >::Element *E = physics_picking_events.front(); E; E = E->next()) { + Ref<InputEventMouseMotion> mm = E->get(); + if (mm.is_valid()) { + has_mouse_motion = true; + break; + } + } + + if (!has_mouse_motion && physics_has_last_mousepos) { + Ref<InputEventMouseMotion> mm; + mm.instance(); + mm->set_global_position(physics_last_mousepos); + mm->set_position(physics_last_mousepos); + mm->set_alt(physics_last_mouse_state.alt); + mm->set_shift(physics_last_mouse_state.shift); + mm->set_control(physics_last_mouse_state.control); + mm->set_metakey(physics_last_mouse_state.meta); + mm->set_button_mask(physics_last_mouse_state.mouse_mask); + physics_picking_events.push_back(mm); + discard_empty_motion = true; + } + } + bool motion_tested = false; while (physics_picking_events.size()) { @@ -417,13 +465,39 @@ void Viewport::_notification(int p_what) { pos = mm->get_position(); motion_tested = true; + physics_has_last_mousepos = true; physics_last_mousepos = pos; + physics_last_mouse_state.alt = mm->get_alt(); + physics_last_mouse_state.shift = mm->get_shift(); + physics_last_mouse_state.control = mm->get_control(); + physics_last_mouse_state.meta = mm->get_metakey(); + physics_last_mouse_state.mouse_mask = mm->get_button_mask(); } Ref<InputEventMouseButton> mb = ev; if (mb.is_valid()) { pos = mb->get_position(); + physics_last_mouse_state.alt = mb->get_alt(); + physics_last_mouse_state.shift = mb->get_shift(); + physics_last_mouse_state.control = mb->get_control(); + physics_last_mouse_state.meta = mb->get_metakey(); + + if (mb->is_pressed()) { + physics_last_mouse_state.mouse_mask |= (1 << (mb->get_button_index() - 1)); + } else { + physics_last_mouse_state.mouse_mask &= ~(1 << (mb->get_button_index() - 1)); + } + } + + Ref<InputEventKey> k = ev; + if (k.is_valid()) { + //only for mask + physics_last_mouse_state.alt = k->get_alt(); + physics_last_mouse_state.shift = k->get_shift(); + physics_last_mouse_state.control = k->get_control(); + physics_last_mouse_state.meta = k->get_metakey(); + continue; } Ref<InputEventScreenDrag> sd = ev; @@ -443,24 +517,39 @@ void Viewport::_notification(int p_what) { uint64_t frame = get_tree()->get_frame(); - Vector2 point = get_canvas_transform().affine_inverse().xform(pos); Physics2DDirectSpaceState::ShapeResult res[64]; - int rc = ss2d->intersect_point(point, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true); - for (int i = 0; i < rc; i++) { - - if (res[i].collider_id && res[i].collider) { - CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider); - if (co) { - - Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.find(res[i].collider_id); - if (!E) { - E = physics_2d_mouseover.insert(res[i].collider_id, frame); - co->_mouse_enter(); - } else { - E->get() = frame; - } + for (Set<CanvasLayer *>::Element *E = canvas_layers.front(); E; E = E->next()) { + Transform2D canvas_transform; + ObjectID canvas_layer_id; + if (E->get()) { + // A descendant CanvasLayer + canvas_transform = E->get()->get_transform(); + canvas_layer_id = E->get()->get_instance_id(); + } else { + // This Viewport's builtin canvas + canvas_transform = get_canvas_transform(); + canvas_layer_id = 0; + } + + Vector2 point = canvas_transform.affine_inverse().xform(pos); + + int rc = ss2d->intersect_point_on_canvas(point, canvas_layer_id, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true); + for (int i = 0; i < rc; i++) { + + if (res[i].collider_id && res[i].collider) { + CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider); + if (co) { + + Map<ObjectID, uint64_t>::Element *F = physics_2d_mouseover.find(res[i].collider_id); + if (!F) { + F = physics_2d_mouseover.insert(res[i].collider_id, frame); + co->_mouse_enter(); + } else { + F->get() = frame; + } - co->_input_event(this, ev, res[i].shape); + co->_input_event(this, ev, res[i].shape); + } } } } @@ -494,7 +583,7 @@ void Viewport::_notification(int p_what) { CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_capture)); if (co) { - co->_input_event(camera, ev, Vector3(), Vector3(), 0); + _collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0, discard_empty_motion); captured = true; if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) { physics_object_capture = 0; @@ -512,7 +601,7 @@ void Viewport::_notification(int p_what) { if (last_id) { if (ObjectDB::get_instance(last_id) && last_object) { //good, exists - last_object->_input_event(camera, ev, result.position, result.normal, result.shape); + _collision_object_input_event(last_object, camera, ev, result.position, result.normal, result.shape, discard_empty_motion); if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { physics_object_capture = last_id; } @@ -535,7 +624,7 @@ void Viewport::_notification(int p_what) { CollisionObject *co = Object::cast_to<CollisionObject>(result.collider); if (co) { - co->_input_event(camera, ev, result.position, result.normal, result.shape); + _collision_object_input_event(co, camera, ev, result.position, result.normal, result.shape, discard_empty_motion); last_object = co; last_id = result.collider_id; new_collider = last_id; @@ -555,7 +644,7 @@ void Viewport::_notification(int p_what) { } } - if (!motion_tested && camera && physics_last_mousepos != Vector2(1e20, 1e20)) { + if (!motion_tested && camera && physics_has_last_mousepos) { //test anyway for mouseenter/exit because objects might move Vector3 from = camera->project_ray_origin(physics_last_mousepos); @@ -583,15 +672,7 @@ void Viewport::_notification(int p_what) { case SceneTree::NOTIFICATION_WM_FOCUS_OUT: { if (gui.mouse_focus) { //if mouse is being pressed, send a release event - Ref<InputEventMouseButton> mb; - mb.instance(); - mb->set_position(gui.mouse_focus->get_local_mouse_position()); - mb->set_global_position(gui.mouse_focus->get_local_mouse_position()); - mb->set_button_index(gui.mouse_focus_button); - mb->set_pressed(false); - Control *c = gui.mouse_focus; - gui.mouse_focus = NULL; - c->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb); + _drop_mouse_focus(); } } break; } @@ -612,6 +693,13 @@ bool Viewport::use_arvr() { return arvr; } +void Viewport::update_canvas_items() { + if (!is_inside_tree()) + return; + + _update_canvas_items(this); +} + void Viewport::set_size(const Size2 &p_size) { if (size == p_size.floor()) @@ -629,10 +717,8 @@ Rect2 Viewport::get_visible_rect() const { Rect2 r; if (size == Size2()) { - - r = Rect2(Point2(), Size2(OS::get_singleton()->get_window_size().width, OS::get_singleton()->get_window_size().height)); + r = Rect2(Point2(), OS::get_singleton()->get_window_size()); } else { - r = Rect2(Point2(), size); } @@ -856,6 +942,16 @@ void Viewport::_camera_make_next_current(Camera *p_exclude) { } #endif +void Viewport::_canvas_layer_add(CanvasLayer *p_canvas_layer) { + + canvas_layers.insert(p_canvas_layer); +} + +void Viewport::_canvas_layer_remove(CanvasLayer *p_canvas_layer) { + + canvas_layers.erase(p_canvas_layer); +} + void Viewport::set_transparent_background(bool p_enable) { transparent_bg = p_enable; @@ -1039,6 +1135,26 @@ Transform2D Viewport::get_final_transform() const { return stretch_transform * global_canvas_transform; } +void Viewport::_update_canvas_items(Node *p_node) { + if (p_node != this) { + + Viewport *vp = Object::cast_to<Viewport>(p_node); + if (vp) + return; + + CanvasItem *ci = Object::cast_to<CanvasItem>(p_node); + if (ci) { + ci->update(); + } + } + + int cc = p_node->get_child_count(); + + for (int i = 0; i < cc; i++) { + _update_canvas_items(p_node->get_child(i)); + } +} + void Viewport::set_size_override(bool p_enable, const Size2 &p_size, const Vector2 &p_margin) { if (size_override == p_enable && p_size == size_override_size) @@ -1414,12 +1530,17 @@ void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu Control *control = Object::cast_to<Control>(ci); if (control) { - control->emit_signal(SceneStringNames::get_singleton()->gui_input, ev); //signal should be first, so it's possible to override an event (and then accept it) + if (control->data.mouse_filter != Control::MOUSE_FILTER_IGNORE) { + control->emit_signal(SceneStringNames::get_singleton()->gui_input, ev); //signal should be first, so it's possible to override an event (and then accept it) + } if (gui.key_event_accepted) break; if (!control->is_inside_tree()) break; - control->call_multilevel(SceneStringNames::get_singleton()->_gui_input, ev); + + if (control->data.mouse_filter != Control::MOUSE_FILTER_IGNORE) { + control->call_multilevel(SceneStringNames::get_singleton()->_gui_input, ev); + } if (!control->is_inside_tree() || control->is_set_as_toplevel()) break; @@ -1439,6 +1560,35 @@ void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu //_unblock(); } +void Viewport::_gui_call_notification(Control *p_control, int p_what) { + + CanvasItem *ci = p_control; + while (ci) { + + Control *control = Object::cast_to<Control>(ci); + if (control) { + + if (control->data.mouse_filter != Control::MOUSE_FILTER_IGNORE) { + control->notification(p_what); + } + + if (!control->is_inside_tree()) + break; + + if (!control->is_inside_tree() || control->is_set_as_toplevel()) + break; + if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP) + break; + } + + if (ci->is_set_as_toplevel()) + break; + + ci = ci->get_parent_item(); + } + + //_unblock(); +} Control *Viewport::_gui_find_control(const Point2 &p_global) { _gui_prepare_subwindows(); @@ -1585,10 +1735,10 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (mb->is_pressed()) { Size2 pos = mpos; - if (gui.mouse_focus && mb->get_button_index() != gui.mouse_focus_button) { - - //do not steal mouse focus and stuff + if (gui.mouse_focus_mask) { + //do not steal mouse focus and stuff while a focus mask exists + gui.mouse_focus_mask |= 1 << (mb->get_button_index() - 1); //add the button to the mask } else { bool is_handled = false; @@ -1597,13 +1747,13 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { while (!gui.modal_stack.empty()) { Control *top = gui.modal_stack.back()->get(); - Vector2 pos = top->get_global_transform_with_canvas().affine_inverse().xform(mpos); - if (!top->has_point(pos)) { + Vector2 pos2 = top->get_global_transform_with_canvas().affine_inverse().xform(mpos); + if (!top->has_point(pos2)) { if (top->data.modal_exclusive || top->data.modal_frame == Engine::get_singleton()->get_frames_drawn()) { //cancel event, sorry, modal exclusive EATS UP ALL //alternative, you can't pop out a window the same frame it was made modal (fixes many issues) - get_tree()->set_input_as_handled(); + set_input_as_handled(); return; // no one gets the event if exclusive NO ONE } @@ -1621,7 +1771,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } if (is_handled) { - get_tree()->set_input_as_handled(); + set_input_as_handled(); return; } @@ -1633,12 +1783,15 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { */ gui.mouse_focus = _gui_find_control(pos); - gui.mouse_focus_button = mb->get_button_index(); + gui.last_mouse_focus = gui.mouse_focus; if (!gui.mouse_focus) { + gui.mouse_focus_mask = 0; return; } + gui.mouse_focus_mask = 1 << (mb->get_button_index() - 1); + if (mb->get_button_index() == BUTTON_LEFT) { gui.drag_accum = Vector2(); gui.drag_attempted = false; @@ -1654,7 +1807,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { mb->set_position(pos); #ifdef DEBUG_ENABLED - if (ScriptDebugger::get_singleton()) { + if (ScriptDebugger::get_singleton() && gui.mouse_focus) { Array arr; arr.push_back(gui.mouse_focus->get_path()); @@ -1687,11 +1840,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } } - if (gui.mouse_focus->can_process()) { + if (gui.mouse_focus && gui.mouse_focus->can_process()) { _gui_call_input(gui.mouse_focus, mb); } - get_tree()->set_input_as_handled(); + set_input_as_handled(); if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == BUTTON_LEFT) { @@ -1736,6 +1889,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { //change mouse accordingly } + gui.mouse_focus_mask &= ~(1 << (mb->get_button_index() - 1)); //remove from mask + if (!gui.mouse_focus) { //release event is only sent if a mouse focus (previously pressed button) exists return; @@ -1751,12 +1906,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Control *mouse_focus = gui.mouse_focus; //disable mouse focus if needed before calling input, this makes popups on mouse press event work better, as the release will never be received otherwise - if (mb->get_button_index() == gui.mouse_focus_button) { + if (gui.mouse_focus_mask == 0) { gui.mouse_focus = NULL; - gui.mouse_focus_button = -1; } - if (mouse_focus->can_process()) { + if (mouse_focus && mouse_focus->can_process()) { _gui_call_input(mouse_focus, mb); } @@ -1765,7 +1919,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { gui.drag_data=Variant(); //always clear }*/ - get_tree()->set_input_as_handled(); + set_input_as_handled(); } } @@ -1799,7 +1953,14 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (gui.drag_data.get_type() != Variant::NIL) { gui.mouse_focus = NULL; + gui.mouse_focus_mask = 0; + break; } else { + if (gui.drag_preview != NULL) { + ERR_PRINT("Don't set a drag preview and return null data. Preview was deleted and drag request ignored."); + memdelete(gui.drag_preview); + gui.drag_preview = NULL; + } gui.dragging = false; } @@ -1841,15 +2002,22 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { MenuButton *popup_menu_parent = NULL; MenuButton *menu_button = Object::cast_to<MenuButton>(over); - if (popup_menu) + if (popup_menu) { popup_menu_parent = Object::cast_to<MenuButton>(popup_menu->get_parent()); + if (!popup_menu_parent) { + // Go through the parents to see if there's a MenuButton at the end. + while (Object::cast_to<PopupMenu>(popup_menu->get_parent())) { + popup_menu = Object::cast_to<PopupMenu>(popup_menu->get_parent()); + } + popup_menu_parent = Object::cast_to<MenuButton>(popup_menu->get_parent()); + } + } // If the mouse is over a menu button, this menu will open automatically // if there is already a pop-up menu open at the same hierarchical level. - if (popup_menu_parent && menu_button && - popup_menu_parent->get_icon().is_null() && - menu_button->get_icon().is_null() && - (popup_menu->get_parent()->get_parent()->is_a_parent_of(menu_button) || + if (popup_menu_parent && menu_button && popup_menu_parent->is_switch_on_hover() && + !menu_button->is_disabled() && menu_button->is_switch_on_hover() && + (popup_menu_parent->get_parent()->is_a_parent_of(menu_button) || menu_button->get_parent()->is_a_parent_of(popup_menu))) { popup_menu->notification(Control::NOTIFICATION_MODAL_CLOSE); @@ -1865,13 +2033,15 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (over != gui.mouse_over) { - if (gui.mouse_over) - gui.mouse_over->notification(Control::NOTIFICATION_MOUSE_EXIT); + if (gui.mouse_over) { + _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT); + } _gui_cancel_tooltip(); - if (over) - over->notification(Control::NOTIFICATION_MOUSE_ENTER); + if (over) { + _gui_call_notification(over, Control::NOTIFICATION_MOUSE_ENTER); + } } gui.mouse_over = over; @@ -1956,11 +2126,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { OS::get_singleton()->set_cursor_shape((OS::CursorShape)cursor_shape); - if (over->can_process()) { + if (over && over->can_process()) { _gui_call_input(over, mm); } - get_tree()->set_input_as_handled(); + set_input_as_handled(); if (gui.drag_data.get_type() != Variant::NIL && mm->get_button_mask() & BUTTON_MASK_LEFT) { @@ -2003,19 +2173,19 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { touch_event->set_position(pos); _gui_call_input(over, touch_event); } - get_tree()->set_input_as_handled(); + set_input_as_handled(); return; } - } else if (gui.mouse_focus) { + } else if (touch_event->get_index() == 0 && gui.last_mouse_focus) { - if (gui.mouse_focus->can_process()) { + if (gui.last_mouse_focus->can_process()) { touch_event = touch_event->xformed_by(Transform2D()); //make a copy touch_event->set_position(gui.focus_inv_xform.xform(pos)); - _gui_call_input(gui.mouse_focus, touch_event); + _gui_call_input(gui.last_mouse_focus, touch_event); } - get_tree()->set_input_as_handled(); + set_input_as_handled(); return; } } @@ -2043,7 +2213,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { gesture_event->set_position(pos); _gui_call_input(over, gesture_event); } - get_tree()->set_input_as_handled(); + set_input_as_handled(); return; } } @@ -2081,7 +2251,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { _gui_call_input(over, drag_event); } - get_tree()->set_input_as_handled(); + set_input_as_handled(); return; } } @@ -2103,7 +2273,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (gui.key_event_accepted) { - get_tree()->set_input_as_handled(); + set_input_as_handled(); return; } } @@ -2118,7 +2288,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { top->_modal_stack_remove(); top->hide(); // Close modal, set input as handled - get_tree()->set_input_as_handled(); + set_input_as_handled(); return; } } @@ -2167,7 +2337,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (next) { next->grab_focus(); - get_tree()->set_input_as_handled(); + set_input_as_handled(); } } } @@ -2297,7 +2467,7 @@ void Viewport::_gui_unfocus_control(Control *p_control) { void Viewport::_gui_hid_control(Control *p_control) { if (gui.mouse_focus == p_control) { - gui.mouse_focus = NULL; + _drop_mouse_focus(); } /* ??? @@ -2324,8 +2494,13 @@ void Viewport::_gui_hid_control(Control *p_control) { void Viewport::_gui_remove_control(Control *p_control) { - if (gui.mouse_focus == p_control) + if (gui.mouse_focus == p_control) { gui.mouse_focus = NULL; + gui.mouse_focus_mask = 0; + } + if (gui.last_mouse_focus == p_control) { + gui.last_mouse_focus = NULL; + } if (gui.key_focus == p_control) gui.key_focus = NULL; if (gui.mouse_over == p_control) @@ -2371,7 +2546,28 @@ void Viewport::_gui_accept_event() { gui.key_event_accepted = true; if (is_inside_tree()) - get_tree()->set_input_as_handled(); + set_input_as_handled(); +} + +void Viewport::_drop_mouse_focus() { + + Control *c = gui.mouse_focus; + int mask = gui.mouse_focus_mask; + gui.mouse_focus = NULL; + gui.mouse_focus_mask = 0; + + for (int i = 0; i < 3; i++) { + + if (mask & (1 << i)) { + Ref<InputEventMouseButton> mb; + mb.instance(); + mb->set_position(c->get_local_mouse_position()); + mb->set_global_position(c->get_local_mouse_position()); + mb->set_button_index(i + 1); + mb->set_pressed(false); + c->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb); + } + } } List<Control *>::Element *Viewport::_gui_show_modal(Control *p_control) { @@ -2383,15 +2579,8 @@ List<Control *>::Element *Viewport::_gui_show_modal(Control *p_control) { p_control->_modal_set_prev_focus_owner(0); if (gui.mouse_focus && !p_control->is_a_parent_of(gui.mouse_focus) && !gui.mouse_click_grabber) { - Ref<InputEventMouseButton> mb; - mb.instance(); - mb->set_position(gui.mouse_focus->get_local_mouse_position()); - mb->set_global_position(gui.mouse_focus->get_local_mouse_position()); - mb->set_button_index(gui.mouse_focus_button); - mb->set_pressed(false); - Control *c = gui.mouse_focus; - gui.mouse_focus = NULL; - c->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb); + + _drop_mouse_focus(); } return gui.modal_stack.back(); @@ -2421,24 +2610,45 @@ void Viewport::_post_gui_grab_click_focus() { if (gui.mouse_focus == focus_grabber) return; - Ref<InputEventMouseButton> mb; - mb.instance(); - - //send unclic + int mask = gui.mouse_focus_mask; Point2 click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos); - mb->set_position(click); - mb->set_button_index(gui.mouse_focus_button); - mb->set_pressed(false); - gui.mouse_focus->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb); + + for (int i = 0; i < 3; i++) { + + if (mask & (1 << i)) { + + Ref<InputEventMouseButton> mb; + mb.instance(); + + //send unclic + + mb->set_position(click); + mb->set_button_index(i + 1); + mb->set_pressed(false); + gui.mouse_focus->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb); + } + } gui.mouse_focus = focus_grabber; gui.focus_inv_xform = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse(); click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos); - mb->set_position(click); - mb->set_button_index(gui.mouse_focus_button); - mb->set_pressed(true); - gui.mouse_focus->call_deferred(SceneStringNames::get_singleton()->_gui_input, mb); + + for (int i = 0; i < 3; i++) { + + if (mask & (1 << i)) { + + Ref<InputEventMouseButton> mb; + mb.instance(); + + //send clic + + mb->set_position(click); + mb->set_button_index(i + 1); + mb->set_pressed(true); + gui.mouse_focus->call_deferred(SceneStringNames::get_singleton()->_gui_input, mb); + } + } } } @@ -2448,11 +2658,13 @@ void Viewport::input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(!is_inside_tree()); - if (!get_tree()->is_input_handled()) { + local_input_handled = false; + + if (!is_input_handled()) { get_tree()->_call_input_pause(input_group, "_input", p_event); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input } - if (!get_tree()->is_input_handled()) { + if (!is_input_handled()) { _gui_input_event(p_event); } //get_tree()->call_group(SceneTree::GROUP_CALL_REVERSE|SceneTree::GROUP_CALL_REALTIME|SceneTree::GROUP_CALL_MULIILEVEL,gui_input_group,"_gui_input",p_event); //special one for GUI, as controls use their own process check @@ -2475,7 +2687,10 @@ void Viewport::unhandled_input(const Ref<InputEvent> &p_event) { (Object::cast_to<InputEventMouseButton>(*p_event) || Object::cast_to<InputEventMouseMotion>(*p_event) || Object::cast_to<InputEventScreenDrag>(*p_event) || - Object::cast_to<InputEventScreenTouch>(*p_event))) { + Object::cast_to<InputEventScreenTouch>(*p_event) || + Object::cast_to<InputEventKey>(*p_event) //to remember state + + )) { physics_picking_events.push_back(p_event); } } @@ -2683,6 +2898,40 @@ bool Viewport::is_snap_controls_to_pixels_enabled() const { bool Viewport::gui_is_dragging() const { return gui.dragging; } + +void Viewport::set_input_as_handled() { + if (handle_input_locally) { + local_input_handled = true; + } else { + ERR_FAIL_COND(!is_inside_tree()); + get_tree()->set_input_as_handled(); + } +} + +bool Viewport::is_input_handled() const { + if (handle_input_locally) { + return local_input_handled; + } else { + ERR_FAIL_COND_V(!is_inside_tree(), false); + return get_tree()->is_input_handled(); + } +} + +void Viewport::set_handle_input_locally(bool p_enable) { + handle_input_locally = p_enable; +} + +bool Viewport::is_handling_input_locally() const { + return handle_input_locally; +} + +void Viewport::_validate_property(PropertyInfo &property) const { + + if (VisualServer::get_singleton()->is_low_end() && property.name == "hdr") { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + } +} + void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_use_arvr", "use"), &Viewport::set_use_arvr); @@ -2795,6 +3044,12 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_atlas_quadrant_subdiv", "quadrant", "subdiv"), &Viewport::set_shadow_atlas_quadrant_subdiv); ClassDB::bind_method(D_METHOD("get_shadow_atlas_quadrant_subdiv", "quadrant"), &Viewport::get_shadow_atlas_quadrant_subdiv); + ClassDB::bind_method(D_METHOD("set_input_as_handled"), &Viewport::set_input_as_handled); + ClassDB::bind_method(D_METHOD("is_input_handled"), &Viewport::is_input_handled); + + ClassDB::bind_method(D_METHOD("set_handle_input_locally", "enable"), &Viewport::set_handle_input_locally); + ClassDB::bind_method(D_METHOD("is_handling_input_locally"), &Viewport::is_handling_input_locally); + ClassDB::bind_method(D_METHOD("_subwindow_visibility_changed"), &Viewport::_subwindow_visibility_changed); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "arvr"), "set_use_arvr", "use_arvr"); @@ -2804,6 +3059,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world", PROPERTY_HINT_RESOURCE_TYPE, "World"), "set_world", "get_world"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", 0), "set_world_2d", "get_world_2d"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transparent_bg"), "set_transparent_background", "has_transparent_background"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally"); ADD_GROUP("Rendering", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x"), "set_msaa", "get_msaa"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr"), "set_hdr", "get_hdr"); @@ -2905,6 +3161,7 @@ Viewport::Viewport() { parent = NULL; listener = NULL; camera = NULL; + canvas_layers.insert(NULL); // This eases picking code (interpreted as the canvas of the Viewport) arvr = false; size_override = false; size_override_stretch = false; @@ -2919,7 +3176,8 @@ Viewport::Viewport() { physics_object_picking = false; physics_object_capture = 0; physics_object_over = 0; - physics_last_mousepos = Vector2(1e20, 1e20); + physics_has_last_mousepos = false; + physics_last_mousepos = Vector2(Math_INF, Math_INF); shadow_atlas_size = 0; for (int i = 0; i < 4; i++) { @@ -2945,6 +3203,7 @@ Viewport::Viewport() { //gui.tooltip_timer->force_parent_owned(); gui.tooltip_delay = GLOBAL_DEF("gui/timers/tooltip_delay_sec", 0.7); + ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/tooltip_delay_sec", PropertyInfo(Variant::REAL, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); // No negative numbers gui.tooltip = NULL; gui.tooltip_label = NULL; @@ -2952,6 +3211,8 @@ Viewport::Viewport() { gui.drag_attempted = false; gui.canvas_sort_index = 0; gui.roots_order_dirty = false; + gui.mouse_focus = NULL; + gui.last_mouse_focus = NULL; msaa = MSAA_DISABLED; hdr = true; @@ -2961,6 +3222,14 @@ Viewport::Viewport() { clear_mode = CLEAR_MODE_ALWAYS; snap_controls_to_pixels = true; + physics_last_mouse_state.alt = false; + physics_last_mouse_state.control = false; + physics_last_mouse_state.shift = false; + physics_last_mouse_state.meta = false; + physics_last_mouse_state.mouse_mask = 0; + local_input_handled = false; + handle_input_locally = true; + physics_last_id = 0; //ensures first time there will be a check } Viewport::~Viewport() { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index c1a4c0e3eb..b8b5bf07a7 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -45,10 +45,12 @@ class Camera2D; class Listener; class Control; class CanvasItem; +class CanvasLayer; class Panel; class Label; class Timer; class Viewport; +class CollisionObject; class ViewportTexture : public Texture { @@ -163,6 +165,7 @@ private: Camera *camera; Set<Camera *> cameras; + Set<CanvasLayer *> canvas_layers; RID viewport; RID current_canvas; @@ -203,7 +206,26 @@ private: List<Ref<InputEvent> > physics_picking_events; ObjectID physics_object_capture; ObjectID physics_object_over; + Transform physics_last_object_transform; + Transform physics_last_camera_transform; + ObjectID physics_last_id; + bool physics_has_last_mousepos; Vector2 physics_last_mousepos; + struct { + + bool alt; + bool control; + bool shift; + bool meta; + int mouse_mask; + + } physics_last_mouse_state; + + void _collision_object_input_event(CollisionObject *p_object, Camera *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape, bool p_discard_empty_motion); + + bool handle_input_locally; + bool local_input_handled; + void _test_new_mouseover(ObjectID new_collider); Map<ObjectID, uint64_t> physics_2d_mouseover; @@ -250,8 +272,9 @@ private: bool key_event_accepted; Control *mouse_focus; + Control *last_mouse_focus; Control *mouse_click_grabber; - int mouse_focus_button; + int mouse_focus_mask; Control *key_focus; Control *mouse_over; Control *tooltip; @@ -282,6 +305,8 @@ private: bool disable_input; void _gui_call_input(Control *p_control, const Ref<InputEvent> &p_input); + void _gui_call_notification(Control *p_control, int p_what); + void _gui_prepare_subwindows(); void _gui_sort_subwindows(); void _gui_sort_roots(); @@ -354,9 +379,18 @@ private: void _camera_remove(Camera *p_camera); void _camera_make_next_current(Camera *p_exclude); + friend class CanvasLayer; + void _canvas_layer_add(CanvasLayer *p_canvas_layer); + void _canvas_layer_remove(CanvasLayer *p_canvas_layer); + + void _drop_mouse_focus(); + + void _update_canvas_items(Node *p_node); + protected: void _notification(int p_what); static void _bind_methods(); + virtual void _validate_property(PropertyInfo &property) const; public: Listener *get_listener() const; @@ -372,6 +406,7 @@ public: bool is_audio_listener_2d() const; void set_size(const Size2 &p_size); + void update_canvas_items(); Size2 get_size() const; Rect2 get_visible_rect() const; @@ -475,6 +510,12 @@ public: void _subwindow_visibility_changed(); + void set_input_as_handled(); + bool is_input_handled() const; + + void set_handle_input_locally(bool p_enable); + bool is_handling_input_locally() const; + bool gui_is_dragging() const; Viewport(); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 97230d422b..49c9c4c23c 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -48,7 +48,7 @@ #include "scene/2d/light_occluder_2d.h" #include "scene/2d/line_2d.h" #include "scene/2d/mesh_instance_2d.h" -#include "scene/2d/navigation2d.h" +#include "scene/2d/navigation_2d.h" #include "scene/2d/parallax_background.h" #include "scene/2d/parallax_layer.h" #include "scene/2d/particles_2d.h" @@ -58,10 +58,10 @@ #include "scene/2d/position_2d.h" #include "scene/2d/ray_cast_2d.h" #include "scene/2d/remote_transform_2d.h" -#include "scene/2d/screen_button.h" #include "scene/2d/skeleton_2d.h" #include "scene/2d/sprite.h" #include "scene/2d/tile_map.h" +#include "scene/2d/touch_screen_button.h" #include "scene/2d/visibility_notifier_2d.h" #include "scene/2d/y_sort.h" #include "scene/animation/animation_blend_space_1d.h" @@ -73,7 +73,7 @@ #include "scene/animation/animation_tree_player.h" #include "scene/animation/root_motion_view.h" #include "scene/animation/tween.h" -#include "scene/audio/audio_player.h" +#include "scene/audio/audio_stream_player.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" #include "scene/gui/center_container.h" @@ -125,12 +125,11 @@ #include "scene/main/timer.h" #include "scene/main/viewport.h" #include "scene/resources/audio_stream_sample.h" -#include "scene/resources/bit_mask.h" +#include "scene/resources/bit_map.h" #include "scene/resources/box_shape.h" #include "scene/resources/capsule_shape.h" #include "scene/resources/capsule_shape_2d.h" #include "scene/resources/circle_shape_2d.h" -#include "scene/resources/color_ramp.h" #include "scene/resources/concave_polygon_shape.h" #include "scene/resources/concave_polygon_shape_2d.h" #include "scene/resources/convex_polygon_shape.h" @@ -139,21 +138,23 @@ #include "scene/resources/default_theme/default_theme.h" #include "scene/resources/dynamic_font.h" #include "scene/resources/dynamic_font_stb.h" +#include "scene/resources/gradient.h" +#include "scene/resources/line_shape_2d.h" #include "scene/resources/material.h" #include "scene/resources/mesh.h" #include "scene/resources/mesh_data_tool.h" #include "scene/resources/mesh_library.h" #include "scene/resources/packed_scene.h" #include "scene/resources/particles_material.h" +#include "scene/resources/physics_material.h" #include "scene/resources/plane_shape.h" #include "scene/resources/polygon_path_finder.h" #include "scene/resources/primitive_meshes.h" #include "scene/resources/ray_shape.h" #include "scene/resources/rectangle_shape_2d.h" -#include "scene/resources/scene_format_text.h" +#include "scene/resources/resource_format_text.h" #include "scene/resources/segment_shape_2d.h" -#include "scene/resources/shape_line_2d.h" -#include "scene/resources/sky_box.h" +#include "scene/resources/sky.h" #include "scene/resources/sphere_shape.h" #include "scene/resources/surface_tool.h" #include "scene/resources/text_file.h" @@ -166,8 +167,8 @@ #include "scene/resources/world_2d.h" #include "scene/scene_string_names.h" -#include "scene/3d/scenario_fx.h" #include "scene/3d/spatial.h" +#include "scene/3d/world_environment.h" #ifndef _3D_DISABLED #include "scene/3d/area.h" @@ -207,23 +208,20 @@ #include "scene/3d/visibility_notifier.h" #include "scene/animation/skeleton_ik.h" #include "scene/resources/environment.h" -#include "scene/resources/physics_material.h" #endif -static ResourceFormatLoaderTheme *resource_loader_theme = NULL; +static Ref<ResourceFormatSaverText> resource_saver_text; +static Ref<ResourceFormatLoaderText> resource_loader_text; -static ResourceFormatSaverText *resource_saver_text = NULL; -static ResourceFormatLoaderText *resource_loader_text = NULL; +static Ref<ResourceFormatLoaderDynamicFont> resource_loader_dynamic_font; -static ResourceFormatLoaderDynamicFont *resource_loader_dynamic_font = NULL; +static Ref<ResourceFormatLoaderStreamTexture> resource_loader_stream_texture; +static Ref<ResourceFormatLoaderTextureLayered> resource_loader_texture_layered; -static ResourceFormatLoaderStreamTexture *resource_loader_stream_texture = NULL; -static ResourceFormatLoaderTextureLayered *resource_loader_texture_layered = NULL; +static Ref<ResourceFormatLoaderBMFont> resource_loader_bmfont; -static ResourceFormatLoaderBMFont *resource_loader_bmfont = NULL; - -static ResourceFormatSaverShader *resource_saver_shader = NULL; -static ResourceFormatLoaderShader *resource_loader_shader = NULL; +static Ref<ResourceFormatSaverShader> resource_saver_shader; +static Ref<ResourceFormatLoaderShader> resource_loader_shader; void register_scene_types() { @@ -233,31 +231,28 @@ void register_scene_types() { Node::init_node_hrcr(); - resource_loader_dynamic_font = memnew(ResourceFormatLoaderDynamicFont); + resource_loader_dynamic_font.instance(); ResourceLoader::add_resource_format_loader(resource_loader_dynamic_font); - resource_loader_stream_texture = memnew(ResourceFormatLoaderStreamTexture); + resource_loader_stream_texture.instance(); ResourceLoader::add_resource_format_loader(resource_loader_stream_texture); - resource_loader_texture_layered = memnew(ResourceFormatLoaderTextureLayered); + resource_loader_texture_layered.instance(); ResourceLoader::add_resource_format_loader(resource_loader_texture_layered); - resource_loader_theme = memnew(ResourceFormatLoaderTheme); - ResourceLoader::add_resource_format_loader(resource_loader_theme); - - resource_saver_text = memnew(ResourceFormatSaverText); + resource_saver_text.instance(); ResourceSaver::add_resource_format_saver(resource_saver_text, true); - resource_loader_text = memnew(ResourceFormatLoaderText); + resource_loader_text.instance(); ResourceLoader::add_resource_format_loader(resource_loader_text, true); - resource_saver_shader = memnew(ResourceFormatSaverShader); + resource_saver_shader.instance(); ResourceSaver::add_resource_format_saver(resource_saver_shader, true); - resource_loader_shader = memnew(ResourceFormatLoaderShader); + resource_loader_shader.instance(); ResourceLoader::add_resource_format_loader(resource_loader_shader, true); - resource_loader_bmfont = memnew(ResourceFormatLoaderBMFont); + resource_loader_bmfont.instance(); ResourceLoader::add_resource_format_loader(resource_loader_bmfont, true); OS::get_singleton()->yield(); //may take time to init @@ -457,7 +452,6 @@ void register_scene_types() { ClassDB::register_class<Curve3D>(); ClassDB::register_class<Path>(); ClassDB::register_class<PathFollow>(); - ClassDB::register_class<OrientedPathFollow>(); ClassDB::register_class<VisibilityNotifier>(); ClassDB::register_class<VisibilityEnabler>(); ClassDB::register_class<WorldEnvironment>(); @@ -608,8 +602,8 @@ void register_scene_types() { ClassDB::register_class<SpatialVelocityTracker>(); - ClassDB::register_class<PhysicsMaterial>(); #endif + ClassDB::register_class<PhysicsMaterial>(); ClassDB::register_class<World>(); ClassDB::register_class<Environment>(); ClassDB::register_class<World2D>(); @@ -740,29 +734,31 @@ void unregister_scene_types() { clear_default_theme(); - memdelete(resource_loader_dynamic_font); - memdelete(resource_loader_stream_texture); - memdelete(resource_loader_texture_layered); - memdelete(resource_loader_theme); + ResourceLoader::remove_resource_format_loader(resource_loader_dynamic_font); + resource_loader_dynamic_font.unref(); + + ResourceLoader::remove_resource_format_loader(resource_loader_texture_layered); + resource_loader_texture_layered.unref(); + + ResourceLoader::remove_resource_format_loader(resource_loader_stream_texture); + resource_loader_stream_texture.unref(); DynamicFont::finish_dynamic_fonts(); - if (resource_saver_text) { - memdelete(resource_saver_text); - } - if (resource_loader_text) { - memdelete(resource_loader_text); - } + ResourceSaver::remove_resource_format_saver(resource_saver_text); + resource_saver_text.unref(); - if (resource_saver_shader) { - memdelete(resource_saver_shader); - } - if (resource_loader_shader) { - memdelete(resource_loader_shader); - } - if (resource_loader_bmfont) { - memdelete(resource_loader_bmfont); - } + ResourceLoader::remove_resource_format_loader(resource_loader_text); + resource_loader_text.unref(); + + ResourceSaver::remove_resource_format_saver(resource_saver_shader); + resource_saver_shader.unref(); + + ResourceLoader::remove_resource_format_loader(resource_loader_shader); + resource_loader_shader.unref(); + + ResourceLoader::remove_resource_format_loader(resource_loader_bmfont); + resource_loader_bmfont.unref(); SpatialMaterial::finish_shaders(); ParticlesMaterial::finish_shaders(); diff --git a/scene/register_scene_types.h b/scene/register_scene_types.h index 9121c015fd..3645f88807 100644 --- a/scene/register_scene_types.h +++ b/scene/register_scene_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 5c01cadcd5..3eb16c544c 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,6 +29,7 @@ /*************************************************************************/ #include "animation.h" +#include "scene/scene_string_names.h" #include "core/math/geometry.h" @@ -268,19 +269,19 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { for (int i = 0; i < valcount; i++) { - Dictionary d = clips[i]; - if (!d.has("start_offset")) + Dictionary d2 = clips[i]; + if (!d2.has("start_offset")) continue; - if (!d.has("end_offset")) + if (!d2.has("end_offset")) continue; - if (!d.has("stream")) + if (!d2.has("stream")) continue; TKey<AudioKey> ak; ak.time = rt[i]; - ak.value.start_offset = d["start_offset"]; - ak.value.end_offset = d["end_offset"]; - ak.value.stream = d["stream"]; + ak.value.start_offset = d2["start_offset"]; + ak.value.end_offset = d2["end_offset"]; + ak.value.stream = d2["stream"]; ad->values.push_back(ak); } @@ -668,6 +669,7 @@ int Animation::add_track(TrackType p_type, int p_at_pos) { } } emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); return p_at_pos; } @@ -719,6 +721,7 @@ void Animation::remove_track(int p_track) { memdelete(t); tracks.remove(p_track); emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); } int Animation::get_track_count() const { @@ -737,6 +740,7 @@ void Animation::track_set_path(int p_track, const NodePath &p_path) { ERR_FAIL_INDEX(p_track, tracks.size()); tracks[p_track]->path = p_path; emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); } NodePath Animation::track_get_path(int p_track) const { @@ -1410,6 +1414,8 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p } break; } + + emit_changed(); } void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_transition) { @@ -1445,6 +1451,8 @@ void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_tra // they don't use transition } break; } + + emit_changed(); } template <class K> @@ -1469,7 +1477,7 @@ int Animation::_find(const Vector<K> &p_keys, float p_time) const { middle = (low + high) / 2; - if (p_time == keys[middle].time) { //match + if (Math::abs(p_time - keys[middle].time) < CMP_EPSILON) { //match return middle; } else if (p_time < keys[middle].time) high = middle - 1; //search low end of array @@ -1815,7 +1823,7 @@ Variant Animation::value_track_interpolate(int p_track, float p_time) const { bool ok = false; - Variant res = _interpolate(vt->values, p_time, vt->update_mode == UPDATE_CONTINUOUS ? vt->interpolation : INTERPOLATION_NEAREST, vt->loop_wrap, &ok); + Variant res = _interpolate(vt->values, p_time, (vt->update_mode == UPDATE_CONTINUOUS || vt->update_mode == UPDATE_CAPTURE) ? vt->interpolation : INTERPOLATION_NEAREST, vt->loop_wrap, &ok); if (ok) { @@ -1828,9 +1836,14 @@ Variant Animation::value_track_interpolate(int p_track, float p_time) const { void Animation::_value_track_get_key_indices_in_range(const ValueTrack *vt, float from_time, float to_time, List<int> *p_indices) const { if (from_time != length && to_time == length) - to_time = length * 1.01; //include a little more if at the end + to_time = length * 1.001; //include a little more if at the end int to = _find(vt->values, to_time); + if (to >= 0 && from_time == to_time && vt->values[to].time == from_time) { + //find exact (0 delta), return if found + p_indices->push_back(to); + return; + } // can't really send the events == time, will be sent in the next frame. // if event>=len then it will probably never be requested by the anim player. @@ -1876,7 +1889,7 @@ void Animation::value_track_get_key_indices(int p_track, float p_time, float p_d if (from_time > to_time) { // handle loop by splitting - _value_track_get_key_indices_in_range(vt, length - from_time, length, p_indices); + _value_track_get_key_indices_in_range(vt, from_time, length, p_indices); _value_track_get_key_indices_in_range(vt, 0, to_time, p_indices); return; } @@ -2332,7 +2345,7 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const { float duration = bt->values[idx + 1].time - bt->values[idx].time; // time duration between our two keyframes float low = 0; // 0% of the current animation segment float high = 1; // 100% of the current animation segment - float middle = 0; + float middle; Vector2 start(0, bt->values[idx].value.value); Vector2 start_out = start + bt->values[idx].value.out_handle; @@ -2554,6 +2567,7 @@ void Animation::track_move_up(int p_track) { } emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); } void Animation::track_set_imported(int p_track, bool p_imported) { @@ -2588,6 +2602,7 @@ void Animation::track_move_down(int p_track) { SWAP(tracks.write[p_track], tracks.write[p_track - 1]); } emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); } void Animation::track_swap(int p_track, int p_with_track) { @@ -2598,6 +2613,7 @@ void Animation::track_swap(int p_track, int p_with_track) { return; SWAP(tracks.write[p_track], tracks.write[p_with_track]); emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); } void Animation::set_step(float p_step) { @@ -2716,6 +2732,8 @@ void Animation::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "step", PROPERTY_HINT_RANGE, "0,4096,0.001"), "set_step", "get_step"); + ADD_SIGNAL(MethodInfo("tracks_changed")); + BIND_ENUM_CONSTANT(TYPE_VALUE); BIND_ENUM_CONSTANT(TYPE_TRANSFORM); BIND_ENUM_CONSTANT(TYPE_METHOD); @@ -2740,6 +2758,8 @@ void Animation::clear() { tracks.clear(); loop = false; length = 1; + emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); } bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, const TKey<TransformKey> &t1, const TKey<TransformKey> &t2, float p_alowed_linear_err, float p_alowed_angular_err, float p_max_optimizable_angle, const Vector3 &p_norm) { diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 6eec2c8bc7..b66ae184e9 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp index 9ee85b64b6..a89cf108bc 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_sample.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -249,6 +249,10 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in int32_t todo = p_frames; + if (base->loop_mode == AudioStreamSample::LOOP_BACKWARD) { + sign = -1; + } + float base_rate = AudioServer::get_singleton()->get_mix_rate(); float srate = base->mix_rate; srate *= p_rate_scale; @@ -621,7 +625,7 @@ void AudioStreamSample::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data"); ADD_PROPERTY(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_ENUM, "8-Bit,16-Bit,IMA-ADPCM"), "set_format", "get_format"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode", PROPERTY_HINT_ENUM, "Disabled,Forward,Ping-Pong"), "set_loop_mode", "get_loop_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode", PROPERTY_HINT_ENUM, "Disabled,Forward,Ping-Pong,Backward"), "set_loop_mode", "get_loop_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_begin"), "set_loop_begin", "get_loop_begin"); ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_end"), "set_loop_end", "get_loop_end"); ADD_PROPERTY(PropertyInfo(Variant::INT, "mix_rate"), "set_mix_rate", "get_mix_rate"); @@ -634,6 +638,7 @@ void AudioStreamSample::_bind_methods() { BIND_ENUM_CONSTANT(LOOP_DISABLED); BIND_ENUM_CONSTANT(LOOP_FORWARD); BIND_ENUM_CONSTANT(LOOP_PING_PONG); + BIND_ENUM_CONSTANT(LOOP_BACKWARD); } AudioStreamSample::AudioStreamSample() { diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h index a27acc92b7..bd701ddd12 100644 --- a/scene/resources/audio_stream_sample.h +++ b/scene/resources/audio_stream_sample.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -94,7 +94,8 @@ public: enum LoopMode { LOOP_DISABLED, LOOP_FORWARD, - LOOP_PING_PONG + LOOP_PING_PONG, + LOOP_BACKWARD }; private: diff --git a/scene/resources/bit_mask.cpp b/scene/resources/bit_map.cpp index 56b236d03b..d2e4d28b44 100644 --- a/scene/resources/bit_mask.cpp +++ b/scene/resources/bit_map.cpp @@ -1,12 +1,12 @@ /*************************************************************************/ -/* bit_mask.cpp */ +/* bit_map.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "bit_mask.h" +#include "bit_map.h" #include "core/io/image_loader.h" @@ -332,7 +332,7 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) prevx = stepx; prevy = stepy; - ERR_FAIL_COND_V(count > width * height, _points); + ERR_FAIL_COND_V((int)count > width * height, _points); } while (curx != startx || cury != starty); return _points; } @@ -432,8 +432,8 @@ static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_ int stack_size = 0; Point2i pos = p_pos; - int next_i; - int next_j; + int next_i = 0; + int next_j = 0; bool reenter = true; bool popped = false; @@ -602,7 +602,7 @@ void BitMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bit", "position", "bit"), &BitMap::set_bit); ClassDB::bind_method(D_METHOD("get_bit", "position"), &BitMap::get_bit); - ClassDB::bind_method(D_METHOD("set_bit_rect", "p_rect", "bit"), &BitMap::set_bit_rect); + ClassDB::bind_method(D_METHOD("set_bit_rect", "rect", "bit"), &BitMap::set_bit_rect); ClassDB::bind_method(D_METHOD("get_true_bit_count"), &BitMap::get_true_bit_count); ClassDB::bind_method(D_METHOD("get_size"), &BitMap::get_size); diff --git a/scene/resources/bit_mask.h b/scene/resources/bit_map.h index 04191a7774..b3c86afd38 100644 --- a/scene/resources/bit_mask.h +++ b/scene/resources/bit_map.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* bit_mask.h */ +/* bit_map.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BIT_MASK_H -#define BIT_MASK_H +#ifndef BIT_MAP_H +#define BIT_MAP_H #include "core/image.h" #include "core/io/resource_loader.h" @@ -72,4 +72,4 @@ public: BitMap(); }; -#endif // BIT_MASK_H +#endif // BIT_MAP_H diff --git a/scene/resources/bounds.cpp b/scene/resources/bounds.cpp deleted file mode 100644 index b115d92be3..0000000000 --- a/scene/resources/bounds.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************/ -/* bounds.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "bounds.h" - -void Bounds::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_bsp_tree", "bsp_tree"), &Bounds::set_bsp_tree); - ClassDB::bind_method(D_METHOD("get_bsp_tree"), &Bounds::get_bsp_tree); - - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "bsp_tree"), "set_bsp_tree", "get_bsp_tree"); -} - -void Bounds::set_bsp_tree(const BSP_Tree &p_bsp_tree) { - - bsp_tree = p_bsp_tree; -} - -BSP_Tree Bounds::get_bsp_tree() const { - - return bsp_tree; -} - -Bounds::Bounds() { -} diff --git a/scene/resources/bounds.h b/scene/resources/bounds.h deleted file mode 100644 index c86e15ae40..0000000000 --- a/scene/resources/bounds.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************/ -/* bounds.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef BOUNDS_H -#define BOUNDS_H - -#include "core/math/bsp_tree.h" -#include "core/resource.h" - -class Bounds : public Resource { - - GDCLASS(Bounds, Resource); - BSP_Tree bsp_tree; - -protected: - static void _bind_methods(); - -public: - void set_bsp_tree(const BSP_Tree &p_bsp_tree); - BSP_Tree get_bsp_tree() const; - - Bounds(); -}; - -#endif // BOUNDS_H diff --git a/scene/resources/box_shape.cpp b/scene/resources/box_shape.cpp index e9e01ed98a..d93754076c 100644 --- a/scene/resources/box_shape.cpp +++ b/scene/resources/box_shape.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/box_shape.h b/scene/resources/box_shape.h index 5ef16b4766..42d54310a8 100644 --- a/scene/resources/box_shape.h +++ b/scene/resources/box_shape.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/canvas.cpp b/scene/resources/canvas.cpp index 8da1da9541..0fc8b22046 100644 --- a/scene/resources/canvas.cpp +++ b/scene/resources/canvas.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/canvas.h b/scene/resources/canvas.h index cd37ea3583..4324b6227c 100644 --- a/scene/resources/canvas.h +++ b/scene/resources/canvas.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/capsule_shape.cpp b/scene/resources/capsule_shape.cpp index 101970bad8..3f7bf1e0ec 100644 --- a/scene/resources/capsule_shape.cpp +++ b/scene/resources/capsule_shape.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/capsule_shape.h b/scene/resources/capsule_shape.h index f89d07c5f1..6bca53f783 100644 --- a/scene/resources/capsule_shape.h +++ b/scene/resources/capsule_shape.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp index 95ab34abb2..fde05bfb7f 100644 --- a/scene/resources/capsule_shape_2d.cpp +++ b/scene/resources/capsule_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/capsule_shape_2d.h b/scene/resources/capsule_shape_2d.h index 04d663c010..3bedf7618d 100644 --- a/scene/resources/capsule_shape_2d.h +++ b/scene/resources/capsule_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp index 1c7bb76b26..76c1440861 100644 --- a/scene/resources/circle_shape_2d.cpp +++ b/scene/resources/circle_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/circle_shape_2d.h b/scene/resources/circle_shape_2d.h index 06bb433170..e2624ac8ed 100644 --- a/scene/resources/circle_shape_2d.h +++ b/scene/resources/circle_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/concave_polygon_shape.cpp b/scene/resources/concave_polygon_shape.cpp index bc9e2848b3..b192d088d8 100644 --- a/scene/resources/concave_polygon_shape.cpp +++ b/scene/resources/concave_polygon_shape.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/concave_polygon_shape.h b/scene/resources/concave_polygon_shape.h index 2cc9095abf..1b8ddfc308 100644 --- a/scene/resources/concave_polygon_shape.h +++ b/scene/resources/concave_polygon_shape.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp index d4343680ef..51dd91fff5 100644 --- a/scene/resources/concave_polygon_shape_2d.cpp +++ b/scene/resources/concave_polygon_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/concave_polygon_shape_2d.h b/scene/resources/concave_polygon_shape_2d.h index e8fa7369ac..8e3267dc2a 100644 --- a/scene/resources/concave_polygon_shape_2d.h +++ b/scene/resources/concave_polygon_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/convex_polygon_shape.cpp b/scene/resources/convex_polygon_shape.cpp index 39488760cd..98d3460ed2 100644 --- a/scene/resources/convex_polygon_shape.cpp +++ b/scene/resources/convex_polygon_shape.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/convex_polygon_shape.h b/scene/resources/convex_polygon_shape.h index 62567fc031..5c192476d3 100644 --- a/scene/resources/convex_polygon_shape.h +++ b/scene/resources/convex_polygon_shape.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp index f325af7ea4..f275405de2 100644 --- a/scene/resources/convex_polygon_shape_2d.cpp +++ b/scene/resources/convex_polygon_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -41,7 +41,11 @@ bool ConvexPolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, dou void ConvexPolygonShape2D::_update_shape() { - Physics2DServer::get_singleton()->shape_set_data(get_rid(), points); + Vector<Vector2> final_points = points; + if (Geometry::is_polygon_clockwise(final_points)) { //needs to be counter clockwise + final_points.invert(); + } + Physics2DServer::get_singleton()->shape_set_data(get_rid(), final_points); emit_changed(); } @@ -55,6 +59,7 @@ void ConvexPolygonShape2D::set_point_cloud(const Vector<Vector2> &p_points) { void ConvexPolygonShape2D::set_points(const Vector<Vector2> &p_points) { points = p_points; + _update_shape(); } diff --git a/scene/resources/convex_polygon_shape_2d.h b/scene/resources/convex_polygon_shape_2d.h index 69c237a0e6..8625b800ed 100644 --- a/scene/resources/convex_polygon_shape_2d.h +++ b/scene/resources/convex_polygon_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index 9188d890f7..464ca60d31 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -761,8 +761,8 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const { //validate// int pc = baked_point_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No points in Curve2D"); - ERR_FAIL_COND_V(pc == 0, Vector2()); + ERR_EXPLAIN("No points in Curve2D."); + ERR_FAIL_V(Vector2()); } if (pc == 1) @@ -826,8 +826,8 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const { //validate// int pc = baked_point_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No points in Curve2D"); - ERR_FAIL_COND_V(pc == 0, Vector2()); + ERR_EXPLAIN("No points in Curve2D."); + ERR_FAIL_V(Vector2()); } if (pc == 1) @@ -865,8 +865,8 @@ float Curve2D::get_closest_offset(const Vector2 &p_to_point) const { //validate// int pc = baked_point_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No points in Curve2D"); - ERR_FAIL_COND_V(pc == 0, 0.0f); + ERR_EXPLAIN("No points in Curve2D."); + ERR_FAIL_V(0.0f); } if (pc == 1) @@ -1331,8 +1331,8 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const { //validate// int pc = baked_point_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No points in Curve3D"); - ERR_FAIL_COND_V(pc == 0, Vector3()); + ERR_EXPLAIN("No points in Curve3D."); + ERR_FAIL_V(Vector3()); } if (pc == 1) @@ -1375,8 +1375,8 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const { //validate// int pc = baked_tilt_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No tilts in Curve3D"); - ERR_FAIL_COND_V(pc == 0, 0); + ERR_EXPLAIN("No tilts in Curve3D."); + ERR_FAIL_V(0); } if (pc == 1) @@ -1413,8 +1413,8 @@ Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt) // curve may not have baked up vectors int count = baked_up_vector_cache.size(); if (count == 0) { - ERR_EXPLAIN("No up vectors in Curve3D"); - ERR_FAIL_COND_V(count == 0, Vector3(0, 1, 0)); + ERR_EXPLAIN("No up vectors in Curve3D."); + ERR_FAIL_V(Vector3(0, 1, 0)); } if (count == 1) @@ -1484,8 +1484,8 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const { //validate// int pc = baked_point_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No points in Curve3D"); - ERR_FAIL_COND_V(pc == 0, Vector3()); + ERR_EXPLAIN("No points in Curve3D."); + ERR_FAIL_V(Vector3()); } if (pc == 1) @@ -1523,8 +1523,8 @@ float Curve3D::get_closest_offset(const Vector3 &p_to_point) const { //validate// int pc = baked_point_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No points in Curve3D"); - ERR_FAIL_COND_V(pc == 0, 0.0f); + ERR_EXPLAIN("No points in Curve3D."); + ERR_FAIL_V(0.0f); } if (pc == 1) diff --git a/scene/resources/curve.h b/scene/resources/curve.h index 234e3a6779..911a440567 100644 --- a/scene/resources/curve.h +++ b/scene/resources/curve.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/cylinder_shape.cpp b/scene/resources/cylinder_shape.cpp index f760462d49..4fd829b349 100644 --- a/scene/resources/cylinder_shape.cpp +++ b/scene/resources/cylinder_shape.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/cylinder_shape.h b/scene/resources/cylinder_shape.h index f510758e91..58a4f5a817 100644 --- a/scene/resources/cylinder_shape.h +++ b/scene/resources/cylinder_shape.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 4de47b2cb0..c7a815d8a4 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -307,10 +307,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("hseparation", "MenuButton", 3 * scale); - // ButtonGroup - - theme->set_stylebox("panel", "ButtonGroup", memnew(StyleBoxEmpty)); - // CheckBox Ref<StyleBox> cbx_empty = memnew(StyleBoxEmpty); @@ -604,6 +600,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_icon("resizer", "GraphNode", make_icon(window_resizer_png)); theme->set_font("title_font", "GraphNode", default_font); theme->set_color("title_color", "GraphNode", Color(0, 0, 0, 1)); + theme->set_color("close_color", "GraphNode", Color(0, 0, 0, 1)); theme->set_constant("title_offset", "GraphNode", 20 * scale); theme->set_constant("close_offset", "GraphNode", 18 * scale); theme->set_constant("port_offset", "GraphNode", 3 * scale); @@ -653,6 +650,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("item_margin", "Tree", 12 * scale); theme->set_constant("button_margin", "Tree", 4 * scale); theme->set_constant("draw_relationship_lines", "Tree", 0); + theme->set_constant("draw_guides", "Tree", 1); theme->set_constant("scroll_border", "Tree", 4); theme->set_constant("scroll_speed", "Tree", 12); @@ -684,6 +682,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("tab_fg", "TabContainer", sb_expand(make_stylebox(tab_current_png, 4, 4, 4, 1, 16, 4, 16, 4), 2, 2, 2, 2)); theme->set_stylebox("tab_bg", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); + theme->set_stylebox("tab_disabled", "TabContainer", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); theme->set_stylebox("panel", "TabContainer", tc_sb); theme->set_icon("increment", "TabContainer", make_icon(scroll_button_right_png)); @@ -709,6 +708,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("tab_fg", "Tabs", sb_expand(make_stylebox(tab_current_png, 4, 3, 4, 1, 16, 3, 16, 2), 2, 2, 2, 2)); theme->set_stylebox("tab_bg", "Tabs", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3)); + theme->set_stylebox("tab_disabled", "Tabs", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); theme->set_stylebox("panel", "Tabs", tc_sb); theme->set_stylebox("button_pressed", "Tabs", make_stylebox(button_pressed_png, 4, 4, 4, 4)); theme->set_stylebox("button", "Tabs", make_stylebox(button_normal_png, 4, 4, 4, 4)); diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h index 8f211af35b..cbf0cc1b79 100644 --- a/scene/resources/default_theme/default_theme.h +++ b/scene/resources/default_theme/default_theme.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/default_theme/error_icon.png b/scene/resources/default_theme/error_icon.png Binary files differindex 7741d00749..00680db5df 100644 --- a/scene/resources/default_theme/error_icon.png +++ b/scene/resources/default_theme/error_icon.png diff --git a/scene/resources/default_theme/tab_disabled.png b/scene/resources/default_theme/tab_disabled.png Binary files differnew file mode 100644 index 0000000000..97157a58dd --- /dev/null +++ b/scene/resources/default_theme/tab_disabled.png diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 353e7eddbe..2b251e5f81 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -71,7 +71,7 @@ static const unsigned char dropdown_png[] = { }; static const unsigned char error_icon_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x4, 0x0, 0x0, 0x0, 0xd9, 0x73, 0xb2, 0x7f, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x36, 0x18, 0x5, 0xa3, 0x60, 0x14, 0xfc, 0x87, 0x40, 0x38, 0xb, 0x21, 0x6, 0x6, 0x18, 0x62, 0x98, 0x6, 0xa0, 0xb1, 0xfe, 0xe3, 0x67, 0xd1, 0xc2, 0x0, 0x10, 0xc4, 0xc5, 0x82, 0x91, 0x43, 0xc0, 0xb, 0xb8, 0x15, 0x63, 0x78, 0x6, 0x5, 0x8c, 0x82, 0x51, 0x30, 0xa, 0x0, 0x35, 0xa3, 0x4c, 0xb4, 0x7c, 0x8a, 0x7, 0x6, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe2, 0xb, 0xf, 0x0, 0x22, 0x18, 0xc, 0x35, 0xef, 0x18, 0x0, 0x0, 0x0, 0xe, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x0, 0x1, 0x0, 0x2, 0x10, 0x0, 0x1, 0x14, 0xc2, 0xc0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char focus_png[] = { @@ -386,6 +386,10 @@ static const unsigned char tab_current_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x99, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3d, 0x48, 0x5b, 0x58, 0x66, 0x5b, 0x57, 0x65, 0x57, 0x54, 0x62, 0x55, 0x53, 0x62, 0x4a, 0x46, 0x52, 0x46, 0x41, 0x4e, 0x45, 0x41, 0x4d, 0x55, 0x52, 0x60, 0x44, 0x41, 0x4c, 0x53, 0x50, 0x5e, 0x43, 0x40, 0x4b, 0x52, 0x4e, 0x5d, 0x41, 0x3e, 0x4a, 0x4f, 0x4d, 0x5a, 0x3f, 0x3d, 0x48, 0x4e, 0x4b, 0x59, 0x3e, 0x3c, 0x47, 0x4d, 0x4a, 0x58, 0x3d, 0x3b, 0x46, 0x4b, 0x49, 0x54, 0x3c, 0x3a, 0x44, 0x4b, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x3b, 0x39, 0x42, 0x3b, 0x38, 0x43, 0x3b, 0x38, 0x42, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3a, 0x38, 0x41, 0x39, 0x36, 0x3f, 0x38, 0x36, 0x3f, 0x39, 0x36, 0x40, 0x38, 0x36, 0x40, 0x37, 0x35, 0x3e, 0x37, 0x34, 0x3e, 0x36, 0x35, 0x3d, 0xd7, 0x41, 0xa4, 0x19, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xa3, 0x31, 0x6b, 0xc2, 0x0, 0x0, 0x0, 0x60, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x55, 0xca, 0x85, 0xd, 0xc0, 0x40, 0x14, 0xc3, 0x50, 0x27, 0xf7, 0xd5, 0xfd, 0xd7, 0x2d, 0xa6, 0x4c, 0x16, 0x3f, 0xb9, 0xd0, 0x11, 0x90, 0xa3, 0x52, 0x77, 0x49, 0x8e, 0x86, 0xd2, 0x26, 0x16, 0x7b, 0x59, 0x32, 0x68, 0x3, 0x37, 0x5d, 0xe0, 0x59, 0x3b, 0x74, 0x31, 0x67, 0x4b, 0x3b, 0xf, 0x71, 0xe5, 0xe8, 0xf, 0xec, 0xc0, 0x1f, 0x28, 0xf8, 0x2, 0x14, 0xf9, 0x42, 0xa8, 0xfc, 0x21, 0x3b, 0xe4, 0x1, 0x6f, 0x0, 0x18, 0x11, 0xac, 0x99, 0xc0, 0xe, 0x25, 0x22, 0x2d, 0x76, 0xc6, 0x13, 0x1a, 0x8, 0xac, 0x78, 0xfc, 0x1c, 0x70, 0x30, 0x2b, 0xba, 0xe9, 0x31, 0x70, 0xc1, 0x7f, 0x3b, 0x77, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; +static const unsigned char tab_disabled_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x3, 0xa7, 0x7a, 0x54, 0x58, 0x74, 0x52, 0x61, 0x77, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x65, 0x78, 0x69, 0x66, 0x0, 0x0, 0x78, 0xda, 0xcd, 0x96, 0x59, 0x92, 0xe3, 0x2a, 0x10, 0x45, 0xff, 0x59, 0x45, 0x2f, 0x81, 0xcc, 0x24, 0x19, 0x96, 0x83, 0x18, 0x22, 0x7a, 0x7, 0x6f, 0xf9, 0x7d, 0xc1, 0x48, 0x1e, 0xab, 0x5c, 0x65, 0xfb, 0xe3, 0x89, 0xb0, 0x40, 0x29, 0x48, 0xae, 0xee, 0x41, 0xc8, 0xa6, 0xfd, 0xf7, 0xb7, 0x9b, 0x3f, 0x38, 0x28, 0x45, 0x6f, 0x9c, 0x86, 0xe8, 0x93, 0xf7, 0x16, 0x87, 0x4b, 0x2e, 0x71, 0x46, 0x23, 0xda, 0xd3, 0x71, 0xaa, 0xc9, 0xba, 0x79, 0x5e, 0x17, 0x76, 0x6f, 0x5c, 0xc5, 0xcd, 0x71, 0x83, 0x11, 0x12, 0xd4, 0x72, 0xba, 0xf4, 0x6d, 0xf5, 0xcf, 0x88, 0xeb, 0x79, 0x40, 0x70, 0x2b, 0xbe, 0x5d, 0xc7, 0x4d, 0x28, 0x2b, 0x4f, 0x5c, 0x89, 0xe8, 0x48, 0x3c, 0xf, 0x19, 0x33, 0x8f, 0xf6, 0xea, 0x17, 0x57, 0x22, 0xe1, 0x53, 0x9c, 0xd6, 0xb5, 0x49, 0x6b, 0x5c, 0x76, 0x17, 0x8f, 0xb3, 0x7e, 0x5c, 0x56, 0xda, 0x95, 0xfc, 0xf6, 0xda, 0x5, 0x98, 0x51, 0x15, 0xf9, 0x84, 0xd, 0x37, 0x21, 0xb1, 0x38, 0xc7, 0x31, 0x8b, 0x40, 0x81, 0x24, 0xc9, 0x32, 0xda, 0x79, 0xde, 0x19, 0x91, 0x80, 0xb6, 0x43, 0x9d, 0x45, 0x84, 0x1e, 0x7b, 0x67, 0x8e, 0xe6, 0x8d, 0x79, 0x47, 0xeb, 0xc6, 0x3b, 0x9b, 0x57, 0x5c, 0xae, 0xad, 0x30, 0xd6, 0xaf, 0xe, 0xfe, 0xc6, 0xa3, 0x15, 0x27, 0xbd, 0x89, 0xcb, 0x31, 0xd, 0xdf, 0x52, 0xdb, 0x67, 0xbe, 0xba, 0x91, 0xcb, 0x31, 0xc5, 0x9d, 0x77, 0xbd, 0xd7, 0xd8, 0x7b, 0x3b, 0x3d, 0x5d, 0x76, 0x1e, 0x4e, 0x79, 0xb3, 0x1e, 0x6a, 0x7f, 0x94, 0xd9, 0x42, 0xc7, 0xd, 0x56, 0xca, 0x1c, 0xe6, 0x51, 0x2, 0x7e, 0x8a, 0x76, 0x98, 0x25, 0xa1, 0x44, 0x3c, 0x62, 0x1, 0xb1, 0xa, 0x9a, 0x1b, 0x4a, 0x31, 0x94, 0x88, 0xe1, 0x69, 0x27, 0x47, 0x95, 0x32, 0x75, 0x6a, 0xb3, 0x2e, 0x54, 0x20, 0xd1, 0x71, 0xe3, 0x80, 0x9a, 0xb9, 0xb0, 0xcc, 0x58, 0x94, 0xc0, 0x89, 0xcb, 0x84, 0xe2, 0x46, 0xa1, 0xce, 0x1, 0x78, 0xaa, 0x91, 0x8, 0x3e, 0x5, 0xd4, 0x4, 0x61, 0x3e, 0xb4, 0xd0, 0x9c, 0x37, 0xcd, 0xf9, 0xa, 0x45, 0xcc, 0x5c, 0x9, 0x3d, 0x99, 0x90, 0x8c, 0x30, 0xe2, 0xae, 0x98, 0x47, 0xc1, 0x57, 0xca, 0x91, 0xa8, 0xf7, 0xb1, 0x74, 0x89, 0x6c, 0x3c, 0xbc, 0x82, 0x2e, 0x1e, 0x6b, 0x1a, 0x32, 0x6, 0xb9, 0x71, 0x46, 0x2f, 0x0, 0xa1, 0xbe, 0x3c, 0xd5, 0xe9, 0xef, 0x2c, 0xe6, 0x62, 0xdd, 0xd8, 0xb, 0xb0, 0x2, 0x82, 0x3a, 0x6d, 0x8e, 0x78, 0xc0, 0x6c, 0xb7, 0x53, 0x8a, 0x4d, 0xe9, 0xbc, 0xb6, 0x64, 0x72, 0x16, 0xf4, 0x53, 0xeb, 0x8c, 0x3d, 0xbd, 0x1a, 0x14, 0xea, 0x4a, 0x0, 0x8b, 0x30, 0xb7, 0x42, 0xc, 0x9, 0x8, 0x58, 0x4f, 0xa2, 0xe4, 0xc9, 0x6, 0xe6, 0x40, 0x4, 0x1f, 0x23, 0xf8, 0x64, 0x28, 0x67, 0x71, 0xbc, 0x81, 0x0, 0xa9, 0x72, 0x25, 0xd3, 0xc1, 0x46, 0xc4, 0x3, 0x4e, 0xe4, 0x31, 0x37, 0xc6, 0x4, 0x9a, 0x7d, 0x59, 0xf9, 0x14, 0xc6, 0xd6, 0x2, 0x10, 0x2a, 0x1e, 0xaf, 0x4a, 0x1c, 0x2f, 0x10, 0x60, 0x39, 0xa7, 0x58, 0x3f, 0xc1, 0x45, 0xac, 0xa1, 0xac, 0xa2, 0xce, 0xa8, 0xaa, 0xd7, 0xa0, 0x51, 0x93, 0x66, 0x2f, 0xde, 0x79, 0xf5, 0xde, 0x7, 0x3f, 0xf6, 0xa8, 0x1c, 0x24, 0xb8, 0xa0, 0xc1, 0x87, 0x10, 0x62, 0x48, 0x21, 0x47, 0x89, 0x2e, 0x6a, 0xf4, 0x31, 0xc4, 0x18, 0x53, 0xcc, 0x89, 0x93, 0x60, 0xb, 0xd3, 0xe4, 0x53, 0x30, 0x29, 0xa6, 0x94, 0x72, 0xc6, 0xa4, 0x19, 0xa9, 0x33, 0x46, 0x67, 0xf4, 0xc8, 0x79, 0xe3, 0x4d, 0x36, 0xb7, 0xe9, 0xe6, 0xb7, 0xb0, 0xc5, 0x2d, 0x6d, 0xb9, 0x60, 0xf9, 0x14, 0x57, 0xb4, 0xf8, 0x12, 0x4a, 0x2c, 0xa9, 0xe4, 0xca, 0x55, 0x2a, 0x5e, 0xff, 0xea, 0x6b, 0x30, 0x35, 0xd6, 0x54, 0x73, 0xa3, 0x86, 0xa5, 0xd4, 0x5c, 0xd3, 0xe6, 0x5b, 0x68, 0xb1, 0xa5, 0x96, 0x3b, 0xd6, 0x5a, 0x97, 0xee, 0xba, 0x76, 0xdf, 0x43, 0x8f, 0x3d, 0xf5, 0x7c, 0x50, 0x5b, 0x54, 0xaf, 0xa9, 0xd1, 0xd, 0xb9, 0xef, 0xa9, 0xd1, 0xa2, 0x36, 0x88, 0xb9, 0xd9, 0x2f, 0x9c, 0xa9, 0x21, 0x1c, 0xc2, 0x9e, 0x82, 0xc6, 0x76, 0xa2, 0x83, 0x19, 0x88, 0xb1, 0x23, 0x10, 0xf, 0x83, 0x0, 0x16, 0x34, 0xf, 0x66, 0x36, 0x92, 0x73, 0x3c, 0xc8, 0xd, 0x66, 0x36, 0x31, 0x5e, 0xa, 0x65, 0x50, 0x23, 0x1d, 0x70, 0x2a, 0xd, 0x62, 0x20, 0xe8, 0x1a, 0xb1, 0x76, 0x3a, 0xd8, 0x9d, 0xc9, 0x7d, 0xcb, 0xcd, 0xa8, 0xfb, 0x15, 0x37, 0xfe, 0x8a, 0x9c, 0x19, 0xe8, 0x3e, 0x41, 0xce, 0xc, 0x74, 0x8b, 0xdc, 0x3d, 0xb7, 0x7, 0xd4, 0x6a, 0x9e, 0x5f, 0x14, 0x99, 0x80, 0xc6, 0x5b, 0x38, 0x3c, 0xb5, 0xd2, 0xb1, 0xb1, 0xa1, 0x43, 0x8b, 0x99, 0x63, 0x1e, 0xdf, 0xa4, 0x97, 0x6b, 0xf3, 0x6e, 0x82, 0xff, 0x59, 0xa2, 0x76, 0x98, 0x52, 0xcd, 0x96, 0x67, 0xd4, 0xe2, 0x7b, 0x78, 0x6a, 0xd8, 0xd7, 0x6a, 0x83, 0x5d, 0x64, 0x45, 0x84, 0x8e, 0x89, 0x9e, 0x4a, 0xe9, 0x9a, 0xf6, 0x51, 0x92, 0x67, 0xc, 0xd4, 0xe2, 0x2e, 0xcf, 0xfd, 0x52, 0xb, 0xf9, 0x35, 0x30, 0x1d, 0x1e, 0xe1, 0x3, 0xb4, 0xf2, 0x97, 0x94, 0x9f, 0x8a, 0x71, 0x37, 0x62, 0x3e, 0x48, 0xd, 0x42, 0xcc, 0xae, 0x24, 0xb7, 0xa7, 0x4a, 0xf8, 0x50, 0xd2, 0x3e, 0x8d, 0xbf, 0xda, 0xc3, 0x12, 0xb3, 0xf9, 0xa7, 0x4a, 0xe8, 0x91, 0x27, 0x9f, 0x51, 0x74, 0x1, 0x67, 0x5b, 0xc9, 0xcd, 0xd7, 0x4a, 0x5c, 0xff, 0xce, 0x93, 0xf7, 0x14, 0x5d, 0x78, 0x52, 0x6e, 0xee, 0x99, 0x7, 0x4a, 0xea, 0xfe, 0xd6, 0x44, 0x25, 0xa7, 0xe3, 0x6f, 0xeb, 0xf, 0x6a, 0xf3, 0x93, 0x8e, 0x14, 0xf6, 0x67, 0xeb, 0xc2, 0x5f, 0x2c, 0x73, 0x73, 0x88, 0xad, 0xb2, 0x6b, 0xca, 0x73, 0xb8, 0x8e, 0xff, 0xd0, 0x3f, 0xaf, 0xcd, 0x77, 0x1d, 0xb4, 0x9f, 0x2d, 0x79, 0xe6, 0xb7, 0xe9, 0x2e, 0xbf, 0x62, 0xc9, 0x5d, 0x6d, 0x9e, 0x58, 0xa2, 0x4f, 0x76, 0x0, 0xa9, 0xec, 0xf7, 0x6d, 0xe4, 0x25, 0x4b, 0xee, 0x6a, 0xf3, 0xd8, 0x92, 0xfa, 0x74, 0x33, 0x71, 0xe9, 0x7a, 0xb9, 0x9a, 0xcf, 0x6c, 0xfd, 0xa7, 0x44, 0x17, 0xeb, 0xf5, 0xf7, 0x4a, 0x2e, 0x13, 0xbd, 0xbd, 0xad, 0xd9, 0x99, 0xe8, 0x4d, 0x25, 0x9f, 0x50, 0x74, 0x65, 0x89, 0x79, 0x57, 0xc9, 0x3b, 0x8a, 0x1e, 0xc2, 0xd9, 0x15, 0x75, 0xfc, 0x61, 0x49, 0xe6, 0x1f, 0xbf, 0x1c, 0xa8, 0x52, 0x2b, 0xb1, 0xc9, 0xd4, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0x2e, 0x23, 0x0, 0x0, 0x2e, 0x23, 0x1, 0x78, 0xa5, 0x3f, 0x76, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe3, 0x2, 0xa, 0x13, 0x29, 0x21, 0x5f, 0x36, 0xe2, 0x14, 0x0, 0x0, 0x0, 0xaf, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x7d, 0x91, 0x41, 0xa, 0xc2, 0x40, 0x10, 0x4, 0x6b, 0x92, 0x61, 0x37, 0xb0, 0x87, 0xec, 0x39, 0x3e, 0xc6, 0x3f, 0xf8, 0x9a, 0x3c, 0xc1, 0xd7, 0xf8, 0x3, 0xf, 0x3e, 0xc6, 0xab, 0x44, 0x50, 0x30, 0x26, 0x66, 0x3c, 0x2c, 0x6, 0x3, 0xd9, 0xf4, 0x69, 0xa0, 0xab, 0x9b, 0x86, 0x11, 0x14, 0x87, 0xa7, 0xc2, 0x51, 0x52, 0x90, 0x34, 0xf1, 0xe1, 0xcd, 0x8b, 0x9e, 0xb7, 0xe2, 0x8, 0x44, 0x6a, 0x2, 0x1e, 0x41, 0x0, 0xc3, 0xe8, 0x79, 0x72, 0xa7, 0x3, 0xc5, 0x13, 0xf7, 0x87, 0x5d, 0x3b, 0x46, 0x16, 0xd2, 0xee, 0x7a, 0xbc, 0x9c, 0x18, 0x95, 0x8a, 0xba, 0x69, 0x6f, 0x71, 0xc4, 0xfe, 0x6c, 0x41, 0x63, 0xd3, 0x72, 0xe6, 0xa1, 0x38, 0xc2, 0x10, 0x87, 0x65, 0x1c, 0x63, 0x60, 0x88, 0x4, 0x9c, 0x52, 0xe2, 0xa7, 0x45, 0x9a, 0x79, 0x29, 0x9e, 0x52, 0x29, 0x10, 0x63, 0x5a, 0x1, 0xc, 0x84, 0x42, 0x1, 0xc9, 0x36, 0x8, 0x68, 0x3a, 0x33, 0x0, 0x9, 0x30, 0x5b, 0x5, 0xc, 0x6c, 0x6e, 0x98, 0x36, 0x1b, 0x24, 0xdb, 0xf0, 0xdb, 0xc0, 0x2a, 0x90, 0x54, 0x6c, 0xba, 0x96, 0x0, 0xc9, 0x2, 0xc2, 0xfc, 0xe0, 0xac, 0xbe, 0xe, 0x38, 0x38, 0x83, 0xbf, 0x35, 0x30, 0x94, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; + static const unsigned char tab_menu_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x5, 0xa3, 0xe0, 0xc1, 0x7f, 0x54, 0x48, 0x3, 0x5, 0xf, 0xe3, 0x1e, 0x7c, 0x81, 0x4b, 0x7f, 0x7b, 0x98, 0x86, 0xc5, 0x15, 0xf7, 0x35, 0xee, 0x5f, 0x2, 0x4b, 0x5f, 0x7f, 0xac, 0x8b, 0xc3, 0xa1, 0x2f, 0xb8, 0x1f, 0xce, 0x7f, 0x38, 0xff, 0x5, 0x37, 0x75, 0xbd, 0xf, 0x0, 0x52, 0xd4, 0x48, 0xb8, 0x2d, 0x78, 0x5a, 0x91, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 458cbf6718..fd7b67a218 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -82,11 +82,14 @@ void DynamicFontData::set_force_autohinter(bool p_force) { } void DynamicFontData::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &DynamicFontData::set_antialiased); + ClassDB::bind_method(D_METHOD("is_antialiased"), &DynamicFontData::is_antialiased); ClassDB::bind_method(D_METHOD("set_font_path", "path"), &DynamicFontData::set_font_path); ClassDB::bind_method(D_METHOD("get_font_path"), &DynamicFontData::get_font_path); ClassDB::bind_method(D_METHOD("set_hinting", "mode"), &DynamicFontData::set_hinting); ClassDB::bind_method(D_METHOD("get_hinting"), &DynamicFontData::get_hinting); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "is_antialiased"); ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting"); BIND_ENUM_CONSTANT(HINTING_NONE); @@ -98,6 +101,7 @@ void DynamicFontData::_bind_methods() { DynamicFontData::DynamicFontData() { + antialiased = true; force_autohinter = false; hinting = DynamicFontData::HINTING_NORMAL; font_mem = NULL; @@ -277,18 +281,6 @@ const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFon return Pair<const Character *, DynamicFontAtSize *>(chr, const_cast<DynamicFontAtSize *>(this)); } -float DynamicFontAtSize::_get_kerning_advance(const DynamicFontAtSize *font, CharType p_char, CharType p_next) const { - float advance = 0.0; - - if (p_next) { - FT_Vector delta; - FT_Get_Kerning(font->face, p_char, p_next, FT_KERNING_DEFAULT, &delta); - advance = (delta.x / 64.0) / oversampling; - } - - return advance; -} - Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const { if (!valid) @@ -297,7 +289,6 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const V Pair<const Character *, DynamicFontAtSize *> char_pair_with_font = _find_char_with_font(p_char, p_fallbacks); const Character *ch = char_pair_with_font.first; - DynamicFontAtSize *font = char_pair_with_font.second; ERR_FAIL_COND_V(!ch, Size2()); Size2 ret(0, get_height()); @@ -305,7 +296,6 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const V if (ch->found) { ret.x = ch->advance; } - ret.x += _get_kerning_advance(font, p_char, p_next); return ret; } @@ -348,14 +338,12 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT modulate.r = modulate.g = modulate.b = 1.0; } RID texture = font->textures[ch->texture_idx].texture->get_rid(); - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size * Vector2(font->scale_color_font, font->scale_color_font)), texture, ch->rect_uv, modulate, false, RID(), false); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size), texture, ch->rect_uv, modulate, false, RID(), false); } advance = ch->advance; } - advance += _get_kerning_advance(font, p_char, p_next); - return advance; } @@ -632,7 +620,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) { if (id.outline_size > 0) { character = _make_outline_char(p_char); } else { - error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); + error = FT_Render_Glyph(face->glyph, font->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO); if (!error) character = _bitmap_to_character(slot->bitmap, slot->bitmap_top, slot->bitmap_left, slot->advance.x / 64.0); } @@ -785,6 +773,18 @@ void DynamicFont::set_use_filter(bool p_enable) { _reload_cache(); } +bool DynamicFontData::is_antialiased() const { + + return antialiased; +} + +void DynamicFontData::set_antialiased(bool p_antialiased) { + + if (antialiased == p_antialiased) + return; + antialiased = p_antialiased; +} + DynamicFontData::Hinting DynamicFontData::get_hinting() const { return hinting; @@ -1009,15 +1009,15 @@ void DynamicFont::_bind_methods() { ADD_GROUP("Settings", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "size"), "set_size", "get_size"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size"), "set_outline_size", "get_outline_size"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,255,1"), "set_outline_size", "get_outline_size"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_color"), "set_outline_color", "get_outline_color"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_mipmaps"), "set_use_mipmaps", "get_use_mipmaps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_filter"), "set_use_filter", "get_use_filter"); ADD_GROUP("Extra Spacing", "extra_spacing"); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "extra_spacing_top"), "set_spacing", "get_spacing", SPACING_TOP); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "extra_spacing_bottom"), "set_spacing", "get_spacing", SPACING_BOTTOM); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "extra_spacing_char"), "set_spacing", "get_spacing", SPACING_CHAR); - ADD_PROPERTYINZ(PropertyInfo(Variant::INT, "extra_spacing_space"), "set_spacing", "get_spacing", SPACING_SPACE); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_top"), "set_spacing", "get_spacing", SPACING_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_bottom"), "set_spacing", "get_spacing", SPACING_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_char"), "set_spacing", "get_spacing", SPACING_CHAR); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_space"), "set_spacing", "get_spacing", SPACING_SPACE); ADD_GROUP("Font", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "font_data", PROPERTY_HINT_RESOURCE_TYPE, "DynamicFontData"), "set_font_data", "get_font_data"); @@ -1029,7 +1029,7 @@ void DynamicFont::_bind_methods() { Mutex *DynamicFont::dynamic_font_mutex = NULL; -SelfList<DynamicFont>::List DynamicFont::dynamic_fonts; +SelfList<DynamicFont>::List *DynamicFont::dynamic_fonts = NULL; DynamicFont::DynamicFont() : font_list(this) { @@ -1041,29 +1041,31 @@ DynamicFont::DynamicFont() : spacing_char = 0; spacing_space = 0; outline_color = Color(1, 1, 1); - if (dynamic_font_mutex) + if (dynamic_font_mutex) { dynamic_font_mutex->lock(); - dynamic_fonts.add(&font_list); - if (dynamic_font_mutex) + dynamic_fonts->add(&font_list); dynamic_font_mutex->unlock(); + } } DynamicFont::~DynamicFont() { - - if (dynamic_font_mutex) + if (dynamic_font_mutex) { dynamic_font_mutex->lock(); - dynamic_fonts.remove(&font_list); - if (dynamic_font_mutex) + dynamic_fonts->remove(&font_list); dynamic_font_mutex->unlock(); + } } void DynamicFont::initialize_dynamic_fonts() { + dynamic_fonts = memnew(SelfList<DynamicFont>::List()); dynamic_font_mutex = Mutex::create(); } void DynamicFont::finish_dynamic_fonts() { memdelete(dynamic_font_mutex); dynamic_font_mutex = NULL; + memdelete(dynamic_fonts); + dynamic_fonts = NULL; } void DynamicFont::update_oversampling() { @@ -1073,7 +1075,7 @@ void DynamicFont::update_oversampling() { if (dynamic_font_mutex) dynamic_font_mutex->lock(); - SelfList<DynamicFont> *E = dynamic_fonts.first(); + SelfList<DynamicFont> *E = dynamic_fonts->first(); while (E) { if (E->self()->data_at_size.is_valid()) { diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index afda48a566..887c7b42c8 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -54,8 +54,9 @@ public: struct { uint32_t size : 16; uint32_t outline_size : 8; - bool mipmaps : 1; - bool filter : 1; + uint32_t mipmaps : 1; + uint32_t filter : 1; + uint32_t unused : 6; }; uint32_t key; }; @@ -71,12 +72,15 @@ public: HINTING_NORMAL }; + bool is_antialiased() const; + void set_antialiased(bool p_antialiased); Hinting get_hinting() const; void set_hinting(Hinting p_hinting); private: const uint8_t *font_mem; int font_mem_size; + bool antialiased; bool force_autohinter; Hinting hinting; @@ -161,7 +165,6 @@ class DynamicFontAtSize : public Reference { const Pair<const Character *, DynamicFontAtSize *> _find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const; Character _make_outline_char(CharType p_char); - float _get_kerning_advance(const DynamicFontAtSize *font, CharType p_char, CharType p_next) const; TexturePosition _find_texture_pos_for_glyph(int p_color_size, Image::Format p_image_format, int p_width, int p_height); Character _bitmap_to_character(FT_Bitmap bitmap, int yofs, int xofs, float advance); @@ -285,7 +288,7 @@ public: SelfList<DynamicFont> font_list; static Mutex *dynamic_font_mutex; - static SelfList<DynamicFont>::List dynamic_fonts; + static SelfList<DynamicFont>::List *dynamic_fonts; static void initialize_dynamic_fonts(); static void finish_dynamic_fonts(); @@ -300,6 +303,7 @@ VARIANT_ENUM_CAST(DynamicFont::SpacingType); ///////////// class ResourceFormatLoaderDynamicFont : public ResourceFormatLoader { + GDCLASS(ResourceFormatLoaderDynamicFont, ResourceFormatLoader) public: virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual void get_recognized_extensions(List<String> *p_extensions) const; diff --git a/scene/resources/dynamic_font_stb.cpp b/scene/resources/dynamic_font_stb.cpp index 8cb2cc4983..3b44f05b94 100644 --- a/scene/resources/dynamic_font_stb.cpp +++ b/scene/resources/dynamic_font_stb.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/dynamic_font_stb.h b/scene/resources/dynamic_font_stb.h index e1ef72ea4f..4c98487600 100644 --- a/scene/resources/dynamic_font_stb.h +++ b/scene/resources/dynamic_font_stb.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -180,6 +180,7 @@ public: ///////////// class ResourceFormatLoaderDynamicFont : public ResourceFormatLoader { + GDCLASS(ResourceFormatLoaderDynamicFont, ResourceFormatLoader) public: virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual void get_recognized_extensions(List<String> *p_extensions) const; diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 7b43c33692..17609ed505 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -61,6 +61,25 @@ void Environment::set_sky_custom_fov(float p_scale) { bg_sky_custom_fov = p_scale; VS::get_singleton()->environment_set_sky_custom_fov(environment, p_scale); } +void Environment::set_sky_orientation(const Basis &p_orientation) { + + bg_sky_orientation = p_orientation; + _change_notify("background_sky_rotation"); + _change_notify("background_sky_rotation_degrees"); + VS::get_singleton()->environment_set_sky_orientation(environment, bg_sky_orientation); +} +void Environment::set_sky_rotation(const Vector3 &p_euler_rad) { + + bg_sky_orientation.set_euler(p_euler_rad); + _change_notify("background_sky_orientation"); + _change_notify("background_sky_rotation_degrees"); + VS::get_singleton()->environment_set_sky_orientation(environment, bg_sky_orientation); +} +void Environment::set_sky_rotation_degrees(const Vector3 &p_euler_deg) { + + set_sky_rotation(p_euler_deg * Math_PI / 180.0); + _change_notify("background_sky_rotation"); +} void Environment::set_bg_color(const Color &p_color) { bg_color = p_color; @@ -106,6 +125,22 @@ float Environment::get_sky_custom_fov() const { return bg_sky_custom_fov; } +Basis Environment::get_sky_orientation() const { + + return bg_sky_orientation; +} + +Vector3 Environment::get_sky_rotation() const { + + // should we cache this? maybe overkill + return bg_sky_orientation.get_euler(); +} + +Vector3 Environment::get_sky_rotation_degrees() const { + + return get_sky_rotation() * 180.0 / Math_PI; +} + Color Environment::get_bg_color() const { return bg_color; @@ -268,7 +303,7 @@ Ref<Texture> Environment::get_adjustment_color_correction() const { void Environment::_validate_property(PropertyInfo &property) const { - if (property.name == "background_sky" || property.name == "background_sky_custom_fov" || property.name == "ambient_light/sky_contribution") { + if (property.name == "background_sky" || property.name == "background_sky_custom_fov" || property.name == "background_sky_orientation" || property.name == "background_sky_rotation" || property.name == "background_sky_rotation_degrees" || property.name == "ambient_light/sky_contribution") { if (bg_mode != BG_SKY && bg_mode != BG_COLOR_SKY) { property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; } @@ -299,6 +334,19 @@ void Environment::_validate_property(PropertyInfo &property) const { }; + static const char *high_end_prefixes[] = { + "auto_exposure_", + "tonemap_", + "ss_reflections_", + "ssao_", + "dof_blur_far_", + "dof_blur_near_", + "glow_", + "adjustment_", + NULL + + }; + const char **prefixes = hide_prefixes; while (*prefixes) { String prefix = String(*prefixes); @@ -311,6 +359,20 @@ void Environment::_validate_property(PropertyInfo &property) const { prefixes++; } + + if (VisualServer::get_singleton()->is_low_end()) { + prefixes = high_end_prefixes; + while (*prefixes) { + String prefix = String(*prefixes); + + if (property.name.begins_with(prefix)) { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + return; + } + + prefixes++; + } + } } void Environment::set_ssr_enabled(bool p_enable) { @@ -504,7 +566,7 @@ float Environment::get_ssao_edge_sharpness() const { void Environment::set_glow_enabled(bool p_enabled) { glow_enabled = p_enabled; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); _change_notify(); } @@ -522,7 +584,7 @@ void Environment::set_glow_level(int p_level, bool p_enabled) { else glow_levels &= ~(1 << p_level); - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } bool Environment::is_glow_level_enabled(int p_level) const { @@ -535,7 +597,7 @@ void Environment::set_glow_intensity(float p_intensity) { glow_intensity = p_intensity; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } float Environment::get_glow_intensity() const { @@ -545,7 +607,7 @@ float Environment::get_glow_intensity() const { void Environment::set_glow_strength(float p_strength) { glow_strength = p_strength; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } float Environment::get_glow_strength() const { @@ -556,7 +618,7 @@ void Environment::set_glow_bloom(float p_threshold) { glow_bloom = p_threshold; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } float Environment::get_glow_bloom() const { @@ -567,7 +629,7 @@ void Environment::set_glow_blend_mode(GlowBlendMode p_mode) { glow_blend_mode = p_mode; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } Environment::GlowBlendMode Environment::get_glow_blend_mode() const { @@ -578,18 +640,29 @@ void Environment::set_glow_hdr_bleed_threshold(float p_threshold) { glow_hdr_bleed_threshold = p_threshold; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } float Environment::get_glow_hdr_bleed_threshold() const { return glow_hdr_bleed_threshold; } +void Environment::set_glow_hdr_luminance_cap(float p_amount) { + + glow_hdr_luminance_cap = p_amount; + + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); +} +float Environment::get_glow_hdr_luminance_cap() const { + + return glow_hdr_luminance_cap; +} + void Environment::set_glow_hdr_bleed_scale(float p_scale) { glow_hdr_bleed_scale = p_scale; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } float Environment::get_glow_hdr_bleed_scale() const { @@ -599,7 +672,7 @@ float Environment::get_glow_hdr_bleed_scale() const { void Environment::set_glow_bicubic_upscale(bool p_enable) { glow_bicubic_upscale = p_enable; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } bool Environment::is_glow_bicubic_upscale_enabled() const { @@ -761,7 +834,7 @@ float Environment::get_fog_sun_amount() const { void Environment::set_fog_depth_enabled(bool p_enabled) { fog_depth_enabled = p_enabled; - VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); + VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); } bool Environment::is_fog_depth_enabled() const { @@ -771,17 +844,28 @@ bool Environment::is_fog_depth_enabled() const { void Environment::set_fog_depth_begin(float p_distance) { fog_depth_begin = p_distance; - VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); + VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); } float Environment::get_fog_depth_begin() const { return fog_depth_begin; } +void Environment::set_fog_depth_end(float p_distance) { + + fog_depth_end = p_distance; + VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); +} + +float Environment::get_fog_depth_end() const { + + return fog_depth_end; +} + void Environment::set_fog_depth_curve(float p_curve) { fog_depth_curve = p_curve; - VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); + VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); } float Environment::get_fog_depth_curve() const { @@ -791,7 +875,7 @@ float Environment::get_fog_depth_curve() const { void Environment::set_fog_transmit_enabled(bool p_enabled) { fog_transmit_enabled = p_enabled; - VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); + VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); } bool Environment::is_fog_transmit_enabled() const { @@ -801,7 +885,7 @@ bool Environment::is_fog_transmit_enabled() const { void Environment::set_fog_transmit_curve(float p_curve) { fog_transmit_curve = p_curve; - VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); + VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); } float Environment::get_fog_transmit_curve() const { @@ -853,6 +937,9 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_background", "mode"), &Environment::set_background); ClassDB::bind_method(D_METHOD("set_sky", "sky"), &Environment::set_sky); ClassDB::bind_method(D_METHOD("set_sky_custom_fov", "scale"), &Environment::set_sky_custom_fov); + ClassDB::bind_method(D_METHOD("set_sky_orientation", "orientation"), &Environment::set_sky_orientation); + ClassDB::bind_method(D_METHOD("set_sky_rotation", "euler_radians"), &Environment::set_sky_rotation); + ClassDB::bind_method(D_METHOD("set_sky_rotation_degrees", "euler_degrees"), &Environment::set_sky_rotation_degrees); ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &Environment::set_bg_color); ClassDB::bind_method(D_METHOD("set_bg_energy", "energy"), &Environment::set_bg_energy); ClassDB::bind_method(D_METHOD("set_canvas_max_layer", "layer"), &Environment::set_canvas_max_layer); @@ -863,6 +950,9 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("get_background"), &Environment::get_background); ClassDB::bind_method(D_METHOD("get_sky"), &Environment::get_sky); ClassDB::bind_method(D_METHOD("get_sky_custom_fov"), &Environment::get_sky_custom_fov); + ClassDB::bind_method(D_METHOD("get_sky_orientation"), &Environment::get_sky_orientation); + ClassDB::bind_method(D_METHOD("get_sky_rotation"), &Environment::get_sky_rotation); + ClassDB::bind_method(D_METHOD("get_sky_rotation_degrees"), &Environment::get_sky_rotation_degrees); ClassDB::bind_method(D_METHOD("get_bg_color"), &Environment::get_bg_color); ClassDB::bind_method(D_METHOD("get_bg_energy"), &Environment::get_bg_energy); ClassDB::bind_method(D_METHOD("get_canvas_max_layer"), &Environment::get_canvas_max_layer); @@ -874,6 +964,9 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Sky,Color+Sky,Canvas,Keep"), "set_background", "get_background"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "background_sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_sky_custom_fov", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_sky_custom_fov", "get_sky_custom_fov"); + ADD_PROPERTY(PropertyInfo(Variant::BASIS, "background_sky_orientation"), "set_sky_orientation", "get_sky_orientation"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "background_sky_rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_sky_rotation", "get_sky_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "background_sky_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_sky_rotation_degrees", "get_sky_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_bg_color", "get_bg_color"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bg_energy", "get_bg_energy"); ADD_PROPERTY(PropertyInfo(Variant::INT, "background_canvas_max_layer", PROPERTY_HINT_RANGE, "-1000,1000,1"), "set_canvas_max_layer", "get_canvas_max_layer"); @@ -900,6 +993,9 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_fog_depth_begin", "distance"), &Environment::set_fog_depth_begin); ClassDB::bind_method(D_METHOD("get_fog_depth_begin"), &Environment::get_fog_depth_begin); + ClassDB::bind_method(D_METHOD("set_fog_depth_end", "distance"), &Environment::set_fog_depth_end); + ClassDB::bind_method(D_METHOD("get_fog_depth_end"), &Environment::get_fog_depth_end); + ClassDB::bind_method(D_METHOD("set_fog_depth_curve", "curve"), &Environment::set_fog_depth_curve); ClassDB::bind_method(D_METHOD("get_fog_depth_curve"), &Environment::get_fog_depth_curve); @@ -928,6 +1024,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_sun_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fog_sun_amount", "get_fog_sun_amount"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_depth_enabled"), "set_fog_depth_enabled", "is_fog_depth_enabled"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_begin", PROPERTY_HINT_RANGE, "0,4000,0.1"), "set_fog_depth_begin", "get_fog_depth_begin"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_end", PROPERTY_HINT_RANGE, "0,4000,0.1,or_greater"), "set_fog_depth_end", "get_fog_depth_end"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_curve", PROPERTY_HINT_EXP_EASING), "set_fog_depth_curve", "get_fog_depth_curve"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_transmit_enabled"), "set_fog_transmit_enabled", "is_fog_transmit_enabled"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_transmit_curve", PROPERTY_HINT_EXP_EASING), "set_fog_transmit_curve", "get_fog_transmit_curve"); @@ -1112,6 +1209,9 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_glow_hdr_bleed_threshold", "threshold"), &Environment::set_glow_hdr_bleed_threshold); ClassDB::bind_method(D_METHOD("get_glow_hdr_bleed_threshold"), &Environment::get_glow_hdr_bleed_threshold); + ClassDB::bind_method(D_METHOD("set_glow_hdr_luminance_cap", "amount"), &Environment::set_glow_hdr_luminance_cap); + ClassDB::bind_method(D_METHOD("get_glow_hdr_luminance_cap"), &Environment::get_glow_hdr_luminance_cap); + ClassDB::bind_method(D_METHOD("set_glow_hdr_bleed_scale", "scale"), &Environment::set_glow_hdr_bleed_scale); ClassDB::bind_method(D_METHOD("get_glow_hdr_bleed_scale"), &Environment::get_glow_hdr_bleed_scale); @@ -1133,6 +1233,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_bloom", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_glow_bloom", "get_glow_bloom"); ADD_PROPERTY(PropertyInfo(Variant::INT, "glow_blend_mode", PROPERTY_HINT_ENUM, "Additive,Screen,Softlight,Replace"), "set_glow_blend_mode", "get_glow_blend_mode"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_threshold", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_threshold", "get_glow_hdr_bleed_threshold"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_luminance_cap", PROPERTY_HINT_RANGE, "0.0,256.0,0.01"), "set_glow_hdr_luminance_cap", "get_glow_hdr_luminance_cap"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_scale", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_scale", "get_glow_hdr_bleed_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "glow_bicubic_upscale"), "set_glow_bicubic_upscale", "is_glow_bicubic_upscale_enabled"); @@ -1190,12 +1291,20 @@ void Environment::_bind_methods() { BIND_ENUM_CONSTANT(SSAO_QUALITY_HIGH); } -Environment::Environment() { +Environment::Environment() : + bg_mode(BG_CLEAR_COLOR), + tone_mapper(TONE_MAPPER_LINEAR), + ssao_blur(SSAO_BLUR_DISABLED), + ssao_quality(SSAO_QUALITY_LOW), + glow_blend_mode(GLOW_BLEND_MODE_ADDITIVE), + dof_blur_far_quality(DOF_BLUR_QUALITY_LOW), + dof_blur_near_quality(DOF_BLUR_QUALITY_LOW) { environment = VS::get_singleton()->environment_create(); bg_mode = BG_CLEAR_COLOR; bg_sky_custom_fov = 0; + bg_sky_orientation = Basis(); bg_energy = 1.0; bg_canvas_max_layer = 0; ambient_energy = 1.0; @@ -1246,6 +1355,7 @@ Environment::Environment() { glow_bloom = 0.0; glow_blend_mode = GLOW_BLEND_MODE_SOFTLIGHT; glow_hdr_bleed_threshold = 1.0; + glow_hdr_luminance_cap = 12.0; glow_hdr_bleed_scale = 2.0; glow_bicubic_upscale = false; @@ -1269,6 +1379,7 @@ Environment::Environment() { fog_depth_enabled = true; fog_depth_begin = 10; + fog_depth_end = 0; fog_depth_curve = 1; fog_transmit_enabled = false; diff --git a/scene/resources/environment.h b/scene/resources/environment.h index aab37719e0..a54f13a88f 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,7 +32,7 @@ #define ENVIRONMENT_H #include "core/resource.h" -#include "scene/resources/sky_box.h" +#include "scene/resources/sky.h" #include "scene/resources/texture.h" #include "servers/visual_server.h" @@ -91,6 +91,7 @@ private: BGMode bg_mode; Ref<Sky> bg_sky; float bg_sky_custom_fov; + Basis bg_sky_orientation; Color bg_color; float bg_energy; int bg_canvas_max_layer; @@ -141,6 +142,7 @@ private: GlowBlendMode glow_blend_mode; float glow_hdr_bleed_threshold; float glow_hdr_bleed_scale; + float glow_hdr_luminance_cap; bool glow_bicubic_upscale; bool dof_blur_far_enabled; @@ -162,6 +164,7 @@ private: bool fog_depth_enabled; float fog_depth_begin; + float fog_depth_end; float fog_depth_curve; bool fog_transmit_enabled; @@ -180,6 +183,9 @@ public: void set_background(BGMode p_bg); void set_sky(const Ref<Sky> &p_sky); void set_sky_custom_fov(float p_scale); + void set_sky_orientation(const Basis &p_orientation); + void set_sky_rotation(const Vector3 &p_euler_rad); + void set_sky_rotation_degrees(const Vector3 &p_euler_deg); void set_bg_color(const Color &p_color); void set_bg_energy(float p_energy); void set_canvas_max_layer(int p_max_layer); @@ -190,6 +196,9 @@ public: BGMode get_background() const; Ref<Sky> get_sky() const; float get_sky_custom_fov() const; + Basis get_sky_orientation() const; + Vector3 get_sky_rotation() const; + Vector3 get_sky_rotation_degrees() const; Color get_bg_color() const; float get_bg_energy() const; int get_canvas_max_layer() const; @@ -311,6 +320,9 @@ public: void set_glow_hdr_bleed_threshold(float p_threshold); float get_glow_hdr_bleed_threshold() const; + void set_glow_hdr_luminance_cap(float p_amount); + float get_glow_hdr_luminance_cap() const; + void set_glow_hdr_bleed_scale(float p_scale); float get_glow_hdr_bleed_scale() const; @@ -365,6 +377,9 @@ public: void set_fog_depth_begin(float p_distance); float get_fog_depth_begin() const; + void set_fog_depth_end(float p_distance); + float get_fog_depth_end() const; + void set_fog_depth_curve(float p_curve); float get_fog_depth_curve() const; diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index b78b3a6ffb..c72ccc97db 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -497,6 +497,7 @@ Size2 Font::get_string_size(const String &p_string) const { } void BitmapFont::set_fallback(const Ref<BitmapFont> &p_fallback) { + ERR_FAIL_COND(p_fallback == this); fallback = p_fallback; } diff --git a/scene/resources/font.h b/scene/resources/font.h index 39e66a822d..6bc8d9b792 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -201,6 +201,7 @@ public: }; class ResourceFormatLoaderBMFont : public ResourceFormatLoader { + GDCLASS(ResourceFormatLoaderBMFont, ResourceFormatLoader) public: virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual void get_recognized_extensions(List<String> *p_extensions) const; diff --git a/scene/resources/color_ramp.cpp b/scene/resources/gradient.cpp index d5e8c17cbc..99ce8ef821 100644 --- a/scene/resources/color_ramp.cpp +++ b/scene/resources/gradient.cpp @@ -1,12 +1,12 @@ /*************************************************************************/ -/* color_ramp.cpp */ +/* gradient.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "color_ramp.h" +#include "gradient.h" + #include "core/core_string_names.h" //setter and getter names for property serialization diff --git a/scene/resources/color_ramp.h b/scene/resources/gradient.h index 88fa4beb7f..a51a0ca0d0 100644 --- a/scene/resources/color_ramp.h +++ b/scene/resources/gradient.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* color_ramp.h */ +/* gradient.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCENE_RESOURCES_COLOR_RAMP_H_ -#define SCENE_RESOURCES_COLOR_RAMP_H_ +#ifndef GRADIENT_H +#define GRADIENT_H #include "core/resource.h" @@ -126,4 +126,4 @@ public: int get_points_count() const; }; -#endif /* SCENE_RESOURCES_COLOR_RAMP_H_ */ +#endif // GRADIENT_H diff --git a/scene/resources/shape_line_2d.cpp b/scene/resources/line_shape_2d.cpp index 1a81eea6e5..f5d5fb561a 100644 --- a/scene/resources/shape_line_2d.cpp +++ b/scene/resources/line_shape_2d.cpp @@ -1,12 +1,12 @@ /*************************************************************************/ -/* shape_line_2d.cpp */ +/* line_shape_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "shape_line_2d.h" +#include "line_shape_2d.h" + #include "servers/physics_2d_server.h" #include "servers/visual_server.h" diff --git a/scene/resources/shape_line_2d.h b/scene/resources/line_shape_2d.h index 7d31941558..f684862025 100644 --- a/scene/resources/shape_line_2d.h +++ b/scene/resources/line_shape_2d.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* shape_line_2d.h */ +/* line_shape_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SHAPE_LINE_2D_H -#define SHAPE_LINE_2D_H +#ifndef LINE_SHAPE_2D_H +#define LINE_SHAPE_2D_H #include "scene/resources/shape_2d.h" @@ -59,4 +59,4 @@ public: LineShape2D(); }; -#endif // SHAPE_LINE_2D_H +#endif // LINE_SHAPE_2D_H diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 274c74a9a2..536eb11a27 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -113,6 +113,9 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) { if (n.find("param/") == 0) { //backwards compatibility pr = n.substr(6, n.length()); } + if (n.find("shader_param/") == 0) { //backwards compatibility + pr = n.replace_first("shader_param/", ""); + } } if (pr) { VisualServer::get_singleton()->material_set_param(_get_material(), pr, p_value); @@ -128,6 +131,16 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const { if (shader.is_valid()) { StringName pr = shader->remap_param(p_name); + if (!pr) { + String n = p_name; + if (n.find("param/") == 0) { //backwards compatibility + pr = n.substr(6, n.length()); + } + if (n.find("shader_param/") == 0) { //backwards compatibility + pr = n.replace_first("shader_param/", ""); + } + } + if (pr) { r_ret = VisualServer::get_singleton()->material_get_param(_get_material(), pr); return true; @@ -258,7 +271,7 @@ ShaderMaterial::~ShaderMaterial() { ///////////////////////////////// Mutex *SpatialMaterial::material_mutex = NULL; -SelfList<SpatialMaterial>::List SpatialMaterial::dirty_materials; +SelfList<SpatialMaterial>::List *SpatialMaterial::dirty_materials = NULL; Map<SpatialMaterial::MaterialKey, SpatialMaterial::ShaderData> SpatialMaterial::shader_map; SpatialMaterial::ShaderNames *SpatialMaterial::shader_names = NULL; @@ -268,6 +281,8 @@ void SpatialMaterial::init_shaders() { material_mutex = Mutex::create(); #endif + dirty_materials = memnew(SelfList<SpatialMaterial>::List); + shader_names = memnew(ShaderNames); shader_names->albedo = "albedo"; @@ -299,6 +314,7 @@ void SpatialMaterial::init_shaders() { shader_names->particles_anim_loop = "particles_anim_loop"; shader_names->depth_min_layers = "depth_min_layers"; shader_names->depth_max_layers = "depth_max_layers"; + shader_names->depth_flip = "depth_flip"; shader_names->grow = "grow"; @@ -347,12 +363,15 @@ void SpatialMaterial::finish_shaders() { memdelete(material_mutex); #endif + memdelete(dirty_materials); + dirty_materials = NULL; + memdelete(shader_names); } void SpatialMaterial::_update_shader() { - dirty_materials.remove(&element); + dirty_materials->remove(&element); MaterialKey mk = _compute_key(); if (mk.key == current_key.key) @@ -532,6 +551,7 @@ void SpatialMaterial::_update_shader() { code += "uniform float depth_scale;\n"; code += "uniform int depth_min_layers;\n"; code += "uniform int depth_max_layers;\n"; + code += "uniform vec2 depth_flip;\n"; } if (flags[FLAG_UV1_USE_TRIPLANAR]) { code += "varying vec3 uv1_triplanar_pos;\n"; @@ -587,17 +607,17 @@ void SpatialMaterial::_update_shader() { code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],CAMERA_MATRIX[1],CAMERA_MATRIX[2],WORLD_MATRIX[3]);\n"; if (flags[FLAG_BILLBOARD_KEEP_SCALE]) { - code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz),0,0,0),vec4(0,length(WORLD_MATRIX[1].xyz),0,0),vec4(0,0,length(WORLD_MATRIX[2].xyz),0),vec4(0,0,0,1));\n"; + code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, length(WORLD_MATRIX[1].xyz), 0.0, 0.0),vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0),vec4(0.0, 0.0, 0.0, 1.0));\n"; } } break; case BILLBOARD_FIXED_Y: { - code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],WORLD_MATRIX[1],vec4(normalize(cross(CAMERA_MATRIX[0].xyz,WORLD_MATRIX[1].xyz)),0.0),WORLD_MATRIX[3]);\n"; + code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],WORLD_MATRIX[1],vec4(normalize(cross(CAMERA_MATRIX[0].xyz,WORLD_MATRIX[1].xyz)), 0.0),WORLD_MATRIX[3]);\n"; if (flags[FLAG_BILLBOARD_KEEP_SCALE]) { - code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz),0,0,0),vec4(0,1,0,0),vec4(0,0,length(WORLD_MATRIX[2].xyz),0),vec4(0,0,0,1));\n"; + code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, 1.0, 0.0, 0.0),vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } else { - code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(1,0,0,0),vec4(0,1.0/length(WORLD_MATRIX[1].xyz),0,0),vec4(0,0,1,0),vec4(0,0,0,1));\n"; + code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(1.0, 0.0, 0.0, 0.0),vec4(0.0, 1.0/length(WORLD_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0),vec4(0.0, 0.0, 0.0 ,1.0));\n"; } } break; case BILLBOARD_PARTICLES: { @@ -605,16 +625,22 @@ void SpatialMaterial::_update_shader() { //make billboard code += "\tmat4 mat_world = mat4(normalize(CAMERA_MATRIX[0])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[1])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[2])*length(WORLD_MATRIX[2]),WORLD_MATRIX[3]);\n"; //rotate by rotation - code += "\tmat_world = mat_world * mat4( vec4(cos(INSTANCE_CUSTOM.x),-sin(INSTANCE_CUSTOM.x),0.0,0.0), vec4(sin(INSTANCE_CUSTOM.x),cos(INSTANCE_CUSTOM.x),0.0,0.0),vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0));\n"; + code += "\tmat_world = mat_world * mat4( vec4(cos(INSTANCE_CUSTOM.x),-sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0),vec4(0.0, 0.0, 1.0, 0.0),vec4(0.0, 0.0, 0.0, 1.0));\n"; //set modelview code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat_world;\n"; //handle animation + code += "\tfloat h_frames = float(particles_anim_h_frames);\n"; + code += "\tfloat v_frames = float(particles_anim_v_frames);\n"; code += "\tfloat particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n"; code += "\tfloat particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n"; - code += "\tif (particles_anim_loop) particle_frame=clamp(particle_frame,0.0,particle_total_frames-1.0); else particle_frame=mod(particle_frame,float(particle_total_frames));\n"; - code += "\tUV /= vec2(float(particles_anim_h_frames),float(particles_anim_v_frames));\n"; - code += "\tUV += vec2(mod(particle_frame,float(particles_anim_h_frames)) / float(particles_anim_h_frames),particle_frame / float(particles_anim_h_frames) / float(particles_anim_v_frames));\n"; + code += "\tif (!particles_anim_loop) {\n"; + code += "\t\tparticle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n"; + code += "\t} else {\n"; + code += "\t\tparticle_frame = mod(particle_frame, particle_total_frames);\n"; + code += "\t}"; + code += "\tUV /= vec2(h_frames, v_frames);\n"; + code += "\tUV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n"; } break; } @@ -695,9 +721,9 @@ void SpatialMaterial::_update_shader() { code += "\tvec2 base_uv2 = UV2;\n"; } - if (features[FEATURE_DEPTH_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //depthmap not supported with triplanar + if (!VisualServer::get_singleton()->is_low_end() && features[FEATURE_DEPTH_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //depthmap not supported with triplanar code += "\t{\n"; - code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT,-BINORMAL,NORMAL));\n"; //binormal is negative due to mikktpsace + code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,-BINORMAL*depth_flip.y,NORMAL));\n"; // binormal is negative due to mikktspace, flip 'unflips' it ;-) if (deep_parallax) { code += "\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n"; @@ -817,7 +843,7 @@ void SpatialMaterial::_update_shader() { code += "\tALPHA = albedo.a * albedo_tex.a;\n"; } - if (!VisualServer::get_singleton()->is_low_end() && proximity_fade_enabled) { + if (proximity_fade_enabled) { code += "\tfloat depth_tex = textureLod(DEPTH_TEXTURE,SCREEN_UV,0.0).r;\n"; code += "\tvec4 world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV*2.0-1.0,depth_tex*2.0-1.0,1.0);\n"; code += "\tworld_pos.xyz/=world_pos.w;\n"; @@ -1000,9 +1026,9 @@ void SpatialMaterial::flush_changes() { if (material_mutex) material_mutex->lock(); - while (dirty_materials.first()) { + while (dirty_materials->first()) { - dirty_materials.first()->self()->_update_shader(); + dirty_materials->first()->self()->_update_shader(); } if (material_mutex) @@ -1015,7 +1041,7 @@ void SpatialMaterial::_queue_shader_change() { material_mutex->lock(); if (!element.in_list()) { - dirty_materials.add(&element); + dirty_materials->add(&element); } if (material_mutex) @@ -1313,7 +1339,7 @@ void SpatialMaterial::set_flag(Flags p_flag, bool p_enabled) { return; flags[p_flag] = p_enabled; - if (p_flag == FLAG_USE_ALPHA_SCISSOR) { + if (p_flag == FLAG_USE_ALPHA_SCISSOR || p_flag == FLAG_UNSHADED) { _change_notify(); } _queue_shader_change(); @@ -1419,6 +1445,48 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const { if ((property.name == "depth_min_layers" || property.name == "depth_max_layers") && !deep_parallax) { property.usage = 0; } + + if (flags[FLAG_UNSHADED]) { + if (property.name.begins_with("anisotropy")) { + property.usage = 0; + } + + if (property.name.begins_with("ao")) { + property.usage = 0; + } + + if (property.name.begins_with("clearcoat")) { + property.usage = 0; + } + + if (property.name.begins_with("emission")) { + property.usage = 0; + } + + if (property.name.begins_with("metallic")) { + property.usage = 0; + } + + if (property.name.begins_with("normal")) { + property.usage = 0; + } + + if (property.name.begins_with("rim")) { + property.usage = 0; + } + + if (property.name.begins_with("roughness")) { + property.usage = 0; + } + + if (property.name.begins_with("subsurf_scatter")) { + property.usage = 0; + } + + if (property.name.begins_with("transmission")) { + property.usage = 0; + } + } } void SpatialMaterial::set_line_width(float p_line_width) { @@ -1541,13 +1609,13 @@ int SpatialMaterial::get_particles_anim_v_frames() const { return particles_anim_v_frames; } -void SpatialMaterial::set_particles_anim_loop(int p_frames) { +void SpatialMaterial::set_particles_anim_loop(bool p_loop) { - particles_anim_loop = p_frames; - VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, p_frames); + particles_anim_loop = p_loop; + VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop); } -int SpatialMaterial::get_particles_anim_loop() const { +bool SpatialMaterial::get_particles_anim_loop() const { return particles_anim_loop; } @@ -1584,6 +1652,28 @@ int SpatialMaterial::get_depth_deep_parallax_max_layers() const { return deep_parallax_max_layers; } +void SpatialMaterial::set_depth_deep_parallax_flip_tangent(bool p_flip) { + + depth_parallax_flip_tangent = p_flip; + VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_flip, Vector2(depth_parallax_flip_tangent ? -1 : 1, depth_parallax_flip_binormal ? -1 : 1)); +} + +bool SpatialMaterial::get_depth_deep_parallax_flip_tangent() const { + + return depth_parallax_flip_tangent; +} + +void SpatialMaterial::set_depth_deep_parallax_flip_binormal(bool p_flip) { + + depth_parallax_flip_binormal = p_flip; + VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_flip, Vector2(depth_parallax_flip_tangent ? -1 : 1, depth_parallax_flip_binormal ? -1 : 1)); +} + +bool SpatialMaterial::get_depth_deep_parallax_flip_binormal() const { + + return depth_parallax_flip_binormal; +} + void SpatialMaterial::set_grow_enabled(bool p_enable) { grow_enabled = p_enable; _queue_shader_change(); @@ -1898,7 +1988,7 @@ void SpatialMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_particles_anim_v_frames", "frames"), &SpatialMaterial::set_particles_anim_v_frames); ClassDB::bind_method(D_METHOD("get_particles_anim_v_frames"), &SpatialMaterial::get_particles_anim_v_frames); - ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "frames"), &SpatialMaterial::set_particles_anim_loop); + ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "loop"), &SpatialMaterial::set_particles_anim_loop); ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &SpatialMaterial::get_particles_anim_loop); ClassDB::bind_method(D_METHOD("set_depth_deep_parallax", "enable"), &SpatialMaterial::set_depth_deep_parallax); @@ -1910,6 +2000,12 @@ void SpatialMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_max_layers", "layer"), &SpatialMaterial::set_depth_deep_parallax_max_layers); ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_max_layers"), &SpatialMaterial::get_depth_deep_parallax_max_layers); + ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_flip_tangent", "flip"), &SpatialMaterial::set_depth_deep_parallax_flip_tangent); + ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_flip_tangent"), &SpatialMaterial::get_depth_deep_parallax_flip_tangent); + + ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_flip_binormal", "flip"), &SpatialMaterial::set_depth_deep_parallax_flip_binormal); + ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_flip_binormal"), &SpatialMaterial::get_depth_deep_parallax_flip_binormal); + ClassDB::bind_method(D_METHOD("set_grow", "amount"), &SpatialMaterial::set_grow); ClassDB::bind_method(D_METHOD("get_grow"), &SpatialMaterial::get_grow); @@ -2045,6 +2141,8 @@ void SpatialMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_deep_parallax"), "set_depth_deep_parallax", "is_depth_deep_parallax_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_min_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_depth_deep_parallax_min_layers", "get_depth_deep_parallax_min_layers"); ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_max_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_depth_deep_parallax_max_layers", "get_depth_deep_parallax_max_layers"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_flip_tangent"), "set_depth_deep_parallax_flip_tangent", "get_depth_deep_parallax_flip_tangent"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_flip_binormal"), "set_depth_deep_parallax_flip_binormal", "get_depth_deep_parallax_flip_binormal"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "depth_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DEPTH); ADD_GROUP("Subsurf Scatter", "subsurf_scatter_"); @@ -2244,8 +2342,11 @@ SpatialMaterial::SpatialMaterial() : set_grow(0.0); deep_parallax = false; + depth_parallax_flip_tangent = false; + depth_parallax_flip_binormal = false; set_depth_deep_parallax_min_layers(8); set_depth_deep_parallax_max_layers(32); + set_depth_deep_parallax_flip_tangent(false); //also sets binormal detail_uv = DETAIL_UV_1; blend_mode = BLEND_MODE_MIX; diff --git a/scene/resources/material.h b/scene/resources/material.h index cf4d19b5a7..1f7fc267af 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -338,6 +338,7 @@ private: StringName particles_anim_loop; StringName depth_min_layers; StringName depth_max_layers; + StringName depth_flip; StringName uv1_blend_sharpness; StringName uv2_blend_sharpness; StringName grow; @@ -359,7 +360,7 @@ private: }; static Mutex *material_mutex; - static SelfList<SpatialMaterial>::List dirty_materials; + static SelfList<SpatialMaterial>::List *dirty_materials; static ShaderNames *shader_names; SelfList<SpatialMaterial> element; @@ -407,6 +408,8 @@ private: bool deep_parallax; int deep_parallax_min_layers; int deep_parallax_max_layers; + bool depth_parallax_flip_tangent; + bool depth_parallax_flip_binormal; bool proximity_fade_enabled; float proximity_fade_distance; @@ -501,6 +504,12 @@ public: void set_depth_deep_parallax_max_layers(int p_layer); int get_depth_deep_parallax_max_layers() const; + void set_depth_deep_parallax_flip_tangent(bool p_flip); + bool get_depth_deep_parallax_flip_tangent() const; + + void set_depth_deep_parallax_flip_binormal(bool p_flip); + bool get_depth_deep_parallax_flip_binormal() const; + void set_subsurface_scattering_strength(float p_subsurface_scattering_strength); float get_subsurface_scattering_strength() const; @@ -574,8 +583,8 @@ public: void set_particles_anim_v_frames(int p_frames); int get_particles_anim_v_frames() const; - void set_particles_anim_loop(int p_frames); - int get_particles_anim_loop() const; + void set_particles_anim_loop(bool p_loop); + bool get_particles_anim_loop() const; void set_grow_enabled(bool p_enable); bool is_grow_enabled() const; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 6cd701eb9a..85018f38d7 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -84,15 +84,15 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { PoolVector<int> indices = a[ARRAY_INDEX]; PoolVector<int>::Read ir = indices.read(); - for (int i = 0; i < ic; i++) { - int index = ir[i]; + for (int j = 0; j < ic; j++) { + int index = ir[j]; facesw[widx++] = vr[index]; } } else { - for (int i = 0; i < vc; i++) - facesw[widx++] = vr[i]; + for (int j = 0; j < vc; j++) + facesw[widx++] = vr[j]; } } @@ -482,7 +482,7 @@ void Mesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lightmap_size_hint", "size"), &Mesh::set_lightmap_size_hint); ClassDB::bind_method(D_METHOD("get_lightmap_size_hint"), &Mesh::get_lightmap_size_hint); - ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint"); ClassDB::bind_method(D_METHOD("get_surface_count"), &Mesh::get_surface_count); ClassDB::bind_method(D_METHOD("surface_get_arrays", "surf_idx"), &Mesh::surface_get_arrays); @@ -706,6 +706,7 @@ bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const { Vector<AABB> skel_aabb = VS::get_singleton()->mesh_surface_get_skeleton_aabb(mesh, idx); Array arr; + arr.resize(skel_aabb.size()); for (int i = 0; i < skel_aabb.size(); i++) { arr[i] = skel_aabb[i]; } @@ -786,7 +787,6 @@ void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array & Surface s; VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)p_primitive, p_arrays, p_blend_shapes, p_flags); - surfaces.push_back(s); /* make aABB? */ { @@ -807,8 +807,9 @@ void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array & aabb.expand_to(vtx[i]); } - surfaces.write[surfaces.size() - 1].aabb = aabb; - surfaces.write[surfaces.size() - 1].is_2d = arr.get_type() == Variant::POOL_VECTOR2_ARRAY; + s.aabb = aabb; + s.is_2d = arr.get_type() == Variant::POOL_VECTOR2_ARRAY; + surfaces.push_back(s); _recompute_aabb(); } @@ -1027,34 +1028,6 @@ AABB ArrayMesh::get_custom_aabb() const { return custom_aabb; } -void ArrayMesh::center_geometry() { - - /* - Vector3 ofs = aabb.pos+aabb.size*0.5; - - for(int i=0;i<get_surface_count();i++) { - - PoolVector<Vector3> geom = surface_get_array(i,ARRAY_VERTEX); - int gc =geom.size(); - PoolVector<Vector3>::Write w = geom.write(); - surfaces[i].aabb.pos-=ofs; - - for(int i=0;i<gc;i++) { - - w[i]-=ofs; - } - - w = PoolVector<Vector3>::Write(); - - surface_set_array(i,ARRAY_VERTEX,geom); - - } - - aabb.pos-=ofs; - -*/ -} - void ArrayMesh::regen_normalmaps() { Vector<Ref<SurfaceTool> > surfs; @@ -1294,8 +1267,6 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("create_trimesh_shape"), &ArrayMesh::create_trimesh_shape); ClassDB::bind_method(D_METHOD("create_convex_shape"), &ArrayMesh::create_convex_shape); ClassDB::bind_method(D_METHOD("create_outline", "margin"), &ArrayMesh::create_outline); - ClassDB::bind_method(D_METHOD("center_geometry"), &ArrayMesh::center_geometry); - ClassDB::set_method_flags(get_class_static(), _scs_create("center_geometry"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); ClassDB::bind_method(D_METHOD("regen_normalmaps"), &ArrayMesh::regen_normalmaps); ClassDB::set_method_flags(get_class_static(), _scs_create("regen_normalmaps"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); ClassDB::bind_method(D_METHOD("lightmap_unwrap", "transform", "texel_size"), &ArrayMesh::lightmap_unwrap); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index aebba09ef8..dabfc6ea60 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -223,7 +223,6 @@ public: AABB get_aabb() const; virtual RID get_rid() const; - void center_geometry(); void regen_normalmaps(); Error lightmap_unwrap(const Transform &p_base_transform = Transform(), float p_texel_size = 0.05); diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp index a5449e1fe8..7cd765fb5d 100644 --- a/scene/resources/mesh_data_tool.cpp +++ b/scene/resources/mesh_data_tool.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -42,8 +42,6 @@ void MeshDataTool::clear() { Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surface) { ERR_FAIL_COND_V(p_mesh.is_null(), ERR_INVALID_PARAMETER); - - ERR_FAIL_COND_V(p_mesh.is_null(), ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_mesh->surface_get_primitive_type(p_surface) != Mesh::PRIMITIVE_TRIANGLES, ERR_INVALID_PARAMETER); Array arrays = p_mesh->surface_get_arrays(p_surface); diff --git a/scene/resources/mesh_data_tool.h b/scene/resources/mesh_data_tool.h index f614b80c3b..8f5def72c7 100644 --- a/scene/resources/mesh_data_tool.h +++ b/scene/resources/mesh_data_tool.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp index a1d3e0ba1e..c5125d576d 100644 --- a/scene/resources/mesh_library.cpp +++ b/scene/resources/mesh_library.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 3ce0cf9b66..849a0577eb 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp index e8e19fdb60..1b406551ab 100644 --- a/scene/resources/multimesh.cpp +++ b/scene/resources/multimesh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -166,11 +166,22 @@ void MultiMesh::set_instance_transform(int p_instance, const Transform &p_transf VisualServer::get_singleton()->multimesh_instance_set_transform(multimesh, p_instance, p_transform); } + +void MultiMesh::set_instance_transform_2d(int p_instance, const Transform2D &p_transform) { + + VisualServer::get_singleton()->multimesh_instance_set_transform_2d(multimesh, p_instance, p_transform); +} + Transform MultiMesh::get_instance_transform(int p_instance) const { return VisualServer::get_singleton()->multimesh_instance_get_transform(multimesh, p_instance); } +Transform2D MultiMesh::get_instance_transform_2d(int p_instance) const { + + return VisualServer::get_singleton()->multimesh_instance_get_transform_2d(multimesh, p_instance); +} + void MultiMesh::set_instance_color(int p_instance, const Color &p_color) { VisualServer::get_singleton()->multimesh_instance_set_color(multimesh, p_instance, p_color); @@ -245,7 +256,9 @@ void MultiMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_instance_count", "count"), &MultiMesh::set_instance_count); ClassDB::bind_method(D_METHOD("get_instance_count"), &MultiMesh::get_instance_count); ClassDB::bind_method(D_METHOD("set_instance_transform", "instance", "transform"), &MultiMesh::set_instance_transform); + ClassDB::bind_method(D_METHOD("set_instance_transform_2d", "instance", "transform"), &MultiMesh::set_instance_transform_2d); ClassDB::bind_method(D_METHOD("get_instance_transform", "instance"), &MultiMesh::get_instance_transform); + ClassDB::bind_method(D_METHOD("get_instance_transform_2d", "instance"), &MultiMesh::get_instance_transform_2d); ClassDB::bind_method(D_METHOD("set_instance_color", "instance", "color"), &MultiMesh::set_instance_color); ClassDB::bind_method(D_METHOD("get_instance_color", "instance"), &MultiMesh::get_instance_color); ClassDB::bind_method(D_METHOD("set_instance_custom_data", "instance", "custom_data"), &MultiMesh::set_instance_custom_data); diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h index ec5a5ca4d5..ac2c69e022 100644 --- a/scene/resources/multimesh.h +++ b/scene/resources/multimesh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -94,7 +94,9 @@ public: int get_instance_count() const; void set_instance_transform(int p_instance, const Transform &p_transform); + void set_instance_transform_2d(int p_instance, const Transform2D &p_transform); Transform get_instance_transform(int p_instance) const; + Transform2D get_instance_transform_2d(int p_instance) const; void set_instance_color(int p_instance, const Color &p_color); Color get_instance_color(int p_instance) const; diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 42ce9d10cd..626ed9f5b4 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -55,7 +55,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { Node *p_name; \ if (p_id & FLAG_ID_IS_PATH) { \ NodePath np = node_paths[p_id & FLAG_MASK]; \ - p_name = ret_nodes[0]->_get_node(np); \ + p_name = ret_nodes[0]->get_node_or_null(np); \ } else { \ ERR_FAIL_INDEX_V(p_id &FLAG_MASK, nc, NULL); \ p_name = ret_nodes[p_id & FLAG_MASK]; \ @@ -92,6 +92,8 @@ Node *SceneState::instance(GenEditState p_edit_state) const { if (i > 0) { + ERR_EXPLAIN(vformat("Invalid scene: node %s does not specify its parent node.", snames[n.name])) + ERR_FAIL_COND_V(n.parent == -1, NULL) NODE_FROM_ID(nparent, n.parent); #ifdef DEBUG_ENABLED if (!nparent && (n.parent & FLAG_ID_IS_PATH)) { @@ -175,8 +177,8 @@ Node *SceneState::instance(GenEditState p_edit_state) const { node = Object::cast_to<Node>(obj); } else { - print_line("Class is disabled for: " + itos(n.type)); - print_line("name: " + String(snames[n.type])); + //print_line("Class is disabled for: " + itos(n.type)); + //print_line("name: " + String(snames[n.type])); } if (node) { @@ -236,8 +238,8 @@ Node *SceneState::instance(GenEditState p_edit_state) const { } else { //for instances, a copy must be made - Node *base = i == 0 ? node : ret_nodes[0]; - Ref<Resource> local_dupe = res->duplicate_for_local_scene(base, resources_local_to_scene); + Node *base2 = i == 0 ? node : ret_nodes[0]; + Ref<Resource> local_dupe = res->duplicate_for_local_scene(base2, resources_local_to_scene); resources_local_to_scene[res] = local_dupe; res = local_dupe; value = local_dupe; @@ -296,8 +298,8 @@ Node *SceneState::instance(GenEditState p_edit_state) const { ret_nodes[i] = node; if (node && gen_node_path_cache && ret_nodes[0]) { - NodePath n = ret_nodes[0]->get_path_to(node); - node_path_cache[n] = i; + NodePath n2 = ret_nodes[0]->get_path_to(node); + node_path_cache[n2] = i; } } @@ -342,7 +344,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { } for (int i = 0; i < editable_instances.size(); i++) { - Node *ei = ret_nodes[0]->_get_node(editable_instances[i]); + Node *ei = ret_nodes[0]->get_node_or_null(editable_instances[i]); if (ei) { ret_nodes[0]->set_editable_instance(ei, true); } @@ -472,6 +474,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map List<PropertyInfo> plist; p_node->get_property_list(&plist); + StringName type = p_node->get_class(); for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { @@ -482,12 +485,23 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map String name = E->get().name; Variant value = p_node->get(E->get().name); - bool isdefault = ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO) && value.is_zero()) || ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONONE) && value.is_one()); + bool isdefault = false; + Variant default_value = ClassDB::class_get_default_property_value(type, name); - if (E->get().usage & PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE) { - isdefault = true; //is script default value + if (default_value.get_type() != Variant::NIL) { + isdefault = bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value)); } + Ref<Script> script = p_node->get_script(); + if (!isdefault && script.is_valid() && script->get_property_default_value(name, default_value)) { + isdefault = bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value)); + } + // the version above makes more sense, because it does not rely on placeholder or usage flag + // in the script, just the default value function. + // if (E->get().usage & PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE) { + // isdefault = true; //is script default value + // } + if (pack_state_stack.size()) { // we are on part of an instanced subscene // or part of instanced scene. @@ -737,7 +751,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName { Node *nl = p_node; - bool exists = false; + bool exists2 = false; while (nl) { @@ -751,7 +765,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName if (from_node >= 0 && to_node >= 0) { //this one has state for this node, save if (state->is_connection(from_node, c.signal, to_node, c.method)) { - exists = true; + exists2 = true; break; } } @@ -769,7 +783,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName if (from_node >= 0 && to_node >= 0) { //this one has state for this node, save if (state->is_connection(from_node, c.signal, to_node, c.method)) { - exists = true; + exists2 = true; break; } } @@ -779,7 +793,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName } } - if (exists) { + if (exists2) { continue; } } diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index e5f22f5e3b..3c05929dea 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index ba48982fda..ef67e6ea80 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,7 +31,7 @@ #include "particles_material.h" Mutex *ParticlesMaterial::material_mutex = NULL; -SelfList<ParticlesMaterial>::List ParticlesMaterial::dirty_materials; +SelfList<ParticlesMaterial>::List *ParticlesMaterial::dirty_materials = NULL; Map<ParticlesMaterial::MaterialKey, ParticlesMaterial::ShaderData> ParticlesMaterial::shader_map; ParticlesMaterial::ShaderNames *ParticlesMaterial::shader_names = NULL; @@ -41,6 +41,8 @@ void ParticlesMaterial::init_shaders() { material_mutex = Mutex::create(); #endif + dirty_materials = memnew(SelfList<ParticlesMaterial>::List); + shader_names = memnew(ShaderNames); shader_names->spread = "spread"; @@ -106,12 +108,15 @@ void ParticlesMaterial::finish_shaders() { memdelete(material_mutex); #endif + memdelete(dirty_materials); + dirty_materials = NULL; + memdelete(shader_names); } void ParticlesMaterial::_update_shader() { - dirty_materials.remove(&element); + dirty_materials->remove(&element); MaterialKey mk = _compute_key(); if (mk.key == current_key.key) @@ -306,8 +311,8 @@ void ParticlesMaterial::_update_shader() { //initiate velocity spread in 3D code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; - code += " vec3 direction_xz = vec3(sin(angle1_rad), 0, cos(angle1_rad));\n"; - code += " vec3 direction_yz = vec3(0, sin(angle2_rad), cos(angle2_rad));\n"; + code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n"; + code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n"; code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n"; code += " vec3 direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n"; code += " direction = normalize(direction);\n"; @@ -342,7 +347,7 @@ void ParticlesMaterial::_update_shader() { code += " VELOCITY.xy = rotm * VELOCITY.xy;\n"; } else { code += " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xyz;\n"; - code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0, 1.0, 0.0);\n"; + code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);\n"; code += " vec3 tangent = normalize(cross(v0, normal));\n"; code += " vec3 bitangent = normalize(cross(tangent, normal));\n"; code += " VELOCITY = mat3(tangent, bitangent, normal) * VELOCITY;\n"; @@ -463,12 +468,6 @@ void ParticlesMaterial::_update_shader() { code += " base_angle += CUSTOM.y * LIFETIME * (angular_velocity + tex_angular_velocity) * mix(1.0, rand_from_seed(alt_seed) * 2.0 - 1.0, angular_velocity_random);\n"; code += " CUSTOM.x = base_angle * degree_to_rad;\n"; // angle code += " CUSTOM.z = (anim_offset + tex_anim_offset) * mix(1.0, anim_offset_rand, anim_offset_random) + CUSTOM.y * (anim_speed + tex_anim_speed) * mix(1.0, rand_from_seed(alt_seed), anim_speed_random);\n"; // angle - if (flags[FLAG_ANIM_LOOP]) { - code += " CUSTOM.z = mod(CUSTOM.z, 1.0);\n"; // loop - - } else { - code += " CUSTOM.z = clamp(CUSTOM.z, 0.0, 1.0);\n"; // 0 to 1 only - } code += " }\n"; // apply color // apply hue rotation @@ -590,9 +589,9 @@ void ParticlesMaterial::flush_changes() { if (material_mutex) material_mutex->lock(); - while (dirty_materials.first()) { + while (dirty_materials->first()) { - dirty_materials.first()->self()->_update_shader(); + dirty_materials->first()->self()->_update_shader(); } if (material_mutex) @@ -605,7 +604,7 @@ void ParticlesMaterial::_queue_shader_change() { material_mutex->lock(); if (!element.in_list()) { - dirty_materials.add(&element); + dirty_materials->add(&element); } if (material_mutex) @@ -803,12 +802,7 @@ void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture> } break; case PARAM_SCALE: { VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_texture, p_texture); - - Ref<CurveTexture> curve_tex = p_texture; - if (curve_tex.is_valid()) { - curve_tex->ensure_default_setup(); - } - + _adjust_curve_range(p_texture, 0, 1); } break; case PARAM_HUE_VARIATION: { VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_texture, p_texture); @@ -1129,7 +1123,7 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY); ADD_GROUP("Angular Velocity", "angular_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-360,360,0.01"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGULAR_VELOCITY); ADD_GROUP("Orbit Velocity", "orbit_"); @@ -1165,7 +1159,7 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_color_ramp", "get_color_ramp"); ADD_GROUP("Hue Variation", "hue_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.1"), "set_param", "get_param", PARAM_HUE_VARIATION); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_HUE_VARIATION); ADD_GROUP("Animation", "anim_"); @@ -1175,7 +1169,6 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_OFFSET); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "anim_loop"), "set_flag", "get_flag", FLAG_ANIM_LOOP); BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY); BIND_ENUM_CONSTANT(PARAM_ANGULAR_VELOCITY); diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 91fdcc0346..8b3248a9cb 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -60,7 +60,6 @@ public: FLAG_ALIGN_Y_TO_VELOCITY, FLAG_ROTATE_Y, FLAG_DISABLE_Z, - FLAG_ANIM_LOOP, FLAG_MAX }; @@ -127,7 +126,7 @@ private: } static Mutex *material_mutex; - static SelfList<ParticlesMaterial>::List dirty_materials; + static SelfList<ParticlesMaterial>::List *dirty_materials; struct ShaderNames { StringName spread; diff --git a/scene/resources/physics_material.cpp b/scene/resources/physics_material.cpp index 03b3589727..7d97c279ed 100644 --- a/scene/resources/physics_material.cpp +++ b/scene/resources/physics_material.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/physics_material.h b/scene/resources/physics_material.h index bf11bf0ac1..30660e80ac 100644 --- a/scene/resources/physics_material.h +++ b/scene/resources/physics_material.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/plane_shape.cpp b/scene/resources/plane_shape.cpp index 4d38ebe090..419ff8f972 100644 --- a/scene/resources/plane_shape.cpp +++ b/scene/resources/plane_shape.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/plane_shape.h b/scene/resources/plane_shape.h index c24c9474fb..87c367cfde 100644 --- a/scene/resources/plane_shape.h +++ b/scene/resources/plane_shape.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp index bd03930c9e..52fc21ac11 100644 --- a/scene/resources/polygon_path_finder.cpp +++ b/scene/resources/polygon_path_finder.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -441,9 +441,9 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) { PoolVector<float> penalties = p_data["penalties"]; if (penalties.size() == pc) { - PoolVector<float>::Read pr = penalties.read(); + PoolVector<float>::Read pr2 = penalties.read(); for (int i = 0; i < pc; i++) { - points.write[i].penalty = pr[i]; + points.write[i].penalty = pr2[i]; } } } diff --git a/scene/resources/polygon_path_finder.h b/scene/resources/polygon_path_finder.h index 66282458af..59387e9672 100644 --- a/scene/resources/polygon_path_finder.h +++ b/scene/resources/polygon_path_finder.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 63aa44e1d8..db58fe7823 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -102,6 +102,9 @@ void PrimitiveMesh::_request_update() { } int PrimitiveMesh::get_surface_count() const { + if (pending_request) { + _update(); + } return 1; } @@ -303,7 +306,7 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { Vector3 p = Vector3(x * radius * w, y * radius * w, z); points.push_back(p + Vector3(0.0, 0.0, 0.5 * mid_height)); normals.push_back(p.normalized()); - ADD_TANGENT(y, -x, 0.0, -1.0) + ADD_TANGENT(-y, x, 0.0, 1.0) uvs.push_back(Vector2(u, v * onethird)); point++; @@ -342,7 +345,7 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { Vector3 p = Vector3(x * radius, y * radius, z); points.push_back(p); normals.push_back(Vector3(x, y, 0.0)); - ADD_TANGENT(y, -x, 0.0, -1.0) + ADD_TANGENT(-y, x, 0.0, 1.0) uvs.push_back(Vector2(u, onethird + (v * onethird))); point++; @@ -373,17 +376,17 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { z = radius * cos(0.5 * Math_PI * v); for (i = 0; i <= radial_segments; i++) { - float u = i; - u /= radial_segments; + float u2 = i; + u2 /= radial_segments; - x = sin(u * (Math_PI * 2.0)); - y = -cos(u * (Math_PI * 2.0)); + x = sin(u2 * (Math_PI * 2.0)); + y = -cos(u2 * (Math_PI * 2.0)); Vector3 p = Vector3(x * radius * w, y * radius * w, z); points.push_back(p + Vector3(0.0, 0.0, -0.5 * mid_height)); normals.push_back(p.normalized()); - ADD_TANGENT(y, -x, 0.0, -1.0) - uvs.push_back(Vector2(u, twothirds + ((v - 1.0) * onethird))); + ADD_TANGENT(-y, x, 0.0, 1.0) + uvs.push_back(Vector2(u2, twothirds + ((v - 1.0) * onethird))); point++; if (i > 0 && j > 0) { @@ -511,14 +514,14 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const { // front points.push_back(Vector3(x, -y, -start_pos.z)); // double negative on the Z! normals.push_back(Vector3(0.0, 0.0, 1.0)); - ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(1.0, 0.0, 0.0, 1.0); uvs.push_back(Vector2(u, v)); point++; // back points.push_back(Vector3(-x, -y, start_pos.z)); normals.push_back(Vector3(0.0, 0.0, -1.0)); - ADD_TANGENT(1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(-1.0, 0.0, 0.0, 1.0); uvs.push_back(Vector2(twothirds + u, v)); point++; @@ -565,14 +568,14 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const { // right points.push_back(Vector3(-start_pos.x, -y, -z)); normals.push_back(Vector3(1.0, 0.0, 0.0)); - ADD_TANGENT(0.0, 0.0, 1.0, -1.0); + ADD_TANGENT(0.0, 0.0, -1.0, 1.0); uvs.push_back(Vector2(onethird + u, v)); point++; // left points.push_back(Vector3(start_pos.x, -y, z)); normals.push_back(Vector3(-1.0, 0.0, 0.0)); - ADD_TANGENT(0.0, 0.0, -1.0, -1.0); + ADD_TANGENT(0.0, 0.0, 1.0, 1.0); uvs.push_back(Vector2(u, 0.5 + v)); point++; @@ -619,14 +622,14 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const { // top points.push_back(Vector3(-x, -start_pos.y, -z)); normals.push_back(Vector3(0.0, 1.0, 0.0)); - ADD_TANGENT(1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(-1.0, 0.0, 0.0, 1.0); uvs.push_back(Vector2(onethird + u, 0.5 + v)); point++; // bottom points.push_back(Vector3(x, start_pos.y, -z)); normals.push_back(Vector3(0.0, -1.0, 0.0)); - ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(1.0, 0.0, 0.0, 1.0); uvs.push_back(Vector2(twothirds + u, 0.5 + v)); point++; @@ -770,7 +773,7 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { Vector3 p = Vector3(x * radius, y, z * radius); points.push_back(p); normals.push_back(Vector3(x, 0.0, z)); - ADD_TANGENT(-z, 0.0, x, -1.0) + ADD_TANGENT(z, 0.0, -x, 1.0) uvs.push_back(Vector2(u, v * 0.5)); point++; @@ -832,7 +835,7 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { thisrow = point; points.push_back(Vector3(0.0, y, 0.0)); normals.push_back(Vector3(0.0, -1.0, 0.0)); - ADD_TANGENT(-1.0, 0.0, 0.0, -1.0) + ADD_TANGENT(1.0, 0.0, 0.0, 1.0) uvs.push_back(Vector2(0.75, 0.75)); point++; @@ -849,7 +852,7 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { Vector3 p = Vector3(x * bottom_radius, y, z * bottom_radius); points.push_back(p); normals.push_back(Vector3(0.0, -1.0, 0.0)); - ADD_TANGENT(-1.0, 0.0, 0.0, -1.0) + ADD_TANGENT(1.0, 0.0, 0.0, 1.0) uvs.push_back(Vector2(u, v)); point++; @@ -979,8 +982,8 @@ void PlaneMesh::_create_mesh_array(Array &p_arr) const { points.push_back(Vector3(-x, 0.0, -z)); normals.push_back(Vector3(0.0, 1.0, 0.0)); - ADD_TANGENT(1.0, 0.0, 0.0, -1.0); - uvs.push_back(Vector2(u, v)); + ADD_TANGENT(1.0, 0.0, 0.0, 1.0); + uvs.push_back(Vector2(1.0 - u, 1.0 - v)); /* 1.0 - uv to match orientation with Quad */ point++; if (i > 0 && j > 0) { @@ -1105,14 +1108,14 @@ void PrismMesh::_create_mesh_array(Array &p_arr) const { /* front */ points.push_back(Vector3(start_x + x, -y, -start_pos.z)); // double negative on the Z! normals.push_back(Vector3(0.0, 0.0, 1.0)); - ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(1.0, 0.0, 0.0, 1.0); uvs.push_back(Vector2(offset_front + u, v)); point++; /* back */ points.push_back(Vector3(start_x + scaled_size_x - x, -y, start_pos.z)); normals.push_back(Vector3(0.0, 0.0, -1.0)); - ADD_TANGENT(1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(-1.0, 0.0, 0.0, 1.0); uvs.push_back(Vector2(twothirds + offset_back + u, v)); point++; @@ -1184,14 +1187,14 @@ void PrismMesh::_create_mesh_array(Array &p_arr) const { /* right */ points.push_back(Vector3(right, -y, -z)); normals.push_back(normal_right); - ADD_TANGENT(0.0, 0.0, 1.0, -1.0); + ADD_TANGENT(0.0, 0.0, -1.0, 1.0); uvs.push_back(Vector2(onethird + u, v)); point++; /* left */ points.push_back(Vector3(left, -y, z)); normals.push_back(normal_left); - ADD_TANGENT(0.0, 0.0, -1.0, -1.0); + ADD_TANGENT(0.0, 0.0, 1.0, 1.0); uvs.push_back(Vector2(u, 0.5 + v)); point++; @@ -1238,7 +1241,7 @@ void PrismMesh::_create_mesh_array(Array &p_arr) const { /* bottom */ points.push_back(Vector3(x, start_pos.y, -z)); normals.push_back(Vector3(0.0, -1.0, 0.0)); - ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(1.0, 0.0, 0.0, 1.0); uvs.push_back(Vector2(twothirds + u, 0.5 + v)); point++; @@ -1282,7 +1285,7 @@ void PrismMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &PrismMesh::get_subdivide_depth); ADD_PROPERTY(PropertyInfo(Variant::REAL, "left_to_right", PROPERTY_HINT_RANGE, "-2.0,2.0,0.1"), "set_left_to_right", "get_left_to_right"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_width", "get_subdivide_width"); ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_height", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_height", "get_subdivide_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_depth", "get_subdivide_depth"); @@ -1465,7 +1468,7 @@ void SphereMesh::_create_mesh_array(Array &p_arr) const { points.push_back(p); normals.push_back(p.normalized()); }; - ADD_TANGENT(-z, 0.0, x, -1.0) + ADD_TANGENT(z, 0.0, -x, 1.0) uvs.push_back(Vector2(u, v)); point++; diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index a91aa09ffe..88a26801b7 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/ray_shape.cpp b/scene/resources/ray_shape.cpp index a9dec3e87c..b7925d8a58 100644 --- a/scene/resources/ray_shape.cpp +++ b/scene/resources/ray_shape.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/ray_shape.h b/scene/resources/ray_shape.h index f11b2e7c3c..89fc34051c 100644 --- a/scene/resources/ray_shape.h +++ b/scene/resources/ray_shape.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp index aeb22f6d0a..ff0743a8dd 100644 --- a/scene/resources/rectangle_shape_2d.cpp +++ b/scene/resources/rectangle_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/rectangle_shape_2d.h b/scene/resources/rectangle_shape_2d.h index 2d66d328fd..27305e5918 100644 --- a/scene/resources/rectangle_shape_2d.h +++ b/scene/resources/rectangle_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/resource_format_text.cpp index 597ffe49ae..210fbe9f20 100644 --- a/scene/resources/scene_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -1,12 +1,12 @@ /*************************************************************************/ -/* scene_format_text.cpp */ +/* resource_format_text.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "scene_format_text.h" +#include "resource_format_text.h" + #include "core/io/resource_format_binary.h" #include "core/os/dir_access.h" #include "core/project_settings.h" @@ -626,14 +627,14 @@ Error ResourceInteractiveLoaderText::poll() { if (!packed_scene.is_valid()) return error; - error = OK; + error = ERR_FILE_EOF; //get it here resource = packed_scene; if (!ResourceCache::has(res_path)) { packed_scene->set_path(res_path); } - return ERR_FILE_EOF; + return error; } else { error_text += "Unknown tag in file: " + next_tag.name; @@ -1360,7 +1361,9 @@ String ResourceFormatSaverTextInstance::_write_resource(const RES &res) { if (internal_resources.has(res)) { return "SubResource( " + itos(internal_resources[res]) + " )"; } else if (res->get_path().length() && res->get_path().find("::") == -1) { - + if (res->get_path() == local_path) { //circular reference attempt + return "null"; + } //external resource String path = relative_paths ? local_path.path_to_file(res->get_path()) : res->get_path(); return "Resource( \"" + path + "\" )"; @@ -1385,6 +1388,10 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, return; if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) { + if (res->get_path() == local_path) { + ERR_PRINTS("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded."); + return; + } int index = external_resources.size(); external_resources[res] = index; return; @@ -1407,7 +1414,20 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, if (pi.usage & PROPERTY_USAGE_STORAGE) { Variant v = res->get(I->get().name); - _find_resources(v); + + if (pi.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { + RES sres = v; + if (sres.is_valid()) { + NonPersistentKey npk; + npk.base = res; + npk.property = pi.name; + non_persistent_map[npk] = sres; + resource_set.insert(sres); + saved_resources.push_back(sres); + } + } else { + _find_resources(v); + } } I = I->next(); @@ -1562,7 +1582,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r break; //save as a scene if (main) { - f->store_line("[resource]\n"); + f->store_line("[resource]"); } else { String line = "[sub_resource "; if (res->get_subindex() == 0) { @@ -1577,7 +1597,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r int idx = res->get_subindex(); line += "type=\"" + res->get_class() + "\" id=" + itos(idx); - f->store_line(line + "]\n"); + f->store_line(line + "]"); if (takeover_paths) { res->set_path(p_path + "::" + itos(idx), true); } @@ -1599,10 +1619,22 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r if (PE->get().usage & PROPERTY_USAGE_STORAGE) { String name = PE->get().name; - Variant value = res->get(name); + Variant value; + if (PE->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { + NonPersistentKey npk; + npk.base = res; + npk.property = name; + if (non_persistent_map.has(npk)) { + value = non_persistent_map[npk]; + } + } else { + value = res->get(name); + } + Variant default_value = ClassDB::class_get_default_property_value(res->get_class(), name); - if ((PE->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO && value.is_zero()) || (PE->get().usage & PROPERTY_USAGE_STORE_IF_NONONE && value.is_one())) + if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value))) { continue; + } if (PE->get().type == Variant::OBJECT && value.is_zero() && !(PE->get().usage & PROPERTY_USAGE_STORE_IF_NULL)) continue; diff --git a/scene/resources/scene_format_text.h b/scene/resources/resource_format_text.h index 8d1af2bbb2..8d78ab33b0 100644 --- a/scene/resources/scene_format_text.h +++ b/scene/resources/resource_format_text.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* scene_format_text.h */ +/* resource_format_text.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCENE_FORMAT_TEXT_H -#define SCENE_FORMAT_TEXT_H +#ifndef RESOURCE_FORMAT_TEXT_H +#define RESOURCE_FORMAT_TEXT_H #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" @@ -128,7 +128,7 @@ public: }; class ResourceFormatLoaderText : public ResourceFormatLoader { - + GDCLASS(ResourceFormatLoaderText, ResourceFormatLoader) public: static ResourceFormatLoaderText *singleton; virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); @@ -155,6 +155,15 @@ class ResourceFormatSaverTextInstance { bool bundle_resources; bool skip_editor; FileAccess *f; + + struct NonPersistentKey { //for resource properties generated on the fly + RES base; + StringName property; + bool operator<(const NonPersistentKey &p_key) const { return base == p_key.base ? property < p_key.property : base < p_key.base; } + }; + + Map<NonPersistentKey, RES> non_persistent_map; + Set<RES> resource_set; List<RES> saved_resources; Map<RES, int> external_resources; @@ -170,6 +179,7 @@ public: }; class ResourceFormatSaverText : public ResourceFormatSaver { + GDCLASS(ResourceFormatSaverText, ResourceFormatSaver) public: static ResourceFormatSaverText *singleton; virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); @@ -179,4 +189,4 @@ public: ResourceFormatSaverText(); }; -#endif // SCENE_FORMAT_TEXT_H +#endif // RESOURCE_FORMAT_TEXT_H diff --git a/scene/resources/room.cpp b/scene/resources/room.cpp index 9493f8fbe6..103a7ede74 100644 --- a/scene/resources/room.cpp +++ b/scene/resources/room.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/room.h b/scene/resources/room.h index d5ad847516..8990056f46 100644 --- a/scene/resources/room.h +++ b/scene/resources/room.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp index 58027c127d..62c5f9bab3 100644 --- a/scene/resources/segment_shape_2d.cpp +++ b/scene/resources/segment_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/segment_shape_2d.h b/scene/resources/segment_shape_2d.h index 700982ac0a..f35707b990 100644 --- a/scene/resources/segment_shape_2d.h +++ b/scene/resources/segment_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 66bf3b4991..89570beb5f 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/shader.h b/scene/resources/shader.h index c2c205237f..fb493046fc 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -100,6 +100,7 @@ public: VARIANT_ENUM_CAST(Shader::Mode); class ResourceFormatLoaderShader : public ResourceFormatLoader { + GDCLASS(ResourceFormatLoaderShader, ResourceFormatLoader) public: virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual void get_recognized_extensions(List<String> *p_extensions) const; @@ -108,6 +109,7 @@ public: }; class ResourceFormatSaverShader : public ResourceFormatSaver { + GDCLASS(ResourceFormatSaverShader, ResourceFormatSaver) public: virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; diff --git a/scene/resources/shape.cpp b/scene/resources/shape.cpp index 869f4a3a9b..825b7f4c8b 100644 --- a/scene/resources/shape.cpp +++ b/scene/resources/shape.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -101,7 +101,7 @@ void Shape::_bind_methods() { ClassDB::bind_method(D_METHOD("set_margin", "margin"), &Shape::set_margin); ClassDB::bind_method(D_METHOD("get_margin"), &Shape::get_margin); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0.04,10,0.001"), "set_margin", "get_margin"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_margin", "get_margin"); } Shape::Shape() : diff --git a/scene/resources/shape.h b/scene/resources/shape.h index 6643f4ee44..de99a967a8 100644 --- a/scene/resources/shape.h +++ b/scene/resources/shape.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/shape_2d.cpp b/scene/resources/shape_2d.cpp index 0ca518e5bb..e2407e4423 100644 --- a/scene/resources/shape_2d.cpp +++ b/scene/resources/shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -59,37 +59,37 @@ bool Shape2D::collide(const Transform2D &p_local_xform, const Ref<Shape2D> &p_sh return Physics2DServer::get_singleton()->shape_collide(get_rid(), p_local_xform, Vector2(), p_shape->get_rid(), p_shape_xform, Vector2(), NULL, 0, r); } -Variant Shape2D::collide_with_motion_and_get_contacts(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion) { +Array Shape2D::collide_with_motion_and_get_contacts(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion) { - ERR_FAIL_COND_V(p_shape.is_null(), Variant()); + ERR_FAIL_COND_V(p_shape.is_null(), Array()); const int max_contacts = 16; Vector2 result[max_contacts * 2]; int contacts = 0; if (!Physics2DServer::get_singleton()->shape_collide(get_rid(), p_local_xform, p_local_motion, p_shape->get_rid(), p_shape_xform, p_shape_motion, result, max_contacts, contacts)) - return Variant(); + return Array(); Array results; results.resize(contacts * 2); - for (int i = 0; i < contacts; i++) { + for (int i = 0; i < contacts * 2; i++) { results[i] = result[i]; } return results; } -Variant Shape2D::collide_and_get_contacts(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform) { +Array Shape2D::collide_and_get_contacts(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform) { - ERR_FAIL_COND_V(p_shape.is_null(), Variant()); + ERR_FAIL_COND_V(p_shape.is_null(), Array()); const int max_contacts = 16; Vector2 result[max_contacts * 2]; int contacts = 0; if (!Physics2DServer::get_singleton()->shape_collide(get_rid(), p_local_xform, Vector2(), p_shape->get_rid(), p_shape_xform, Vector2(), result, max_contacts, contacts)) - return Variant(); + return Array(); Array results; results.resize(contacts * 2); - for (int i = 0; i < contacts; i++) { + for (int i = 0; i < contacts * 2; i++) { results[i] = result[i]; } diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h index fa39daa565..da9b80477c 100644 --- a/scene/resources/shape_2d.h +++ b/scene/resources/shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -53,8 +53,8 @@ public: bool collide_with_motion(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion); bool collide(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform); - Variant collide_with_motion_and_get_contacts(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion); - Variant collide_and_get_contacts(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform); + Array collide_with_motion_and_get_contacts(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion); + Array collide_and_get_contacts(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform); virtual void draw(const RID &p_to_rid, const Color &p_color) {} virtual Rect2 get_rect() const { return Rect2(); } diff --git a/scene/resources/sky_box.cpp b/scene/resources/sky.cpp index a6a52c7bba..f9f8ff19e4 100644 --- a/scene/resources/sky_box.cpp +++ b/scene/resources/sky.cpp @@ -1,12 +1,12 @@ /*************************************************************************/ -/* sky_box.cpp */ +/* sky.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "sky_box.h" +#include "sky.h" + #include "core/io/image_loader.h" void Sky::set_radiance_size(RadianceSize p_size) { @@ -155,7 +156,10 @@ Ref<Image> ProceduralSky::_generate_sky() { Color ground_bottom_linear = ground_bottom_color.to_linear(); Color ground_horizon_linear = ground_horizon_color.to_linear(); - //Color sun_linear = sun_color.to_linear(); + Color sun_linear; + sun_linear.r = sun_color.r * sun_energy; + sun_linear.g = sun_color.g * sun_energy; + sun_linear.b = sun_color.b * sun_energy; Vector3 sun(0, 0, -1); @@ -190,20 +194,26 @@ Ref<Image> ProceduralSky::_generate_sky() { float c = (v_angle - (Math_PI * 0.5)) / (Math_PI * 0.5); color = ground_horizon_linear.linear_interpolate(ground_bottom_linear, Math::ease(c, ground_curve)); + color.r *= ground_energy; + color.g *= ground_energy; + color.b *= ground_energy; } else { float c = v_angle / (Math_PI * 0.5); color = sky_horizon_linear.linear_interpolate(sky_top_linear, Math::ease(1.0 - c, sky_curve)); + color.r *= sky_energy; + color.g *= sky_energy; + color.b *= sky_energy; float sun_angle = Math::rad2deg(Math::acos(CLAMP(sun.dot(normal), -1.0, 1.0))); if (sun_angle < sun_angle_min) { - color = color.blend(sun_color); + color = color.blend(sun_linear); } else if (sun_angle < sun_angle_max) { float c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min); c2 = Math::ease(c2, sun_curve); - color = color.blend(sun_color).linear_interpolate(color, c2); + color = color.blend(sun_linear).linear_interpolate(color, c2); } } @@ -526,7 +536,7 @@ void ProceduralSky::_bind_methods() { BIND_ENUM_CONSTANT(TEXTURE_SIZE_MAX); } -ProceduralSky::ProceduralSky() { +ProceduralSky::ProceduralSky(bool p_desaturate) { sky = VS::get_singleton()->sky_create(); texture = VS::get_singleton()->texture_create(); @@ -542,13 +552,19 @@ ProceduralSky::ProceduralSky() { ground_curve = 0.02; ground_energy = 1; + if (p_desaturate) { + sky_top_color.set_hsv(sky_top_color.get_h(),0,sky_top_color.get_v()); + sky_horizon_color.set_hsv(sky_horizon_color.get_h(),0,sky_horizon_color.get_v()); + ground_bottom_color.set_hsv(ground_bottom_color.get_h(),0,ground_bottom_color.get_v()); + ground_horizon_color.set_hsv(ground_horizon_color.get_h(),0,ground_horizon_color.get_v()); + } sun_color = Color(1, 1, 1); sun_latitude = 35; sun_longitude = 0; sun_angle_min = 1; sun_angle_max = 100; sun_curve = 0.05; - sun_energy = 16; + sun_energy = 1; texture_size = TEXTURE_SIZE_1024; sky_thread = NULL; diff --git a/scene/resources/sky_box.h b/scene/resources/sky.h index bbb852822d..7327b2a627 100644 --- a/scene/resources/sky_box.h +++ b/scene/resources/sky.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* sky_box.h */ +/* sky.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,11 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKY_BOX_H -#define SKY_BOX_H +#ifndef SKY_H +#define SKY_H #include "core/os/thread.h" #include "scene/resources/texture.h" + class Sky : public Resource { GDCLASS(Sky, Resource); @@ -190,10 +191,10 @@ public: virtual RID get_rid() const; - ProceduralSky(); + ProceduralSky(bool p_desaturate=false); ~ProceduralSky(); }; VARIANT_ENUM_CAST(ProceduralSky::TextureSize) -#endif // SKY_BOX_H +#endif // SKY_H diff --git a/scene/resources/space_2d.cpp b/scene/resources/space_2d.cpp index 062f4099db..e6d366c501 100644 --- a/scene/resources/space_2d.cpp +++ b/scene/resources/space_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/space_2d.h b/scene/resources/space_2d.h index 1143ad2bd5..ced7c87406 100644 --- a/scene/resources/space_2d.h +++ b/scene/resources/space_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/sphere_shape.cpp b/scene/resources/sphere_shape.cpp index d8ca1cf3f1..492cf3959d 100644 --- a/scene/resources/sphere_shape.cpp +++ b/scene/resources/sphere_shape.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/sphere_shape.h b/scene/resources/sphere_shape.h index 5dd7daabc5..682928e885 100644 --- a/scene/resources/sphere_shape.h +++ b/scene/resources/sphere_shape.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index 05050a5ea2..cdd65c7642 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,6 +29,8 @@ /*************************************************************************/ #include "style_box.h" +#include "scene/2d/canvas_item.h" + #include <limits.h> bool StyleBox::test_mask(const Point2 &p_point, const Rect2 &p_rect) const { @@ -54,6 +56,10 @@ float StyleBox::get_margin(Margin p_margin) const { return margin[p_margin]; } +CanvasItem *StyleBox::get_current_item_drawn() const { + return CanvasItem::get_current_item_drawn(); +} + Size2 StyleBox::get_minimum_size() const { return Size2(get_margin(MARGIN_LEFT) + get_margin(MARGIN_RIGHT), get_margin(MARGIN_TOP) + get_margin(MARGIN_BOTTOM)); @@ -83,6 +89,7 @@ void StyleBox::_bind_methods() { ClassDB::bind_method(D_METHOD("get_minimum_size"), &StyleBox::get_minimum_size); ClassDB::bind_method(D_METHOD("get_center_size"), &StyleBox::get_center_size); ClassDB::bind_method(D_METHOD("get_offset"), &StyleBox::get_offset); + ClassDB::bind_method(D_METHOD("get_current_item_drawn"), &StyleBox::get_current_item_drawn); ClassDB::bind_method(D_METHOD("draw", "canvas_item", "rect"), &StyleBox::draw); @@ -310,7 +317,7 @@ void StyleBoxTexture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); - ADD_PROPERTYNZ(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); + ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); ADD_GROUP("Margin", "margin_"); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_LEFT); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_RIGHT); @@ -322,8 +329,8 @@ void StyleBoxTexture::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_TOP); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_BOTTOM); ADD_GROUP("Axis Stretch", "axis_stretch_"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "axis_stretch_horizontal", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_h_axis_stretch_mode", "get_h_axis_stretch_mode"); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "axis_stretch_vertical", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_v_axis_stretch_mode", "get_v_axis_stretch_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "axis_stretch_horizontal", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_h_axis_stretch_mode", "get_h_axis_stretch_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "axis_stretch_vertical", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_v_axis_stretch_mode", "get_v_axis_stretch_mode"); ADD_GROUP("Modulate", "modulate_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate_color"), "set_modulate", "get_modulate"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled"); @@ -896,6 +903,7 @@ int StyleBoxLine::get_thickness() const { void StyleBoxLine::set_vertical(bool p_vertical) { vertical = p_vertical; + emit_changed(); } bool StyleBoxLine::is_vertical() const { return vertical; diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index df3ebe1c36..9062270765 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -37,6 +37,8 @@ /** @author Juan Linietsky <reduzio@gmail.com> */ +class CanvasItem; + class StyleBox : public Resource { GDCLASS(StyleBox, Resource); @@ -58,6 +60,8 @@ public: virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const = 0; + CanvasItem *get_current_item_drawn() const; + Size2 get_minimum_size() const; Point2 get_offset() const; diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 5d4c7861e3..83f29503fa 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -190,10 +190,10 @@ void SurfaceTool::add_smooth_group(bool p_smooth) { } } -void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertexes, const Vector<Vector2> &p_uvs, const Vector<Color> &p_colors, const Vector<Vector2> &p_uv2s, const Vector<Vector3> &p_normals, const Vector<Plane> &p_tangents) { +void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<Color> &p_colors, const Vector<Vector2> &p_uv2s, const Vector<Vector3> &p_normals, const Vector<Plane> &p_tangents) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(primitive != Mesh::PRIMITIVE_TRIANGLES); - ERR_FAIL_COND(p_vertexes.size() < 3); + ERR_FAIL_COND(p_vertices.size() < 3); #define ADD_POINT(n) \ { \ @@ -207,10 +207,10 @@ void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertexes, const Vect add_normal(p_normals[n]); \ if (p_tangents.size() > n) \ add_tangent(p_tangents[n]); \ - add_vertex(p_vertexes[n]); \ + add_vertex(p_vertices[n]); \ } - for (int i = 0; i < p_vertexes.size() - 2; i++) { + for (int i = 0; i < p_vertices.size() - 2; i++) { ADD_POINT(0); ADD_POINT(i + 1); ADD_POINT(i + 2); @@ -764,10 +764,22 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const } //mikktspace callbacks +namespace { +struct TangentGenerationContextUserData { + Vector<List<SurfaceTool::Vertex>::Element *> vertices; + Vector<List<int>::Element *> indices; +}; +} // namespace + int SurfaceTool::mikktGetNumFaces(const SMikkTSpaceContext *pContext) { - Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData); - return varr.size() / 3; + TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData); + + if (triangle_data.indices.size() > 0) { + return triangle_data.indices.size() / 3; + } else { + return triangle_data.vertices.size() / 3; + } } int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, const int iFace) { @@ -775,8 +787,17 @@ int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, c } void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) { - Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData); - Vector3 v = varr[iFace * 3 + iVert]->get().vertex; + TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData); + Vector3 v; + if (triangle_data.indices.size() > 0) { + int index = triangle_data.indices[iFace * 3 + iVert]->get(); + if (index < triangle_data.vertices.size()) { + v = triangle_data.vertices[index]->get().vertex; + } + } else { + v = triangle_data.vertices[iFace * 3 + iVert]->get().vertex; + } + fvPosOut[0] = v.x; fvPosOut[1] = v.y; fvPosOut[2] = v.z; @@ -784,38 +805,56 @@ void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvP void SurfaceTool::mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) { - Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData); - Vector3 v = varr[iFace * 3 + iVert]->get().normal; + TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData); + Vector3 v; + if (triangle_data.indices.size() > 0) { + int index = triangle_data.indices[iFace * 3 + iVert]->get(); + if (index < triangle_data.vertices.size()) { + v = triangle_data.vertices[index]->get().normal; + } + } else { + v = triangle_data.vertices[iFace * 3 + iVert]->get().normal; + } + fvNormOut[0] = v.x; fvNormOut[1] = v.y; fvNormOut[2] = v.z; } void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) { - Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData); - Vector2 v = varr[iFace * 3 + iVert]->get().uv; + TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData); + Vector2 v; + if (triangle_data.indices.size() > 0) { + int index = triangle_data.indices[iFace * 3 + iVert]->get(); + if (index < triangle_data.vertices.size()) { + v = triangle_data.vertices[index]->get().uv; + } + } else { + v = triangle_data.vertices[iFace * 3 + iVert]->get().uv; + } + fvTexcOut[0] = v.x; fvTexcOut[1] = v.y; - //fvTexcOut[1]=1.0-v.y; } void SurfaceTool::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT, const tbool bIsOrientationPreserving, const int iFace, const int iVert) { - Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData); - Vertex *vtx = &varr[iFace * 3 + iVert]->get(); - - vtx->tangent = Vector3(fvTangent[0], fvTangent[1], fvTangent[2]); - vtx->binormal = Vector3(fvBiTangent[0], fvBiTangent[1], fvBiTangent[2]); -} - -void SurfaceTool::mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) { - - Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData); - Vertex &vtx = varr[iFace * 3 + iVert]->get(); + TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData); + Vertex *vtx = NULL; + if (triangle_data.indices.size() > 0) { + int index = triangle_data.indices[iFace * 3 + iVert]->get(); + if (index < triangle_data.vertices.size()) { + vtx = &triangle_data.vertices[index]->get(); + } + } else { + vtx = &triangle_data.vertices[iFace * 3 + iVert]->get(); + } - vtx.tangent = Vector3(fvTangent[0], fvTangent[1], fvTangent[2]); - vtx.binormal = vtx.normal.cross(vtx.tangent) * fSign; + if (vtx != NULL) { + vtx->tangent = Vector3(fvTangent[0], fvTangent[1], fvTangent[2]); + vtx->binormal = Vector3(-fvBiTangent[0], -fvBiTangent[1], -fvBiTangent[2]); // for some reason these are reversed, something with the coordinate system in Godot + } } void SurfaceTool::generate_tangents() { @@ -823,10 +862,6 @@ void SurfaceTool::generate_tangents() { ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_TEX_UV)); ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_NORMAL)); - bool indexed = index_array.size() > 0; - if (indexed) - deindex(); - SMikkTSpaceInterface mkif; mkif.m_getNormal = mikktGetNormal; mkif.m_getNumFaces = mikktGetNumFaces; @@ -839,24 +874,25 @@ void SurfaceTool::generate_tangents() { SMikkTSpaceContext msc; msc.m_pInterface = &mkif; - Vector<List<Vertex>::Element *> vtx; - vtx.resize(vertex_array.size()); + TangentGenerationContextUserData triangle_data; + triangle_data.vertices.resize(vertex_array.size()); int idx = 0; for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next()) { - vtx.write[idx++] = E; + triangle_data.vertices.write[idx++] = E; E->get().binormal = Vector3(); E->get().tangent = Vector3(); } - msc.m_pUserData = &vtx; + triangle_data.indices.resize(index_array.size()); + idx = 0; + for (List<int>::Element *E = index_array.front(); E; E = E->next()) { + triangle_data.indices.write[idx++] = E; + } + msc.m_pUserData = &triangle_data; bool res = genTangSpaceDefault(&msc); ERR_FAIL_COND(!res); format |= Mesh::ARRAY_FORMAT_TANGENT; - - if (indexed) { - index(); - } } void SurfaceTool::generate_normals(bool p_flip) { @@ -976,7 +1012,7 @@ void SurfaceTool::_bind_methods() { ClassDB::bind_method(D_METHOD("add_weights", "weights"), &SurfaceTool::add_weights); ClassDB::bind_method(D_METHOD("add_smooth_group", "smooth"), &SurfaceTool::add_smooth_group); - ClassDB::bind_method(D_METHOD("add_triangle_fan", "vertexes", "uvs", "colors", "uv2s", "normals", "tangents"), &SurfaceTool::add_triangle_fan, DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Color>()), DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Vector3>()), DEFVAL(Vector<Plane>())); + ClassDB::bind_method(D_METHOD("add_triangle_fan", "vertices", "uvs", "colors", "uv2s", "normals", "tangents"), &SurfaceTool::add_triangle_fan, DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Color>()), DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Vector3>()), DEFVAL(Vector<Plane>())); ClassDB::bind_method(D_METHOD("add_index", "index"), &SurfaceTool::add_index); @@ -985,8 +1021,6 @@ void SurfaceTool::_bind_methods() { ClassDB::bind_method(D_METHOD("generate_normals", "flip"), &SurfaceTool::generate_normals, DEFVAL(false)); ClassDB::bind_method(D_METHOD("generate_tangents"), &SurfaceTool::generate_tangents); - ClassDB::bind_method(D_METHOD("add_to_format", "flags"), &SurfaceTool::add_to_format); - ClassDB::bind_method(D_METHOD("set_material", "material"), &SurfaceTool::set_material); ClassDB::bind_method(D_METHOD("clear"), &SurfaceTool::clear); diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index 459d399380..a3b110f0d8 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -90,7 +90,6 @@ private: static void mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert); static void mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert); static void mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert); - static void mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert); static void mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT, const tbool bIsOrientationPreserving, const int iFace, const int iVert); @@ -110,7 +109,7 @@ public: void add_weights(const Vector<float> &p_weights); void add_smooth_group(bool p_smooth); - void add_triangle_fan(const Vector<Vector3> &p_vertexes, const Vector<Vector2> &p_uvs = Vector<Vector2>(), const Vector<Color> &p_colors = Vector<Color>(), const Vector<Vector2> &p_uv2s = Vector<Vector2>(), const Vector<Vector3> &p_normals = Vector<Vector3>(), const Vector<Plane> &p_tangents = Vector<Plane>()); + void add_triangle_fan(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs = Vector<Vector2>(), const Vector<Color> &p_colors = Vector<Color>(), const Vector<Vector2> &p_uv2s = Vector<Vector2>(), const Vector<Vector3> &p_normals = Vector<Vector3>(), const Vector<Plane> &p_tangents = Vector<Plane>()); void add_index(int p_index); @@ -119,8 +118,6 @@ public: void generate_normals(bool p_flip = false); void generate_tangents(); - void add_to_format(int p_flags) { format |= p_flags; } - void set_material(const Ref<Material> &p_material); void clear(); diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp index 2af24ad2d5..37bdd691b4 100644 --- a/scene/resources/text_file.cpp +++ b/scene/resources/text_file.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/text_file.h b/scene/resources/text_file.h index 3abc769dc6..91bb98a3b1 100644 --- a/scene/resources/text_file.h +++ b/scene/resources/text_file.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 682bfebdd2..08b2a05d43 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,7 +34,7 @@ #include "core/io/image_loader.h" #include "core/method_bind_ext.gen.inc" #include "core/os/os.h" -#include "scene/resources/bit_mask.h" +#include "scene/resources/bit_map.h" Size2 Texture::get_size() const { @@ -157,7 +157,7 @@ bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const { void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat")); - p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image")); + p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT)); p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, "")); } @@ -185,6 +185,7 @@ void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uin format = p_format; w = p_width; h = p_height; + _change_notify(); } void ImageTexture::create_from_image(const Ref<Image> &p_image, uint32_t p_flags) { @@ -197,6 +198,8 @@ void ImageTexture::create_from_image(const Ref<Image> &p_image, uint32_t p_flags VisualServer::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, p_flags); VisualServer::get_singleton()->texture_set_data(texture, p_image); _change_notify(); + + image_stored = true; } void ImageTexture::set_flags(uint32_t p_flags) { @@ -211,6 +214,7 @@ void ImageTexture::set_flags(uint32_t p_flags) { return; //uninitialized, do not set to texture } VisualServer::get_singleton()->texture_set_flags(texture, p_flags); + _change_notify("flags"); } uint32_t ImageTexture::get_flags() const { @@ -243,6 +247,7 @@ void ImageTexture::set_data(const Ref<Image> &p_image) { _change_notify(); alpha_cache.unref(); + image_stored = true; } void ImageTexture::_resource_path_changed() { @@ -252,7 +257,11 @@ void ImageTexture::_resource_path_changed() { Ref<Image> ImageTexture::get_data() const { - return VisualServer::get_singleton()->texture_get_data(texture); + if (image_stored) { + return VisualServer::get_singleton()->texture_get_data(texture); + } else { + return Ref<Image>(); + } } int ImageTexture::get_width() const { @@ -324,7 +333,7 @@ bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const { int y = p_y * ah / h; x = CLAMP(x, 0, aw); - y = CLAMP(y, 0, aw); + y = CLAMP(y, 0, ah); return alpha_cache->get_bit(Point2(x, y)); } @@ -417,6 +426,8 @@ ImageTexture::ImageTexture() { texture = VisualServer::get_singleton()->texture_create(); storage = STORAGE_RAW; lossy_storage_quality = 0.7; + image_stored = false; + format = Image::FORMAT_L8; } ImageTexture::~ImageTexture() { @@ -472,7 +483,7 @@ Image::Format StreamTexture::get_format() const { return format; } -Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &flags, Ref<Image> &image, int p_size_limit) { +Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, int &flags, Ref<Image> &image, int p_size_limit) { alpha_cache.unref(); @@ -488,8 +499,11 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'D' || header[2] != 'S' || header[3] != 'T', ERR_FILE_CORRUPT); } - tw = f->get_32(); - th = f->get_32(); + tw = f->get_16(); + tw_custom = f->get_16(); + th = f->get_16(); + th_custom = f->get_16(); + flags = f->get_32(); //texture flags! uint32_t df = f->get_32(); //data format @@ -642,16 +656,16 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla int sw = tw; int sh = th; - int mipmaps = Image::get_image_required_mipmaps(tw, th, format); + int mipmaps2 = Image::get_image_required_mipmaps(tw, th, format); int total_size = Image::get_image_data_size(tw, th, format, true); int idx = 0; int ofs = 0; - while (mipmaps > 1 && p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) { + while (mipmaps2 > 1 && p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) { sw = MAX(sw >> 1, 1); sh = MAX(sh >> 1, 1); - mipmaps--; + mipmaps2--; idx++; } @@ -678,7 +692,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla int expected = total_size - ofs; if (bytes < expected) { - //this is a compatibility workaround for older format, which saved less mipmaps. It is still recommended the image is reimported. + //this is a compatibility workaround for older format, which saved less mipmaps2. It is still recommended the image is reimported. zeromem(w.ptr() + bytes, (expected - bytes)); } else if (bytes != expected) { ERR_FAIL_V(ERR_FILE_CORRUPT); @@ -696,22 +710,31 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla Error StreamTexture::load(const String &p_path) { - int lw, lh, lflags; + int lw, lh, lwc, lhc, lflags; Ref<Image> image; image.instance(); - Error err = _load_data(p_path, lw, lh, lflags, image); + Error err = _load_data(p_path, lw, lh, lwc, lhc, lflags, image); if (err) return err; + if (get_path() == String()) { + //temporarily set path if no path set for resource, helps find errors + VisualServer::get_singleton()->texture_set_path(texture, p_path); + } VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), 0, image->get_format(), VS::TEXTURE_TYPE_2D, lflags); VS::get_singleton()->texture_set_data(texture, image); + if (lwc || lhc) { + VS::get_singleton()->texture_set_size_override(texture, lwc, lhc, 0); + } else { + } - w = lw; - h = lh; + w = lwc ? lwc : lw; + h = lhc ? lhc : lh; flags = lflags; path_to_file = p_path; format = image->get_format(); + _change_notify(); return OK; } String StreamTexture::get_load_path() const { @@ -774,6 +797,7 @@ bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const { decom->decompress(); img = decom; } + alpha_cache.instance(); alpha_cache->create_from_image_alpha(img); } @@ -791,7 +815,7 @@ bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const { int y = p_y * ah / h; x = CLAMP(x, 0, aw); - y = CLAMP(y, 0, aw); + y = CLAMP(y, 0, ah); return alpha_cache->get_bit(Point2(x, y)); } @@ -801,6 +825,7 @@ bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const { void StreamTexture::set_flags(uint32_t p_flags) { flags = p_flags; VS::get_singleton()->texture_set_flags(texture, flags); + _change_notify("flags"); } void StreamTexture::reload_from_file() { @@ -921,6 +946,7 @@ uint32_t AtlasTexture::get_flags() const { void AtlasTexture::set_atlas(const Ref<Texture> &p_atlas) { + ERR_FAIL_COND(p_atlas == this); if (atlas == p_atlas) return; atlas = p_atlas; @@ -994,11 +1020,11 @@ void AtlasTexture::_bind_methods() { void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { - Rect2 rc = region; - if (!atlas.is_valid()) return; + Rect2 rc = region; + if (rc.size.width == 0) { rc.size.width = atlas->get_width(); } @@ -1013,11 +1039,11 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_m void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { - Rect2 rc = region; - if (!atlas.is_valid()) return; + Rect2 rc = region; + if (rc.size.width == 0) { rc.size.width = atlas->get_width(); } @@ -1048,11 +1074,11 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { - Rect2 rc = region; - if (!atlas.is_valid()) return false; + Rect2 rc = region; + Rect2 src = p_src_rect; if (src.size == Size2()) { src.size = rc.size; @@ -1084,11 +1110,17 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const { - if (atlas.is_valid()) { - return atlas->is_pixel_opaque(p_x + region.position.x + margin.position.x, p_x + region.position.y + margin.position.y); - } + if (!atlas.is_valid()) + return true; - return true; + int x = p_x + region.position.x - margin.position.x; + int y = p_y + region.position.y - margin.position.y; + + // margin edge may outside of atlas + if (x < 0 || x >= atlas->get_width()) return false; + if (y < 0 || y >= atlas->get_height()) return false; + + return atlas->is_pixel_opaque(x, y); } AtlasTexture::AtlasTexture() { @@ -1154,6 +1186,7 @@ void LargeTexture::set_piece_offset(int p_idx, const Point2 &p_offset) { void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture> &p_texture) { + ERR_FAIL_COND(p_texture == this); ERR_FAIL_INDEX(p_idx, pieces.size()); pieces.write[p_idx].texture = p_texture; }; @@ -1203,6 +1236,17 @@ Ref<Texture> LargeTexture::get_piece_texture(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, pieces.size(), Ref<Texture>()); return pieces[p_idx].texture; } +Ref<Image> LargeTexture::to_image() const { + + Ref<Image> img = memnew(Image(this->get_width(), this->get_height(), false, Image::FORMAT_RGBA8)); + for (int i = 0; i < pieces.size(); i++) { + + Ref<Image> src_img = pieces[i].texture->get_data(); + img->blit_rect(src_img, Rect2(0, 0, src_img->get_width(), src_img->get_height()), pieces[i].offset); + } + + return img; +} void LargeTexture::_bind_methods() { @@ -1472,6 +1516,7 @@ CubeMap::CubeMap() { cubemap = VisualServer::get_singleton()->texture_create(); storage = STORAGE_RAW; lossy_storage_quality = 0.7; + format = Image::FORMAT_BPTC_RGBA; } CubeMap::~CubeMap() { @@ -1708,6 +1753,7 @@ void ProxyTexture::_bind_methods() { void ProxyTexture::set_base(const Ref<Texture> &p_texture) { + ERR_FAIL_COND(p_texture == this); base = p_texture; if (base.is_valid()) { VS::get_singleton()->texture_set_proxy(proxy, base->get_rid()); @@ -1823,6 +1869,8 @@ int AnimatedTexture::get_frames() const { } void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture> &p_texture) { + + ERR_FAIL_COND(p_texture == this); ERR_FAIL_INDEX(p_frame, MAX_FRAMES); RWLockWrite w(rw_lock); @@ -1958,9 +2006,11 @@ void AnimatedTexture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps"); for (int i = 0; i < MAX_FRAMES; i++) { - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_frame_texture", "get_frame_texture", i); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_frame_delay", "get_frame_delay", i); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_texture", "get_frame_texture", i); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_delay", "get_frame_delay", i); } + + BIND_CONSTANT(MAX_FRAMES); } AnimatedTexture::AnimatedTexture() { @@ -2065,7 +2115,7 @@ void TextureLayered::create(uint32_t p_width, uint32_t p_height, uint32_t p_dept width = p_width; height = p_height; depth = p_depth; - + format = p_format; flags = p_flags; } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index e9b69e9cb1..21d3782897 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -37,8 +37,8 @@ #include "core/os/rw_lock.h" #include "core/os/thread_safe.h" #include "core/resource.h" -#include "scene/resources/color_ramp.h" #include "scene/resources/curve.h" +#include "scene/resources/gradient.h" #include "servers/visual_server.h" /** @@ -111,6 +111,7 @@ private: Size2 size_override; float lossy_storage_quality; mutable Ref<BitMap> alpha_cache; + bool image_stored; protected: virtual void reload_from_file(); @@ -186,7 +187,7 @@ public: }; private: - Error _load_data(const String &p_path, int &tw, int &th, int &flags, Ref<Image> &image, int p_size_limit = 0); + Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, int &flags, Ref<Image> &image, int p_size_limit = 0); String path_to_file; RID texture; Image::Format format; @@ -236,6 +237,7 @@ public: }; class ResourceFormatLoaderStreamTexture : public ResourceFormatLoader { + GDCLASS(ResourceFormatLoaderStreamTexture, ResourceFormatLoader) public: virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual void get_recognized_extensions(List<String> *p_extensions) const; @@ -329,6 +331,7 @@ public: int get_piece_count() const; Vector2 get_piece_offset(int p_idx) const; Ref<Texture> get_piece_texture(int p_idx) const; + Ref<Image> to_image() const; virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; @@ -489,6 +492,7 @@ public: }; class ResourceFormatLoaderTextureLayered : public ResourceFormatLoader { + GDCLASS(ResourceFormatLoaderTextureLayered, ResourceFormatLoader) public: enum Compression { COMPRESSION_LOSSLESS, diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index b102d477f2..69258bc834 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,26 +39,6 @@ void Theme::_emit_theme_changed() { emit_changed(); } -void Theme::_ref_font(Ref<Font> p_sc) { - - if (!font_refcount.has(p_sc)) { - font_refcount[p_sc] = 1; - p_sc->connect("changed", this, "_emit_theme_changed"); - } else { - font_refcount[p_sc] += 1; - } -} - -void Theme::_unref_font(Ref<Font> p_sc) { - - ERR_FAIL_COND(!font_refcount.has(p_sc)); - font_refcount[p_sc]--; - if (font_refcount[p_sc] == 0) { - p_sc->disconnect("changed", this, "_emit_theme_changed"); - font_refcount.erase(p_sc); - } -} - bool Theme::_set(const StringName &p_name, const Variant &p_value) { String sname = p_name; @@ -217,13 +197,13 @@ void Theme::set_default_theme_font(const Ref<Font> &p_default_font) { return; if (default_theme_font.is_valid()) { - _unref_font(default_theme_font); + default_theme_font->disconnect("changed", this, "_emit_theme_changed"); } default_theme_font = p_default_font; if (default_theme_font.is_valid()) { - _ref_font(default_theme_font); + default_theme_font->connect("changed", this, "_emit_theme_changed", varray(), CONNECT_REFERENCE_COUNTED); } _change_notify(); @@ -263,8 +243,16 @@ void Theme::set_icon(const StringName &p_name, const StringName &p_type, const R bool new_value = !icon_map.has(p_type) || !icon_map[p_type].has(p_name); + if (icon_map[p_type].has(p_name) && icon_map[p_type][p_name].is_valid()) { + icon_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed"); + } + icon_map[p_type][p_name] = p_icon; + if (p_icon.is_valid()) { + icon_map[p_type][p_name]->connect("changed", this, "_emit_theme_changed", varray(), CONNECT_REFERENCE_COUNTED); + } + if (new_value) { _change_notify(); emit_changed(); @@ -290,7 +278,12 @@ void Theme::clear_icon(const StringName &p_name, const StringName &p_type) { ERR_FAIL_COND(!icon_map.has(p_type)); ERR_FAIL_COND(!icon_map[p_type].has(p_name)); + if (icon_map[p_type][p_name].is_valid()) { + icon_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed"); + } + icon_map[p_type].erase(p_name); + _change_notify(); emit_changed(); } @@ -358,8 +351,16 @@ void Theme::set_stylebox(const StringName &p_name, const StringName &p_type, con bool new_value = !style_map.has(p_type) || !style_map[p_type].has(p_name); + if (style_map[p_type].has(p_name) && style_map[p_type][p_name].is_valid()) { + style_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed"); + } + style_map[p_type][p_name] = p_style; + if (p_style.is_valid()) { + style_map[p_type][p_name]->connect("changed", this, "_emit_theme_changed", varray(), CONNECT_REFERENCE_COUNTED); + } + if (new_value) _change_notify(); emit_changed(); @@ -385,7 +386,12 @@ void Theme::clear_stylebox(const StringName &p_name, const StringName &p_type) { ERR_FAIL_COND(!style_map.has(p_type)); ERR_FAIL_COND(!style_map[p_type].has(p_name)); + if (style_map[p_type][p_name].is_valid()) { + style_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed"); + } + style_map[p_type].erase(p_name); + _change_notify(); emit_changed(); } @@ -416,15 +422,14 @@ void Theme::set_font(const StringName &p_name, const StringName &p_type, const R bool new_value = !font_map.has(p_type) || !font_map[p_type].has(p_name); - if (!new_value) { - if (font_map[p_type][p_name].is_valid()) { - _unref_font(font_map[p_type][p_name]); - } + if (font_map[p_type][p_name].is_valid()) { + font_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed"); } + font_map[p_type][p_name] = p_font; if (p_font.is_valid()) { - _ref_font(p_font); + font_map[p_type][p_name]->connect("changed", this, "_emit_theme_changed", varray(), CONNECT_REFERENCE_COUNTED); } if (new_value) { @@ -452,8 +457,8 @@ void Theme::clear_font(const StringName &p_name, const StringName &p_type) { ERR_FAIL_COND(!font_map.has(p_type)); ERR_FAIL_COND(!font_map[p_type].has(p_name)); - if (font_map.has(p_type) && font_map[p_type].has(p_name) && font_map[p_type][p_name].is_valid()) { - _unref_font(font_map[p_type][p_name]); + if (font_map[p_type][p_name].is_valid()) { + font_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed"); } font_map[p_type].erase(p_name); @@ -570,15 +575,95 @@ void Theme::get_constant_list(StringName p_type, List<StringName> *p_list) const } } +void Theme::clear() { + + //these need disconnecting + { + const StringName *K = NULL; + while ((K = icon_map.next(K))) { + const StringName *L = NULL; + while ((L = icon_map[*K].next(L))) { + icon_map[*K][*L]->disconnect("changed", this, "_emit_theme_changed"); + } + } + } + + { + const StringName *K = NULL; + while ((K = style_map.next(K))) { + const StringName *L = NULL; + while ((L = style_map[*K].next(L))) { + style_map[*K][*L]->disconnect("changed", this, "_emit_theme_changed"); + } + } + } + + { + const StringName *K = NULL; + while ((K = font_map.next(K))) { + const StringName *L = NULL; + while ((L = font_map[*K].next(L))) { + font_map[*K][*L]->disconnect("changed", this, "_emit_theme_changed"); + } + } + } + + icon_map.clear(); + style_map.clear(); + font_map.clear(); + shader_map.clear(); + color_map.clear(); + constant_map.clear(); + + _change_notify(); + emit_changed(); +} + void Theme::copy_default_theme() { - Ref<Theme> default_theme = get_default(); + Ref<Theme> default_theme2 = get_default(); + copy_theme(default_theme2); +} + +void Theme::copy_theme(const Ref<Theme> &p_other) { + + //these need reconnecting, so add normally + { + const StringName *K = NULL; + while ((K = p_other->icon_map.next(K))) { + const StringName *L = NULL; + while ((L = p_other->icon_map[*K].next(L))) { + set_icon(*L, *K, p_other->icon_map[*K][*L]); + } + } + } + + { + const StringName *K = NULL; + while ((K = p_other->style_map.next(K))) { + const StringName *L = NULL; + while ((L = p_other->style_map[*K].next(L))) { + set_stylebox(*L, *K, p_other->style_map[*K][*L]); + } + } + } + + { + const StringName *K = NULL; + while ((K = p_other->font_map.next(K))) { + const StringName *L = NULL; + while ((L = p_other->font_map[*K].next(L))) { + set_font(*L, *K, p_other->font_map[*K][*L]); + } + } + } + + //these are ok to just copy + + color_map = p_other->color_map; + constant_map = p_other->constant_map; + shader_map = p_other->shader_map; - icon_map = default_theme->icon_map; - style_map = default_theme->style_map; - font_map = default_theme->font_map; - color_map = default_theme->color_map; - constant_map = default_theme->constant_map; _change_notify(); emit_changed(); } @@ -661,6 +746,8 @@ void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_constant", "name", "type"), &Theme::clear_constant); ClassDB::bind_method(D_METHOD("get_constant_list", "type"), &Theme::_get_constant_list); + ClassDB::bind_method(D_METHOD("clear"), &Theme::clear); + ClassDB::bind_method(D_METHOD("set_default_font", "font"), &Theme::set_default_theme_font); ClassDB::bind_method(D_METHOD("get_default_font"), &Theme::get_default_theme_font); @@ -669,6 +756,7 @@ void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("_emit_theme_changed"), &Theme::_emit_theme_changed); ClassDB::bind_method("copy_default_theme", &Theme::copy_default_theme); + ClassDB::bind_method(D_METHOD("copy_theme", "other"), &Theme::copy_theme); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "default_font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_default_font", "get_default_font"); } @@ -678,411 +766,3 @@ Theme::Theme() { Theme::~Theme() { } - -RES ResourceFormatLoaderTheme::load(const String &p_path, const String &p_original_path, Error *r_error) { - if (r_error) - *r_error = ERR_CANT_OPEN; - - Error err; - FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); - - ERR_EXPLAIN("Unable to open theme file: " + p_path); - ERR_FAIL_COND_V(err, RES()); - String base_path = p_path.get_base_dir(); - Ref<Theme> theme(memnew(Theme)); - Map<StringName, Variant> library; - if (r_error) - *r_error = ERR_FILE_CORRUPT; - - bool reading_library = false; - int line = 0; - - while (!f->eof_reached()) { - - String l = f->get_line().strip_edges(); - line++; - - int comment = l.find(";"); - if (comment != -1) - l = l.substr(0, comment); - if (l == "") - continue; - - if (l.begins_with("[")) { - if (l == "[library]") { - reading_library = true; - } else if (l == "[theme]") { - reading_library = false; - } else { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Unknown section type: '" + l + "'."); - ERR_FAIL_V(RES()); - } - continue; - } - - int eqpos = l.find("="); - if (eqpos == -1) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Expected '='."); - ERR_FAIL_V(RES()); - } - - String right = l.substr(eqpos + 1, l.length()).strip_edges(); - if (right == "") { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Expected value after '='."); - ERR_FAIL_V(RES()); - } - - Variant value; - - if (right.is_valid_integer()) { - //is number - value = right.to_int(); - } else if (right.is_valid_html_color()) { - //is html color - value = Color::html(right); - } else if (right.begins_with("@")) { //reference - - String reference = right.substr(1, right.length()); - if (!library.has(reference)) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Invalid reference to '" + reference + "'."); - ERR_FAIL_V(RES()); - } - - value = library[reference]; - - } else if (right.begins_with("default")) { //use default - //do none - } else { - //attempt to parse a constructor - int popenpos = right.find("("); - - if (popenpos == -1) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Invalid constructor syntax: " + right); - ERR_FAIL_V(RES()); - } - - int pclosepos = right.find_last(")"); - - if (pclosepos == -1) { - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Invalid constructor parameter syntax: " + right); - ERR_FAIL_V(RES()); - } - - String type = right.substr(0, popenpos); - String param = right.substr(popenpos + 1, pclosepos - popenpos - 1); - - if (type == "icon") { - - String path; - - if (param.is_abs_path()) - path = param; - else - path = base_path + "/" + param; - - Ref<Texture> texture = ResourceLoader::load(path); - if (!texture.is_valid()) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Couldn't find icon at path: " + path); - ERR_FAIL_V(RES()); - } - - value = texture; - - } else if (type == "sbox") { - - String path; - - if (param.is_abs_path()) - path = param; - else - path = base_path + "/" + param; - - Ref<StyleBox> stylebox = ResourceLoader::load(path); - if (!stylebox.is_valid()) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Couldn't find stylebox at path: " + path); - ERR_FAIL_V(RES()); - } - - value = stylebox; - - } else if (type == "sboxt") { - - Vector<String> params = param.split(","); - if (params.size() != 5 && params.size() != 9) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Invalid param count for sboxt(): '" + right + "'."); - ERR_FAIL_V(RES()); - } - - String path = params[0]; - - if (!param.is_abs_path()) - path = base_path + "/" + path; - - Ref<Texture> tex = ResourceLoader::load(path); - if (tex.is_null()) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Could not open texture for sboxt at path: '" + params[0] + "'."); - ERR_FAIL_V(RES()); - } - - Ref<StyleBoxTexture> sbtex(memnew(StyleBoxTexture)); - - sbtex->set_texture(tex); - - for (int i = 0; i < 4; i++) { - if (!params[i + 1].is_valid_integer()) { - - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Invalid expand margin parameter for sboxt #" + itos(i + 1) + ", expected integer constant, got: '" + params[i + 1] + "'."); - ERR_FAIL_V(RES()); - } - - int margin = params[i + 1].to_int(); - sbtex->set_expand_margin_size(Margin(i), margin); - } - - if (params.size() == 9) { - - for (int i = 0; i < 4; i++) { - - if (!params[i + 5].is_valid_integer()) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Invalid expand margin parameter for sboxt #" + itos(i + 5) + ", expected integer constant, got: '" + params[i + 5] + "'."); - ERR_FAIL_V(RES()); - } - - int margin = params[i + 5].to_int(); - sbtex->set_margin_size(Margin(i), margin); - } - } - - value = sbtex; - } else if (type == "sboxf") { - - Vector<String> params = param.split(","); - if (params.size() < 2) { - - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Invalid param count for sboxf(): '" + right + "'."); - ERR_FAIL_V(RES()); - } - - Ref<StyleBoxFlat> sbflat(memnew(StyleBoxFlat)); - - if (!params[0].is_valid_integer()) { - - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Expected integer numeric constant for parameter 0 (border size)."); - ERR_FAIL_V(RES()); - } - - sbflat->set_border_width_all(params[0].to_int()); - - if (!params[0].is_valid_integer()) { - - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Expected integer numeric constant for parameter 0 (border size)."); - ERR_FAIL_V(RES()); - } - - int left = MIN(params.size() - 1, 3); - - int ccodes = 0; - - for (int i = 0; i < left; i++) { - - if (params[i + 1].is_valid_html_color()) - ccodes++; - else - break; - } - - Color normal; - Color bright; - Color dark; - - if (ccodes < 1) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Expected at least 1, 2 or 3 html color codes."); - ERR_FAIL_V(RES()); - } else if (ccodes == 1) { - - normal = Color::html(params[1]); - bright = Color::html(params[1]); - dark = Color::html(params[1]); - } else if (ccodes == 2) { - - normal = Color::html(params[1]); - bright = Color::html(params[2]); - dark = Color::html(params[2]); - } else { - - normal = Color::html(params[1]); - bright = Color::html(params[2]); - dark = Color::html(params[3]); - } - - sbflat->set_border_color_all(bright); - // sbflat->set_dark_color(dark); - sbflat->set_bg_color(normal); - - if (params.size() == ccodes + 5) { - //margins - for (int i = 0; i < 4; i++) { - - if (!params[i + ccodes + 1].is_valid_integer()) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Invalid expand margin parameter for sboxf #" + itos(i + ccodes + 1) + ", expected integer constant, got: '" + params[i + ccodes + 1] + "'."); - ERR_FAIL_V(RES()); - } - - //int margin = params[i+ccodes+1].to_int(); - //sbflat->set_margin_size(Margin(i),margin); - } - } else if (params.size() != ccodes + 1) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Invalid amount of margin parameters for sboxt."); - ERR_FAIL_V(RES()); - } - - value = sbflat; - - } else { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Invalid constructor type: '" + type + "'."); - ERR_FAIL_V(RES()); - } - } - - //parse left and do something with it - String left = l.substr(0, eqpos); - - if (reading_library) { - - left = left.strip_edges(); - if (!left.is_valid_identifier()) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": <LibraryItem> is not a valid identifier."); - ERR_FAIL_V(RES()); - } - if (library.has(left)) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Already in library: '" + left + "'."); - ERR_FAIL_V(RES()); - } - - library[left] = value; - } else { - - int pointpos = left.find("."); - if (pointpos == -1) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Expected 'control.item=..' assign syntax."); - ERR_FAIL_V(RES()); - } - - String control = left.substr(0, pointpos).strip_edges(); - if (!control.is_valid_identifier()) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": <Control> is not a valid identifier."); - ERR_FAIL_V(RES()); - } - String item = left.substr(pointpos + 1, left.size()).strip_edges(); - if (!item.is_valid_identifier()) { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": <Item> is not a valid identifier."); - ERR_FAIL_V(RES()); - } - - if (value.get_type() == Variant::NIL) { - //try to use exiting - if (Theme::get_default()->has_stylebox(item, control)) - value = Theme::get_default()->get_stylebox(item, control); - else if (Theme::get_default()->has_font(item, control)) - value = Theme::get_default()->get_font(item, control); - else if (Theme::get_default()->has_icon(item, control)) - value = Theme::get_default()->get_icon(item, control); - else if (Theme::get_default()->has_color(item, control)) - value = Theme::get_default()->get_color(item, control); - else if (Theme::get_default()->has_constant(item, control)) - value = Theme::get_default()->get_constant(item, control); - else { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Default not present for: '" + control + "." + item + "'."); - ERR_FAIL_V(RES()); - } - } - - if (value.get_type() == Variant::OBJECT) { - - Ref<Resource> res = value; - if (!res.is_valid()) { - - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Invalid resource (NULL)."); - ERR_FAIL_V(RES()); - } - - if (Object::cast_to<StyleBox>(*res)) { - theme->set_stylebox(item, control, res); - } else if (Object::cast_to<Font>(*res)) { - theme->set_font(item, control, res); - } else if (Object::cast_to<Font>(*res)) { - theme->set_font(item, control, res); - } else if (Object::cast_to<Texture>(*res)) { - theme->set_icon(item, control, res); - } else { - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Invalid resource type."); - ERR_FAIL_V(RES()); - } - } else if (value.get_type() == Variant::COLOR) { - - theme->set_color(item, control, value); - - } else if (value.get_type() == Variant::INT) { - - theme->set_constant(item, control, value); - - } else { - - memdelete(f); - ERR_EXPLAIN(p_path + ":" + itos(line) + ": Couldn't even determine what this setting is! what did you do!?"); - ERR_FAIL_V(RES()); - } - } - } - - f->close(); - memdelete(f); - - if (r_error) - *r_error = OK; - - return theme; -} - -void ResourceFormatLoaderTheme::get_recognized_extensions(List<String> *p_extensions) const { - - p_extensions->push_back("theme"); -} - -bool ResourceFormatLoaderTheme::handles_type(const String &p_type) const { - - return p_type == "Theme"; -} - -String ResourceFormatLoaderTheme::get_resource_type(const String &p_path) const { - - if (p_path.get_extension().to_lower() == "theme") - return "Theme"; - return ""; -} diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 0b76e95f18..fb59073cbe 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -47,12 +47,6 @@ class Theme : public Resource { RES_BASE_EXTENSION("theme"); static Ref<Theme> default_theme; - - //keep a reference count to font, so each time the font changes, we emit theme changed too - Map<Ref<Font>, int> font_refcount; - - void _ref_font(Ref<Font> p_sc); - void _unref_font(Ref<Font> p_sc); void _emit_theme_changed(); HashMap<StringName, HashMap<StringName, Ref<Texture> > > icon_map; @@ -190,17 +184,11 @@ public: void get_type_list(List<StringName> *p_list) const; void copy_default_theme(); + void copy_theme(const Ref<Theme> &p_other); + void clear(); Theme(); ~Theme(); }; -class ResourceFormatLoaderTheme : public ResourceFormatLoader { -public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); - virtual void get_recognized_extensions(List<String> *p_extensions) const; - virtual bool handles_type(const String &p_type) const; - virtual String get_resource_type(const String &p_path) const; -}; - #endif diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index f852ecd7eb..4ddfc0331b 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,6 +30,7 @@ #include "tile_set.h" #include "core/array.h" +#include "core/engine.h" bool TileSet::_set(const StringName &p_name, const Variant &p_value) { @@ -129,6 +130,22 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { } p.pop_front(); } + } else if (what == "z_index_map") { + tile_map[id].autotile_data.z_index_map.clear(); + Array p = p_value; + Vector3 val; + Vector2 v; + int z_index; + while (p.size() > 0) { + val = p[0]; + if (val.z != 0) { + v.x = val.x; + v.y = val.y; + z_index = (int)val.z; + tile_map[id].autotile_data.z_index_map[v] = z_index; + } + p.pop_front(); + } } } else if (what == "shape") tile_set_shape(id, 0, p_value); @@ -138,6 +155,8 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { tile_set_shape_transform(id, 0, p_value); else if (what == "shape_one_way") tile_set_shape_one_way(id, 0, p_value); + else if (what == "shape_one_way_margin") + tile_set_shape_one_way_margin(id, 0, p_value); else if (what == "shapes") _tile_set_shapes(id, p_value); else if (what == "occluder") @@ -228,6 +247,19 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const { } } r_ret = p; + } else if (what == "z_index_map") { + Array p; + Vector3 v; + for (Map<Vector2, int>::Element *E = tile_map[id].autotile_data.z_index_map.front(); E; E = E->next()) { + if (E->value() != 0) { + //Don't save default value + v.x = E->key().x; + v.y = E->key().y; + v.z = E->value(); + p.push_back(v); + } + } + r_ret = p; } } else if (what == "shape") r_ret = tile_get_shape(id, 0); @@ -237,6 +269,8 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const { r_ret = tile_get_shape_transform(id, 0); else if (what == "shape_one_way") r_ret = tile_get_shape_one_way(id, 0); + else if (what == "shape_one_way_margin") + r_ret = tile_get_shape_one_way_margin(id, 0); else if (what == "shapes") r_ret = _tile_get_shapes(id); else if (what == "occluder") @@ -278,12 +312,14 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/occluder_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/navpoly_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/priority_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); + p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/z_index_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); } else if (tile_get_tile_mode(id) == ATLAS_TILE) { p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "autotile/icon_coordinate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "autotile/tile_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::INT, pre + "autotile/spacing", PROPERTY_HINT_RANGE, "0,256,1", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/occluder_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/navpoly_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); + p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/z_index_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); } p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "occluder_offset")); p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "occluder", PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D")); @@ -293,6 +329,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "shape_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D", PROPERTY_USAGE_EDITOR)); p_list->push_back(PropertyInfo(Variant::BOOL, pre + "shape_one_way", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); + p_list->push_back(PropertyInfo(Variant::REAL, pre + "shape_one_way_margin", PROPERTY_HINT_RANGE, "0,128,0.01", PROPERTY_USAGE_EDITOR)); p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "shapes", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::INT, pre + "z_index", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1")); } @@ -483,6 +520,30 @@ const Map<Vector2, int> &TileSet::autotile_get_priority_map(int p_id) const { return tile_map[p_id].autotile_data.priority_map; } +void TileSet::autotile_set_z_index(int p_id, const Vector2 &p_coord, int p_z_index) { + + ERR_FAIL_COND(!tile_map.has(p_id)); + tile_map[p_id].autotile_data.z_index_map[p_coord] = p_z_index; + emit_changed(); +} + +int TileSet::autotile_get_z_index(int p_id, const Vector2 &p_coord) { + + ERR_FAIL_COND_V(!tile_map.has(p_id), 1); + if (tile_map[p_id].autotile_data.z_index_map.has(p_coord)) { + return tile_map[p_id].autotile_data.z_index_map[p_coord]; + } + //When not custom z index set return the default value + return 0; +} + +const Map<Vector2, int> &TileSet::autotile_get_z_index_map(int p_id) const { + + static Map<Vector2, int> dummy; + ERR_FAIL_COND_V(!tile_map.has(p_id), dummy); + return tile_map[p_id].autotile_data.z_index_map; +} + void TileSet::autotile_set_bitmask(int p_id, Vector2 p_coord, uint16_t p_flag) { ERR_FAIL_COND(!tile_map.has(p_id)); @@ -554,7 +615,7 @@ Vector2 TileSet::autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, if (coords.size() == 0) { return autotile_get_icon_coordinate(p_id); } else { - return coords[Math::random(0, (int)coords.size())]; + return coords[Math::rand() % coords.size()]; } } @@ -602,6 +663,7 @@ void TileSet::tile_set_shape(int p_id, int p_shape_id, const Ref<Shape2D> &p_sha if (tile_map[p_id].shapes_data.size() <= p_shape_id) tile_map[p_id].shapes_data.resize(p_shape_id + 1); tile_map[p_id].shapes_data.write[p_shape_id].shape = p_shape; + _decompose_convex_shape(p_shape); emit_changed(); } @@ -660,6 +722,22 @@ bool TileSet::tile_get_shape_one_way(int p_id, int p_shape_id) const { return false; } +void TileSet::tile_set_shape_one_way_margin(int p_id, int p_shape_id, float p_margin) { + ERR_FAIL_COND(!tile_map.has(p_id)); + if (tile_map[p_id].shapes_data.size() <= p_shape_id) + tile_map[p_id].shapes_data.resize(p_shape_id + 1); + tile_map[p_id].shapes_data.write[p_shape_id].one_way_collision_margin = p_margin; + emit_changed(); +} + +float TileSet::tile_get_shape_one_way_margin(int p_id, int p_shape_id) const { + ERR_FAIL_COND_V(!tile_map.has(p_id), 0); + if (tile_map[p_id].shapes_data.size() > p_shape_id) + return tile_map[p_id].shapes_data[p_shape_id].one_way_collision_margin; + + return 0; +} + void TileSet::tile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder) { ERR_FAIL_COND(!tile_map.has(p_id)); @@ -768,6 +846,9 @@ void TileSet::tile_set_shapes(int p_id, const Vector<ShapeData> &p_shapes) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].shapes_data = p_shapes; + for (int i = 0; i < p_shapes.size(); i++) { + _decompose_convex_shape(p_shapes[i].shape); + } emit_changed(); } @@ -812,9 +893,10 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) { } else if (p_shapes[i].get_type() == Variant::DICTIONARY) { Dictionary d = p_shapes[i]; - if (d.has("shape") && d["shape"].get_type() == Variant::OBJECT) + if (d.has("shape") && d["shape"].get_type() == Variant::OBJECT) { s.shape = d["shape"]; - else + _decompose_convex_shape(s.shape); + } else continue; if (d.has("shape_transform") && d["shape_transform"].get_type() == Variant::TRANSFORM2D) @@ -829,6 +911,11 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) { else s.one_way_collision = default_one_way; + if (d.has("one_way_margin") && d["one_way_margin"].is_num()) + s.one_way_collision_margin = d["one_way_margin"]; + else + s.one_way_collision_margin = 1.0; + if (d.has("autotile_coord") && d["autotile_coord"].get_type() == Variant::VECTOR2) s.autotile_coord = d["autotile_coord"]; else @@ -856,6 +943,7 @@ Array TileSet::_tile_get_shapes(int p_id) const { shape_data["shape"] = data[i].shape; shape_data["shape_transform"] = data[i].shape_transform; shape_data["one_way"] = data[i].one_way_collision; + shape_data["one_way_margin"] = data[i].one_way_collision_margin; shape_data["autotile_coord"] = data[i].autotile_coord; arr.push_back(shape_data); } @@ -874,6 +962,26 @@ Array TileSet::_get_tiles_ids() const { return arr; } +void TileSet::_decompose_convex_shape(Ref<Shape2D> p_shape) { + if (Engine::get_singleton()->is_editor_hint()) + return; + Ref<ConvexPolygonShape2D> convex = p_shape; + if (!convex.is_valid()) + return; + Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon_in_convex(convex->get_points()); + if (decomp.size() > 1) { + Array sub_shapes; + for (int i = 0; i < decomp.size(); i++) { + Ref<ConvexPolygonShape2D> _convex = memnew(ConvexPolygonShape2D); + _convex->set_points(decomp[i]); + sub_shapes.append(_convex); + } + convex->set_meta("decomposed", sub_shapes); + } else { + convex->set_meta("decomposed", Variant()); + } +} + void TileSet::get_tile_list(List<int> *p_tiles) const { for (Map<int, TileData>::Element *E = tile_map.front(); E; E = E->next()) { @@ -938,8 +1046,23 @@ void TileSet::clear() { void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("create_tile", "id"), &TileSet::create_tile); + ClassDB::bind_method(D_METHOD("autotile_clear_bitmask_map", "id"), &TileSet::autotile_clear_bitmask_map); + ClassDB::bind_method(D_METHOD("autotile_set_icon_coordinate", "id", "coord"), &TileSet::autotile_set_icon_coordinate); + ClassDB::bind_method(D_METHOD("autotile_get_icon_coordinate", "id"), &TileSet::autotile_get_icon_coordinate); + ClassDB::bind_method(D_METHOD("autotile_set_subtile_priority", "id", "coord", "priority"), &TileSet::autotile_set_subtile_priority); + ClassDB::bind_method(D_METHOD("autotile_get_subtile_priority", "id", "coord"), &TileSet::autotile_get_subtile_priority); + ClassDB::bind_method(D_METHOD("autotile_set_z_index", "id", "coord", "z_index"), &TileSet::autotile_set_z_index); + ClassDB::bind_method(D_METHOD("autotile_get_z_index", "id", "coord"), &TileSet::autotile_get_z_index); + ClassDB::bind_method(D_METHOD("autotile_set_light_occluder", "id", "light_occluder", "coord"), &TileSet::autotile_set_light_occluder); + ClassDB::bind_method(D_METHOD("autotile_get_light_occluder", "id", "coord"), &TileSet::autotile_get_light_occluder); + ClassDB::bind_method(D_METHOD("autotile_set_navigation_polygon", "id", "navigation_polygon", "coord"), &TileSet::autotile_set_navigation_polygon); + ClassDB::bind_method(D_METHOD("autotile_get_navigation_polygon", "id", "coord"), &TileSet::autotile_get_navigation_polygon); + ClassDB::bind_method(D_METHOD("autotile_set_bitmask", "id", "bitmask", "flag"), &TileSet::autotile_set_bitmask); + ClassDB::bind_method(D_METHOD("autotile_get_bitmask", "id", "coord"), &TileSet::autotile_get_bitmask); ClassDB::bind_method(D_METHOD("autotile_set_bitmask_mode", "id", "mode"), &TileSet::autotile_set_bitmask_mode); ClassDB::bind_method(D_METHOD("autotile_get_bitmask_mode", "id"), &TileSet::autotile_get_bitmask_mode); + ClassDB::bind_method(D_METHOD("autotile_set_spacing", "id", "spacing"), &TileSet::autotile_set_spacing); + ClassDB::bind_method(D_METHOD("autotile_get_spacing", "id"), &TileSet::autotile_get_spacing); ClassDB::bind_method(D_METHOD("autotile_set_size", "id", "size"), &TileSet::autotile_set_size); ClassDB::bind_method(D_METHOD("autotile_get_size", "id"), &TileSet::autotile_get_size); ClassDB::bind_method(D_METHOD("tile_set_name", "id", "name"), &TileSet::tile_set_name); @@ -964,6 +1087,8 @@ void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("tile_get_shape_transform", "id", "shape_id"), &TileSet::tile_get_shape_transform); ClassDB::bind_method(D_METHOD("tile_set_shape_one_way", "id", "shape_id", "one_way"), &TileSet::tile_set_shape_one_way); ClassDB::bind_method(D_METHOD("tile_get_shape_one_way", "id", "shape_id"), &TileSet::tile_get_shape_one_way); + ClassDB::bind_method(D_METHOD("tile_set_shape_one_way_margin", "id", "shape_id", "one_way"), &TileSet::tile_set_shape_one_way_margin); + ClassDB::bind_method(D_METHOD("tile_get_shape_one_way_margin", "id", "shape_id"), &TileSet::tile_get_shape_one_way_margin); ClassDB::bind_method(D_METHOD("tile_add_shape", "id", "shape", "shape_transform", "one_way", "autotile_coord"), &TileSet::tile_add_shape, DEFVAL(false), DEFVAL(Vector2())); ClassDB::bind_method(D_METHOD("tile_get_shape_count", "id"), &TileSet::tile_get_shape_count); ClassDB::bind_method(D_METHOD("tile_set_shapes", "id", "shapes"), &TileSet::_tile_set_shapes); diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 1802bf12b6..fac48243d0 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,6 +35,7 @@ #include "core/resource.h" #include "scene/2d/light_occluder_2d.h" #include "scene/2d/navigation_polygon.h" +#include "scene/resources/convex_polygon_shape_2d.h" #include "scene/resources/shape_2d.h" #include "scene/resources/texture.h" @@ -48,9 +49,11 @@ public: Transform2D shape_transform; Vector2 autotile_coord; bool one_way_collision; + float one_way_collision_margin; ShapeData() { one_way_collision = false; + one_way_collision_margin = 1.0; } }; @@ -87,6 +90,7 @@ public: Map<Vector2, Ref<OccluderPolygon2D> > occluder_map; Map<Vector2, Ref<NavigationPolygon> > navpoly_map; Map<Vector2, int> priority_map; + Map<Vector2, int> z_index_map; // Default size to prevent invalid value explicit AutotileData() : @@ -131,6 +135,7 @@ protected: void _tile_set_shapes(int p_id, const Array &p_shapes); Array _tile_get_shapes(int p_id) const; Array _get_tiles_ids() const; + void _decompose_convex_shape(Ref<Shape2D> p_shape); static void _bind_methods(); @@ -172,6 +177,10 @@ public: int autotile_get_subtile_priority(int p_id, const Vector2 &p_coord); const Map<Vector2, int> &autotile_get_priority_map(int p_id) const; + void autotile_set_z_index(int p_id, const Vector2 &p_coord, int p_z_index); + int autotile_get_z_index(int p_id, const Vector2 &p_coord); + const Map<Vector2, int> &autotile_get_z_index_map(int p_id) const; + void autotile_set_bitmask(int p_id, Vector2 p_coord, uint16_t p_flag); uint16_t autotile_get_bitmask(int p_id, Vector2 p_coord); const Map<Vector2, uint16_t> &autotile_get_bitmask_map(int p_id); @@ -189,6 +198,9 @@ public: void tile_set_shape_one_way(int p_id, int p_shape_id, bool p_one_way); bool tile_get_shape_one_way(int p_id, int p_shape_id) const; + void tile_set_shape_one_way_margin(int p_id, int p_shape_id, float p_margin); + float tile_get_shape_one_way_margin(int p_id, int p_shape_id) const; + void tile_clear_shapes(int p_id); void tile_add_shape(int p_id, const Ref<Shape2D> &p_shape, const Transform2D &p_transform, bool p_one_way = false, const Vector2 &p_autotile_coord = Vector2()); int tile_get_shape_count(int p_id) const; diff --git a/scene/resources/video_stream.cpp b/scene/resources/video_stream.cpp index 3cd8cbae77..a85db0c592 100644 --- a/scene/resources/video_stream.cpp +++ b/scene/resources/video_stream.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h index 0d25d9d687..eb3bf6770f 100644 --- a/scene/resources/video_stream.h +++ b/scene/resources/video_stream.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 96b9cfa137..4e5909eb2e 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -106,7 +106,7 @@ void VisualShaderNode::_bind_methods() { ClassDB::bind_method(D_METHOD("_get_default_input_values"), &VisualShaderNode::_get_default_input_values); ADD_PROPERTY(PropertyInfo(Variant::INT, "output_port_for_preview"), "set_output_port_for_preview", "get_output_port_for_preview"); - ADD_PROPERTYNZ(PropertyInfo(Variant::ARRAY, "default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_default_input_values", "_get_default_input_values"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_default_input_values", "_get_default_input_values"); ADD_SIGNAL(MethodInfo("editor_refresh_request")); } @@ -569,7 +569,7 @@ bool VisualShader::_set(const StringName &p_name, const Variant &p_value) { String mode = name.get_slicec('/', 1); int value = p_value; if (value == 0) { - modes.erase(mode); //means its default anyway, so dont store it + modes.erase(mode); //means it's default anyway, so don't store it } else { modes[mode] = value; } @@ -834,15 +834,15 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui } Ref<VisualShaderNodeInput> input = vsnode; + bool skip_global = input.is_valid() && for_preview; - if (input.is_valid() && for_preview) { - //handle for preview - code += input->generate_code_for_preview(type, node, inputs, outputs); - } else { - //handle normally + if (!skip_global) { global_code += vsnode->generate_global(get_mode(), type, node); - code += vsnode->generate_code(get_mode(), type, node, inputs, outputs); } + + //handle normally + code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview); + code += "\n"; // processed.insert(node); @@ -1046,32 +1046,40 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "modelview", "MODELVIEW_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "camera", "CAMERA_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(VIEWPORT_SIZE, 0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0)" }, // Spatial, Fragment + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "VERTEX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "TANGENT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "BINORMAL" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "view", "VIEW" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV2,0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec2(POINT_COORD,0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD,0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "side", "float(FRONT_FACING ? 1.0 : 0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "camera", "CAMERA_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(VIEWPORT_SIZE, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0.0)" }, // Spatial, Light + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "view", "VIEW" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT" }, @@ -1079,19 +1087,24 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "attenuation", "ATTENUATION" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "albedo", "ALBEDO" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "transmission", "TRANSMISSION" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "diffuse", "DIFFUSE_LIGHT" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "specular", "SPECULAR_LIGHT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "roughness", "ROUGHNESS" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "camera", "CAMERA_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(VIEWPORT_SIZE, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0.0)" }, // Canvas Item, Vertex { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" }, @@ -1099,14 +1112,18 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "light_pass", "float(AT_LIGHT_PASS ? 1.0 : 0.0)" }, // Canvas Item, Fragment + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec2(POINT_COORD,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_pixel_size", "vec3(SCREEN_PIXEL_SIZE, 1.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "light_pass", "float(AT_LIGHT_PASS ? 1.0 : 0.0)" }, // Canvas Item, Light + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, @@ -1117,10 +1134,11 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_alpha", "LIGHT_COLOR.a" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_uv", "vec3(LIGHT_UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "shadow_color", "SHADOW_COLOR.rgb" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec2(POINT_COORD,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + // Particles, Vertex { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, @@ -1151,16 +1169,16 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(UV,0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "side", "1.0" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(1.0,1.0, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(1.0,1.0, 0.0)" }, // Spatial, Light { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0,0.0,1.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(1.0, 1.0, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(1.0, 1.0, 0.0)" }, // Canvas Item, Vertex { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, @@ -1171,7 +1189,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, // Canvas Item, Light { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, @@ -1179,7 +1197,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, // Particles, Vertex { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, @@ -1218,56 +1236,56 @@ String VisualShaderNodeInput::get_caption() const { return TTR("Input"); } -String VisualShaderNodeInput::generate_code_for_preview(VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - int idx = 0; + if (p_for_preview) { + int idx = 0; - String code; + String code; - while (preview_ports[idx].mode != Shader::MODE_MAX) { - if (preview_ports[idx].mode == shader_mode && preview_ports[idx].shader_type == shader_type && preview_ports[idx].name == input_name) { - code = "\t" + p_output_vars[0] + " = " + preview_ports[idx].string + ";\n"; - break; + while (preview_ports[idx].mode != Shader::MODE_MAX) { + if (preview_ports[idx].mode == shader_mode && preview_ports[idx].shader_type == shader_type && preview_ports[idx].name == input_name) { + code = "\t" + p_output_vars[0] + " = " + preview_ports[idx].string + ";\n"; + break; + } + idx++; } - idx++; - } - if (code == String()) { - switch (get_output_port_type(0)) { - case PORT_TYPE_SCALAR: { - code = "\t" + p_output_vars[0] + " = 0.0;\n"; - } break; //default (none found) is scalar - case PORT_TYPE_VECTOR: { - code = "\t" + p_output_vars[0] + " = vec3(0.0);\n"; - } break; //default (none found) is scalar - case PORT_TYPE_TRANSFORM: { - code = "\t" + p_output_vars[0] + " = mat4( vec4(1.0,0.0,0.0,0.0), vec4(0.0,1.0,0.0,0.0), vec4(0.0,0.0,1.0,0.0), vec4(0.0,0.0,0.0,1.0) );\n"; - } break; //default (none found) is scalar + if (code == String()) { + switch (get_output_port_type(0)) { + case PORT_TYPE_SCALAR: { + code = "\t" + p_output_vars[0] + " = 0.0;\n"; + } break; //default (none found) is scalar + case PORT_TYPE_VECTOR: { + code = "\t" + p_output_vars[0] + " = vec3(0.0);\n"; + } break; //default (none found) is scalar + case PORT_TYPE_TRANSFORM: { + code = "\t" + p_output_vars[0] + " = mat4( vec4(1.0,0.0,0.0,0.0), vec4(0.0,1.0,0.0,0.0), vec4(0.0,0.0,1.0,0.0), vec4(0.0,0.0,0.0,1.0) );\n"; + } break; //default (none found) is scalar + } } - } - return code; -} + return code; -String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { + } else { + int idx = 0; - int idx = 0; + String code; - String code; + while (ports[idx].mode != Shader::MODE_MAX) { + if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type && ports[idx].name == input_name) { + code = "\t" + p_output_vars[0] + " = " + ports[idx].string + ";\n"; + break; + } + idx++; + } - while (ports[idx].mode != Shader::MODE_MAX) { - if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type && ports[idx].name == input_name) { - code = "\t" + p_output_vars[0] + " = " + ports[idx].string + ";\n"; - break; + if (code == String()) { + code = "\t" + p_output_vars[0] + " = 0.0;\n"; //default (none found) is scalar } - idx++; - } - if (code == String()) { - code = "\t" + p_output_vars[0] + " = 0.0;\n"; //default (none found) is scalar + return code; } - - return code; } void VisualShaderNodeInput::set_input_name(String p_name) { @@ -1535,7 +1553,7 @@ String VisualShaderNodeOutput::get_caption() const { return TTR("Output"); } -String VisualShaderNodeOutput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeOutput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { int idx = 0; int count = 0; diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 2867daac3a..4792038351 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -200,7 +200,7 @@ public: virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const = 0; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const = 0; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const; @@ -243,8 +243,7 @@ public: virtual String get_caption() const; - virtual String generate_code_for_preview(VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; void set_input_name(String p_name); String get_input_name() const; @@ -293,7 +292,7 @@ public: virtual String get_caption() const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; VisualShaderNodeOutput(); }; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index d011b102a2..e47069d723 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -55,7 +55,7 @@ String VisualShaderNodeScalarConstant::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeScalarConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeScalarConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = " + vformat("%.6f", constant) + ";\n"; } @@ -114,7 +114,7 @@ String VisualShaderNodeColorConstant::get_output_port_name(int p_port) const { return p_port == 0 ? "" : "alpha"; //no output port means the editor will be used as port } -String VisualShaderNodeColorConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeColorConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code; code += "\t" + p_output_vars[0] + " = " + vformat("vec3(%.6f,%.6f,%.6f)", constant.r, constant.g, constant.b) + ";\n"; @@ -178,7 +178,7 @@ String VisualShaderNodeVec3Constant::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeVec3Constant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeVec3Constant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = " + vformat("vec3(%.6f,%.6f,%.6f)", constant.x, constant.y, constant.z) + ";\n"; } @@ -236,7 +236,7 @@ String VisualShaderNodeTransformConstant::get_output_port_name(int p_port) const return ""; //no output port means the editor will be used as port } -String VisualShaderNodeTransformConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeTransformConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { Transform t = constant; t.basis.transpose(); @@ -324,7 +324,7 @@ String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShade String u = "uniform sampler2D " + make_unique_id(p_type, p_id, "tex"); switch (texture_type) { case TYPE_DATA: break; - case TYPE_COLOR: u += " : hint_color"; break; + case TYPE_COLOR: u += " : hint_albedo"; break; case TYPE_NORMALMAP: u += " : hint_normal"; break; } return u + ";"; @@ -333,7 +333,7 @@ String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShade return String(); } -String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { if (source == SOURCE_TEXTURE) { String id = make_unique_id(p_type, p_id, "tex"); @@ -357,7 +357,7 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_SCREEN && (p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) { String code = "\t{\n"; - if (p_input_vars[0] == String()) { //none bound, do nothing + if (p_input_vars[0] == String() || p_for_preview) { //none bound, do nothing code += "\t\tvec4 _tex_read = vec4(0.0);\n"; @@ -554,13 +554,13 @@ String VisualShaderNodeCubeMap::generate_global(Shader::Mode p_mode, VisualShade String u = "uniform sampler2DCube " + make_unique_id(p_type, p_id, "cube"); switch (texture_type) { case TYPE_DATA: break; - case TYPE_COLOR: u += " : hint_color"; break; + case TYPE_COLOR: u += " : hint_albedo"; break; case TYPE_NORMALMAP: u += " : hint_normal"; break; } return u + ";"; } -String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String id = make_unique_id(p_type, p_id, "cube"); String code; @@ -652,7 +652,7 @@ String VisualShaderNodeScalarOp::get_output_port_name(int p_port) const { return "op"; //no output port means the editor will be used as port } -String VisualShaderNodeScalarOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeScalarOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code = "\t" + p_output_vars[0] + " = "; switch (op) { @@ -738,7 +738,7 @@ String VisualShaderNodeVectorOp::get_output_port_name(int p_port) const { return "op"; //no output port means the editor will be used as port } -String VisualShaderNodeVectorOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeVectorOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code = "\t" + p_output_vars[0] + " = "; switch (op) { @@ -824,7 +824,7 @@ String VisualShaderNodeColorOp::get_output_port_name(int p_port) const { return "op"; //no output port means the editor will be used as port } -String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code; static const char *axisn[3] = { "x", "y", "z" }; @@ -972,7 +972,7 @@ String VisualShaderNodeTransformMult::get_output_port_name(int p_port) const { return "mult"; //no output port means the editor will be used as port } -String VisualShaderNodeTransformMult::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeTransformMult::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { if (op == OP_AxB) { return "\t" + p_output_vars[0] + " = " + p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; @@ -1041,7 +1041,7 @@ String VisualShaderNodeTransformVecMult::get_output_port_name(int p_port) const return ""; //no output port means the editor will be used as port } -String VisualShaderNodeTransformVecMult::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeTransformVecMult::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { if (op == OP_AxB) { return "\t" + p_output_vars[0] + " = ( " + p_input_vars[0] + " * vec4(" + p_input_vars[1] + ", 1.0) ).xyz;\n"; } else if (op == OP_BxA) { @@ -1115,7 +1115,7 @@ String VisualShaderNodeScalarFunc::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeScalarFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeScalarFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { static const char *scalar_func_id[FUNC_NEGATE + 1] = { "sin($)", @@ -1136,7 +1136,7 @@ String VisualShaderNodeScalarFunc::generate_code(Shader::Mode p_mode, VisualShad "round($)", "ceil($)", "fract($)", - "min(max($,0),1)", + "min(max($,0.0),1.0)", "-($)", }; @@ -1220,7 +1220,7 @@ String VisualShaderNodeVectorFunc::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { static const char *vec_func_id[FUNC_HSV2RGB + 1] = { "normalize($)", @@ -1321,7 +1321,7 @@ String VisualShaderNodeDotProduct::get_output_port_name(int p_port) const { return "dot"; } -String VisualShaderNodeDotProduct::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeDotProduct::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = dot( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; } @@ -1356,7 +1356,7 @@ String VisualShaderNodeVectorLen::get_output_port_name(int p_port) const { return "length"; } -String VisualShaderNodeVectorLen::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeVectorLen::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = length( " + p_input_vars[0] + " );\n"; } @@ -1396,7 +1396,7 @@ String VisualShaderNodeScalarInterp::get_output_port_name(int p_port) const { return "mix"; } -String VisualShaderNodeScalarInterp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeScalarInterp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = mix( " + p_input_vars[0] + " , " + p_input_vars[1] + " , " + p_input_vars[2] + " );\n"; } @@ -1438,7 +1438,7 @@ String VisualShaderNodeVectorInterp::get_output_port_name(int p_port) const { return "mix"; } -String VisualShaderNodeVectorInterp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeVectorInterp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = mix( " + p_input_vars[0] + " , " + p_input_vars[1] + " , " + p_input_vars[2] + " );\n"; } @@ -1479,7 +1479,7 @@ String VisualShaderNodeVectorCompose::get_output_port_name(int p_port) const { return "vec"; } -String VisualShaderNodeVectorCompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeVectorCompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = vec3( " + p_input_vars[0] + " , " + p_input_vars[1] + " , " + p_input_vars[2] + " );\n"; } @@ -1524,7 +1524,7 @@ String VisualShaderNodeTransformCompose::get_output_port_name(int p_port) const return "xform"; } -String VisualShaderNodeTransformCompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeTransformCompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = mat4( vec4(" + p_input_vars[0] + ", 0.0) , vec4(" + p_input_vars[1] + ", 0.0) , vec4(" + p_input_vars[2] + ",0.0), vec4(" + p_input_vars[3] + ",1.0) );\n"; } @@ -1567,7 +1567,7 @@ String VisualShaderNodeVectorDecompose::get_output_port_name(int p_port) const { } } -String VisualShaderNodeVectorDecompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeVectorDecompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code; code += "\t" + p_output_vars[0] + " = " + p_input_vars[0] + ".x;\n"; code += "\t" + p_output_vars[1] + " = " + p_input_vars[0] + ".y;\n"; @@ -1613,7 +1613,7 @@ String VisualShaderNodeTransformDecompose::get_output_port_name(int p_port) cons } } -String VisualShaderNodeTransformDecompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeTransformDecompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code; code += "\t" + p_output_vars[0] + " = " + p_input_vars[0] + "[0].xyz;\n"; code += "\t" + p_output_vars[1] + " = " + p_input_vars[0] + "[1].xyz;\n"; @@ -1655,7 +1655,7 @@ String VisualShaderNodeScalarUniform::get_output_port_name(int p_port) const { String VisualShaderNodeScalarUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { return "uniform float " + get_uniform_name() + ";\n"; } -String VisualShaderNodeScalarUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeScalarUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; } @@ -1693,7 +1693,7 @@ String VisualShaderNodeColorUniform::generate_global(Shader::Mode p_mode, Visual return "uniform vec4 " + get_uniform_name() + " : hint_color;\n"; } -String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code = "\t" + p_output_vars[0] + " = " + get_uniform_name() + ".rgb;\n"; code += "\t" + p_output_vars[1] + " = " + get_uniform_name() + ".a;\n"; return code; @@ -1731,7 +1731,7 @@ String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualS return "uniform vec3 " + get_uniform_name() + ";\n"; } -String VisualShaderNodeVec3Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeVec3Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; } @@ -1767,7 +1767,7 @@ String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, Vi return "uniform mat4 " + get_uniform_name() + ";\n"; } -String VisualShaderNodeTransformUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeTransformUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; } @@ -1823,7 +1823,7 @@ String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, Visu return code; } -String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String id = get_uniform_name(); String code = "\t{\n"; @@ -1918,7 +1918,7 @@ String VisualShaderNodeCubeMapUniform::get_output_port_name(int p_port) const { return p_port == 0 ? "rgb" : "alpha"; } -String VisualShaderNodeCubeMapUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const { +String VisualShaderNodeCubeMapUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return String(); } diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 3057f7239a..27b557494a 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -53,7 +53,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty void set_constant(float p_value); float get_constant() const; @@ -81,7 +81,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty void set_constant(Color p_value); Color get_constant() const; @@ -109,7 +109,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty void set_constant(Vector3 p_value); Vector3 get_constant() const; @@ -137,7 +137,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty void set_constant(Transform p_value); Transform get_constant() const; @@ -187,7 +187,7 @@ public: virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty void set_source(Source p_source); Source get_source() const; @@ -240,7 +240,7 @@ public: virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty void set_cube_map(Ref<CubeMap> p_value); Ref<CubeMap> get_cube_map() const; @@ -288,7 +288,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty void set_operator(Operator p_op); Operator get_operator() const; @@ -333,7 +333,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty void set_operator(Operator p_op); Operator get_operator() const; @@ -377,7 +377,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty void set_operator(Operator p_op); Operator get_operator() const; @@ -414,7 +414,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty void set_operator(Operator p_op); Operator get_operator() const; @@ -453,7 +453,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty void set_operator(Operator p_op); Operator get_operator() const; @@ -510,7 +510,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty void set_function(Function p_func); Function get_function() const; @@ -553,7 +553,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty void set_function(Function p_func); Function get_function() const; @@ -581,7 +581,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeDotProduct(); }; @@ -602,7 +602,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeVectorLen(); }; @@ -623,7 +623,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeScalarInterp(); }; @@ -644,7 +644,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeVectorInterp(); }; @@ -665,7 +665,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeVectorCompose(); }; @@ -686,7 +686,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeTransformCompose(); }; @@ -707,7 +707,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeVectorDecompose(); }; @@ -728,7 +728,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeTransformDecompose(); }; @@ -750,7 +750,7 @@ public: virtual String get_output_port_name(int p_port) const; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeScalarUniform(); }; @@ -770,7 +770,7 @@ public: virtual String get_output_port_name(int p_port) const; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeColorUniform(); }; @@ -790,7 +790,7 @@ public: virtual String get_output_port_name(int p_port) const; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeVec3Uniform(); }; @@ -810,7 +810,7 @@ public: virtual String get_output_port_name(int p_port) const; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeTransformUniform(); }; @@ -851,7 +851,7 @@ public: virtual String get_output_port_name(int p_port) const; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty Vector<StringName> get_editable_properties() const; @@ -883,7 +883,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeCubeMapUniform(); }; diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp index b4588cd87c..0ca5d7eb36 100644 --- a/scene/resources/world.cpp +++ b/scene/resources/world.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/world.h b/scene/resources/world.h index 4ba6b13476..05d5ceb411 100644 --- a/scene/resources/world.h +++ b/scene/resources/world.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index dd78d04104..13b45f58dc 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h index 88ad392f85..e0c671e1a7 100644 --- a/scene/resources/world_2d.h +++ b/scene/resources/world_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index e468b3dab4..634f4d7160 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -203,4 +203,6 @@ SceneStringNames::SceneStringNames() { _mesh_changed = StaticCString::create("_mesh_changed"); parameters_base_path = "parameters/"; + + tracks_changed = "tracks_changed"; } diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 25e2c5d4a6..bc75165b8c 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,7 +32,7 @@ #define SCENE_STRING_NAMES_H #include "core/node_path.h" -#include "core/string_db.h" +#include "core/string_name.h" class SceneStringNames { friend void register_scene_types(); @@ -205,6 +205,8 @@ public: StringName parameters_base_path; + StringName tracks_changed; + enum { MAX_MATERIALS = 32 }; |