diff options
Diffstat (limited to 'scene/resources')
-rw-r--r-- | scene/resources/bit_mask.cpp | 348 | ||||
-rw-r--r-- | scene/resources/bit_mask.h | 8 | ||||
-rw-r--r-- | scene/resources/dynamic_font.cpp | 123 | ||||
-rw-r--r-- | scene/resources/dynamic_font.h | 13 | ||||
-rw-r--r-- | scene/resources/material.cpp | 15 | ||||
-rw-r--r-- | scene/resources/material.h | 2 | ||||
-rw-r--r-- | scene/resources/primitive_meshes.h | 2 | ||||
-rw-r--r-- | scene/resources/ray_shape.cpp | 23 | ||||
-rw-r--r-- | scene/resources/ray_shape.h | 4 | ||||
-rw-r--r-- | scene/resources/scene_format_text.cpp | 12 | ||||
-rw-r--r-- | scene/resources/segment_shape_2d.cpp | 20 | ||||
-rw-r--r-- | scene/resources/segment_shape_2d.h | 5 | ||||
-rw-r--r-- | scene/resources/shape_2d.h | 2 | ||||
-rw-r--r-- | scene/resources/style_box.cpp | 12 | ||||
-rw-r--r-- | scene/resources/style_box.h | 8 | ||||
-rw-r--r-- | scene/resources/tile_set.cpp | 31 | ||||
-rw-r--r-- | scene/resources/tile_set.h | 17 |
17 files changed, 566 insertions, 79 deletions
diff --git a/scene/resources/bit_mask.cpp b/scene/resources/bit_mask.cpp index ea313b5a20..29ffefd9d6 100644 --- a/scene/resources/bit_mask.cpp +++ b/scene/resources/bit_mask.cpp @@ -42,7 +42,7 @@ void BitMap::create(const Size2 &p_size) { zeromem(bitmask.ptrw(), bitmask.size()); } -void BitMap::create_from_image_alpha(const Ref<Image> &p_image) { +void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_threshold) { ERR_FAIL_COND(p_image.is_null() || p_image->empty()); Ref<Image> img = p_image->duplicate(); @@ -58,8 +58,9 @@ void BitMap::create_from_image_alpha(const Ref<Image> &p_image) { int bbyte = i / 8; int bbit = i % 8; - if (r[i * 2]) + if (r[i * 2 + 1] / 255.0 > p_threshold) { w[bbyte] |= (1 << bbit); + } } } @@ -168,10 +169,351 @@ Dictionary BitMap::_get_data() const { return d; } +Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) const { + + int stepx = 0; + int stepy = 0; + int prevx = 0; + int prevy = 0; + int startx = start.x; + int starty = start.y; + int curx = startx; + int cury = starty; + unsigned int count = 0; + Set<Point2i> case9s; + Set<Point2i> case6s; + int i; + Vector<Vector2> _points; + do { + int sv = 0; + { //square value + + /* + checking the 2x2 pixel grid, assigning these values to each pixel, if not transparent + +---+---+ + | 1 | 2 | + +---+---+ + | 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; + Point2i tr = Point2i(curx, cury - 1); + sv += (fixed_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; + Point2i br = Point2i(curx, cury); + sv += (fixed_rect.has_point(br) && get_bit(br)) ? 8 : 0; + ERR_FAIL_COND_V(sv == 0 || sv == 15, Vector<Vector2>()); + } + + switch (sv) { + + case 1: + case 5: + case 13: + /* going UP with these cases: + 1 5 13 + +---+---+ +---+---+ +---+---+ + | 1 | | | 1 | | | 1 | | + +---+---+ +---+---+ +---+---+ + | | | | 4 | | | 4 | 8 | + +---+---+ +---+---+ +---+---+ + */ + stepx = 0; + stepy = -1; + break; + + case 8: + case 10: + case 11: + /* going DOWN with these cases: + 8 10 11 + +---+---+ +---+---+ +---+---+ + | | | | | 2 | | 1 | 2 | + +---+---+ +---+---+ +---+---+ + | | 8 | | | 8 | | | 8 | + +---+---+ +---+---+ +---+---+ + */ + stepx = 0; + stepy = 1; + break; + + case 4: + case 12: + case 14: + /* going LEFT with these cases: + 4 12 14 + +---+---+ +---+---+ +---+---+ + | | | | | | | | 2 | + +---+---+ +---+---+ +---+---+ + | 4 | | | 4 | 8 | | 4 | 8 | + +---+---+ +---+---+ +---+---+ + */ + stepx = -1; + stepy = 0; + break; + + case 2: + case 3: + case 7: + /* going RIGHT with these cases: + 2 3 7 + +---+---+ +---+---+ +---+---+ + | | 2 | | 1 | 2 | | 1 | 2 | + +---+---+ +---+---+ +---+---+ + | | | | | | | 4 | | + +---+---+ +---+---+ +---+---+ + */ + stepx = 1; + stepy = 0; + break; + case 9: + /* + +---+---+ + | 1 | | + +---+---+ + | | 8 | + +---+---+ + this should normally go UP, but if we already been here, we go down + */ + if (case9s.has(Point2i(curx, cury))) { + //found, so we go down, and delete from case9s; + stepx = 0; + stepy = 1; + case9s.erase(Point2i(curx, cury)); + } else { + //not found, we go up, and add to case9s; + stepx = 0; + stepy = -1; + case9s.insert(Point2i(curx, cury)); + } + break; + case 6: + /* + 6 + +---+---+ + | | 2 | + +---+---+ + | 4 | | + +---+---+ + this normally go RIGHT, but if its coming from UP, it should go LEFT + */ + if (case6s.has(Point2i(curx, cury))) { + //found, so we go down, and delete from case6s; + stepx = -1; + stepy = 0; + case6s.erase(Point2i(curx, cury)); + } else { + //not found, we go up, and add to case6s; + stepx = 1; + stepy = 0; + case6s.insert(Point2i(curx, cury)); + } + break; + default: + ERR_PRINT("this shouldn't happen."); + } + //little optimization + // if previous direction is same as current direction, + // then we should modify the last vec to current + curx += stepx; + cury += stepy; + if (stepx == prevx && stepy == prevy) { + _points[_points.size() - 1].x = (float)(curx - rect.position.x); + _points[_points.size() - 1].y = (float)(cury + rect.position.y); + } else { + _points.push_back(Vector2((float)(curx - rect.position.x), (float)(cury + rect.position.y))); + } + + count++; + prevx = stepx; + prevy = stepy; + + ERR_FAIL_COND_V(count > width * height, _points); + } while (curx != startx || cury != starty); + return _points; +} + +static float perpendicular_distance(const Vector2 &i, const Vector2 &start, const Vector2 &end) { + float res; + float slope; + float intercept; + + if (start.x == end.x) { + res = Math::absf(i.x - end.x); + } else if (start.y == end.y) { + res = Math::absf(i.y - end.y); + } else { + slope = (end.y - start.y) / (end.x - start.x); + intercept = start.y - (slope * start.x); + res = Math::absf(slope * i.x - i.y + intercept) / Math::sqrt(Math::pow(slope, 2.0f) + 1.0); + } + return res; +} + +static Vector<Vector2> rdp(const Vector<Vector2> &v, float optimization) { + if (v.size() < 3) + return v; + + int index = -1; + float dist = 0; + //not looping first and last point + for (size_t i = 1, size = v.size(); i < size - 1; ++i) { + float cdist = perpendicular_distance(v[i], v[0], v[v.size() - 1]); + if (cdist > dist) { + dist = cdist; + index = static_cast<int>(i); + } + } + if (dist > optimization) { + + Vector<Vector2> left, right; + left.resize(index); + for (int i = 0; i < index; i++) { + left[i] = v[i]; + } + right.resize(v.size() - index); + for (int i = 0; i < right.size(); i++) { + right[i] = v[index + i]; + } + Vector<Vector2> r1 = rdp(left, optimization); + Vector<Vector2> r2 = rdp(right, optimization); + + int middle = r1.size(); + r1.resize(r1.size() + r2.size()); + for (int i = 0; i < r2.size(); i++) { + r1[middle + i] = r2[i]; + } + return r1; + } else { + Vector<Vector2> ret; + ret.push_back(v[0]); + ret.push_back(v[v.size() - 1]); + return ret; + } +} + +static Vector<Vector2> reduce(const Vector<Vector2> &points, const Rect2i &rect, float epsilon) { + int size = points.size(); + // if there are less than 3 points, then we have nothing + ERR_FAIL_COND_V(size < 3, Vector<Vector2>()); + // if there are less than 9 points (but more than 3), then we don't need to reduce it + if (size < 9) { + return points; + } + + float maxEp = MIN(rect.size.width, rect.size.height); + float ep = CLAMP(epsilon, 0.0, maxEp / 2); + Vector<Vector2> result = rdp(points, ep); + + Vector2 last = result[result.size() - 1]; + + if (last.y > result[0].y && last.distance_to(result[0]) < ep * 0.5f) { + result[0].y = last.y; + result.resize(result.size() - 1); + } + return result; +} + +static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_pos, const Rect2i &rect) { + + for (int i = p_pos.x - 1; i <= p_pos.x + 1; i++) { + for (int j = p_pos.y - 1; j <= p_pos.y + 1; j++) { + + if (i < rect.position.x || i >= rect.position.x + rect.size.x) + continue; + if (j < rect.position.y || j >= rect.position.y + rect.size.y) + continue; + + if (p_map->get_bit(Vector2(i, j))) + continue; + + else if (p_src->get_bit(Vector2(i, j))) { + p_map->set_bit(Vector2(i, j), true); + fill_bits(p_src, p_map, Point2i(i, j), rect); + } + } + } +} +Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon) const { + + Rect2i r = Rect2i(0, 0, width, height).clip(p_rect); + + print_line("Rect: " + r); + Point2i from; + Ref<BitMap> fill; + fill.instance(); + fill->create(get_size()); + + Vector<Vector<Vector2> > polygons; + 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 (!fill->get_bit(Point2(j, i)) && get_bit(Point2(j, i))) { + + Vector<Vector2> polygon = _march_square(r, Point2i(j, i)); + print_line("pre reduce: " + itos(polygon.size())); + polygon = reduce(polygon, r, p_epsilon); + print_line("post reduce: " + itos(polygon.size())); + polygons.push_back(polygon); + fill_bits(this, fill, Point2i(j, i), r); + } + } + } + + return polygons; +} + +void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { + + Rect2i r = Rect2i(0, 0, width, height).clip(p_rect); + + Ref<BitMap> copy; + copy.instance(); + copy->create(get_size()); + copy->bitmask = bitmask; + + 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))) + continue; + + bool found = false; + + 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; + + float d = Point2(j, i).distance_to(Point2(x, y)) - CMP_EPSILON; + if (d > p_pixels) + continue; + + if (copy->get_bit(Point2(x, y))) { + found = true; + break; + } + } + if (found) + break; + } + + if (found) { + set_bit(Point2(j, i), true); + } + } + } +} + void BitMap::_bind_methods() { ClassDB::bind_method(D_METHOD("create", "size"), &BitMap::create); - ClassDB::bind_method(D_METHOD("create_from_image_alpha", "image"), &BitMap::create_from_image_alpha); + ClassDB::bind_method(D_METHOD("create_from_image_alpha", "image", "threshold"), &BitMap::create_from_image_alpha, DEFVAL(0.1)); ClassDB::bind_method(D_METHOD("set_bit", "position", "bit"), &BitMap::set_bit); ClassDB::bind_method(D_METHOD("get_bit", "position"), &BitMap::get_bit); diff --git a/scene/resources/bit_mask.h b/scene/resources/bit_mask.h index cf126ef96b..dcd5edb4fb 100644 --- a/scene/resources/bit_mask.h +++ b/scene/resources/bit_mask.h @@ -44,6 +44,8 @@ class BitMap : public Resource { int width; int height; + Vector<Vector2> _march_square(const Rect2i &rect, const Point2i &start) const; + protected: void _set_data(const Dictionary &p_d); Dictionary _get_data() const; @@ -52,7 +54,7 @@ protected: public: void create(const Size2 &p_size); - void create_from_image_alpha(const Ref<Image> &p_image); + void create_from_image_alpha(const Ref<Image> &p_image, float p_threshold = 0.1); void set_bit(const Point2 &p_pos, bool p_value); bool get_bit(const Point2 &p_pos) const; @@ -61,6 +63,10 @@ public: Size2 get_size() const; + void grow_mask(int p_pixels, const Rect2 &p_rect); + + Vector<Vector<Vector2> > clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon = 2.0) const; + BitMap(); }; diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index e9d5ca969e..26e29b3ccb 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -80,6 +80,14 @@ void DynamicFontData::set_force_autohinter(bool p_force) { void DynamicFontData::_bind_methods() { ClassDB::bind_method(D_METHOD("set_font_path", "path"), &DynamicFontData::set_font_path); ClassDB::bind_method(D_METHOD("get_font_path"), &DynamicFontData::get_font_path); + ClassDB::bind_method(D_METHOD("set_hinting", "mode"), &DynamicFontData::set_hinting); + ClassDB::bind_method(D_METHOD("get_hinting"), &DynamicFontData::get_hinting); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting"); + + BIND_ENUM_CONSTANT(HINTING_NONE); + BIND_ENUM_CONSTANT(HINTING_LIGHT); + BIND_ENUM_CONSTANT(HINTING_NORMAL); ADD_PROPERTY(PropertyInfo(Variant::STRING, "font_path", PROPERTY_HINT_FILE, "*.ttf,*.otf"), "set_font_path", "get_font_path"); } @@ -87,6 +95,7 @@ void DynamicFontData::_bind_methods() { DynamicFontData::DynamicFontData() { force_autohinter = false; + hinting = DynamicFontData::HINTING_NORMAL; font_mem = NULL; font_mem_size = 0; } @@ -186,10 +195,25 @@ Error DynamicFontAtSize::_load() { ERR_FAIL_COND_V( error, ERR_INVALID_PARAMETER ); }*/ - error = FT_Set_Pixel_Sizes(face, 0, id.size * oversampling); + if (FT_HAS_COLOR(face)) { + int best_match = 0; + int diff = ABS(id.size - face->available_sizes[0].width); + scale_color_font = float(id.size) / face->available_sizes[0].width; + for (int i = 1; i < face->num_fixed_sizes; i++) { + int ndiff = ABS(id.size - face->available_sizes[i].width); + if (ndiff < diff) { + best_match = i; + diff = ndiff; + scale_color_font = float(id.size) / face->available_sizes[i].width; + } + } + error = FT_Select_Size(face, best_match); + } else { + error = FT_Set_Pixel_Sizes(face, 0, id.size * oversampling); + } - ascent = (face->size->metrics.ascender >> 6) / oversampling; - descent = (-face->size->metrics.descender >> 6) / oversampling; + ascent = (face->size->metrics.ascender >> 6) / oversampling * scale_color_font; + descent = (-face->size->metrics.descender >> 6) / oversampling * scale_color_font; linegap = 0; texture_flags = 0; if (id.mipmaps) @@ -197,8 +221,6 @@ Error DynamicFontAtSize::_load() { if (id.filter) texture_flags |= Texture::FLAG_FILTER; - //print_line("ASCENT: "+itos(ascent)+" descent "+itos(descent)+" hinted: "+itos(face->face_flags&FT_FACE_FLAG_HINTER)); - valid = true; return OK; } @@ -286,7 +308,6 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const V ret.x += (delta.x >> 6) / oversampling; } } - return ret; } @@ -328,14 +349,18 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT if (!ch->found) continue; - Point2 cpos = p_pos; cpos.x += ch->h_align; - cpos.y -= get_ascent(); + cpos.y -= fb->get_ascent(); cpos.y += ch->v_align; ERR_FAIL_COND_V(ch->texture_idx < -1 || ch->texture_idx >= fb->textures.size(), 0); - if (ch->texture_idx != -1) - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size), fb->textures[ch->texture_idx].texture->get_rid(), ch->rect_uv, p_modulate, false, RID(), false); + if (ch->texture_idx != -1) { + Color modulate = p_modulate; + if (FT_HAS_COLOR(fb->face)) { + modulate.r = modulate.g = modulate.b = 1; + } + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size * Vector2(fb->scale_color_font, fb->scale_color_font)), fb->textures[ch->texture_idx].texture->get_rid(), ch->rect_uv, modulate, false, RID(), false); + } advance = ch->advance; used_fallback = true; break; @@ -356,8 +381,13 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT 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_uv, p_modulate, false, RID(), false); + if (c->texture_idx != -1) { + Color modulate = p_modulate; + if (FT_HAS_COLOR(face)) { + modulate.r = modulate.g = modulate.b = 1; + } + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, c->rect.size * Vector2(scale_color_font, scale_color_font)), textures[c->texture_idx].texture->get_rid(), c->rect_uv, modulate, false, RID(), false); + } advance = c->advance; //textures[c->texture_idx].texture->draw(p_canvas_item,Vector2()); } @@ -431,15 +461,28 @@ void DynamicFontAtSize::_update_char(CharType p_char) { char_map[p_char] = ch; return; } - int error = FT_Load_Char(face, p_char, FT_LOAD_RENDER | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)); + + int ft_hinting; + + switch (font->hinting) { + case DynamicFontData::HINTING_NONE: + ft_hinting = FT_LOAD_NO_HINTING; + break; + case DynamicFontData::HINTING_LIGHT: + ft_hinting = FT_LOAD_TARGET_LIGHT; + break; + default: + ft_hinting = FT_LOAD_TARGET_NORMAL; + break; + } + + int error = FT_Load_Char(face, p_char, FT_HAS_COLOR(face) ? FT_LOAD_COLOR : FT_LOAD_DEFAULT | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0) | ft_hinting); if (!error) { - error = FT_Render_Glyph(face->glyph, ft_render_mode_normal); + error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); } if (error) { int advance = 0; - //stbtt_GetCodepointHMetrics(&font->info, p_char, &advance, 0); - //print_line("char has no bitmap: "+itos(p_char)+" but advance is "+itos(advance*scale)); Character ch; ch.texture_idx = -1; ch.advance = advance; @@ -454,7 +497,6 @@ void DynamicFontAtSize::_update_char(CharType p_char) { int w = slot->bitmap.width; int h = slot->bitmap.rows; - //int p = slot->bitmap.pitch; int yofs = slot->bitmap_top; int xofs = slot->bitmap_left; int advance = slot->advance.x >> 6; @@ -470,6 +512,8 @@ void DynamicFontAtSize::_update_char(CharType p_char) { //find a texture to fit this... + int color_size = slot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA ? 4 : 2; + Image::Format require_format = color_size == 4 ? Image::FORMAT_RGBA8 : Image::FORMAT_LA8; int tex_index = -1; int tex_x = 0; int tex_y = 0; @@ -478,6 +522,9 @@ void DynamicFontAtSize::_update_char(CharType p_char) { CharTexture &ct = textures[i]; + if (ct.texture->get_format() != require_format) + continue; + if (mw > ct.texture_size || mh > ct.texture_size) //too big for this texture continue; @@ -508,8 +555,6 @@ void DynamicFontAtSize::_update_char(CharType p_char) { break; } - //print_line("CHAR: "+String::chr(p_char)+" TEX INDEX: "+itos(tex_index)+" X: "+itos(tex_x)+" Y: "+itos(tex_y)); - if (tex_index == -1) { //could not find texture to fit, create one tex_x = 0; @@ -527,13 +572,13 @@ void DynamicFontAtSize::_update_char(CharType p_char) { CharTexture tex; tex.texture_size = texsize; - tex.imgdata.resize(texsize * texsize * 2); //grayscale alpha + tex.imgdata.resize(texsize * texsize * color_size); { //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++) { + ERR_FAIL_COND(texsize * texsize * color_size > tex.imgdata.size()); + for (int i = 0; i < texsize * texsize * color_size; i++) { w[i] = 0; } } @@ -555,7 +600,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) { 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; + int ofs = ((i + tex_y + rect_margin) * tex.texture_size + j + tex_x + rect_margin) * color_size; ERR_FAIL_COND(ofs >= tex.imgdata.size()); switch (slot->bitmap.pixel_mode) { case FT_PIXEL_MODE_MONO: { @@ -568,7 +613,14 @@ void DynamicFontAtSize::_update_char(CharType p_char) { wr[ofs + 0] = 255; //grayscale as 1 wr[ofs + 1] = slot->bitmap.buffer[i * slot->bitmap.pitch + j]; break; - // TODO: FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_BGRA + case FT_PIXEL_MODE_BGRA: { + int ofs_color = i * slot->bitmap.pitch + (j << 2); + wr[ofs + 2] = slot->bitmap.buffer[ofs_color + 0]; + wr[ofs + 1] = slot->bitmap.buffer[ofs_color + 1]; + wr[ofs + 0] = slot->bitmap.buffer[ofs_color + 2]; + wr[ofs + 3] = slot->bitmap.buffer[ofs_color + 3]; + } break; + // TODO: FT_PIXEL_MODE_LCD default: ERR_EXPLAIN("Font uses unsupported pixel format: " + itos(slot->bitmap.pixel_mode)); ERR_FAIL(); @@ -581,7 +633,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) { //blit to image and texture { - Ref<Image> img = memnew(Image(tex.texture_size, tex.texture_size, 0, Image::FORMAT_LA8, tex.imgdata)); + Ref<Image> img = memnew(Image(tex.texture_size, tex.texture_size, 0, require_format, tex.imgdata)); if (tex.texture.is_null()) { tex.texture.instance(); @@ -599,9 +651,9 @@ void DynamicFontAtSize::_update_char(CharType p_char) { } Character chr; - chr.h_align = xofs / oversampling; - chr.v_align = ascent - (yofs / oversampling); // + ascent - descent; - chr.advance = advance / oversampling; + chr.h_align = xofs * scale_color_font / oversampling; + chr.v_align = ascent - (yofs * scale_color_font / oversampling); // + ascent - descent; + chr.advance = advance * scale_color_font / oversampling; chr.texture_idx = tex_index; chr.found = true; @@ -610,8 +662,6 @@ void DynamicFontAtSize::_update_char(CharType p_char) { chr.rect.position /= oversampling; chr.rect.size /= oversampling; - //print_line("CHAR: "+String::chr(p_char)+" TEX INDEX: "+itos(tex_index)+" RECT: "+chr.rect+" X OFS: "+itos(xofs)+" Y OFS: "+itos(yofs)); - char_map[p_char] = chr; } @@ -640,6 +690,7 @@ DynamicFontAtSize::DynamicFontAtSize() { linegap = 1; texture_flags = 0; oversampling = font_oversampling; + scale_color_font = 1; } DynamicFontAtSize::~DynamicFontAtSize() { @@ -722,6 +773,18 @@ void DynamicFont::set_use_filter(bool p_enable) { _reload_cache(); } +DynamicFontData::Hinting DynamicFontData::get_hinting() const { + + return hinting; +} + +void DynamicFontData::set_hinting(Hinting p_hinting) { + + if (hinting == p_hinting) + return; + hinting = p_hinting; +} + int DynamicFont::get_spacing(int p_type) const { if (p_type == SPACING_TOP) { diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index 92bb77bed3..db8bd87587 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -64,10 +64,20 @@ public: } }; + enum Hinting { + HINTING_NONE, + HINTING_LIGHT, + HINTING_NORMAL + }; + + Hinting get_hinting() const; + void set_hinting(Hinting p_hinting); + private: const uint8_t *font_mem; int font_mem_size; bool force_autohinter; + Hinting hinting; String font_path; Map<CacheID, DynamicFontAtSize *> size_cache; @@ -91,6 +101,8 @@ public: ~DynamicFontData(); }; +VARIANT_ENUM_CAST(DynamicFontData::Hinting); + class DynamicFontAtSize : public Reference { GDCLASS(DynamicFontAtSize, Reference) @@ -106,6 +118,7 @@ class DynamicFontAtSize : public Reference { float linegap; float rect_margin; float oversampling; + float scale_color_font; uint32_t texture_flags; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 8a1978cf85..a83ef198fb 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -737,15 +737,18 @@ void SpatialMaterial::_update_shader() { } } - if (features[FEATURE_REFRACTION] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //refraction not supported with triplanar + if (features[FEATURE_REFRACTION]) { if (features[FEATURE_NORMAL_MAPPING]) { code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * NORMALMAP.x + BINORMAL * NORMALMAP.y + NORMAL * NORMALMAP.z,NORMALMAP_DEPTH) );\n"; } else { code += "\tvec3 ref_normal = NORMAL;\n"; } - - code += "\tvec2 ref_ofs = SCREEN_UV - ref_normal.xy * dot(texture(texture_refraction,base_uv),refraction_texture_channel) * refraction;\n"; + if (flags[FLAG_UV1_USE_TRIPLANAR]) { + code += "\tvec2 ref_ofs = SCREEN_UV - ref_normal.xy * dot(triplanar_texture(texture_refraction,uv1_power_normal,uv1_triplanar_pos),refraction_texture_channel) * refraction;\n"; + } else { + code += "\tvec2 ref_ofs = SCREEN_UV - ref_normal.xy * dot(texture(texture_refraction,base_uv),refraction_texture_channel) * refraction;\n"; + } code += "\tfloat ref_amount = 1.0 - albedo.a * albedo_tex.a;\n"; code += "\tEMISSION += textureLod(SCREEN_TEXTURE,ref_ofs,ROUGHNESS * 8.0).rgb * ref_amount;\n"; code += "\tALBEDO *= 1.0 - ref_amount;\n"; @@ -1479,9 +1482,9 @@ bool SpatialMaterial::is_grow_enabled() const { return grow_enabled; } -void SpatialMaterial::set_alpha_scissor_threshold(float p_treshold) { - alpha_scissor_threshold = p_treshold; - VS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_scissor_threshold, p_treshold); +void SpatialMaterial::set_alpha_scissor_threshold(float p_threshold) { + alpha_scissor_threshold = p_threshold; + VS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_scissor_threshold, p_threshold); } float SpatialMaterial::get_alpha_scissor_threshold() const { diff --git a/scene/resources/material.h b/scene/resources/material.h index 10bbcfd642..2c297cda41 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -566,7 +566,7 @@ public: void set_grow(float p_grow); float get_grow() const; - void set_alpha_scissor_threshold(float p_treshold); + void set_alpha_scissor_threshold(float p_threshold); float get_alpha_scissor_threshold() const; void set_on_top_of_alpha(); diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index 1eaa007bd7..94a7a055a3 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -189,7 +189,7 @@ public: }; /** - Similar to quadmesh but with tesselation support + Similar to quadmesh but with tessellation support */ class PlaneMesh : public PrimitiveMesh { diff --git a/scene/resources/ray_shape.cpp b/scene/resources/ray_shape.cpp index 78a19050f1..a9dec3e87c 100644 --- a/scene/resources/ray_shape.cpp +++ b/scene/resources/ray_shape.cpp @@ -43,7 +43,10 @@ Vector<Vector3> RayShape::_gen_debug_mesh_lines() { void RayShape::_update_shape() { - PhysicsServer::get_singleton()->shape_set_data(get_shape(), length); + Dictionary d; + d["length"] = length; + d["slips_on_slope"] = slips_on_slope; + PhysicsServer::get_singleton()->shape_set_data(get_shape(), d); emit_changed(); } @@ -52,6 +55,7 @@ void RayShape::set_length(float p_length) { length = p_length; _update_shape(); notify_change_to_owners(); + _change_notify("length"); } float RayShape::get_length() const { @@ -59,16 +63,33 @@ float RayShape::get_length() const { return length; } +void RayShape::set_slips_on_slope(bool p_active) { + + slips_on_slope = p_active; + _update_shape(); + notify_change_to_owners(); + _change_notify("slips_on_slope"); +} + +bool RayShape::get_slips_on_slope() const { + return slips_on_slope; +} + void RayShape::_bind_methods() { ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape::set_length); ClassDB::bind_method(D_METHOD("get_length"), &RayShape::get_length); + ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape::set_slips_on_slope); + ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape::get_slips_on_slope); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_length", "get_length"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slips_on_slope"), "set_slips_on_slope", "get_slips_on_slope"); } RayShape::RayShape() : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_RAY)) { set_length(1.0); + set_slips_on_slope(false); } diff --git a/scene/resources/ray_shape.h b/scene/resources/ray_shape.h index 4bd96116fe..f11b2e7c3c 100644 --- a/scene/resources/ray_shape.h +++ b/scene/resources/ray_shape.h @@ -36,6 +36,7 @@ class RayShape : public Shape { GDCLASS(RayShape, Shape); float length; + bool slips_on_slope; protected: static void _bind_methods(); @@ -46,6 +47,9 @@ public: void set_length(float p_length); float get_length() const; + void set_slips_on_slope(bool p_active); + bool get_slips_on_slope() const; + RayShape(); }; #endif // RAY_SHAPE_H diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp index 91c801c016..030b822f3b 100644 --- a/scene/resources/scene_format_text.cpp +++ b/scene/resources/scene_format_text.cpp @@ -1445,8 +1445,15 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, static String _valprop(const String &p_name) { - if (p_name.find("\"") != -1 || p_name.find("=") != -1 || p_name.find(" ") != -1) - return "\"" + p_name.c_escape_multiline() + "\""; + // Escape and quote strings with extended ASCII or further Unicode characters + // as well as '"', '=' or ' ' (32) + const CharType *cstr = p_name.c_str(); + for (int i = 0; cstr[i]; i++) { + if (cstr[i] == '=' || cstr[i] == '"' || cstr[i] < 33 || cstr[i] > 126) { + return "\"" + p_name.c_escape_multiline() + "\""; + } + } + // Keep as is return p_name; } @@ -1506,7 +1513,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r title += "load_steps=" + itos(load_steps) + " "; } title += "format=" + itos(FORMAT_VERSION) + ""; - //title+="engine_version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\""; f->store_string(title); f->store_line("]\n"); //one empty line diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp index 81110015b5..58027c127d 100644 --- a/scene/resources/segment_shape_2d.cpp +++ b/scene/resources/segment_shape_2d.cpp @@ -106,7 +106,10 @@ SegmentShape2D::SegmentShape2D() : void RayShape2D::_update_shape() { - Physics2DServer::get_singleton()->shape_set_data(get_rid(), length); + Dictionary d; + d["length"] = length; + d["slips_on_slope"] = slips_on_slope; + Physics2DServer::get_singleton()->shape_set_data(get_rid(), d); emit_changed(); } @@ -140,7 +143,11 @@ void RayShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape2D::set_length); ClassDB::bind_method(D_METHOD("get_length"), &RayShape2D::get_length); + ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape2D::set_slips_on_slope); + ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape2D::get_slips_on_slope); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "length"), "set_length", "get_length"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slips_on_slope"), "set_slips_on_slope", "get_slips_on_slope"); } void RayShape2D::set_length(real_t p_length) { @@ -153,9 +160,20 @@ real_t RayShape2D::get_length() const { return length; } +void RayShape2D::set_slips_on_slope(bool p_active) { + + slips_on_slope = p_active; + _update_shape(); +} + +bool RayShape2D::get_slips_on_slope() const { + return slips_on_slope; +} + RayShape2D::RayShape2D() : Shape2D(Physics2DServer::get_singleton()->ray_shape_create()) { length = 20; + slips_on_slope = false; _update_shape(); } diff --git a/scene/resources/segment_shape_2d.h b/scene/resources/segment_shape_2d.h index 4ed30c0443..700982ac0a 100644 --- a/scene/resources/segment_shape_2d.h +++ b/scene/resources/segment_shape_2d.h @@ -63,6 +63,7 @@ class RayShape2D : public Shape2D { GDCLASS(RayShape2D, Shape2D); real_t length; + bool slips_on_slope; void _update_shape(); @@ -72,6 +73,10 @@ protected: public: void set_length(real_t p_length); real_t get_length() const; + + void set_slips_on_slope(bool p_active); + bool get_slips_on_slope() const; + virtual void draw(const RID &p_to_rid, const Color &p_color); virtual Rect2 get_rect() const; diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h index ed655b8a93..7eb0406bd8 100644 --- a/scene/resources/shape_2d.h +++ b/scene/resources/shape_2d.h @@ -45,7 +45,7 @@ protected: Shape2D(const RID &p_rid); public: - virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { return true; } + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { return get_rect().has_point(p_point); } void set_custom_solver_bias(real_t p_bias); real_t get_custom_solver_bias() const; diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index de75bb3976..626fda50df 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -101,7 +101,7 @@ StyleBox::StyleBox() { } } -void StyleBoxTexture::set_texture(RES p_texture) { +void StyleBoxTexture::set_texture(Ref<Texture> p_texture) { if (texture == p_texture) return; @@ -112,12 +112,12 @@ void StyleBoxTexture::set_texture(RES p_texture) { _change_notify("texture"); } -RES StyleBoxTexture::get_texture() const { +Ref<Texture> StyleBoxTexture::get_texture() const { return texture; } -void StyleBoxTexture::set_normal_map(RES p_normal_map) { +void StyleBoxTexture::set_normal_map(Ref<Texture> p_normal_map) { if (normal_map == p_normal_map) return; @@ -125,7 +125,7 @@ void StyleBoxTexture::set_normal_map(RES p_normal_map) { emit_changed(); } -RES StyleBoxTexture::get_normal_map() const { +Ref<Texture> StyleBoxTexture::get_normal_map() const { return normal_map; } @@ -650,14 +650,14 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { style_rect = style_rect.grow(-((aa_size + 1) / 2)); } - //adapt borders (prevent weired overlapping/glitchy drawings) + //adapt borders (prevent weird overlapping/glitchy drawings) int width = MAX(style_rect.size.width, 0); int height = MAX(style_rect.size.height, 0); int adapted_border[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX }; adapt_values(MARGIN_TOP, MARGIN_BOTTOM, adapted_border, border_width, height, height, height); adapt_values(MARGIN_LEFT, MARGIN_RIGHT, adapted_border, border_width, width, width, width); - //adapt corners (prevent weired overlapping/glitchy drawings) + //adapt corners (prevent weird overlapping/glitchy drawings) int adapted_corner[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX }; adapt_values(CORNER_TOP_RIGHT, CORNER_BOTTOM_RIGHT, adapted_corner, corner_radius, height, height - adapted_border[MARGIN_BOTTOM], height - adapted_border[MARGIN_TOP]); adapt_values(CORNER_TOP_LEFT, CORNER_BOTTOM_LEFT, adapted_corner, corner_radius, height, height - adapted_border[MARGIN_BOTTOM], height - adapted_border[MARGIN_TOP]); diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index fb79aa360e..c1d84fe19f 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -112,11 +112,11 @@ public: void set_region_rect(const Rect2 &p_region_rect); Rect2 get_region_rect() const; - void set_texture(RES p_texture); - RES get_texture() const; + void set_texture(Ref<Texture> p_texture); + Ref<Texture> get_texture() const; - void set_normal_map(RES p_normal_map); - RES get_normal_map() const; + void set_normal_map(Ref<Texture> p_normal_map); + Ref<Texture> get_normal_map() const; void set_draw_center(bool p_enabled); bool is_draw_center_enabled() const; diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 3138d73caf..4463f98b07 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -57,8 +57,8 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { tile_set_modulate(id, p_value); else if (what == "region") tile_set_region(id, p_value); - else if (what == "is_autotile") - tile_set_is_autotile(id, p_value); + else if (what == "tile_mode") + tile_set_tile_mode(id, (TileMode)((int)p_value)); else if (what.left(9) == "autotile/") { what = what.right(9); if (what == "bitmask_mode") @@ -174,8 +174,8 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const { r_ret = tile_get_modulate(id); else if (what == "region") r_ret = tile_get_region(id); - else if (what == "is_autotile") - r_ret = tile_get_is_autotile(id); + else if (what == "tile_mode") + r_ret = tile_get_tile_mode(id); else if (what.left(9) == "autotile/") { what = what.right(9); if (what == "bitmask_mode") @@ -258,13 +258,13 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial")); p_list->push_back(PropertyInfo(Variant::COLOR, pre + "modulate")); p_list->push_back(PropertyInfo(Variant::RECT2, pre + "region")); - p_list->push_back(PropertyInfo(Variant::BOOL, pre + "is_autotile", PROPERTY_HINT_NONE, "")); - if (tile_get_is_autotile(id)) { + p_list->push_back(PropertyInfo(Variant::INT, pre + "tile_mode", PROPERTY_HINT_ENUM, "SINGLE_TILE,AUTO_TILE")); + if (tile_get_tile_mode(id) == AUTO_TILE) { p_list->push_back(PropertyInfo(Variant::INT, pre + "autotile/bitmask_mode", PROPERTY_HINT_ENUM, "2X2,3X3", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); + p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/bitmask_flags", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "autotile/icon_coordinate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "autotile/tile_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::INT, pre + "autotile/spacing", PROPERTY_HINT_RANGE, "0,256,1", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); - p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/bitmask_flags", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/occluder_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/navpoly_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/priority_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); @@ -282,7 +282,6 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { } void TileSet::create_tile(int p_id) { - ERR_FAIL_COND(tile_map.has(p_id)); tile_map[p_id] = TileData(); tile_map[p_id].autotile_data = AutotileData(); @@ -291,7 +290,6 @@ void TileSet::create_tile(int p_id) { } void TileSet::autotile_set_bitmask_mode(int p_id, BitmaskMode p_mode) { - ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].autotile_data.bitmask_mode = p_mode; _change_notify(""); @@ -375,6 +373,7 @@ void TileSet::tile_set_region(int p_id, const Rect2 &p_region) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].region = p_region; emit_changed(); + _change_notify("region"); } Rect2 TileSet::tile_get_region(int p_id) const { @@ -383,18 +382,17 @@ Rect2 TileSet::tile_get_region(int p_id) const { return tile_map[p_id].region; } -void TileSet::tile_set_is_autotile(int p_id, bool p_is_autotile) { - +void TileSet::tile_set_tile_mode(int p_id, TileMode p_tile_mode) { ERR_FAIL_COND(!tile_map.has(p_id)); - tile_map[p_id].is_autotile = p_is_autotile; + tile_map[p_id].tile_mode = p_tile_mode; emit_changed(); - _change_notify("is_autotile"); + _change_notify("tile_mode"); } -bool TileSet::tile_get_is_autotile(int p_id) const { +TileSet::TileMode TileSet::tile_get_tile_mode(int p_id) const { - ERR_FAIL_COND_V(!tile_map.has(p_id), false); - return tile_map[p_id].is_autotile; + ERR_FAIL_COND_V(!tile_map.has(p_id), SINGLE_TILE); + return tile_map[p_id].tile_mode; } void TileSet::autotile_set_icon_coordinate(int p_id, Vector2 coord) { @@ -534,6 +532,7 @@ void TileSet::tile_set_name(int p_id, const String &p_name) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].name = p_name; emit_changed(); + _change_notify("name"); } String TileSet::tile_get_name(int p_id) const { diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 1306e2878c..46f34b6252 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -71,6 +71,12 @@ public: BIND_BOTTOMRIGHT = 256 }; + enum TileMode { + SINGLE_TILE, + AUTO_TILE, + ANIMATED_TILE + }; + struct AutotileData { BitmaskMode bitmask_mode; int spacing; @@ -84,6 +90,7 @@ public: // Default size to prevent invalid value explicit AutotileData() : size(64, 64), + spacing(0), icon_coord(0, 0) { bitmask_mode = BITMASK_2X2; } @@ -104,13 +111,13 @@ private: Ref<NavigationPolygon> navigation_polygon; Ref<ShaderMaterial> material; Color modulate; - bool is_autotile; + TileMode tile_mode; AutotileData autotile_data; // Default modulate for back-compat explicit TileData() : - modulate(1, 1, 1), - is_autotile(false) {} + tile_mode(SINGLE_TILE), + modulate(1, 1, 1) {} }; Map<int, TileData> tile_map; @@ -146,8 +153,8 @@ public: void tile_set_region(int p_id, const Rect2 &p_region); Rect2 tile_get_region(int p_id) const; - void tile_set_is_autotile(int p_id, bool p_is_autotile); - bool tile_get_is_autotile(int p_id) const; + void tile_set_tile_mode(int p_id, TileMode p_tile_mode); + TileMode tile_get_tile_mode(int p_id) const; void autotile_set_icon_coordinate(int p_id, Vector2 coord); Vector2 autotile_get_icon_coordinate(int p_id) const; |