diff options
Diffstat (limited to 'scene/resources')
-rw-r--r-- | scene/resources/bit_map.cpp | 56 | ||||
-rw-r--r-- | scene/resources/bit_map.h | 1 | ||||
-rw-r--r-- | scene/resources/dynamic_font.cpp | 2 | ||||
-rw-r--r-- | scene/resources/dynamic_font_stb.cpp | 524 | ||||
-rw-r--r-- | scene/resources/dynamic_font_stb.h | 191 | ||||
-rw-r--r-- | scene/resources/environment.cpp | 4 | ||||
-rw-r--r-- | scene/resources/texture.cpp | 13 | ||||
-rw-r--r-- | scene/resources/visual_shader.cpp | 29 | ||||
-rw-r--r-- | scene/resources/visual_shader.h | 5 | ||||
-rw-r--r-- | scene/resources/visual_shader_nodes.cpp | 129 | ||||
-rw-r--r-- | scene/resources/visual_shader_nodes.h | 8 | ||||
-rw-r--r-- | scene/resources/world.cpp | 2 | ||||
-rw-r--r-- | scene/resources/world_2d.cpp | 4 |
13 files changed, 199 insertions, 769 deletions
diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index e4a64a1de1..b5354bc3e2 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -197,16 +197,14 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) | 4 | 8 | <- current pixel (curx,cury) +---+---+ */ - //NOTE: due to the way we pick points from texture, rect needs to be smaller, otherwise it goes outside 1 pixel - Rect2i fixed_rect = Rect2i(rect.position, rect.size - Size2i(2, 2)); Point2i tl = Point2i(curx - 1, cury - 1); - sv += (fixed_rect.has_point(tl) && get_bit(tl)) ? 1 : 0; + sv += (rect.has_point(tl) && get_bit(tl)) ? 1 : 0; Point2i tr = Point2i(curx, cury - 1); - sv += (fixed_rect.has_point(tr) && get_bit(tr)) ? 2 : 0; + sv += (rect.has_point(tr) && get_bit(tr)) ? 2 : 0; Point2i bl = Point2i(curx - 1, cury); - sv += (fixed_rect.has_point(bl) && get_bit(bl)) ? 4 : 0; + sv += (rect.has_point(bl) && get_bit(bl)) ? 4 : 0; Point2i br = Point2i(curx, cury); - sv += (fixed_rect.has_point(br) && get_bit(br)) ? 8 : 0; + sv += (rect.has_point(br) && get_bit(br)) ? 8 : 0; ERR_FAIL_COND_V(sv == 0 || sv == 15, Vector<Vector2>()); } @@ -300,15 +298,15 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) +---+---+ | 4 | | +---+---+ - this normally go RIGHT, but if its coming from UP, it should go LEFT + this normally go RIGHT, but if its coming from RIGHT, it should go LEFT */ if (case6s.has(Point2i(curx, cury))) { - //found, so we go down, and delete from case6s; + //found, so we go left, and delete from case6s; stepx = -1; stepy = 0; case6s.erase(Point2i(curx, cury)); } else { - //not found, we go up, and add to case6s; + //not found, we go right, and add to case6s; stepx = 1; stepy = 0; case6s.insert(Point2i(curx, cury)); @@ -510,12 +508,19 @@ Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, fl for (int j = r.position.x; j < r.position.x + r.size.width; j++) { if (!fill->get_bit(Point2(j, i)) && get_bit(Point2(j, i))) { + fill_bits(this, fill, Point2i(j, i), r); + Vector<Vector2> polygon = _march_square(r, Point2i(j, i)); print_verbose("BitMap: Pre reduce: " + itos(polygon.size())); polygon = reduce(polygon, r, p_epsilon); print_verbose("BitMap: Post reduce: " + itos(polygon.size())); + + if (polygon.size() < 3) { + print_verbose("Invalid polygon, skipped"); + continue; + } + polygons.push_back(polygon); - fill_bits(this, fill, Point2i(j, i), r); } } } @@ -525,6 +530,13 @@ Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, fl void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { + if (p_pixels == 0) { + return; + } + + bool bit_value = (p_pixels > 0) ? true : false; + p_pixels = Math::abs(p_pixels); + Rect2i r = Rect2i(0, 0, width, height).clip(p_rect); Ref<BitMap> copy; @@ -534,7 +546,7 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { for (int i = r.position.y; i < r.position.y + r.size.height; i++) { for (int j = r.position.x; j < r.position.x + r.size.width; j++) { - if (copy->get_bit(Point2(j, i))) + if (bit_value == get_bit(Point2(j, i))) continue; bool found = false; @@ -542,16 +554,21 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { for (int y = i - p_pixels; y <= i + p_pixels; y++) { for (int x = j - p_pixels; x <= j + p_pixels; x++) { - if (x < p_rect.position.x || x >= p_rect.position.x + p_rect.size.x) - continue; - if (y < p_rect.position.y || y >= p_rect.position.y + p_rect.size.y) - continue; + bool outside = false; + + if ((x < p_rect.position.x) || (x >= p_rect.position.x + p_rect.size.x) || (y < p_rect.position.y) || (y >= p_rect.position.y + p_rect.size.y)) { + // outside of rectangle counts as bit not set + if (!bit_value) + outside = true; + else + continue; + } float d = Point2(j, i).distance_to(Point2(x, y)) - CMP_EPSILON; if (d > p_pixels) continue; - if (copy->get_bit(Point2(x, y))) { + if (outside || (bit_value == copy->get_bit(Point2(x, y)))) { found = true; break; } @@ -561,12 +578,17 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { } if (found) { - set_bit(Point2(j, i), true); + set_bit(Point2(j, i), bit_value); } } } } +void BitMap::shrink_mask(int p_pixels, const Rect2 &p_rect) { + + grow_mask(-p_pixels, p_rect); +} + Array BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) const { Vector<Vector<Vector2> > result = clip_opaque_to_polygons(p_rect, p_epsilon); diff --git a/scene/resources/bit_map.h b/scene/resources/bit_map.h index daf24affb1..b062dd7376 100644 --- a/scene/resources/bit_map.h +++ b/scene/resources/bit_map.h @@ -67,6 +67,7 @@ public: void resize(const Size2 &p_new_size); void grow_mask(int p_pixels, const Rect2 &p_rect); + void shrink_mask(int p_pixels, const Rect2 &p_rect); void blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap); Ref<Image> convert_to_image() const; diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 5704212831..99a2881d58 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -192,7 +192,7 @@ Error DynamicFontAtSize::_load() { ERR_FAIL_V_MSG(ERR_FILE_CANT_OPEN, "Error loading font."); } - if (FT_HAS_COLOR(face)) { + if (FT_HAS_COLOR(face) && face->num_fixed_sizes > 0) { int best_match = 0; int diff = ABS(id.size - ((int64_t)face->available_sizes[0].width)); scale_color_font = float(id.size) / face->available_sizes[0].width; diff --git a/scene/resources/dynamic_font_stb.cpp b/scene/resources/dynamic_font_stb.cpp deleted file mode 100644 index 412bffa5dc..0000000000 --- a/scene/resources/dynamic_font_stb.cpp +++ /dev/null @@ -1,524 +0,0 @@ -/*************************************************************************/ -/* dynamic_font_stb.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (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 "dynamic_font_stb.h" - -#ifndef FREETYPE_ENABLED - -#define STB_TRUETYPE_IMPLEMENTATION -#include "core/os/file_access.h" - -void DynamicFontData::lock() { - - fr = font_data.read(); - - if (fr.ptr() != last_data_ptr) { - - last_data_ptr = fr.ptr(); - - if (!stbtt_InitFont(&info, last_data_ptr, 0)) { - valid = false; - } else { - valid = true; - } - - last_data_ptr = fr.ptr(); - } -} - -void DynamicFontData::unlock() { - - fr.release(); -} - -void DynamicFontData::set_font_data(const PoolVector<uint8_t> &p_font) { - //clear caches and stuff - ERR_FAIL_COND(font_data.size()); - font_data = p_font; - - lock(); - - if (valid) { - stbtt_GetFontVMetrics(&info, &ascent, &descent, &linegap); - descent = -descent + linegap; - - for (int i = 32; i < 1024; i++) { - for (int j = 32; j < 1024; j++) { - - int kern = stbtt_GetCodepointKernAdvance(&info, i, j); - if (kern != 0) { - KerningPairKey kpk; - kpk.A = i; - kpk.B = j; - kerning_map[kpk] = kern; - } - } - } - } - - unlock(); - //clear existing stuff - - ERR_FAIL_COND(!valid); -} - -Ref<DynamicFontAtSize> DynamicFontData::_get_dynamic_font_at_size(int p_size) { - - ERR_FAIL_COND_V(!valid, Ref<DynamicFontAtSize>()); - - if (size_cache.has(p_size)) { - return Ref<DynamicFontAtSize>(size_cache[p_size]); - } - - Ref<DynamicFontAtSize> dfas; - dfas.instance(); - - dfas->font = Ref<DynamicFontData>(this); - - size_cache[p_size] = dfas.ptr(); - - dfas->size = p_size; - - lock(); - - dfas->scale = stbtt_ScaleForPixelHeight(&info, p_size); - - unlock(); - - return dfas; -} - -DynamicFontData::DynamicFontData() { - last_data_ptr = NULL; - valid = false; -} - -DynamicFontData::~DynamicFontData() { -} - -//////////////////// - -float DynamicFontAtSize::get_height() const { - - return (font->ascent + font->descent) * scale; -} - -float DynamicFontAtSize::get_ascent() const { - - return font->ascent * scale; -} -float DynamicFontAtSize::get_descent() const { - - return font->descent * scale; -} - -Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next) const { - - const_cast<DynamicFontAtSize *>(this)->_update_char(p_char); - - const Character *c = char_map.getptr(p_char); - ERR_FAIL_COND_V(!c, Size2()); - - Size2 ret(c->advance, get_height()); - - if (p_next) { - DynamicFontData::KerningPairKey kpk; - kpk.A = p_char; - kpk.B = p_next; - - const Map<DynamicFontData::KerningPairKey, int>::Element *K = font->kerning_map.find(kpk); - if (K) { - ret.x += K->get() * scale; - } - } - - return ret; -} - -float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, bool p_outline) const { - - const_cast<DynamicFontAtSize *>(this)->_update_char(p_char); - - const Character *c = char_map.getptr(p_char); - - if (!c) { - return 0; - } - - if (!p_outline) { - Point2 cpos = p_pos; - cpos.x += c->h_align; - cpos.y -= get_ascent(); - cpos.y += c->v_align; - ERR_FAIL_COND_V(c->texture_idx < -1 || c->texture_idx >= textures.size(), 0); - if (c->texture_idx != -1) - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, c->rect.size), textures[c->texture_idx].texture->get_rid(), c->rect, p_modulate); - } - - //textures[c->texture_idx].texture->draw(p_canvas_item,Vector2()); - - float ret = c->advance; - if (p_next) { - DynamicFontData::KerningPairKey kpk; - kpk.A = p_char; - kpk.B = p_next; - - const Map<DynamicFontData::KerningPairKey, int>::Element *K = font->kerning_map.find(kpk); - if (K) { - ret += K->get() * scale; - } - } - - return ret; -} - -void DynamicFontAtSize::_update_char(CharType p_char) { - - if (char_map.has(p_char)) - return; - - font->lock(); - - int w, h, xofs, yofs; - unsigned char *cpbitmap = stbtt_GetCodepointBitmap(&font->info, scale, scale, p_char, &w, &h, &xofs, &yofs); - - if (!cpbitmap) { - //no glyph - - int advance; - stbtt_GetCodepointHMetrics(&font->info, p_char, &advance, 0); - Character ch; - ch.texture_idx = -1; - ch.advance = advance * scale; - ch.h_align = 0; - ch.v_align = 0; - - char_map[p_char] = ch; - - font->unlock(); - - return; - } - - int mw = w + rect_margin * 2; - int mh = h + rect_margin * 2; - - if (mw > 4096 || mh > 4096) { - - stbtt_FreeBitmap(cpbitmap, NULL); - font->unlock(); - ERR_FAIL_COND(mw > 4096); - ERR_FAIL_COND(mh > 4096); - } - - //find a texture to fit this... - - int tex_index = -1; - int tex_x = 0; - int tex_y = 0; - - for (int i = 0; i < textures.size(); i++) { - - CharTexture &ct = textures[i]; - - if (mw > ct.texture_size || mh > ct.texture_size) //too big for this texture - continue; - - tex_y = 0x7FFFFFFF; - tex_x = 0; - - for (int j = 0; j < ct.texture_size - mw; j++) { - - int max_y = 0; - - for (int k = j; k < j + mw; k++) { - - int y = ct.offsets[k]; - if (y > max_y) - max_y = y; - } - - if (max_y < tex_y) { - tex_y = max_y; - tex_x = j; - } - } - - if (tex_y == 0x7FFFFFFF || tex_y + mh > ct.texture_size) - continue; //fail, could not fit it here - - tex_index = i; - break; - } - - if (tex_index == -1) { - //could not find texture to fit, create one - tex_x = 0; - tex_y = 0; - - int texsize = MAX(size * 8, 256); - if (mw > texsize) - texsize = mw; //special case, adapt to it? - if (mh > texsize) - texsize = mh; //special case, adapt to it? - - texsize = next_power_of_2(texsize); - - texsize = MIN(texsize, 4096); - - CharTexture tex; - tex.texture_size = texsize; - tex.imgdata.resize(texsize * texsize * 2); //grayscale alpha - - { - //zero texture - PoolVector<uint8_t>::Write w = tex.imgdata.write(); - ERR_FAIL_COND(texsize * texsize * 2 > tex.imgdata.size()); - for (int i = 0; i < texsize * texsize * 2; i++) { - w[i] = 0; - } - } - tex.offsets.resize(texsize); - for (int i = 0; i < texsize; i++) //zero offsets - tex.offsets[i] = 0; - - textures.push_back(tex); - tex_index = textures.size() - 1; - } - - //fit character in char texture - - CharTexture &tex = textures[tex_index]; - - { - PoolVector<uint8_t>::Write wr = tex.imgdata.write(); - - for (int i = 0; i < h; i++) { - for (int j = 0; j < w; j++) { - - int ofs = ((i + tex_y + rect_margin) * tex.texture_size + j + tex_x + rect_margin) * 2; - ERR_FAIL_COND(ofs >= tex.imgdata.size()); - wr[ofs + 0] = 255; //grayscale as 1 - wr[ofs + 1] = cpbitmap[i * w + j]; //alpha as 0 - } - } - } - - //blit to image and texture - { - Ref<Image> img = memnew(Image(tex.texture_size, tex.texture_size, 0, Image::FORMAT_LA8, tex.imgdata)); - - if (tex.texture.is_null()) { - tex.texture.instance(); - tex.texture->create_from_image(img, Texture::FLAG_FILTER); - } else { - tex.texture->set_data(img); //update - } - } - - // update height array - - for (int k = tex_x; k < tex_x + mw; k++) { - - tex.offsets[k] = tex_y + mh; - } - - int advance; - stbtt_GetCodepointHMetrics(&font->info, p_char, &advance, 0); - - Character chr; - chr.h_align = xofs; - chr.v_align = yofs + get_ascent(); - chr.advance = advance * scale; - chr.texture_idx = tex_index; - - chr.rect = Rect2(tex_x + rect_margin, tex_y + rect_margin, w, h); - - char_map[p_char] = chr; - - stbtt_FreeBitmap(cpbitmap, NULL); - - font->unlock(); -} - -DynamicFontAtSize::DynamicFontAtSize() { - - rect_margin = 1; -} - -DynamicFontAtSize::~DynamicFontAtSize() { - - ERR_FAIL_COND(!font.ptr()); - font->size_cache.erase(size); -} - -///////////////////////// - -void DynamicFont::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_font_data", "data"), &DynamicFont::set_font_data); - ClassDB::bind_method(D_METHOD("get_font_data"), &DynamicFont::get_font_data); - - ClassDB::bind_method(D_METHOD("set_size", "data"), &DynamicFont::set_size); - ClassDB::bind_method(D_METHOD("get_size"), &DynamicFont::get_size); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "font/size"), "set_size", "get_size"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "font/font", PROPERTY_HINT_RESOURCE_TYPE, "DynamicFontData"), "set_font_data", "get_font_data"); -} - -void DynamicFont::set_font_data(const Ref<DynamicFontData> &p_data) { - - data = p_data; - data_at_size = data->_get_dynamic_font_at_size(size); -} - -Ref<DynamicFontData> DynamicFont::get_font_data() const { - - return data; -} - -void DynamicFont::set_size(int p_size) { - - if (size == p_size) - return; - size = p_size; - ERR_FAIL_COND(p_size < 1); - if (!data.is_valid()) - return; - data_at_size = data->_get_dynamic_font_at_size(size); -} -int DynamicFont::get_size() const { - - return size; -} - -float DynamicFont::get_height() const { - - if (!data_at_size.is_valid()) - return 1; - - return data_at_size->get_height(); -} - -float DynamicFont::get_ascent() const { - - if (!data_at_size.is_valid()) - return 1; - - return data_at_size->get_ascent(); -} - -float DynamicFont::get_descent() const { - - if (!data_at_size.is_valid()) - return 1; - - return data_at_size->get_descent(); -} - -Size2 DynamicFont::get_char_size(CharType p_char, CharType p_next) const { - - if (!data_at_size.is_valid()) - return Size2(1, 1); - - return data_at_size->get_char_size(p_char, p_next); -} - -bool DynamicFont::is_distance_field_hint() const { - - return false; -} - -float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, bool p_outline) const { - - if (!data_at_size.is_valid()) - return 0; - - return data_at_size->draw_char(p_canvas_item, p_pos, p_char, p_next, p_modulate, p_outline); -} - -DynamicFont::DynamicFont() { - - size = 16; -} - -DynamicFont::~DynamicFont() { -} - -///////////////////////// - -RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error) { - - if (r_error) - *r_error = ERR_FILE_CANT_OPEN; - - FileAccess *f = FileAccess::open(p_path, FileAccess::READ); - ERR_FAIL_COND_V_MSG(!f, RES(), "Cannot load font from file '" + p_path + "'."); - - PoolVector<uint8_t> data; - - data.resize(f->get_len()); - - ERR_FAIL_COND_V(data.size() == 0, RES()); - - { - PoolVector<uint8_t>::Write w = data.write(); - f->get_buffer(w.ptr(), data.size()); - } - - Ref<DynamicFontData> dfd; - dfd.instance(); - dfd->set_font_data(data); - - if (r_error) - *r_error = OK; - - return dfd; -} - -void ResourceFormatLoaderDynamicFont::get_recognized_extensions(List<String> *p_extensions) const { - - p_extensions->push_back("ttf"); -} - -bool ResourceFormatLoaderDynamicFont::handles_type(const String &p_type) const { - - return (p_type == "DynamicFontData"); -} - -String ResourceFormatLoaderDynamicFont::get_resource_type(const String &p_path) const { - - String el = p_path.get_extension().to_lower(); - if (el == "ttf") - return "DynamicFontData"; - return ""; -} - -#endif diff --git a/scene/resources/dynamic_font_stb.h b/scene/resources/dynamic_font_stb.h deleted file mode 100644 index caee6e7e32..0000000000 --- a/scene/resources/dynamic_font_stb.h +++ /dev/null @@ -1,191 +0,0 @@ -/*************************************************************************/ -/* dynamic_font_stb.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (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 DYNAMICFONT_STB_H -#define DYNAMICFONT_STB_H - -#ifndef FREETYPE_ENABLED - -#include "core/io/resource_loader.h" -#include "font.h" - -#include "thirdparty/misc/stb_truetype.h" - -class DynamicFontAtSize; -class DynamicFont; - -class DynamicFontData : public Resource { - - GDCLASS(DynamicFontData, Resource); - - bool valid; - - PoolVector<uint8_t> font_data; - PoolVector<uint8_t>::Read fr; - const uint8_t *last_data_ptr; - - struct KerningPairKey { - - union { - struct { - uint32_t A, B; - }; - - uint64_t pair; - }; - - _FORCE_INLINE_ bool operator<(const KerningPairKey &p_r) const { return pair < p_r.pair; } - }; - - Map<KerningPairKey, int> kerning_map; - - Map<int, DynamicFontAtSize *> size_cache; - - friend class DynamicFontAtSize; - - stbtt_fontinfo info; - int ascent; - int descent; - int linegap; - - void lock(); - void unlock(); - - friend class DynamicFont; - - Ref<DynamicFontAtSize> _get_dynamic_font_at_size(int p_size); - -public: - void set_font_data(const PoolVector<uint8_t> &p_font); - DynamicFontData(); - ~DynamicFontData(); -}; - -class DynamicFontAtSize : public Reference { - - GDCLASS(DynamicFontAtSize, Reference); - - int rect_margin; - - struct CharTexture { - - PoolVector<uint8_t> imgdata; - int texture_size; - Vector<int> offsets; - Ref<ImageTexture> texture; - }; - - Vector<CharTexture> textures; - - struct Character { - - int texture_idx; - Rect2 rect; - float v_align; - float h_align; - float advance; - - Character() { - texture_idx = 0; - v_align = 0; - } - }; - - HashMap<CharType, Character> char_map; - - _FORCE_INLINE_ void _update_char(CharType p_char); - - friend class DynamicFontData; - Ref<DynamicFontData> font; - float scale; - int size; - -protected: -public: - float get_height() const; - - float get_ascent() const; - float get_descent() const; - - Size2 get_char_size(CharType p_char, CharType p_next = 0) const; - - float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const; - - DynamicFontAtSize(); - ~DynamicFontAtSize(); -}; - -/////////////// - -class DynamicFont : public Font { - - GDCLASS(DynamicFont, Font); - - Ref<DynamicFontData> data; - Ref<DynamicFontAtSize> data_at_size; - int size; - -protected: - static void _bind_methods(); - -public: - void set_font_data(const Ref<DynamicFontData> &p_data); - Ref<DynamicFontData> get_font_data() const; - - void set_size(int p_size); - int get_size() const; - - virtual float get_height() const; - - virtual float get_ascent() const; - virtual float get_descent() const; - - virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const; - - virtual bool is_distance_field_hint() const; - - virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const; - - DynamicFont(); - ~DynamicFont(); -}; - -///////////// - -class ResourceFormatLoaderDynamicFont : 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 -#endif // DYNAMICFONT_H diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index afb7f1102b..bc96b5e9f3 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -354,10 +354,6 @@ void Environment::_validate_property(PropertyInfo &property) const { "tonemap_", "ss_reflections_", "ssao_", - "dof_blur_far_", - "dof_blur_near_", - "glow_", - "adjustment_", NULL }; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index d15a972358..c2e2f85723 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -117,6 +117,7 @@ void ImageTexture::reload_from_file() { } else { Resource::reload_from_file(); _change_notify(); + emit_changed(); } } @@ -180,6 +181,7 @@ void ImageTexture::_reload_hook(const RID &p_hook) { VisualServer::get_singleton()->texture_set_data(texture, img); _change_notify(); + emit_changed(); } void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags) { @@ -190,6 +192,7 @@ void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uin w = p_width; h = p_height; _change_notify(); + emit_changed(); } void ImageTexture::create_from_image(const Ref<Image> &p_image, uint32_t p_flags) { @@ -202,23 +205,23 @@ 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(); + emit_changed(); image_stored = true; } void ImageTexture::set_flags(uint32_t p_flags) { - /* uint32_t cube = flags & FLAG_CUBEMAP; - if (flags == p_flags&cube) + if (flags == p_flags) return; - flags=p_flags|cube; */ flags = p_flags; if (w == 0 || h == 0) { return; //uninitialized, do not set to texture } VisualServer::get_singleton()->texture_set_flags(texture, p_flags); _change_notify("flags"); + emit_changed(); } uint32_t ImageTexture::get_flags() const { @@ -250,6 +253,8 @@ void ImageTexture::set_data(const Ref<Image> &p_image) { VisualServer::get_singleton()->texture_set_data(texture, p_image); _change_notify(); + emit_changed(); + alpha_cache.unref(); image_stored = true; } @@ -736,6 +741,7 @@ Error StreamTexture::load(const String &p_path) { format = image->get_format(); _change_notify(); + emit_changed(); return OK; } String StreamTexture::get_load_path() const { @@ -827,6 +833,7 @@ void StreamTexture::set_flags(uint32_t p_flags) { flags = p_flags; VS::get_singleton()->texture_set_flags(texture, flags); _change_notify("flags"); + emit_changed(); } void StreamTexture::reload_from_file() { diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 3f2261b043..58bbf86241 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -103,6 +103,10 @@ String VisualShaderNode::get_warning(Shader::Mode p_mode, VisualShader::Type p_t return String(); } +String VisualShaderNode::get_input_port_default_hint(int p_port) const { + return ""; +} + void VisualShaderNode::_bind_methods() { ClassDB::bind_method(D_METHOD("set_output_port_for_preview", "port"), &VisualShaderNode::set_output_port_for_preview); @@ -122,7 +126,8 @@ void VisualShaderNode::_bind_methods() { BIND_ENUM_CONSTANT(PORT_TYPE_VECTOR); BIND_ENUM_CONSTANT(PORT_TYPE_BOOLEAN); BIND_ENUM_CONSTANT(PORT_TYPE_TRANSFORM); - BIND_ENUM_CONSTANT(PORT_TYPE_ICON_COLOR); + BIND_ENUM_CONSTANT(PORT_TYPE_SAMPLER); + BIND_ENUM_CONSTANT(PORT_TYPE_MAX); } VisualShaderNode::VisualShaderNode() { @@ -1058,7 +1063,15 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui String src_var = "n_out" + itos(from_node) + "p" + itos(from_port); - if (in_type == out_type) { + if (in_type == VisualShaderNode::PORT_TYPE_SAMPLER && out_type == VisualShaderNode::PORT_TYPE_SAMPLER) { + + VisualShaderNodeUniform *uniform = (VisualShaderNodeUniform *)graph[type].nodes[from_node].node.ptr(); + if (uniform) { + inputs[i] = uniform->get_uniform_name(); + } else { + inputs[i] = ""; + } + } else if (in_type == out_type) { inputs[i] = src_var; } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_VECTOR) { inputs[i] = "dot(" + src_var + ",vec3(0.333333,0.333333,0.333333))"; @@ -1139,12 +1152,16 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui global_code += vsnode->generate_global(get_mode(), type, node); - if (!r_classes.has(vsnode->get_class_name())) { + String class_name = vsnode->get_class_name(); + if (class_name == "VisualShaderNodeCustom") { + class_name = vsnode->get_script_instance()->get_script()->get_language()->get_global_class_name(vsnode->get_script_instance()->get_script()->get_path()); + } + if (!r_classes.has(class_name)) { global_code_per_node += vsnode->generate_global_per_node(get_mode(), type, node); for (int i = 0; i < TYPE_MAX; i++) { global_code_per_func[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node); } - r_classes.insert(vsnode->get_class_name()); + r_classes.insert(class_name); } } @@ -2207,7 +2224,7 @@ void VisualShaderNodeGroupBase::clear_output_ports() { void VisualShaderNodeGroupBase::set_input_port_type(int p_id, int p_type) { ERR_FAIL_COND(!has_input_port(p_id)); - ERR_FAIL_COND(p_type < 0 || p_type > PORT_TYPE_TRANSFORM); + ERR_FAIL_COND(p_type < 0 || p_type >= PORT_TYPE_MAX); if (input_ports[p_id].type == p_type) return; @@ -2273,7 +2290,7 @@ String VisualShaderNodeGroupBase::get_input_port_name(int p_id) const { void VisualShaderNodeGroupBase::set_output_port_type(int p_id, int p_type) { ERR_FAIL_COND(!has_output_port(p_id)); - ERR_FAIL_COND(p_type < 0 || p_type > PORT_TYPE_TRANSFORM); + ERR_FAIL_COND(p_type < 0 || p_type >= PORT_TYPE_MAX); if (output_ports[p_id].type == p_type) return; diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 45beb8e6ca..8b6b659836 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -184,7 +184,8 @@ public: PORT_TYPE_VECTOR, PORT_TYPE_BOOLEAN, PORT_TYPE_TRANSFORM, - PORT_TYPE_ICON_COLOR // just a hint for node tree icons, do not use it as actual port type ! + PORT_TYPE_SAMPLER, + PORT_TYPE_MAX, }; virtual String get_caption() const = 0; @@ -200,6 +201,8 @@ public: virtual PortType get_output_port_type(int p_port) const = 0; virtual String get_output_port_name(int p_port) const = 0; + virtual String get_input_port_default_hint(int p_port) const; + void set_output_port_for_preview(int p_index); int get_output_port_for_preview() const; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index b7173b157e..2e58c512b8 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -361,15 +361,35 @@ String VisualShaderNodeTexture::get_caption() const { } int VisualShaderNodeTexture::get_input_port_count() const { - return 2; + return 3; } VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_input_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; + + switch (p_port) { + case 0: + return PORT_TYPE_VECTOR; + case 1: + return PORT_TYPE_SCALAR; + case 2: + return PORT_TYPE_SAMPLER; + default: + return PORT_TYPE_SCALAR; + } } String VisualShaderNodeTexture::get_input_port_name(int p_port) const { - return p_port == 0 ? "uv" : "lod"; + + switch (p_port) { + case 0: + return "uv"; + case 1: + return "lod"; + case 2: + return "sampler"; + default: + return ""; + } } int VisualShaderNodeTexture::get_output_port_count() const { @@ -388,6 +408,13 @@ String VisualShaderNodeTexture::get_output_port_name(int p_port) const { return p_port == 0 ? "rgb" : "alpha"; } +String VisualShaderNodeTexture::get_input_port_default_hint(int p_port) const { + if (p_port == 0) { + return "UV.xy"; + } + return ""; +} + static String make_unique_id(VisualShader::Type p_type, int p_id, const String &p_name) { static const char *typepf[VisualShader::TYPE_MAX] = { "vtx", "frg", "lgt" }; @@ -424,10 +451,9 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_TEXTURE) { String id = make_unique_id(p_type, p_id, "tex"); String code; - if (p_input_vars[0] == String()) { //none bound, do nothing - - code += "\tvec4 " + id + "_read = vec4(0.0);\n"; + if (p_input_vars[0] == String()) { // Use UV by default. + code += "\tvec4 " + id + "_read = texture( " + id + " , UV.xy );\n"; } else if (p_input_vars[1] == String()) { //no lod code += "\tvec4 " + id + "_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; @@ -440,12 +466,35 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: return code; } + if (source == SOURCE_PORT) { + String id = p_input_vars[2]; + String code; + if (id == String()) { + code += "\tvec4 " + id + "_tex_read = vec4(0.0);\n"; + } else { + if (p_input_vars[0] == String()) { // Use UV by default. + + code += "\tvec4 " + id + "_tex_read = texture( " + id + " , UV.xy );\n"; + + } else if (p_input_vars[1] == String()) { + //no lod + code += "\tvec4 " + id + "_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; + } else { + code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; + } + + code += "\t" + p_output_vars[0] + " = " + id + "_tex_read.rgb;\n"; + code += "\t" + p_output_vars[1] + " = " + id + "_tex_read.a;\n"; + } + return code; + } + 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() || p_for_preview) { //none bound, do nothing + if (p_input_vars[0] == String() || p_for_preview) { // Use UV by default. - code += "\t\tvec4 _tex_read = vec4(0.0);\n"; + code += "\t\tvec4 _tex_read = textureLod( SCREEN_TEXTURE , UV.xy, 0.0 );\n"; } else if (p_input_vars[1] == String()) { //no lod @@ -463,9 +512,9 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_2D_TEXTURE && 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()) { // Use UV by default. - code += "\t\tvec4 _tex_read = vec4(0.0);\n"; + code += "\t\tvec4 _tex_read = texture( TEXTURE , UV.xy );\n"; } else if (p_input_vars[1] == String()) { //no lod @@ -483,9 +532,9 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_2D_NORMAL && 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()) { // Use UV by default. - code += "\t\tvec4 _tex_read = vec4(0.0);\n"; + code += "\t\tvec4 _tex_read = texture( NORMAL_TEXTURE , UV.xy );\n"; } else if (p_input_vars[1] == String()) { //no lod @@ -513,9 +562,9 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_DEPTH && p_mode == Shader::MODE_SPATIAL && 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()) { // Use UV by default. - code += "\t\tfloat _depth = 0.0;\n"; + code += "\t\tfloat _depth = texture( DEPTH_TEXTURE , UV.xy ).r;\n"; } else if (p_input_vars[1] == String()) { //no lod @@ -588,6 +637,10 @@ String VisualShaderNodeTexture::get_warning(Shader::Mode p_mode, VisualShader::T return String(); // all good } + if (source == SOURCE_PORT) { + return String(); // all good + } + if (source == SOURCE_SCREEN && (p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) { return String(); // all good @@ -625,7 +678,7 @@ void VisualShaderNodeTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeTexture::set_texture_type); ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTexture::get_texture_type); - ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D,Depth"), "set_source", "get_source"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D,Depth,SamplerPort"), "set_source", "get_source"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type"); @@ -3023,15 +3076,35 @@ String VisualShaderNodeTextureUniform::get_input_port_name(int p_port) const { } int VisualShaderNodeTextureUniform::get_output_port_count() const { - return 2; + return 3; } VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_output_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; + + switch (p_port) { + case 0: + return PORT_TYPE_VECTOR; + case 1: + return PORT_TYPE_SCALAR; + case 2: + return PORT_TYPE_SAMPLER; + default: + return PORT_TYPE_SCALAR; + } } String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const { - return p_port == 0 ? "rgb" : "alpha"; + + switch (p_port) { + case 0: + return "rgb"; + case 1: + return "alpha"; + case 2: + return "sampler"; + default: + return ""; + } } String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { @@ -3061,9 +3134,9 @@ String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, Visual String id = get_uniform_name(); String code = "\t{\n"; - if (p_input_vars[0] == String()) { //none bound, do nothing + if (p_input_vars[0] == String()) { // Use UV by default. - code += "\t\tvec4 n_tex_read = vec4(0.0);\n"; + code += "\t\tvec4 n_tex_read = texture( " + id + " , UV.xy );\n"; } else if (p_input_vars[1] == String()) { //no lod code += "\t\tvec4 n_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; @@ -3122,6 +3195,13 @@ void VisualShaderNodeTextureUniform::_bind_methods() { BIND_ENUM_CONSTANT(COLOR_DEFAULT_BLACK); } +String VisualShaderNodeTextureUniform::get_input_port_default_hint(int p_port) const { + if (p_port == 0) { + return "UV.xy"; + } + return ""; +} + VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() { texture_type = TYPE_DATA; color_default = COLOR_DEFAULT_WHITE; @@ -3216,6 +3296,15 @@ String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mod return code; } +String VisualShaderNodeTextureUniformTriplanar::get_input_port_default_hint(int p_port) const { + if (p_port == 0) { + return "default"; + } else if (p_port == 1) { + return "default"; + } + return ""; +} + VisualShaderNodeTextureUniformTriplanar::VisualShaderNodeTextureUniformTriplanar() { } diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 0c6e060353..d5ee990191 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -199,7 +199,8 @@ public: SOURCE_SCREEN, SOURCE_2D_TEXTURE, SOURCE_2D_NORMAL, - SOURCE_DEPTH + SOURCE_DEPTH, + SOURCE_PORT, }; enum TextureType { @@ -226,6 +227,8 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; + virtual String get_input_port_default_hint(int p_port) const; + 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, 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 @@ -1422,6 +1425,7 @@ public: virtual int get_input_port_count() const; virtual PortType get_input_port_type(int p_port) const; virtual String get_input_port_name(int p_port) const; + virtual String get_input_port_default_hint(int p_port) const; virtual int get_output_port_count() const; virtual PortType get_output_port_type(int p_port) const; @@ -1456,6 +1460,8 @@ public: virtual PortType get_input_port_type(int p_port) const; virtual String get_input_port_name(int p_port) const; + virtual String get_input_port_default_hint(int p_port) const; + virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; virtual String generate_global_per_func(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, 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 diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp index 0ca5d7eb36..2c22f45f9d 100644 --- a/scene/resources/world.cpp +++ b/scene/resources/world.cpp @@ -332,7 +332,9 @@ World::World() { PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/3d/default_gravity", 9.8)); PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/3d/default_gravity_vector", Vector3(0, -1, 0))); PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_LINEAR_DAMP, GLOBAL_DEF("physics/3d/default_linear_damp", 0.1)); + ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_linear_damp", PropertyInfo(Variant::REAL, "physics/3d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/3d/default_angular_damp", 0.1)); + ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_angular_damp", PropertyInfo(Variant::REAL, "physics/3d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); #ifdef _3D_DISABLED indexer = NULL; diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index 13b45f58dc..b5743ad416 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -394,7 +394,9 @@ World2D::World2D() { Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/2d/default_gravity", 98)); Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/2d/default_gravity_vector", Vector2(0, 1))); Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_LINEAR_DAMP, GLOBAL_DEF("physics/2d/default_linear_damp", 0.1)); - Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/2d/default_angular_damp", 1)); + ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_linear_damp", PropertyInfo(Variant::REAL, "physics/2d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); + Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/2d/default_angular_damp", 1.0)); + ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_angular_damp", PropertyInfo(Variant::REAL, "physics/2d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); indexer = memnew(SpatialIndexer2D); } |