diff options
32 files changed, 497 insertions, 1255 deletions
diff --git a/core/image.cpp b/core/image.cpp index e0cf82d920..023a058667 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -1646,6 +1646,62 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po } } +void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) { + + ERR_FAIL_COND(p_src.is_null()); + ERR_FAIL_COND(p_mask.is_null()); + int dsize = data.size(); + int srcdsize = p_src->data.size(); + int maskdsize = p_mask->data.size(); + ERR_FAIL_COND(dsize == 0); + ERR_FAIL_COND(srcdsize == 0); + ERR_FAIL_COND(maskdsize == 0); + ERR_FAIL_COND(p_src->width != p_mask->width); + ERR_FAIL_COND(p_src->height != p_mask->height); + ERR_FAIL_COND(format != p_src->format); + + Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect); + if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) + return; + + Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size)); + + PoolVector<uint8_t>::Write wp = data.write(); + uint8_t *dst_data_ptr = wp.ptr(); + + PoolVector<uint8_t>::Read rp = p_src->data.read(); + const uint8_t *src_data_ptr = rp.ptr(); + + int pixel_size = get_format_pixel_size(format); + + Ref<Image> msk = p_mask; + msk->lock(); + + for (int i = 0; i < dest_rect.size.y; i++) { + + for (int j = 0; j < dest_rect.size.x; j++) { + + int src_x = clipped_src_rect.position.x + j; + int src_y = clipped_src_rect.position.y + i; + + if (msk->get_pixel(src_x, src_y).a != 0) { + + int dst_x = dest_rect.position.x + j; + int dst_y = dest_rect.position.y + i; + + const uint8_t *src = &src_data_ptr[(src_y * p_src->width + src_x) * pixel_size]; + uint8_t *dst = &dst_data_ptr[(dst_y * width + dst_x) * pixel_size]; + + for (int k = 0; k < pixel_size; k++) { + dst[k] = src[k]; + } + } + } + } + + msk->unlock(); +} + void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) { ERR_FAIL_COND(p_src.is_null()); @@ -2199,6 +2255,7 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("normalmap_to_xy"), &Image::normalmap_to_xy); ClassDB::bind_method(D_METHOD("blit_rect", "src:Image", "src_rect", "dst"), &Image::blit_rect); + ClassDB::bind_method(D_METHOD("blit_rect_mask", "src:Image", "mask:Image", "src_rect", "dst"), &Image::blit_rect_mask); ClassDB::bind_method(D_METHOD("blend_rect", "src:Image", "src_rect", "dst"), &Image::blend_rect); ClassDB::bind_method(D_METHOD("blend_rect_mask", "src:Image", "mask:Image", "src_rect", "dst"), &Image::blend_rect_mask); ClassDB::bind_method(D_METHOD("fill", "color"), &Image::fill); diff --git a/core/image.h b/core/image.h index 3323afdc4b..e523f703fa 100644 --- a/core/image.h +++ b/core/image.h @@ -283,6 +283,7 @@ public: void normalmap_to_xy(); void blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest); + void blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest); void blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest); void blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest); void fill(const Color &c); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 7b2d0f6886..a463a5a23f 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -2236,30 +2236,30 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { return _data._int > 0; } break; case REAL: { - r_iter = 0.0; + r_iter = 0; return _data._real > 0.0; } break; case VECTOR2: { - real_t from = reinterpret_cast<const Vector2 *>(_data._mem)->x; - real_t to = reinterpret_cast<const Vector2 *>(_data._mem)->y; + int64_t from = reinterpret_cast<const Vector2 *>(_data._mem)->x; + int64_t to = reinterpret_cast<const Vector2 *>(_data._mem)->y; r_iter = from; return from < to; } break; case VECTOR3: { - real_t from = reinterpret_cast<const Vector3 *>(_data._mem)->x; - real_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; - real_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z; + int64_t from = reinterpret_cast<const Vector3 *>(_data._mem)->x; + int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; + int64_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z; r_iter = from; if (from == to) { return false; } else if (from < to) { - return step > 0.0; + return step > 0; } else { - return step < 0.0; + return step < 0; } //return true; } break; @@ -2387,7 +2387,6 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { valid = true; switch (type) { case INT: { - int64_t idx = r_iter; idx++; if (idx >= _data._int) @@ -2396,33 +2395,36 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { return true; } break; case REAL: { - - double idx = r_iter; - idx += 1.0; + int64_t idx = r_iter; + idx++; if (idx >= _data._real) return false; r_iter = idx; return true; } break; case VECTOR2: { - real_t idx = r_iter; - idx += 1.0; - if (idx >= reinterpret_cast<const Vector2 *>(_data._mem)->y) + int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; + + int64_t idx = r_iter; + idx++; + + if (idx >= to) return false; + r_iter = idx; return true; } break; case VECTOR3: { - real_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; - real_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z; + int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; + int64_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z; - real_t idx = r_iter; + int64_t idx = r_iter; idx += step; - if (step < 0.0 && idx <= to) + if (step < 0 && idx <= to) return false; - if (step > 0.0 && idx >= to) + if (step > 0 && idx >= to) return false; r_iter = idx; diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 913aa62452..96c3da99f0 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -977,6 +977,27 @@ void RasterizerSceneGLES3::environment_set_fog_height(RID p_env, bool p_enable, env->fog_height_curve = p_height_curve; } +bool RasterizerSceneGLES3::is_environment(RID p_env) { + + return environment_owner.owns(p_env); +} + +VS::EnvironmentBG RasterizerSceneGLES3::environment_get_background(RID p_env) { + + const Environment *env = environment_owner.getornull(p_env); + ERR_FAIL_COND_V(!env, VS::ENV_BG_MAX); + + return env->bg_mode; +} + +int RasterizerSceneGLES3::environment_get_canvas_max_layer(RID p_env) { + + const Environment *env = environment_owner.getornull(p_env); + ERR_FAIL_COND_V(!env, -1); + + return env->canvas_max_layer; +} + RID RasterizerSceneGLES3::light_instance_create(RID p_light) { LightInstance *light_instance = memnew(LightInstance); @@ -3561,7 +3582,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p glUniform2iv(state.exposure_shader.get_uniform(ExposureShaderGLES3::SOURCE_RENDER_SIZE), 1, ss); glUniform2iv(state.exposure_shader.get_uniform(ExposureShaderGLES3::TARGET_SIZE), 1, ds); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->buffers.diffuse); + glBindTexture(GL_TEXTURE_2D, composite_from); glBindFramebuffer(GL_FRAMEBUFFER, exposure_shrink[0].fbo); glViewport(0, 0, exposure_shrink_size, exposure_shrink_size); @@ -3957,6 +3978,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]; use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS]; use_mrt = use_mrt && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW; + use_mrt = use_mrt && env && (env->bg_mode != VS::ENV_BG_KEEP && env->bg_mode != VS::ENV_BG_CANVAS); glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height); @@ -4020,6 +4042,10 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const storage->frame.clear_request = false; } + } else if (env->bg_mode == VS::ENV_BG_CANVAS) { + + clear_color = env->bg_color.to_linear(); + storage->frame.clear_request = false; } else if (env->bg_mode == VS::ENV_BG_COLOR) { clear_color = env->bg_color.to_linear(); @@ -4037,7 +4063,39 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const storage->frame.clear_request = false; } - glClearBufferfv(GL_COLOR, 0, clear_color.components); // specular + if (!env || env->bg_mode != VS::ENV_BG_KEEP) { + glClearBufferfv(GL_COLOR, 0, clear_color.components); // specular + } + + if (env && env->bg_mode == VS::ENV_BG_CANVAS) { + //copy canvas to 3d buffer and convert it to linear + + glDisable(GL_BLEND); + glDepthMask(GL_FALSE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color); + + storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, true); + + storage->shaders.copy.set_conditional(CopyShaderGLES3::SRGB_TO_LINEAR, true); + + storage->shaders.copy.bind(); + + _copy_screen(); + + //turn off everything used + storage->shaders.copy.set_conditional(CopyShaderGLES3::SRGB_TO_LINEAR, false); + storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, false); + + //restore + glEnable(GL_BLEND); + glDepthMask(GL_TRUE); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + } state.texscreen_copied = false; diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 3e15da52ab..c52a00bf17 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -536,6 +536,11 @@ public: virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve); virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve); + virtual bool is_environment(RID p_env); + + virtual VS::EnvironmentBG environment_get_background(RID p_env); + virtual int environment_get_canvas_max_layer(RID p_env); + /* LIGHT INSTANCE */ struct LightDataUBO { diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl index 4c8648903e..b0fb525e20 100644 --- a/drivers/gles3/shaders/copy.glsl +++ b/drivers/gles3/shaders/copy.glsl @@ -129,6 +129,11 @@ void main() { color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308))); #endif +#ifdef SRGB_TO_LINEAR + + color.rgb = mix(pow((color.rgb + vec3(0.055)) * (1.0 / (1 + 0.055)),vec3(2.4)),color.rgb * (1.0 / 12.92),lessThan(color.rgb,vec3(0.04045))); +#endif + #ifdef DEBUG_GRADIENT color.rg=uv_interp; color.b=0.0; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 2b29e4b08a..04257b8cd1 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -77,7 +77,6 @@ #include "plugins/curve_editor_plugin.h" #include "plugins/gi_probe_editor_plugin.h" #include "plugins/gradient_editor_plugin.h" -#include "plugins/gradient_texture_editor_plugin.h" #include "plugins/item_list_editor_plugin.h" #include "plugins/light_occluder_2d_editor_plugin.h" #include "plugins/line_2d_editor_plugin.h" @@ -6112,7 +6111,6 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(LightOccluder2DEditorPlugin(this))); add_editor_plugin(memnew(NavigationPolygonEditorPlugin(this))); add_editor_plugin(memnew(GradientEditorPlugin(this))); - add_editor_plugin(memnew(GradientTextureEditorPlugin(this))); add_editor_plugin(memnew(CollisionShape2DEditorPlugin(this))); add_editor_plugin(memnew(CurveEditorPlugin(this))); add_editor_plugin(memnew(TextureEditorPlugin(this))); diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp index 9884db934b..4aaa155cfd 100644 --- a/editor/plugins/gradient_editor_plugin.cpp +++ b/editor/plugins/gradient_editor_plugin.cpp @@ -91,8 +91,7 @@ void GradientEditorPlugin::_ramp_changed() { } } -void GradientEditorPlugin::_undo_redo_gradient(const Vector<float> &offsets, - const Vector<Color> &colors) { +void GradientEditorPlugin::_undo_redo_gradient(const Vector<float> &offsets, const Vector<Color> &colors) { gradient_ref->set_offsets(offsets); gradient_ref->set_colors(colors); diff --git a/editor/plugins/gradient_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h index 843e98a917..c319a13a01 100644 --- a/editor/plugins/gradient_editor_plugin.h +++ b/editor/plugins/gradient_editor_plugin.h @@ -38,7 +38,6 @@ class GradientEditorPlugin : public EditorPlugin { GDCLASS(GradientEditorPlugin, EditorPlugin); - bool _2d; Ref<Gradient> gradient_ref; GradientEdit *ramp_editor; EditorNode *editor; diff --git a/editor/plugins/gradient_texture_editor_plugin.cpp b/editor/plugins/gradient_texture_editor_plugin.cpp deleted file mode 100644 index bc985dcdf7..0000000000 --- a/editor/plugins/gradient_texture_editor_plugin.cpp +++ /dev/null @@ -1,539 +0,0 @@ -/*************************************************************************/ -/* gradient_texture_editor_plugin.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (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 "gradient_texture_editor_plugin.h" - -#include "canvas_item_editor_plugin.h" -#include "os/keyboard.h" -#include "scene/resources/default_theme/theme_data.h" -#include "spatial_editor_plugin.h" - -#define POINT_WIDTH 8 - -GradientTextureEdit::GradientTextureEdit() { - grabbed = -1; - grabbing = false; - set_focus_mode(FOCUS_ALL); - - popup = memnew(PopupPanel); - picker = memnew(ColorPicker); - popup->add_child(picker); - - add_child(popup); - - checker = Ref<ImageTexture>(memnew(ImageTexture)); - Ref<Image> checker_bg = memnew(Image(checker_bg_png)); - checker->create_from_image(checker_bg, ImageTexture::FLAG_REPEAT); -} - -int GradientTextureEdit::_get_point_from_pos(int x) { - int result = -1; - int total_w = get_size().width - get_size().height - 3; - for (int i = 0; i < points.size(); i++) { - //Check if we clicked at point - if (ABS(x - points[i].offset * total_w + 1) < (POINT_WIDTH / 2 + 1)) { - result = i; - } - } - return result; -} - -void GradientTextureEdit::_show_color_picker() { - if (grabbed == -1) - return; - Size2 ms = Size2(350, picker->get_combined_minimum_size().height + 10); - picker->set_pick_color(points[grabbed].color); - popup->set_position(get_global_position() - Vector2(ms.width - get_size().width, ms.height)); - popup->set_size(ms); - popup->popup(); -} - -GradientTextureEdit::~GradientTextureEdit() { -} - -void GradientTextureEdit::_gui_input(const Ref<InputEvent> &p_event) { - - Ref<InputEventKey> k = p_event; - - if (k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_DELETE && grabbed != -1) { - - points.remove(grabbed); - grabbed = -1; - grabbing = false; - update(); - emit_signal("ramp_changed"); - accept_event(); - } - - Ref<InputEventMouseButton> mb = p_event; - //Show color picker on double click. - if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_doubleclick() && mb->is_pressed()) { - grabbed = _get_point_from_pos(mb->get_position().x); - _show_color_picker(); - accept_event(); - } - - //Delete point on right click - if (mb.is_valid() && mb->get_button_index() == 2 && mb->is_pressed()) { - grabbed = _get_point_from_pos(mb->get_position().x); - if (grabbed != -1) { - points.remove(grabbed); - grabbed = -1; - grabbing = false; - update(); - emit_signal("ramp_changed"); - accept_event(); - } - } - - //Hold alt key to duplicate selected color - if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed() && mb->get_alt()) { - - int x = mb->get_position().x; - grabbed = _get_point_from_pos(x); - - if (grabbed != -1) { - int total_w = get_size().width - get_size().height - 3; - GradientTexture::Point newPoint = points[grabbed]; - newPoint.offset = CLAMP(x / float(total_w), 0, 1); - - points.push_back(newPoint); - points.sort(); - for (int i = 0; i < points.size(); ++i) { - if (points[i].offset == newPoint.offset) { - grabbed = i; - break; - } - } - - emit_signal("ramp_changed"); - update(); - } - } - - if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { - - update(); - int x = mb->get_position().x; - int total_w = get_size().width - get_size().height - 3; - - //Check if color selector was clicked. - if (x > total_w + 3) { - _show_color_picker(); - return; - } - - grabbing = true; - - grabbed = _get_point_from_pos(x); - //grab or select - if (grabbed != -1) { - return; - } - - //insert - GradientTexture::Point newPoint; - newPoint.offset = CLAMP(x / float(total_w), 0, 1); - - GradientTexture::Point prev; - GradientTexture::Point next; - - int pos = -1; - for (int i = 0; i < points.size(); i++) { - if (points[i].offset < newPoint.offset) - pos = i; - } - - if (pos == -1) { - - prev.color = Color(0, 0, 0); - prev.offset = 0; - if (points.size()) { - next = points[0]; - } else { - next.color = Color(1, 1, 1); - next.offset = 1.0; - } - } else { - - if (pos == points.size() - 1) { - next.color = Color(1, 1, 1); - next.offset = 1.0; - } else { - next = points[pos + 1]; - } - prev = points[pos]; - } - - newPoint.color = prev.color.linear_interpolate(next.color, (newPoint.offset - prev.offset) / (next.offset - prev.offset)); - - points.push_back(newPoint); - points.sort(); - for (int i = 0; i < points.size(); i++) { - if (points[i].offset == newPoint.offset) { - grabbed = i; - break; - } - } - - emit_signal("ramp_changed"); - } - - if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) { - - if (grabbing) { - grabbing = false; - emit_signal("ramp_changed"); - } - update(); - } - - Ref<InputEventMouseMotion> mm = p_event; - - if (mm.is_valid() && grabbing) { - - int total_w = get_size().width - get_size().height - 3; - - int x = mm->get_position().x; - float newofs = CLAMP(x / float(total_w), 0, 1); - - //Snap to nearest point if holding shift - if (mm->get_shift()) { - float snap_treshhold = 0.03; - float smallest_ofs = snap_treshhold; - bool founded = false; - int nearest_point; - for (int i = 0; i < points.size(); ++i) { - if (i != grabbed) { - float temp_ofs = ABS(points[i].offset - newofs); - if (temp_ofs < smallest_ofs) { - smallest_ofs = temp_ofs; - nearest_point = i; - if (founded) - break; - founded = true; - } - } - } - if (founded) { - if (points[nearest_point].offset < newofs) - newofs = points[nearest_point].offset + 0.00001; - else - newofs = points[nearest_point].offset - 0.00001; - newofs = CLAMP(newofs, 0, 1); - } - } - - bool valid = true; - for (int i = 0; i < points.size(); i++) { - - if (points[i].offset == newofs && i != grabbed) { - valid = false; - } - } - - if (!valid) - return; - - points[grabbed].offset = newofs; - - points.sort(); - for (int i = 0; i < points.size(); i++) { - if (points[i].offset == newofs) { - grabbed = i; - break; - } - } - - emit_signal("ramp_changed"); - - update(); - } -} - -void GradientTextureEdit::_notification(int p_what) { - - if (p_what == NOTIFICATION_ENTER_TREE) { - if (!picker->is_connected("color_changed", this, "_color_changed")) { - picker->connect("color_changed", this, "_color_changed"); - } - } - if (p_what == NOTIFICATION_DRAW) { - - int w = get_size().x; - int h = get_size().y; - - if (w == 0 || h == 0) - return; //Safety check. We have division by 'h'. And in any case there is nothing to draw with such size - - int total_w = get_size().width - get_size().height - 3; - - //Draw checker pattern for ramp - _draw_checker(0, 0, total_w, h); - - //Draw color ramp - GradientTexture::Point prev; - prev.offset = 0; - if (points.size() == 0) - prev.color = Color(0, 0, 0); //Draw black rectangle if we have no points - else - prev.color = points[0].color; //Extend color of first point to the beginning. - - for (int i = -1; i < points.size(); i++) { - - GradientTexture::Point next; - //If there is no next point - if (i + 1 == points.size()) { - if (points.size() == 0) - next.color = Color(0, 0, 0); //Draw black rectangle if we have no points - else - next.color = points[i].color; //Extend color of last point to the end. - next.offset = 1; - } else { - next = points[i + 1]; - } - - if (prev.offset == next.offset) { - prev = next; - continue; - } - - Vector<Vector2> points; - Vector<Color> colors; - points.push_back(Vector2(prev.offset * total_w, h)); - points.push_back(Vector2(prev.offset * total_w, 0)); - points.push_back(Vector2(next.offset * total_w, 0)); - points.push_back(Vector2(next.offset * total_w, h)); - colors.push_back(prev.color); - colors.push_back(prev.color); - colors.push_back(next.color); - colors.push_back(next.color); - draw_primitive(points, colors, Vector<Point2>()); - prev = next; - } - - //Draw point markers - for (int i = 0; i < points.size(); i++) { - - Color col = i == grabbed ? Color(1, 0.0, 0.0, 0.9) : points[i].color.contrasted(); - col.a = 0.9; - - draw_line(Vector2(points[i].offset * total_w, 0), Vector2(points[i].offset * total_w, h / 2), col); - draw_rect(Rect2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2, POINT_WIDTH, h / 2), Color(0.6, 0.6, 0.6, i == grabbed ? 0.9 : 0.4)); - draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h - 1), col); - draw_line(Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h - 1), col); - draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h / 2), col); - draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h - 1), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h - 1), col); - } - - //Draw "button" for color selector - _draw_checker(total_w + 3, 0, h, h); - if (grabbed != -1) { - //Draw with selection color - draw_rect(Rect2(total_w + 3, 0, h, h), points[grabbed].color); - } else { - //if no color selected draw grey color with 'X' on top. - draw_rect(Rect2(total_w + 3, 0, h, h), Color(0.5, 0.5, 0.5, 1)); - draw_line(Vector2(total_w + 3, 0), Vector2(total_w + 3 + h, h), Color(1, 1, 1, 0.6)); - draw_line(Vector2(total_w + 3, h), Vector2(total_w + 3 + h, 0), Color(1, 1, 1, 0.6)); - } - - //Draw borders around color ramp if in focus - if (has_focus()) { - - draw_line(Vector2(-1, -1), Vector2(total_w + 1, -1), Color(1, 1, 1, 0.6)); - draw_line(Vector2(total_w + 1, -1), Vector2(total_w + 1, h + 1), Color(1, 1, 1, 0.6)); - draw_line(Vector2(total_w + 1, h + 1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6)); - draw_line(Vector2(-1, -1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6)); - } - } -} - -void GradientTextureEdit::_draw_checker(int x, int y, int w, int h) { - //Draw it with polygon to insert UVs for scale - Vector<Vector2> backPoints; - backPoints.push_back(Vector2(x, y)); - backPoints.push_back(Vector2(x, y + h)); - backPoints.push_back(Vector2(x + w, y + h)); - backPoints.push_back(Vector2(x + w, y)); - Vector<Color> colorPoints; - colorPoints.push_back(Color(1, 1, 1, 1)); - colorPoints.push_back(Color(1, 1, 1, 1)); - colorPoints.push_back(Color(1, 1, 1, 1)); - colorPoints.push_back(Color(1, 1, 1, 1)); - Vector<Vector2> uvPoints; - //Draw checker pattern pixel-perfect and scale it by 2. - uvPoints.push_back(Vector2(x, y)); - uvPoints.push_back(Vector2(x, y + h * .5f / checker->get_height())); - uvPoints.push_back(Vector2(x + w * .5f / checker->get_width(), y + h * .5f / checker->get_height())); - uvPoints.push_back(Vector2(x + w * .5f / checker->get_width(), y)); - draw_polygon(backPoints, colorPoints, uvPoints, checker); -} - -Size2 GradientTextureEdit::get_minimum_size() const { - - return Vector2(0, 16); -} - -void GradientTextureEdit::_color_changed(const Color &p_color) { - - if (grabbed == -1) - return; - points[grabbed].color = p_color; - update(); - emit_signal("ramp_changed"); -} - -void GradientTextureEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors) { - - ERR_FAIL_COND(p_offsets.size() != p_colors.size()); - points.clear(); - for (int i = 0; i < p_offsets.size(); i++) { - GradientTexture::Point p; - p.offset = p_offsets[i]; - p.color = p_colors[i]; - points.push_back(p); - } - - points.sort(); - update(); -} - -Vector<float> GradientTextureEdit::get_offsets() const { - Vector<float> ret; - for (int i = 0; i < points.size(); i++) - ret.push_back(points[i].offset); - return ret; -} - -Vector<Color> GradientTextureEdit::get_colors() const { - Vector<Color> ret; - for (int i = 0; i < points.size(); i++) - ret.push_back(points[i].color); - return ret; -} - -void GradientTextureEdit::set_points(Vector<GradientTexture::Point> &p_points) { - if (points.size() != p_points.size()) - grabbed = -1; - points.clear(); - points = p_points; -} - -Vector<GradientTexture::Point> &GradientTextureEdit::get_points() { - return points; -} - -void GradientTextureEdit::_bind_methods() { - ClassDB::bind_method(D_METHOD("_gui_input"), &GradientTextureEdit::_gui_input); - ClassDB::bind_method(D_METHOD("_color_changed"), &GradientTextureEdit::_color_changed); - ADD_SIGNAL(MethodInfo("ramp_changed")); -} - -GradientTextureEditorPlugin::GradientTextureEditorPlugin(EditorNode *p_node) { - - editor = p_node; - ramp_editor = memnew(GradientTextureEdit); - - gradient_button = editor->add_bottom_panel_item("GradientTexture", ramp_editor); - - gradient_button->hide(); - ramp_editor->set_custom_minimum_size(Size2(100, 100 * EDSCALE)); - ramp_editor->hide(); - ramp_editor->connect("ramp_changed", this, "ramp_changed"); -} - -void GradientTextureEditorPlugin::edit(Object *p_object) { - - GradientTexture *gradient_texture = p_object->cast_to<GradientTexture>(); - if (!gradient_texture) - return; - gradient_texture_ref = Ref<GradientTexture>(gradient_texture); - ramp_editor->set_points(gradient_texture_ref->get_points()); -} - -bool GradientTextureEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("GradientTexture"); -} - -void GradientTextureEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - gradient_button->show(); - editor->make_bottom_panel_item_visible(ramp_editor); - - } else { - - gradient_button->hide(); - if (ramp_editor->is_visible_in_tree()) - editor->hide_bottom_panel(); - } -} - -void GradientTextureEditorPlugin::_ramp_changed() { - - if (gradient_texture_ref.is_valid()) { - - UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); - - //Not sure if I should convert this data to PoolVector - Vector<float> new_offsets = ramp_editor->get_offsets(); - Vector<Color> new_colors = ramp_editor->get_colors(); - Vector<float> old_offsets = gradient_texture_ref->get_offsets(); - Vector<Color> old_colors = gradient_texture_ref->get_colors(); - - if (old_offsets.size() != new_offsets.size()) - ur->create_action(TTR("Add/Remove Color Ramp Point")); - else - ur->create_action(TTR("Modify Color Ramp"), UndoRedo::MERGE_ENDS); - ur->add_do_method(this, "undo_redo_gradient_texture", new_offsets, new_colors); - ur->add_undo_method(this, "undo_redo_gradient_texture", old_offsets, old_colors); - ur->commit_action(); - - //gradient_texture_ref->set_points(ramp_editor->get_points()); - } -} - -void GradientTextureEditorPlugin::_undo_redo_gradient_texture(const Vector<float> &offsets, - const Vector<Color> &colors) { - - gradient_texture_ref->set_offsets(offsets); - gradient_texture_ref->set_colors(colors); - ramp_editor->set_points(gradient_texture_ref->get_points()); - ramp_editor->update(); -} - -GradientTextureEditorPlugin::~GradientTextureEditorPlugin() { -} - -void GradientTextureEditorPlugin::_bind_methods() { - ClassDB::bind_method(D_METHOD("ramp_changed"), &GradientTextureEditorPlugin::_ramp_changed); - ClassDB::bind_method(D_METHOD("undo_redo_gradient_texture", "offsets", "colors"), &GradientTextureEditorPlugin::_undo_redo_gradient_texture); -} diff --git a/editor/plugins/gradient_texture_editor_plugin.h b/editor/plugins/gradient_texture_editor_plugin.h deleted file mode 100644 index 842d586541..0000000000 --- a/editor/plugins/gradient_texture_editor_plugin.h +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************/ -/* gradient_texture_editor_plugin.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (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 GRADIENT_TEXTURE_EDITOR_PLUGIN_H -#define GRADIENT_TEXTURE_EDITOR_PLUGIN_H - -#include "editor/editor_node.h" -#include "editor/editor_plugin.h" -#include "scene/resources/texture.h" - -class GradientTextureEdit : public Control { - - GDCLASS(GradientTextureEdit, Control); - - PopupPanel *popup; - ColorPicker *picker; - - Ref<ImageTexture> checker; - - bool grabbing; - int grabbed; - Vector<GradientTexture::Point> points; - - void _draw_checker(int x, int y, int w, int h); - void _color_changed(const Color &p_color); - int _get_point_from_pos(int x); - void _show_color_picker(); - -protected: - void _gui_input(const Ref<InputEvent> &p_event); - void _notification(int p_what); - static void _bind_methods(); - -public: - void set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors); - Vector<float> get_offsets() const; - Vector<Color> get_colors() const; - void set_points(Vector<GradientTexture::Point> &p_points); - Vector<GradientTexture::Point> &get_points(); - virtual Size2 get_minimum_size() const; - - GradientTextureEdit(); - virtual ~GradientTextureEdit(); -}; - -class GradientTextureEditorPlugin : public EditorPlugin { - - GDCLASS(GradientTextureEditorPlugin, EditorPlugin); - - bool _2d; - Ref<GradientTexture> gradient_texture_ref; - GradientTextureEdit *ramp_editor; - EditorNode *editor; - ToolButton *gradient_button; - -protected: - static void _bind_methods(); - void _ramp_changed(); - void _undo_redo_gradient_texture(const Vector<float> &offsets, const Vector<Color> &colors); - -public: - virtual String get_name() const { return "GradientTexture"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - GradientTextureEditorPlugin(EditorNode *p_node); - ~GradientTextureEditorPlugin(); -}; - -#endif // GRADIENT_TEXTURE_EDITOR_PLUGIN_H diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 2d27e218ec..c55bef1b03 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -775,6 +775,11 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } freelook_active = b->is_pressed(); + if (freelook_active && !surface->has_focus()) { + // Focus usually doesn't trigger on right-click, but in case of freelook it should, + // otherwise using keyboard navigation would misbehave + surface->grab_focus(); + } } break; case BUTTON_MIDDLE: { diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index da26c84e45..65ec697b73 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -824,7 +824,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: color_picker->show(); color_picker->set_edit_alpha(hint != PROPERTY_HINT_COLOR_NO_ALPHA); color_picker->set_pick_color(v); - set_size(Size2(300 * EDSCALE, color_picker->get_combined_minimum_size().height + 10 * EDSCALE)); + set_size(Size2(307 * EDSCALE, 460 * EDSCALE)); color_picker->set_focus_on_line_edit(); /* int ofs=80; diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index dbd0758256..0f3f5500a8 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -245,7 +245,7 @@ void ScriptCreateDialog::_lang_changed(int l) { template_menu->clear(); template_menu->add_item(TTR("Default")); for (int i = 0; i < template_list.size(); i++) { - template_menu->add_item(template_list[i]); + template_menu->add_item(template_list[i].capitalize()); } } diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index d64cd86de6..75029a020b 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -2626,7 +2626,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { ConstantNode *cn = alloc_node<ConstantNode>(); switch (args.size()) { - case 1: cn->value = constants[0]; break; + case 1: cn->value = (int)constants[0]; break; case 2: cn->value = Vector2(constants[0], constants[1]); break; case 3: cn->value = Vector3(constants[0], constants[1], constants[2]); break; } @@ -2639,7 +2639,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { on->arguments.push_back(tn); switch (args.size()) { - case 1: tn->vtype = Variant::REAL; break; + case 1: tn->vtype = Variant::INT; break; case 2: tn->vtype = Variant::VECTOR2; break; case 3: tn->vtype = Variant::VECTOR3; break; } diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index 045f1f51aa..c5c274e225 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -160,9 +160,9 @@ void CollisionObject2D::shape_owner_set_transform(uint32_t p_owner, const Transf sd.xform = p_transform; for (int i = 0; i < sd.shapes.size(); i++) { if (area) { - Physics2DServer::get_singleton()->area_set_shape_transform(rid, i, p_transform); + Physics2DServer::get_singleton()->area_set_shape_transform(rid, sd.shapes[i].index, p_transform); } else { - Physics2DServer::get_singleton()->body_set_shape_transform(rid, i, p_transform); + Physics2DServer::get_singleton()->body_set_shape_transform(rid, sd.shapes[i].index, p_transform); } } } diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 2540a5b6a3..fd261117e1 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -941,248 +941,105 @@ RigidBody2D::~RigidBody2D() { ////////////////////////// -Variant KinematicBody2D::_get_collider() const { - - ObjectID oid = get_collider(); - if (oid == 0) - return Variant(); - Object *obj = ObjectDB::get_instance(oid); - if (!obj) - return Variant(); - - Reference *ref = obj->cast_to<Reference>(); - if (ref) { - return Ref<Reference>(ref); - } +Dictionary KinematicBody2D::_move(const Vector2 &p_motion) { + + Collision col; + if (move(p_motion, col)) { + Dictionary d; + d["position"] = col.collision; + d["normal"] = col.collision; + d["local_shape"] = col.local_shape; + d["travel"] = col.travel; + d["remainder"] = col.remainder; + d["collider_id"] = col.collider; + if (col.collider) { + d["collider"] = ObjectDB::get_instance(col.collider); + } else { + d["collider"] = Variant(); + } - return obj; -} + d["collider_shape_index"] = col.collider_shape; + d["collider_metadata"] = col.collider_metadata; -void KinematicBody2D::revert_motion() { + return d; - Transform2D gt = get_global_transform(); - gt.elements[2] -= travel; - travel = Vector2(); - set_global_transform(gt); -} - -Vector2 KinematicBody2D::get_travel() const { - - return travel; + } else { + return Dictionary(); + } } -Vector2 KinematicBody2D::move(const Vector2 &p_motion) { - -#if 1 +bool KinematicBody2D::move(const Vector2 &p_motion, Collision &r_collision) { Transform2D gt = get_global_transform(); Physics2DServer::MotionResult result; - colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, margin, &result); - - collider_metadata = result.collider_metadata; - collider_shape = result.collider_shape; - collider_vel = result.collider_velocity; - collision = result.collision_point; - normal = result.collision_normal; - collider = result.collider_id; - - gt.elements[2] += result.motion; - set_global_transform(gt); - travel = result.motion; - - return result.remainder; - -#else - //give me back regular physics engine logic - //this is madness - //and most people using this function will think - //what it does is simpler than using physics - //this took about a week to get right.. - //but is it right? who knows at this point.. - - colliding = false; - ERR_FAIL_COND_V(!is_inside_tree(), Vector2()); - Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(get_world_2d()->get_space()); - ERR_FAIL_COND_V(!dss, Vector2()); - const int max_shapes = 32; - Vector2 sr[max_shapes * 2]; - int res_shapes; - - Set<RID> exclude; - exclude.insert(get_rid()); - - //recover first - int recover_attempts = 4; - - bool collided = false; - uint32_t mask = 0; - if (true) - mask |= Physics2DDirectSpaceState::TYPE_MASK_STATIC_BODY; - if (true) - mask |= Physics2DDirectSpaceState::TYPE_MASK_KINEMATIC_BODY; - if (true) - mask |= Physics2DDirectSpaceState::TYPE_MASK_RIGID_BODY; - if (true) - mask |= Physics2DDirectSpaceState::TYPE_MASK_CHARACTER_BODY; - - //print_line("margin: "+rtos(margin)); - do { - - //motion recover - for (int i = 0; i < get_shape_count(); i++) { - - if (is_shape_set_as_trigger(i)) - continue; - if (dss->collide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), Vector2(), margin, sr, max_shapes, res_shapes, exclude, get_layer_mask(), mask)) - collided = true; - } - - if (!collided) - break; - - Vector2 recover_motion; - - for (int i = 0; i < res_shapes; i++) { - - Vector2 a = sr[i * 2 + 0]; - Vector2 b = sr[i * 2 + 1]; - - float d = a.distance_to(b); - - /* - if (d<margin) - continue; - */ - recover_motion += (b - a) * 0.4; - } - - if (recover_motion == Vector2()) { - collided = false; - break; - } - - Transform2D gt = get_global_transform(); - gt.elements[2] += recover_motion; - set_global_transform(gt); - - recover_attempts--; - - } while (recover_attempts); - - //move second - float safe = 1.0; - float unsafe = 1.0; - int best_shape = -1; - - for (int i = 0; i < get_shape_count(); i++) { - - if (is_shape_set_as_trigger(i)) - continue; - - float lsafe, lunsafe; - bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0, lsafe, lunsafe, exclude, get_layer_mask(), mask); - //print_line("shape: "+itos(i)+" travel:"+rtos(ltravel)); - if (!valid) { - - safe = 0; - unsafe = 0; - best_shape = i; //sadly it's the best - break; - } - if (lsafe == 1.0) { - continue; - } - if (lsafe < safe) { - - safe = lsafe; - unsafe = lunsafe; - best_shape = i; - } - } - - //print_line("best shape: "+itos(best_shape)+" motion "+p_motion); - - if (safe >= 1) { - //not collided - colliding = false; - - } else { - - //it collided, let's get the rest info in unsafe advance - Transform2D ugt = get_global_transform(); - ugt.elements[2] += p_motion * unsafe; - Physics2DDirectSpaceState::ShapeRestInfo rest_info; - bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt * get_shape_transform(best_shape), Vector2(), margin, &rest_info, exclude, get_layer_mask(), mask); - if (!c2) { - //should not happen, but floating point precision is so weird.. - - colliding = false; - } else { - - //print_line("Travel: "+rtos(travel)); - colliding = true; - collision = rest_info.point; - normal = rest_info.normal; - collider = rest_info.collider_id; - collider_vel = rest_info.linear_velocity; - collider_shape = rest_info.shape; - collider_metadata = rest_info.metadata; - } + bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, margin, &result); + + if (colliding) { + r_collision.collider_metadata = result.collider_metadata; + r_collision.collider_shape = result.collider_shape; + r_collision.collider_vel = result.collider_velocity; + r_collision.collision = result.collision_point; + r_collision.normal = result.collision_normal; + r_collision.collider = result.collider_id; + r_collision.travel = result.motion; + r_collision.remainder = result.remainder; + r_collision.local_shape = result.collision_local_shape; } - Vector2 motion = p_motion * safe; - Transform2D gt = get_global_transform(); - gt.elements[2] += motion; + gt.elements[2] += result.motion; set_global_transform(gt); - return p_motion - motion; -#endif + return colliding; } Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_bounces, float p_floor_max_angle) { - Vector2 motion = (move_and_slide_floor_velocity + p_linear_velocity) * get_fixed_process_delta_time(); + Vector2 motion = (floor_velocity + p_linear_velocity) * get_fixed_process_delta_time(); Vector2 lv = p_linear_velocity; - move_and_slide_on_floor = false; - move_and_slide_on_ceiling = false; - move_and_slide_on_wall = false; - move_and_slide_colliders.clear(); - move_and_slide_floor_velocity = Vector2(); + on_floor = false; + on_ceiling = false; + on_wall = false; + colliders.clear(); + floor_velocity = Vector2(); while (p_max_bounces) { - motion = move(motion); + Collision collision; - if (is_colliding()) { + bool collided = move(motion, collision); + + if (collided) { + + motion = collision.remainder; if (p_floor_direction == Vector2()) { //all is a wall - move_and_slide_on_wall = true; + on_wall = true; } else { - if (get_collision_normal().dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor + if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor - move_and_slide_on_floor = true; - move_and_slide_floor_velocity = get_collider_velocity(); + on_floor = true; + floor_velocity = collision.collider_vel; - if (get_travel().length() < 1 && ABS((lv.x - move_and_slide_floor_velocity.x)) < p_slope_stop_min_velocity) { - revert_motion(); + if (collision.travel.length() < 1 && ABS((lv.x - floor_velocity.x)) < p_slope_stop_min_velocity) { + Transform2D gt = get_global_transform(); + gt.elements[2] -= collision.travel; + set_global_transform(gt); return Vector2(); } - } else if (get_collision_normal().dot(-p_floor_direction) >= Math::cos(p_floor_max_angle)) { //ceiling - move_and_slide_on_ceiling = true; + } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle)) { //ceiling + on_ceiling = true; } else { - move_and_slide_on_wall = true; + on_wall = true; } } - Vector2 n = get_collision_normal(); + Vector2 n = collision.normal; motion = motion.slide(n); lv = lv.slide(n); - Variant collider = _get_collider(); - if (collider.get_type() != Variant::NIL) { - move_and_slide_colliders.push_back(collider); - } + + colliders.push_back(collision); } else { break; @@ -1196,26 +1053,22 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const return lv; } -bool KinematicBody2D::is_move_and_slide_on_floor() const { +bool KinematicBody2D::is_on_floor() const { - return move_and_slide_on_floor; + return on_floor; } -bool KinematicBody2D::is_move_and_slide_on_wall() const { +bool KinematicBody2D::is_on_wall() const { - return move_and_slide_on_wall; + return on_wall; } -bool KinematicBody2D::is_move_and_slide_on_ceiling() const { +bool KinematicBody2D::is_on_ceiling() const { - return move_and_slide_on_ceiling; + return on_ceiling; } -Array KinematicBody2D::get_move_and_slide_colliders() const { - return move_and_slide_colliders; -} +Vector2 KinematicBody2D::get_floor_velocity() const { -Vector2 KinematicBody2D::move_to(const Vector2 &p_position) { - - return move(p_position - get_global_position()); + return floor_velocity; } bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion) { @@ -1225,98 +1078,123 @@ bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_moti return Physics2DServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, margin); } -Vector2 KinematicBody2D::get_collision_pos() const { +void KinematicBody2D::set_safe_margin(float p_margin) { - ERR_FAIL_COND_V(!colliding, Vector2()); - return collision; + margin = p_margin; } -Vector2 KinematicBody2D::get_collision_normal() const { +float KinematicBody2D::get_safe_margin() const { - ERR_FAIL_COND_V(!colliding, Vector2()); - return normal; + return margin; } -Vector2 KinematicBody2D::get_collider_velocity() const { +int KinematicBody2D::get_collision_count() const { - return collider_vel; + return colliders.size(); } +Vector2 KinematicBody2D::get_collision_position(int p_collision) const { -ObjectID KinematicBody2D::get_collider() const { + ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2()); - ERR_FAIL_COND_V(!colliding, 0); - return collider; + return colliders[p_collision].collision; } - -int KinematicBody2D::get_collider_shape() const { - - ERR_FAIL_COND_V(!colliding, 0); - return collider_shape; +Vector2 KinematicBody2D::get_collision_normal(int p_collision) const { + ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2()); + return colliders[p_collision].normal; } -Variant KinematicBody2D::get_collider_metadata() const { - - ERR_FAIL_COND_V(!colliding, 0); - return collider_metadata; +Vector2 KinematicBody2D::get_collision_travel(int p_collision) const { + ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2()); + return colliders[p_collision].travel; } - -bool KinematicBody2D::is_colliding() const { - - return colliding; +Vector2 KinematicBody2D::get_collision_remainder(int p_collision) const { + ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2()); + return colliders[p_collision].remainder; } +Object *KinematicBody2D::get_collision_local_shape(int p_collision) const { + ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL); + uint32_t owner = shape_find_owner(colliders[p_collision].local_shape); + return shape_owner_get_owner(owner); +} +Object *KinematicBody2D::get_collision_collider(int p_collision) const { + ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL); -void KinematicBody2D::set_collision_margin(float p_margin) { + if (colliders[p_collision].collider) { + return ObjectDB::get_instance(colliders[p_collision].collider); + } - margin = p_margin; + return NULL; } +ObjectID KinematicBody2D::get_collision_collider_id(int p_collision) const { + ERR_FAIL_INDEX_V(p_collision, colliders.size(), 0); -float KinematicBody2D::get_collision_margin() const { + return colliders[p_collision].collider; +} +Object *KinematicBody2D::get_collision_collider_shape(int p_collision) const { + ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL); + Object *collider = get_collision_collider(p_collision); + if (collider) { + CollisionObject2D *obj2d = collider->cast_to<CollisionObject2D>(); + if (obj2d) { + uint32_t owner = shape_find_owner(colliders[p_collision].collider_shape); + return obj2d->shape_owner_get_owner(owner); + } + } - return margin; + return NULL; +} +int KinematicBody2D::get_collision_collider_shape_index(int p_collision) const { + ERR_FAIL_INDEX_V(p_collision, colliders.size(), -1); + return colliders[p_collision].collider_shape; +} +Vector2 KinematicBody2D::get_collision_collider_velocity(int p_collision) const { + ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2()); + return colliders[p_collision].collider_vel; +} +Variant KinematicBody2D::get_collision_collider_metadata(int p_collision) const { + ERR_FAIL_INDEX_V(p_collision, colliders.size(), Variant()); + return colliders[p_collision].collider_metadata; } void KinematicBody2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("move", "rel_vec"), &KinematicBody2D::move); - ClassDB::bind_method(D_METHOD("move_to", "position"), &KinematicBody2D::move_to); + ClassDB::bind_method(D_METHOD("move", "rel_vec"), &KinematicBody2D::_move); ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45))); ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec"), &KinematicBody2D::test_move); - ClassDB::bind_method(D_METHOD("get_travel"), &KinematicBody2D::get_travel); - ClassDB::bind_method(D_METHOD("revert_motion"), &KinematicBody2D::revert_motion); - ClassDB::bind_method(D_METHOD("is_colliding"), &KinematicBody2D::is_colliding); + ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody2D::is_on_floor); + ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody2D::is_on_ceiling); + ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody2D::is_on_wall); + ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody2D::get_floor_velocity); - ClassDB::bind_method(D_METHOD("get_collision_pos"), &KinematicBody2D::get_collision_pos); - ClassDB::bind_method(D_METHOD("get_collision_normal"), &KinematicBody2D::get_collision_normal); - ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicBody2D::get_collider_velocity); - ClassDB::bind_method(D_METHOD("get_collider:Variant"), &KinematicBody2D::_get_collider); - ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicBody2D::get_collider_shape); - ClassDB::bind_method(D_METHOD("get_collider_metadata:Variant"), &KinematicBody2D::get_collider_metadata); - ClassDB::bind_method(D_METHOD("get_move_and_slide_colliders"), &KinematicBody2D::get_move_and_slide_colliders); - ClassDB::bind_method(D_METHOD("is_move_and_slide_on_floor"), &KinematicBody2D::is_move_and_slide_on_floor); - ClassDB::bind_method(D_METHOD("is_move_and_slide_on_ceiling"), &KinematicBody2D::is_move_and_slide_on_ceiling); - ClassDB::bind_method(D_METHOD("is_move_and_slide_on_wall"), &KinematicBody2D::is_move_and_slide_on_wall); + ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody2D::set_safe_margin); + ClassDB::bind_method(D_METHOD("get_safe_margin", "pixels"), &KinematicBody2D::get_safe_margin); - ClassDB::bind_method(D_METHOD("set_collision_margin", "pixels"), &KinematicBody2D::set_collision_margin); - ClassDB::bind_method(D_METHOD("get_collision_margin", "pixels"), &KinematicBody2D::get_collision_margin); + ClassDB::bind_method(D_METHOD("get_collision_count"), &KinematicBody2D::get_collision_count); + ClassDB::bind_method(D_METHOD("get_collision_position", "collision"), &KinematicBody2D::get_collision_position); + ClassDB::bind_method(D_METHOD("get_collision_normal", "collision"), &KinematicBody2D::get_collision_normal); + ClassDB::bind_method(D_METHOD("get_collision_travel", "collision"), &KinematicBody2D::get_collision_travel); + ClassDB::bind_method(D_METHOD("get_collision_remainder", "collision"), &KinematicBody2D::get_collision_remainder); + ClassDB::bind_method(D_METHOD("get_collision_local_shape", "collision"), &KinematicBody2D::get_collision_local_shape); + ClassDB::bind_method(D_METHOD("get_collision_collider", "collision"), &KinematicBody2D::get_collision_collider); + ClassDB::bind_method(D_METHOD("get_collision_collider_id", "collision"), &KinematicBody2D::get_collision_collider_id); + ClassDB::bind_method(D_METHOD("get_collision_collider_shape", "collision"), &KinematicBody2D::get_collision_collider_shape); + ClassDB::bind_method(D_METHOD("get_collision_collider_shape_index", "collision"), &KinematicBody2D::get_collision_collider_shape_index); + ClassDB::bind_method(D_METHOD("get_collision_collider_velocity", "collision"), &KinematicBody2D::get_collision_collider_velocity); + ClassDB::bind_method(D_METHOD("get_collision_collider_metadata", "collision"), &KinematicBody2D::get_collision_collider_metadata); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_collision_margin", "get_collision_margin"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); } KinematicBody2D::KinematicBody2D() : PhysicsBody2D(Physics2DServer::BODY_MODE_KINEMATIC) { - colliding = false; - collider = 0; - - collider_shape = 0; - margin = 0.08; - move_and_slide_on_floor = false; - move_and_slide_on_ceiling = false; - move_and_slide_on_wall = false; + on_floor = false; + on_ceiling = false; + on_wall = false; } KinematicBody2D::~KinematicBody2D() { } diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 9871a56fe2..8c8e4ebc77 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -264,54 +264,60 @@ class KinematicBody2D : public PhysicsBody2D { GDCLASS(KinematicBody2D, PhysicsBody2D); +public: + struct Collision { + Vector2 collision; + Vector2 normal; + Vector2 collider_vel; + ObjectID collider; + int collider_shape; + Variant collider_metadata; + Vector2 remainder; + Vector2 travel; + int local_shape; + }; + +private: float margin; - bool colliding; - Vector2 collision; - Vector2 normal; - Vector2 collider_vel; - ObjectID collider; - int collider_shape; - Variant collider_metadata; - Vector2 travel; - - Vector2 move_and_slide_floor_velocity; - bool move_and_slide_on_floor; - bool move_and_slide_on_ceiling; - bool move_and_slide_on_wall; - Array move_and_slide_colliders; - - Variant _get_collider() const; + + Vector2 floor_velocity; + bool on_floor; + bool on_ceiling; + bool on_wall; + Vector<Collision> colliders; _FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const; + Dictionary _move(const Vector2 &p_motion); + protected: static void _bind_methods(); public: - Vector2 move(const Vector2 &p_motion); - Vector2 move_to(const Vector2 &p_position); - + bool move(const Vector2 &p_motion, Collision &r_collision); bool test_move(const Transform2D &p_from, const Vector2 &p_motion); - bool is_colliding() const; - - Vector2 get_travel() const; - void revert_motion(); - - Vector2 get_collision_pos() const; - Vector2 get_collision_normal() const; - Vector2 get_collider_velocity() const; - ObjectID get_collider() const; - int get_collider_shape() const; - Variant get_collider_metadata() const; - void set_collision_margin(float p_margin); - float get_collision_margin() const; + 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), float p_slope_stop_min_velocity = 5, int p_max_bounces = 4, float p_floor_max_angle = Math::deg2rad((float)45)); - bool is_move_and_slide_on_floor() const; - bool is_move_and_slide_on_wall() const; - bool is_move_and_slide_on_ceiling() const; - Array get_move_and_slide_colliders() const; + bool is_on_floor() const; + bool is_on_wall() const; + bool is_on_ceiling() const; + Vector2 get_floor_velocity() const; + + int get_collision_count() const; + Vector2 get_collision_position(int p_collision) const; + Vector2 get_collision_normal(int p_collision) const; + Vector2 get_collision_travel(int p_collision) const; + Vector2 get_collision_remainder(int p_collision) const; + Object *get_collision_local_shape(int p_collision) const; + Object *get_collision_collider(int p_collision) const; + ObjectID get_collision_collider_id(int p_collision) const; + Object *get_collision_collider_shape(int p_collision) const; + int get_collision_collider_shape_index(int p_collision) const; + Vector2 get_collision_collider_velocity(int p_collision) const; + Variant get_collision_collider_metadata(int p_collision) const; KinematicBody2D(); ~KinematicBody2D(); diff --git a/scene/3d/scenario_fx.cpp b/scene/3d/scenario_fx.cpp index 874c21546d..abc7766ecb 100644 --- a/scene/3d/scenario_fx.cpp +++ b/scene/3d/scenario_fx.cpp @@ -28,43 +28,44 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "scenario_fx.h" +#include "scene/main/viewport.h" void WorldEnvironment::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_WORLD) { + if (p_what == Spatial::NOTIFICATION_ENTER_WORLD || p_what == Spatial::NOTIFICATION_ENTER_TREE) { if (environment.is_valid()) { - if (get_world()->get_environment().is_valid()) { + if (get_viewport()->find_world()->get_environment().is_valid()) { WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding."); } - get_world()->set_environment(environment); - add_to_group("_world_environment_" + itos(get_world()->get_scenario().get_id())); + get_viewport()->find_world()->set_environment(environment); + add_to_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id())); } - } else if (p_what == NOTIFICATION_EXIT_WORLD) { + } else if (p_what == Spatial::NOTIFICATION_EXIT_WORLD || p_what == Spatial::NOTIFICATION_EXIT_TREE) { - if (environment.is_valid() && get_world()->get_environment() == environment) { - get_world()->set_environment(Ref<Environment>()); - remove_from_group("_world_environment_" + itos(get_world()->get_scenario().get_id())); + if (environment.is_valid() && get_viewport()->find_world()->get_environment() == environment) { + get_viewport()->find_world()->set_environment(Ref<Environment>()); + remove_from_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id())); } } } void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) { - if (is_inside_world() && environment.is_valid() && get_world()->get_environment() == environment) { - get_world()->set_environment(Ref<Environment>()); - remove_from_group("_world_environment_" + itos(get_world()->get_scenario().get_id())); + if (is_inside_tree() && environment.is_valid() && get_viewport()->find_world()->get_environment() == environment) { + get_viewport()->find_world()->set_environment(Ref<Environment>()); + remove_from_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id())); //clean up } environment = p_environment; - if (is_inside_world() && environment.is_valid()) { - if (get_world()->get_environment().is_valid()) { + if (is_inside_tree() && environment.is_valid()) { + if (get_viewport()->find_world()->get_environment().is_valid()) { WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding."); } - get_world()->set_environment(environment); - add_to_group("_world_environment_" + itos(get_world()->get_scenario().get_id())); + get_viewport()->find_world()->set_environment(environment); + add_to_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id())); } update_configuration_warning(); @@ -77,11 +78,11 @@ Ref<Environment> WorldEnvironment::get_environment() const { String WorldEnvironment::get_configuration_warning() const { - if (!is_visible_in_tree() || !is_inside_tree() || !environment.is_valid()) + if (/*!is_visible_in_tree() ||*/ !is_inside_tree() || !environment.is_valid()) return String(); List<Node *> nodes; - get_tree()->get_nodes_in_group("_world_environment_" + itos(get_world()->get_scenario().get_id()), &nodes); + get_tree()->get_nodes_in_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()), &nodes); if (nodes.size() > 1) { return TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."); diff --git a/scene/3d/scenario_fx.h b/scene/3d/scenario_fx.h index b2a4bc5472..d1e0a63130 100644 --- a/scene/3d/scenario_fx.h +++ b/scene/3d/scenario_fx.h @@ -36,9 +36,9 @@ @author Juan Linietsky <reduzio@gmail.com> */ -class WorldEnvironment : public Spatial { +class WorldEnvironment : public Node { - GDCLASS(WorldEnvironment, Spatial); + GDCLASS(WorldEnvironment, Node); Ref<Environment> environment; diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index ee6af21dbd..9ef340edbc 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -122,9 +122,6 @@ void ColorPicker::_value_changed(double) { } set_pick_color(color); - - _update_text_value(); - emit_signal("color_changed", color); } @@ -257,7 +254,7 @@ void ColorPicker::_update_text_value() { } void ColorPicker::_sample_draw() { - sample->draw_rect(Rect2(Point2(), Size2(256, 20)), color); + sample->draw_rect(Rect2(Point2(), Size2(uv_edit->get_size().width, 20)), color); } void ColorPicker::_hsv_draw(int p_wich, Control *c) { @@ -277,12 +274,12 @@ void ColorPicker::_hsv_draw(int p_wich, Control *c) { c->draw_polygon(points, colors); Vector<Color> colors2; Color col = color; - col.set_hsv(color.get_h(), 1, 1); + col.set_hsv(h, 1, 1); col.a = 0; colors2.push_back(col); col.a = 1; colors2.push_back(col); - col.set_hsv(color.get_h(), 1, 0); + col.set_hsv(h, 1, 0); colors2.push_back(col); col.a = 0; colors2.push_back(col); @@ -311,10 +308,10 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &ev) { if (bev.is_valid()) { if (bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) { changing_color = true; - float x = CLAMP((float)bev->get_position().x, 0, 256); - float y = CLAMP((float)bev->get_position().y, 0, 256); - s = x / 256; - v = 1.0 - y / 256.0; + float x = CLAMP((float)bev->get_position().x, 0, uv_edit->get_size().width); + float y = CLAMP((float)bev->get_position().y, 0, uv_edit->get_size().height); + s = x / uv_edit->get_size().width; + v = 1.0 - y / uv_edit->get_size().height; color.set_hsv(h, s, v, color.a); last_hsv = color; set_pick_color(color); @@ -330,10 +327,10 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &ev) { if (mev.is_valid()) { if (!changing_color) return; - float x = CLAMP((float)mev->get_position().x, 0, 256); - float y = CLAMP((float)mev->get_position().y, 0, 256); - s = x / 256; - v = 1.0 - y / 256.0; + float x = CLAMP((float)mev->get_position().x, 0, uv_edit->get_size().width); + float y = CLAMP((float)mev->get_position().y, 0, uv_edit->get_size().height); + s = x / uv_edit->get_size().width; + v = 1.0 - y / uv_edit->get_size().height; color.set_hsv(h, s, v, color.a); last_hsv = color; set_pick_color(color); @@ -350,8 +347,8 @@ void ColorPicker::_w_input(const Ref<InputEvent> &ev) { if (bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) { changing_color = true; - h = 1 - (256.0 - (float)bev->get_position().y) / 256.0; - + float y = CLAMP((float)bev->get_position().y, 0, w_edit->get_size().height); + h = y / w_edit->get_size().height; } else { changing_color = false; } @@ -368,9 +365,8 @@ void ColorPicker::_w_input(const Ref<InputEvent> &ev) { if (!changing_color) return; - float y = CLAMP((float)mev->get_position().y, 0, 256); - //h = 1.0 - y / 256.0; - h = y / 256.0; + float y = CLAMP((float)mev->get_position().y, 0, w_edit->get_size().height); + h = y / w_edit->get_size().height; color.set_hsv(h, s, v, color.a); last_hsv = color; set_pick_color(color); @@ -508,12 +504,14 @@ ColorPicker::ColorPicker() add_child(hb_smpl); HBoxContainer *hb_edit = memnew(HBoxContainer); + hb_edit->set_v_size_flags(SIZE_EXPAND_FILL); uv_edit = memnew(Control); uv_edit->connect("gui_input", this, "_uv_input"); uv_edit->set_mouse_filter(MOUSE_FILTER_PASS); - uv_edit->set_custom_minimum_size(Size2(256, 256)); + uv_edit->set_h_size_flags(SIZE_EXPAND_FILL); + uv_edit->set_v_size_flags(SIZE_EXPAND_FILL); Vector<Variant> args = Vector<Variant>(); args.push_back(0); args.push_back(uv_edit); @@ -523,7 +521,9 @@ ColorPicker::ColorPicker() w_edit = memnew(Control); //w_edit->set_ignore_mouse(false); - w_edit->set_custom_minimum_size(Size2(30, 256)); + w_edit->set_custom_minimum_size(Size2(30, 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"); args.clear(); args.push_back(1); @@ -549,6 +549,7 @@ ColorPicker::ColorPicker() HBoxContainer *hbc = memnew(HBoxContainer); labels[i] = memnew(Label(lt[i])); + labels[i]->set_custom_minimum_size(Size2(10, 0)); hbc->add_child(labels[i]); scroll[i] = memnew(HSlider); @@ -570,7 +571,7 @@ ColorPicker::ColorPicker() HBoxContainer *hhb = memnew(HBoxContainer); btn_mode = memnew(CheckButton); - btn_mode->set_text("RAW 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); @@ -601,7 +602,7 @@ ColorPicker::ColorPicker() bt_add_preset = memnew(Button); bt_add_preset->set_icon(get_icon("add_preset")); - bt_add_preset->set_tooltip("Add current color as a preset"); + 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); } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 0b8595de42..78ede6e494 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1831,7 +1831,7 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("add_image", "image:Texture"), &RichTextLabel::add_image); ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline); ClassDB::bind_method(D_METHOD("remove_line"), &RichTextLabel::remove_line); - ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font); + ClassDB::bind_method(D_METHOD("push_font", "font:Font"), &RichTextLabel::push_font); ClassDB::bind_method(D_METHOD("push_color", "color"), &RichTextLabel::push_color); ClassDB::bind_method(D_METHOD("push_align", "align"), &RichTextLabel::push_align); ClassDB::bind_method(D_METHOD("push_indent", "level"), &RichTextLabel::push_indent); @@ -1854,7 +1854,7 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("set_scroll_follow", "follow"), &RichTextLabel::set_scroll_follow); ClassDB::bind_method(D_METHOD("is_scroll_following"), &RichTextLabel::is_scroll_following); - ClassDB::bind_method(D_METHOD("get_v_scroll"), &RichTextLabel::get_v_scroll); + ClassDB::bind_method(D_METHOD("get_v_scroll:VScrollBar"), &RichTextLabel::get_v_scroll); ClassDB::bind_method(D_METHOD("scroll_to_line", "line"), &RichTextLabel::scroll_to_line); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 714327c5b7..a87c83f17c 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -49,6 +49,7 @@ #include "scene/scene_string_names.h" #include "global_config.h" +#include "scene/3d/scenario_fx.h" void ViewportTexture::setup_local_to_scene() { @@ -1017,10 +1018,9 @@ void Viewport::_propagate_enter_world(Node *p_node) { if (!p_node->is_inside_tree()) //may not have entered scene yet return; - Spatial *s = p_node->cast_to<Spatial>(); - if (s) { + if (p_node->cast_to<Spatial>() || p_node->cast_to<WorldEnvironment>()) { - s->notification(Spatial::NOTIFICATION_ENTER_WORLD); + p_node->notification(Spatial::NOTIFICATION_ENTER_WORLD); } else { Viewport *v = p_node->cast_to<Viewport>(); if (v) { @@ -1055,10 +1055,9 @@ void Viewport::_propagate_exit_world(Node *p_node) { if (!p_node->is_inside_tree()) //may have exited scene already return; - Spatial *s = p_node->cast_to<Spatial>(); - if (s) { + if (p_node->cast_to<Spatial>() || p_node->cast_to<WorldEnvironment>()) { - s->notification(Spatial::NOTIFICATION_EXIT_WORLD, true); + p_node->notification(Spatial::NOTIFICATION_EXIT_WORLD); } else { Viewport *v = p_node->cast_to<Viewport>(); if (v) { diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index a435ba06cc..24e3977de8 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -959,7 +959,6 @@ void Environment::_bind_methods() { ADD_GROUP("SS Reflections", "ss_reflections_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ss_reflections_enabled"), "set_ssr_enabled", "is_ssr_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "ss_reflections_max_steps", PROPERTY_HINT_RANGE, "1,512,1"), "set_ssr_max_steps", "get_ssr_max_steps"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_accel", PROPERTY_HINT_RANGE, "0,4,0.01"), "set_ssr_accel", "get_ssr_accel"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_fade_in", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_in", "get_ssr_fade_in"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_fade_out", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_out", "get_ssr_fade_out"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_depth_tolerance", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance"); @@ -1040,7 +1039,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_far_amount", "get_dof_blur_far_amount"); ADD_PROPERTY(PropertyInfo(Variant::INT, "dof_blur_far_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_dof_blur_far_quality", "get_dof_blur_far_quality"); - ADD_GROUP("DOF Far Near", "dof_blur_near_"); + ADD_GROUP("DOF Near Blur", "dof_blur_near_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_near_enabled"), "set_dof_blur_near_enabled", "is_dof_blur_near_enabled"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_distance", "get_dof_blur_near_distance"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_transition", "get_dof_blur_near_transition"); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 7b393233f1..5049c0a1d6 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -1508,13 +1508,6 @@ CurveTexture::~CurveTexture() { #define COLOR_RAMP_SET_COLORS "set_colors" GradientTexture::GradientTexture() { - //Set initial color ramp transition from black to white - points.resize(2); - points[0].color = Color(0, 0, 0, 1); - points[0].offset = 0; - points[1].color = Color(1, 1, 1, 1); - points[1].offset = 1; - is_sorted = true; update_pending = false; width = 2048; @@ -1528,32 +1521,33 @@ GradientTexture::~GradientTexture() { void GradientTexture::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_point", "offset", "color"), &GradientTexture::add_point); - ClassDB::bind_method(D_METHOD("remove_point", "offset", "color"), &GradientTexture::remove_point); - - ClassDB::bind_method(D_METHOD("set_offset", "point", "offset"), &GradientTexture::set_offset); - ClassDB::bind_method(D_METHOD("get_offset", "point"), &GradientTexture::get_offset); - - ClassDB::bind_method(D_METHOD("set_color", "point", "color"), &GradientTexture::set_color); - ClassDB::bind_method(D_METHOD("get_color", "point"), &GradientTexture::get_color); + ClassDB::bind_method(D_METHOD("set_gradient", "gradient:Gradient"), &GradientTexture::set_gradient); + ClassDB::bind_method(D_METHOD("get_gradient:Gradient"), &GradientTexture::get_gradient); ClassDB::bind_method(D_METHOD("set_width", "width"), &GradientTexture::set_width); - ClassDB::bind_method(D_METHOD("interpolate", "offset"), &GradientTexture::get_color_at_offset); - - ClassDB::bind_method(D_METHOD("get_point_count"), &GradientTexture::get_points_count); - ClassDB::bind_method(D_METHOD("_update"), &GradientTexture::_update); - ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_OFFSETS, "offsets"), &GradientTexture::set_offsets); - ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_OFFSETS), &GradientTexture::get_offsets); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "width"), "set_width", "get_width"); +} - ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_COLORS, "colors"), &GradientTexture::set_colors); - ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_COLORS), &GradientTexture::get_colors); +void GradientTexture::set_gradient(Ref<Gradient> p_gradient) { + if (p_gradient == gradient) + return; + if (gradient.is_valid()) { + gradient->disconnect(CoreStringNames::get_singleton()->changed, this, "_update"); + } + gradient = p_gradient; + if (gradient.is_valid()) { + gradient->connect(CoreStringNames::get_singleton()->changed, this, "_update"); + } + _update(); + emit_changed(); +} - ADD_PROPERTY(PropertyInfo(Variant::INT, "width"), "set_width", "get_width"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "offsets"), COLOR_RAMP_SET_OFFSETS, COLOR_RAMP_GET_OFFSETS); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "colors"), COLOR_RAMP_SET_COLORS, COLOR_RAMP_GET_COLORS); +Ref<Gradient> GradientTexture::get_gradient() const { + return gradient; } void GradientTexture::_queue_update() { @@ -1566,16 +1560,22 @@ void GradientTexture::_queue_update() { void GradientTexture::_update() { + if (gradient.is_null()) + return; + update_pending = false; PoolVector<uint8_t> data; data.resize(width * 4); { PoolVector<uint8_t>::Write wd8 = data.write(); + Gradient &g = **gradient; + for (int i = 0; i < width; i++) { + float ofs = float(i) / (width - 1); + Color color = g.get_color_at_offset(ofs); - Color color = get_color_at_offset(ofs); wd8[i * 4 + 0] = uint8_t(CLAMP(color.r * 255.0, 0, 255)); wd8[i * 4 + 1] = uint8_t(CLAMP(color.g * 255.0, 0, 255)); wd8[i * 4 + 2] = uint8_t(CLAMP(color.b * 255.0, 0, 255)); @@ -1601,112 +1601,6 @@ int GradientTexture::get_width() const { return width; } -Vector<float> GradientTexture::get_offsets() const { - Vector<float> offsets; - offsets.resize(points.size()); - for (int i = 0; i < points.size(); i++) { - offsets[i] = points[i].offset; - } - return offsets; -} - -Vector<Color> GradientTexture::get_colors() const { - Vector<Color> colors; - colors.resize(points.size()); - for (int i = 0; i < points.size(); i++) { - colors[i] = points[i].color; - } - return colors; -} - -void GradientTexture::set_offsets(const Vector<float> &p_offsets) { - points.resize(p_offsets.size()); - for (int i = 0; i < points.size(); i++) { - points[i].offset = p_offsets[i]; - } - is_sorted = false; - emit_changed(); - _queue_update(); -} - -void GradientTexture::set_colors(const Vector<Color> &p_colors) { - if (points.size() < p_colors.size()) - is_sorted = false; - points.resize(p_colors.size()); - for (int i = 0; i < points.size(); i++) { - points[i].color = p_colors[i]; - } - emit_changed(); - _queue_update(); -} - -Vector<GradientTexture::Point> &GradientTexture::get_points() { - return points; -} - -void GradientTexture::add_point(float p_offset, const Color &p_color) { - - Point p; - p.offset = p_offset; - p.color = p_color; - is_sorted = false; - points.push_back(p); - - emit_changed(); - _queue_update(); -} - -void GradientTexture::remove_point(int p_index) { - - ERR_FAIL_INDEX(p_index, points.size()); - ERR_FAIL_COND(points.size() <= 2); - points.remove(p_index); - emit_changed(); - _queue_update(); -} - -void GradientTexture::set_points(Vector<GradientTexture::Point> &p_points) { - points = p_points; - is_sorted = false; - emit_changed(); - _queue_update(); -} - -void GradientTexture::set_offset(int pos, const float offset) { - if (points.size() <= pos) - points.resize(pos + 1); - points[pos].offset = offset; - is_sorted = false; - emit_changed(); - _queue_update(); -} - -float GradientTexture::get_offset(int pos) const { - if (points.size() > pos) - return points[pos].offset; - return 0; //TODO: Maybe throw some error instead? -} - Ref<Image> GradientTexture::get_data() const { return VisualServer::get_singleton()->texture_get_data(texture); } - -void GradientTexture::set_color(int pos, const Color &color) { - if (points.size() <= pos) { - points.resize(pos + 1); - is_sorted = false; - } - points[pos].color = color; - emit_changed(); - _queue_update(); -} - -Color GradientTexture::get_color(int pos) const { - if (points.size() > pos) - return points[pos].color; - return Color(0, 0, 0, 1); //TODO: Maybe throw some error instead? -} - -int GradientTexture::get_points_count() const { - return points.size(); -} diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 2c36cdef87..ff5a58c221 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -34,6 +34,7 @@ #include "io/resource_loader.h" #include "math_2d.h" #include "resource.h" +#include "scene/resources/color_ramp.h" #include "servers/visual_server.h" /** @@ -451,7 +452,7 @@ public: //VARIANT_ENUM_CAST( Texture::CubeMapSide ); class GradientTexture : public Texture { - GDCLASS(GradientTexture, Texture); + GDCLASS(GradientTexture, Texture) public: struct Point { @@ -464,8 +465,7 @@ public: }; private: - Vector<Point> points; - bool is_sorted; + Ref<Gradient> gradient; bool update_pending; RID texture; int width; @@ -477,23 +477,8 @@ protected: static void _bind_methods(); public: - void add_point(float p_offset, const Color &p_color); - void remove_point(int p_index); - - void set_points(Vector<Point> &points); - Vector<Point> &get_points(); - - void set_offset(int pos, const float offset); - float get_offset(int pos) const; - - void set_color(int pos, const Color &color); - Color get_color(int pos) const; - - void set_offsets(const Vector<float> &offsets); - Vector<float> get_offsets() const; - - void set_colors(const Vector<Color> &colors); - Vector<Color> get_colors() const; + void set_gradient(Ref<Gradient> p_gradient); + Ref<Gradient> get_gradient() const; void set_width(int p_width); int get_width() const; @@ -505,52 +490,8 @@ public: virtual void set_flags(uint32_t p_flags) {} virtual uint32_t get_flags() const { return FLAG_FILTER; } - _FORCE_INLINE_ Color get_color_at_offset(float p_offset) { - - if (points.empty()) - return Color(0, 0, 0, 1); - - if (!is_sorted) { - points.sort(); - is_sorted = true; - } - - //binary search - int low = 0; - int high = points.size() - 1; - int middle; - - while (low <= high) { - middle = (low + high) / 2; - Point &point = points[middle]; - if (point.offset > p_offset) { - high = middle - 1; //search low end of array - } else if (point.offset < p_offset) { - low = middle + 1; //search high end of array - } else { - return point.color; - } - } - - //return interpolated value - if (points[middle].offset > p_offset) { - middle--; - } - int first = middle; - int second = middle + 1; - if (second >= points.size()) - return points[points.size() - 1].color; - if (first < 0) - return points[0].color; - Point &pointFirst = points[first]; - Point &pointSecond = points[second]; - return pointFirst.color.linear_interpolate(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset)); - } - virtual Ref<Image> get_data() const; - int get_points_count() const; - GradientTexture(); virtual ~GradientTexture(); }; diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index b197ba5905..0b31ff144b 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -781,6 +781,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co r_result->collider = rcd.best_object->get_self(); r_result->collider_id = rcd.best_object->get_instance_id(); r_result->collider_shape = rcd.best_shape; + r_result->collision_local_shape = best_shape; r_result->collision_normal = rcd.best_normal; r_result->collision_point = rcd.best_contact; r_result->collider_metadata = rcd.best_object->get_shape_metadata(rcd.best_shape); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index f25f05bafc..f50faa42eb 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -474,6 +474,7 @@ public: Vector2 collision_point; Vector2 collision_normal; Vector2 collider_velocity; + int collision_local_shape; ObjectID collider_id; RID collider; int collider_shape; diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 43452b714c..2ce83e6c64 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -75,6 +75,10 @@ public: virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0; virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0; + virtual bool is_environment(RID p_env) = 0; + virtual VS::EnvironmentBG environment_get_background(RID p_env) = 0; + virtual int environment_get_canvas_max_layer(RID p_env) = 0; + struct InstanceBase : RID_Data { VS::InstanceType base_type; diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 6d1f698a5c..fb1c66d0b9 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -2162,6 +2162,18 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam VSG::scene_render->render_scene(p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, environment, p_shadow_atlas, scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass); } +void VisualServerScene::render_empty_scene(RID p_scenario, RID p_shadow_atlas) { + + Scenario *scenario = scenario_owner.getornull(p_scenario); + + RID environment; + if (scenario->environment.is_valid()) + environment = scenario->environment; + else + environment = scenario->fallback_environment; + VSG::scene_render->render_scene(Transform(), CameraMatrix(), true, NULL, 0, NULL, 0, NULL, 0, environment, p_shadow_atlas, scenario->reflection_atlas, RID(), 0); +} + bool VisualServerScene::_render_reflection_probe_step(Instance *p_instance, int p_step) { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data); diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h index 92c6421987..d13c24ae24 100644 --- a/servers/visual/visual_server_scene.h +++ b/servers/visual/visual_server_scene.h @@ -519,6 +519,7 @@ public: _FORCE_INLINE_ void _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario); void _render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass); + void render_empty_scene(RID p_scenario, RID p_shadow_atlas); void render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas); void update_dirty_instances(); diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp index 2fbbcd225f..2c2bd2b167 100644 --- a/servers/visual/visual_server_viewport.cpp +++ b/servers/visual/visual_server_viewport.cpp @@ -35,23 +35,24 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) { -/* Camera should always be BEFORE any other 3D */ -#if 0 - bool scenario_draw_canvas_bg=false; - int scenario_canvas_max_layer=0; + /* Camera should always be BEFORE any other 3D */ - if (!p_viewport->hide_canvas && !p_viewport->disable_environment && scenario_owner.owns(p_viewport->scenario)) { + bool scenario_draw_canvas_bg = false; //draw canvas, or some layer of it, as BG for 3D instead of in front + int scenario_canvas_max_layer = 0; - Scenario *scenario=scenario_owner.get(p_viewport->scenario); - if (scenario->environment.is_valid()) { - if (rasterizer->is_environment(scenario->environment)) { - scenario_draw_canvas_bg=rasterizer->environment_get_background(scenario->environment)==VS::ENV_BG_CANVAS; - scenario_canvas_max_layer=rasterizer->environment_get_background_param(scenario->environment,VS::ENV_BG_PARAM_CANVAS_MAX_LAYER); - } + if (!p_viewport->hide_canvas && !p_viewport->disable_environment && VSG::scene->scenario_owner.owns(p_viewport->scenario)) { + + VisualServerScene::Scenario *scenario = VSG::scene->scenario_owner.get(p_viewport->scenario); + if (VSG::scene_render->is_environment(scenario->environment)) { + scenario_draw_canvas_bg = VSG::scene_render->environment_get_background(scenario->environment) == VS::ENV_BG_CANVAS; + + scenario_canvas_max_layer = VSG::scene_render->environment_get_canvas_max_layer(scenario->environment); } } - bool can_draw_3d=!p_viewport->hide_scenario && camera_owner.owns(p_viewport->camera) && scenario_owner.owns(p_viewport->scenario); + bool can_draw_3d = !p_viewport->disable_3d && !p_viewport->disable_3d_by_usage && VSG::scene->camera_owner.owns(p_viewport->camera); +#if 0 + if (scenario_draw_canvas_bg) { @@ -88,7 +89,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) { } } - if (!p_viewport->disable_3d && !p_viewport->disable_3d_by_usage && p_viewport->camera.is_valid()) { + if (!scenario_draw_canvas_bg && can_draw_3d) { VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } @@ -199,14 +200,15 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) { VSG::rasterizer->restore_render_target(); -#if 0 - if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer>scenario_canvas_max_layer) { - - _draw_viewport_camera(p_viewport,!can_draw_3d); - scenario_draw_canvas_bg=false; + if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer > scenario_canvas_max_layer) { + if (can_draw_3d) { + VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + } else { + VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); + } + scenario_draw_canvas_bg = false; } -#endif for (Map<Viewport::CanvasKey, Viewport::CanvasData *>::Element *E = canvas_map.front(); E; E = E->next()) { @@ -229,19 +231,29 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) { VSG::canvas->render_canvas(canvas, xform, canvas_lights, lights_with_mask, clip_rect); i++; -#if 0 - if (scenario_draw_canvas_bg && E->key().layer>=scenario_canvas_max_layer) { - _draw_viewport_camera(p_viewport,!can_draw_3d); - scenario_draw_canvas_bg=false; + + if (scenario_draw_canvas_bg && E->key().layer >= scenario_canvas_max_layer) { + + if (can_draw_3d) { + VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + } else { + VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); + } + + scenario_draw_canvas_bg = false; } -#endif } -#if 0 + if (scenario_draw_canvas_bg) { - _draw_viewport_camera(p_viewport,!can_draw_3d); - scenario_draw_canvas_bg=false; + + if (can_draw_3d) { + VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + } else { + VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); + } + + scenario_draw_canvas_bg = false; } -#endif //VSG::canvas_render->canvas_debug_viewport_shadows(lights_with_shadow); } |