summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/animation.cpp54
-rw-r--r--scene/resources/animation.h1
-rw-r--r--scene/resources/audio_stream_sample.cpp41
-rw-r--r--scene/resources/audio_stream_sample.h5
-rw-r--r--scene/resources/bit_mask.cpp359
-rw-r--r--scene/resources/bit_mask.h10
-rw-r--r--scene/resources/bounds.cpp1
-rw-r--r--scene/resources/bounds.h1
-rw-r--r--scene/resources/box_shape.cpp1
-rw-r--r--scene/resources/box_shape.h1
-rw-r--r--scene/resources/canvas.cpp1
-rw-r--r--scene/resources/canvas.h1
-rw-r--r--scene/resources/capsule_shape.cpp1
-rw-r--r--scene/resources/capsule_shape.h1
-rw-r--r--scene/resources/capsule_shape_2d.cpp1
-rw-r--r--scene/resources/capsule_shape_2d.h1
-rw-r--r--scene/resources/circle_shape_2d.cpp1
-rw-r--r--scene/resources/circle_shape_2d.h1
-rw-r--r--scene/resources/color_ramp.cpp5
-rw-r--r--scene/resources/color_ramp.h1
-rw-r--r--scene/resources/concave_polygon_shape.cpp25
-rw-r--r--scene/resources/concave_polygon_shape.h4
-rw-r--r--scene/resources/concave_polygon_shape_2d.cpp1
-rw-r--r--scene/resources/concave_polygon_shape_2d.h1
-rw-r--r--scene/resources/convex_polygon_shape.cpp1
-rw-r--r--scene/resources/convex_polygon_shape.h1
-rw-r--r--scene/resources/convex_polygon_shape_2d.cpp1
-rw-r--r--scene/resources/convex_polygon_shape_2d.h1
-rw-r--r--scene/resources/curve.cpp173
-rw-r--r--scene/resources/curve.h5
-rw-r--r--scene/resources/default_theme/default_theme.cpp19
-rw-r--r--scene/resources/dynamic_font.cpp589
-rw-r--r--scene/resources/dynamic_font.h67
-rw-r--r--scene/resources/dynamic_font_stb.cpp23
-rw-r--r--scene/resources/dynamic_font_stb.h5
-rw-r--r--scene/resources/environment.cpp11
-rw-r--r--scene/resources/environment.h1
-rw-r--r--scene/resources/font.cpp89
-rw-r--r--scene/resources/font.h58
-rw-r--r--scene/resources/material.cpp72
-rw-r--r--scene/resources/material.h6
-rw-r--r--scene/resources/mesh.cpp30
-rw-r--r--scene/resources/mesh.h1
-rw-r--r--scene/resources/mesh_data_tool.cpp1
-rw-r--r--scene/resources/mesh_data_tool.h1
-rw-r--r--scene/resources/mesh_library.cpp1
-rw-r--r--scene/resources/mesh_library.h1
-rw-r--r--scene/resources/multimesh.cpp5
-rw-r--r--scene/resources/multimesh.h1
-rw-r--r--scene/resources/packed_scene.cpp11
-rw-r--r--scene/resources/packed_scene.h1
-rw-r--r--scene/resources/plane_shape.cpp1
-rw-r--r--scene/resources/plane_shape.h1
-rw-r--r--scene/resources/polygon_path_finder.cpp3
-rw-r--r--scene/resources/polygon_path_finder.h1
-rw-r--r--scene/resources/primitive_meshes.cpp74
-rw-r--r--scene/resources/primitive_meshes.h12
-rw-r--r--scene/resources/ray_shape.cpp24
-rw-r--r--scene/resources/ray_shape.h5
-rw-r--r--scene/resources/rectangle_shape_2d.cpp1
-rw-r--r--scene/resources/rectangle_shape_2d.h1
-rw-r--r--scene/resources/room.cpp1
-rw-r--r--scene/resources/room.h1
-rw-r--r--scene/resources/scene_format_text.cpp30
-rw-r--r--scene/resources/scene_format_text.h5
-rw-r--r--scene/resources/segment_shape_2d.cpp21
-rw-r--r--scene/resources/segment_shape_2d.h6
-rw-r--r--scene/resources/shader.cpp1
-rw-r--r--scene/resources/shader.h1
-rw-r--r--scene/resources/shader_graph.cpp3
-rw-r--r--scene/resources/shader_graph.h1
-rw-r--r--scene/resources/shape.cpp1
-rw-r--r--scene/resources/shape.h1
-rw-r--r--scene/resources/shape_2d.cpp1
-rw-r--r--scene/resources/shape_2d.h3
-rw-r--r--scene/resources/shape_line_2d.cpp1
-rw-r--r--scene/resources/shape_line_2d.h1
-rw-r--r--scene/resources/sky_box.cpp1
-rw-r--r--scene/resources/sky_box.h7
-rw-r--r--scene/resources/space_2d.cpp1
-rw-r--r--scene/resources/space_2d.h1
-rw-r--r--scene/resources/sphere_shape.cpp1
-rw-r--r--scene/resources/sphere_shape.h1
-rw-r--r--scene/resources/style_box.cpp26
-rw-r--r--scene/resources/style_box.h9
-rw-r--r--scene/resources/surface_tool.cpp11
-rw-r--r--scene/resources/surface_tool.h3
-rw-r--r--scene/resources/texture.cpp26
-rw-r--r--scene/resources/texture.h1
-rw-r--r--scene/resources/theme.cpp1
-rw-r--r--scene/resources/theme.h1
-rw-r--r--scene/resources/tile_set.cpp76
-rw-r--r--scene/resources/tile_set.h22
-rw-r--r--scene/resources/video_stream.cpp1
-rw-r--r--scene/resources/video_stream.h1
-rw-r--r--scene/resources/world.cpp4
-rw-r--r--scene/resources/world.h1
-rw-r--r--scene/resources/world_2d.cpp5
-rw-r--r--scene/resources/world_2d.h1
99 files changed, 1551 insertions, 545 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 367c8235f5..7a1fffaa26 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "animation.h"
#include "geometry.h"
@@ -35,13 +36,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
String name = p_name;
- if (name == "length")
- set_length(p_value);
- else if (name == "loop")
- set_loop(p_value);
- else if (name == "step")
- set_step(p_value);
- else if (name.begins_with("tracks/")) {
+ if (name.begins_with("tracks/")) {
int track = name.get_slicec('/', 1).to_int();
String what = name.get_slicec('/', 2);
@@ -383,20 +378,15 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
}
void Animation::_get_property_list(List<PropertyInfo> *p_list) const {
-
- p_list->push_back(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_RANGE, "0.001,99999,0.001"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "loop"));
- p_list->push_back(PropertyInfo(Variant::REAL, "step", PROPERTY_HINT_RANGE, "0,4096,0.001"));
-
for (int i = 0; i < tracks.size(); i++) {
- p_list->push_back(PropertyInfo(Variant::STRING, "tracks/" + itos(i) + "/type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::NODE_PATH, "tracks/" + itos(i) + "/path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::INT, "tracks/" + itos(i) + "/interp", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/loop_wrap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/imported", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::ARRAY, "tracks/" + itos(i) + "/keys", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::STRING, "tracks/" + itos(i) + "/type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::NODE_PATH, "tracks/" + itos(i) + "/path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::INT, "tracks/" + itos(i) + "/interp", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/loop_wrap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/imported", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, "tracks/" + itos(i) + "/keys", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
}
@@ -1613,19 +1603,19 @@ float Animation::get_step() const {
return step;
}
-void Animation::copy_track(int src_track, Ref<Animation> p_to_animation) {
+void Animation::copy_track(int p_track, Ref<Animation> p_to_animation) {
ERR_FAIL_COND(p_to_animation.is_null());
- ERR_FAIL_INDEX(src_track, get_track_count());
+ ERR_FAIL_INDEX(p_track, get_track_count());
int dst_track = p_to_animation->get_track_count();
- p_to_animation->add_track(track_get_type(src_track));
-
- p_to_animation->track_set_path(dst_track, track_get_path(src_track));
- p_to_animation->track_set_imported(dst_track, track_is_imported(src_track));
- p_to_animation->track_set_enabled(dst_track, track_is_enabled(src_track));
- p_to_animation->track_set_interpolation_type(dst_track, track_get_interpolation_type(src_track));
- p_to_animation->track_set_interpolation_loop_wrap(dst_track, track_get_interpolation_loop_wrap(src_track));
- for (int i = 0; i < track_get_key_count(src_track); i++) {
- p_to_animation->track_insert_key(dst_track, track_get_key_time(src_track, i), track_get_key_value(src_track, i), track_get_key_transition(src_track, i));
+ p_to_animation->add_track(track_get_type(p_track));
+
+ p_to_animation->track_set_path(dst_track, track_get_path(p_track));
+ p_to_animation->track_set_imported(dst_track, track_is_imported(p_track));
+ p_to_animation->track_set_enabled(dst_track, track_is_enabled(p_track));
+ p_to_animation->track_set_interpolation_type(dst_track, track_get_interpolation_type(p_track));
+ p_to_animation->track_set_interpolation_loop_wrap(dst_track, track_get_interpolation_loop_wrap(p_track));
+ for (int i = 0; i < track_get_key_count(p_track); i++) {
+ p_to_animation->track_insert_key(dst_track, track_get_key_time(p_track, i), track_get_key_value(p_track, i), track_get_key_transition(p_track, i));
}
}
@@ -1689,6 +1679,10 @@ void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear"), &Animation::clear);
ClassDB::bind_method(D_METHOD("copy_track", "track", "to_animation"), &Animation::copy_track);
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_RANGE, "0.001,99999,0.001"), "set_length", "get_length");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "step", PROPERTY_HINT_RANGE, "0,4096,0.001"), "set_step", "get_step");
+
BIND_ENUM_CONSTANT(TYPE_VALUE);
BIND_ENUM_CONSTANT(TYPE_TRANSFORM);
BIND_ENUM_CONSTANT(TYPE_METHOD);
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index 2975c7fd9d..73691a69f2 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef ANIMATION_H
#define ANIMATION_H
diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp
index e52a83d17e..b77143cd9d 100644
--- a/scene/resources/audio_stream_sample.cpp
+++ b/scene/resources/audio_stream_sample.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "audio_stream_sample.h"
void AudioStreamPlaybackSample::start(float p_from_pos) {
@@ -76,7 +77,7 @@ void AudioStreamPlaybackSample::seek(float p_time) {
if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM)
return; //no seeking in ima-adpcm
- float max = get_length();
+ float max = base->get_length();
if (p_time < 0) {
p_time = 0;
} else if (p_time >= max) {
@@ -389,22 +390,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
}
}
-float AudioStreamPlaybackSample::get_length() const {
-
- int len = base->data_bytes;
- switch (base->format) {
- case AudioStreamSample::FORMAT_8_BITS: len /= 1; break;
- case AudioStreamSample::FORMAT_16_BITS: len /= 2; break;
- case AudioStreamSample::FORMAT_IMA_ADPCM: len *= 2; break;
- }
-
- if (base->stereo) {
- len /= 2;
- }
-
- return float(len) / base->mix_rate;
-}
-
AudioStreamPlaybackSample::AudioStreamPlaybackSample() {
active = false;
@@ -468,6 +453,22 @@ bool AudioStreamSample::is_stereo() const {
return stereo;
}
+float AudioStreamSample::get_length() const {
+
+ int len = data_bytes;
+ switch (format) {
+ case AudioStreamSample::FORMAT_8_BITS: len /= 1; break;
+ case AudioStreamSample::FORMAT_16_BITS: len /= 2; break;
+ case AudioStreamSample::FORMAT_IMA_ADPCM: len *= 2; break;
+ }
+
+ if (stereo) {
+ len /= 2;
+ }
+
+ return float(len) / mix_rate;
+}
+
void AudioStreamSample::set_data(const PoolVector<uint8_t> &p_data) {
AudioServer::get_singleton()->lock();
@@ -541,8 +542,8 @@ void AudioStreamSample::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_stereo", "stereo"), &AudioStreamSample::set_stereo);
ClassDB::bind_method(D_METHOD("is_stereo"), &AudioStreamSample::is_stereo);
- ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamSample::set_data);
- ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamSample::get_data);
+ ClassDB::bind_method(D_METHOD("_set_data", "data"), &AudioStreamSample::set_data);
+ ClassDB::bind_method(D_METHOD("_get_data"), &AudioStreamSample::get_data);
ADD_PROPERTY(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_ENUM, "8-Bit,16-Bit,IMA-ADPCM"), "set_format", "get_format");
ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode", PROPERTY_HINT_ENUM, "Disabled,Forward,Ping-Pong"), "set_loop_mode", "get_loop_mode");
@@ -550,7 +551,7 @@ void AudioStreamSample::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_end"), "set_loop_end", "get_loop_end");
ADD_PROPERTY(PropertyInfo(Variant::INT, "mix_rate"), "set_mix_rate", "get_mix_rate");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stereo"), "set_stereo", "is_stereo");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
BIND_ENUM_CONSTANT(FORMAT_8_BITS);
BIND_ENUM_CONSTANT(FORMAT_16_BITS);
diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h
index a51483aa21..5fe65c194e 100644
--- a/scene/resources/audio_stream_sample.h
+++ b/scene/resources/audio_stream_sample.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef AUDIOSTREAMSAMPLE_H
#define AUDIOSTREAMSAMPLE_H
@@ -76,8 +77,6 @@ public:
virtual void mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames);
- virtual float get_length() const; //if supported, otherwise return 0
-
AudioStreamPlaybackSample();
};
@@ -136,6 +135,8 @@ public:
void set_stereo(bool p_enable);
bool is_stereo() const;
+ virtual float get_length() const; //if supported, otherwise return 0
+
void set_data(const PoolVector<uint8_t> &p_data);
PoolVector<uint8_t> get_data() const;
diff --git a/scene/resources/bit_mask.cpp b/scene/resources/bit_mask.cpp
index 85bcfc9ecd..29ffefd9d6 100644
--- a/scene/resources/bit_mask.cpp
+++ b/scene/resources/bit_mask.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "bit_mask.h"
#include "io/image_loader.h"
@@ -41,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();
@@ -57,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);
+ }
}
}
@@ -80,7 +82,7 @@ void BitMap::set_bit_rect(const Rect2 &p_rect, bool p_value) {
if (p_value)
b |= (1 << bbit);
else
- b &= !(1 << bbit);
+ b &= ~(1 << bbit);
data[bbyte] = b;
}
@@ -111,8 +113,8 @@ int BitMap::get_true_bit_count() const {
void BitMap::set_bit(const Point2 &p_pos, bool p_value) {
- int x = Math::fast_ftoi(p_pos.x);
- int y = Math::fast_ftoi(p_pos.y);
+ int x = p_pos.x;
+ int y = p_pos.y;
ERR_FAIL_INDEX(x, width);
ERR_FAIL_INDEX(y, height);
@@ -126,7 +128,7 @@ void BitMap::set_bit(const Point2 &p_pos, bool p_value) {
if (p_value)
b |= (1 << bbit);
else
- b &= !(1 << bbit);
+ b &= ~(1 << bbit);
bitmask[bbyte] = b;
}
@@ -167,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);
@@ -183,7 +526,7 @@ void BitMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_data"), &BitMap::_set_data);
ClassDB::bind_method(D_METHOD("_get_data"), &BitMap::_get_data);
- ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
}
BitMap::BitMap() {
diff --git a/scene/resources/bit_mask.h b/scene/resources/bit_mask.h
index 403f151004..dcd5edb4fb 100644
--- a/scene/resources/bit_mask.h
+++ b/scene/resources/bit_mask.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef BIT_MASK_H
#define BIT_MASK_H
@@ -38,12 +39,13 @@ class BitMap : public Resource {
GDCLASS(BitMap, Resource);
OBJ_SAVE_TYPE(BitMap);
- RES_BASE_EXTENSION("pbm");
Vector<uint8_t> bitmask;
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/bounds.cpp b/scene/resources/bounds.cpp
index 3e4be0defa..b115d92be3 100644
--- a/scene/resources/bounds.cpp
+++ b/scene/resources/bounds.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "bounds.h"
void Bounds::_bind_methods() {
diff --git a/scene/resources/bounds.h b/scene/resources/bounds.h
index 1454064853..dfe2fe40c6 100644
--- a/scene/resources/bounds.h
+++ b/scene/resources/bounds.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef BOUNDS_H
#define BOUNDS_H
diff --git a/scene/resources/box_shape.cpp b/scene/resources/box_shape.cpp
index d93791ef4f..e9e01ed98a 100644
--- a/scene/resources/box_shape.cpp
+++ b/scene/resources/box_shape.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "box_shape.h"
#include "servers/physics_server.h"
diff --git a/scene/resources/box_shape.h b/scene/resources/box_shape.h
index 2bbf455a46..5ef16b4766 100644
--- a/scene/resources/box_shape.h
+++ b/scene/resources/box_shape.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef BOX_SHAPE_H
#define BOX_SHAPE_H
diff --git a/scene/resources/canvas.cpp b/scene/resources/canvas.cpp
index e46b40736e..8da1da9541 100644
--- a/scene/resources/canvas.cpp
+++ b/scene/resources/canvas.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "canvas.h"
#include "servers/visual_server.h"
diff --git a/scene/resources/canvas.h b/scene/resources/canvas.h
index 1bb57987e3..dfdea82ca5 100644
--- a/scene/resources/canvas.h
+++ b/scene/resources/canvas.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef CANVAS_H
#define CANVAS_H
diff --git a/scene/resources/capsule_shape.cpp b/scene/resources/capsule_shape.cpp
index bb721759c9..101970bad8 100644
--- a/scene/resources/capsule_shape.cpp
+++ b/scene/resources/capsule_shape.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "capsule_shape.h"
#include "servers/physics_server.h"
diff --git a/scene/resources/capsule_shape.h b/scene/resources/capsule_shape.h
index 6a0b27bb0b..f89d07c5f1 100644
--- a/scene/resources/capsule_shape.h
+++ b/scene/resources/capsule_shape.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef CAPSULE_SHAPE_H
#define CAPSULE_SHAPE_H
diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp
index 2722ff7207..95ab34abb2 100644
--- a/scene/resources/capsule_shape_2d.cpp
+++ b/scene/resources/capsule_shape_2d.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "capsule_shape_2d.h"
#include "servers/physics_2d_server.h"
diff --git a/scene/resources/capsule_shape_2d.h b/scene/resources/capsule_shape_2d.h
index 784f2c02c8..04d663c010 100644
--- a/scene/resources/capsule_shape_2d.h
+++ b/scene/resources/capsule_shape_2d.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef CAPSULE_SHAPE_2D_H
#define CAPSULE_SHAPE_2D_H
diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp
index 669b1d8e7d..1c7bb76b26 100644
--- a/scene/resources/circle_shape_2d.cpp
+++ b/scene/resources/circle_shape_2d.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "circle_shape_2d.h"
#include "servers/physics_2d_server.h"
diff --git a/scene/resources/circle_shape_2d.h b/scene/resources/circle_shape_2d.h
index 3668521a55..06bb433170 100644
--- a/scene/resources/circle_shape_2d.h
+++ b/scene/resources/circle_shape_2d.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef CIRCLE_SHAPE_2D_H
#define CIRCLE_SHAPE_2D_H
diff --git a/scene/resources/color_ramp.cpp b/scene/resources/color_ramp.cpp
index 22d52ef1ec..b2f586d02d 100644
--- a/scene/resources/color_ramp.cpp
+++ b/scene/resources/color_ramp.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "color_ramp.h"
#include "core_string_names.h"
@@ -70,8 +71,8 @@ void Gradient::_bind_methods() {
ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_COLORS, "colors"), &Gradient::set_colors);
ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_COLORS), &Gradient::get_colors);
- 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);
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_REAL_ARRAY, "offsets"), COLOR_RAMP_SET_OFFSETS, COLOR_RAMP_GET_OFFSETS);
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "colors"), COLOR_RAMP_SET_COLORS, COLOR_RAMP_GET_COLORS);
}
Vector<float> Gradient::get_offsets() const {
diff --git a/scene/resources/color_ramp.h b/scene/resources/color_ramp.h
index 4e041355b2..c042a0d3d0 100644
--- a/scene/resources/color_ramp.h
+++ b/scene/resources/color_ramp.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef SCENE_RESOURCES_COLOR_RAMP_H_
#define SCENE_RESOURCES_COLOR_RAMP_H_
diff --git a/scene/resources/concave_polygon_shape.cpp b/scene/resources/concave_polygon_shape.cpp
index 718aaeb27a..935f041837 100644
--- a/scene/resources/concave_polygon_shape.cpp
+++ b/scene/resources/concave_polygon_shape.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "concave_polygon_shape.h"
#include "servers/physics_server.h"
@@ -63,29 +64,6 @@ Vector<Vector3> ConcavePolygonShape::_gen_debug_mesh_lines() {
return points;
}
-bool ConcavePolygonShape::_set(const StringName &p_name, const Variant &p_value) {
-
- if (p_name == "data")
- PhysicsServer::get_singleton()->shape_set_data(get_shape(), p_value);
- else
- return false;
-
- return true;
-}
-
-bool ConcavePolygonShape::_get(const StringName &p_name, Variant &r_ret) const {
-
- if (p_name == "data")
- r_ret = PhysicsServer::get_singleton()->shape_get_data(get_shape());
- else
- return false;
- return true;
-}
-void ConcavePolygonShape::_get_property_list(List<PropertyInfo> *p_list) const {
-
- p_list->push_back(PropertyInfo(Variant::ARRAY, "data"));
-}
-
void ConcavePolygonShape::_update_shape() {
}
@@ -104,6 +82,7 @@ void ConcavePolygonShape::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_faces", "faces"), &ConcavePolygonShape::set_faces);
ClassDB::bind_method(D_METHOD("get_faces"), &ConcavePolygonShape::get_faces);
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_faces", "get_faces");
}
ConcavePolygonShape::ConcavePolygonShape() :
diff --git a/scene/resources/concave_polygon_shape.h b/scene/resources/concave_polygon_shape.h
index b94e3eca9c..2cc9095abf 100644
--- a/scene/resources/concave_polygon_shape.h
+++ b/scene/resources/concave_polygon_shape.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef CONCAVE_POLYGON_SHAPE_H
#define CONCAVE_POLYGON_SHAPE_H
@@ -57,9 +58,6 @@ class ConcavePolygonShape : public Shape {
};
protected:
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
static void _bind_methods();
virtual void _update_shape();
diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp
index 69765796f6..d4343680ef 100644
--- a/scene/resources/concave_polygon_shape_2d.cpp
+++ b/scene/resources/concave_polygon_shape_2d.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "concave_polygon_shape_2d.h"
#include "servers/physics_2d_server.h"
diff --git a/scene/resources/concave_polygon_shape_2d.h b/scene/resources/concave_polygon_shape_2d.h
index 7ca14d4d66..e8fa7369ac 100644
--- a/scene/resources/concave_polygon_shape_2d.h
+++ b/scene/resources/concave_polygon_shape_2d.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef CONCAVE_POLYGON_SHAPE_2D_H
#define CONCAVE_POLYGON_SHAPE_2D_H
diff --git a/scene/resources/convex_polygon_shape.cpp b/scene/resources/convex_polygon_shape.cpp
index e022b76907..a2e0996996 100644
--- a/scene/resources/convex_polygon_shape.cpp
+++ b/scene/resources/convex_polygon_shape.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "convex_polygon_shape.h"
#include "quick_hull.h"
#include "servers/physics_server.h"
diff --git a/scene/resources/convex_polygon_shape.h b/scene/resources/convex_polygon_shape.h
index 0a840f0bc5..62567fc031 100644
--- a/scene/resources/convex_polygon_shape.h
+++ b/scene/resources/convex_polygon_shape.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef CONVEX_POLYGON_SHAPE_H
#define CONVEX_POLYGON_SHAPE_H
diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp
index 0402a70898..d061c4ea1e 100644
--- a/scene/resources/convex_polygon_shape_2d.cpp
+++ b/scene/resources/convex_polygon_shape_2d.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "convex_polygon_shape_2d.h"
#include "geometry.h"
diff --git a/scene/resources/convex_polygon_shape_2d.h b/scene/resources/convex_polygon_shape_2d.h
index 320cf94a5e..69c237a0e6 100644
--- a/scene/resources/convex_polygon_shape_2d.h
+++ b/scene/resources/convex_polygon_shape_2d.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef CONVEX_POLYGON_SHAPE_2D_H
#define CONVEX_POLYGON_SHAPE_2D_H
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index 95cb336740..4ec1e8973d 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "curve.h"
#include "core_string_names.h"
@@ -510,7 +511,7 @@ void Curve::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "min_value", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_min_value", "get_min_value");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_value", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_max_value", "get_max_value");
ADD_PROPERTY(PropertyInfo(Variant::INT, "bake_resolution", PROPERTY_HINT_RANGE, "1,1000,1"), "set_bake_resolution", "get_bake_resolution");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
ADD_SIGNAL(MethodInfo(SIGNAL_RANGE_CHANGED));
@@ -805,6 +806,87 @@ float Curve2D::get_bake_interval() const {
return bake_interval;
}
+Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const {
+ // Brute force method
+
+ if (baked_cache_dirty)
+ _bake();
+
+ //validate//
+ int pc = baked_point_cache.size();
+ if (pc == 0) {
+ ERR_EXPLAIN("No points in Curve2D");
+ ERR_FAIL_COND_V(pc == 0, Vector2());
+ }
+
+ if (pc == 1)
+ return baked_point_cache.get(0);
+
+ PoolVector2Array::Read r = baked_point_cache.read();
+
+ Vector2 nearest;
+ float nearest_dist = -1.0f;
+
+ for (int i = 0; i < pc - 1; i++) {
+ Vector2 origin = r[i];
+ Vector2 direction = (r[i + 1] - origin) / bake_interval;
+
+ float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ Vector2 proj = origin + direction * d;
+
+ float dist = proj.distance_squared_to(p_to_point);
+
+ if (nearest_dist < 0.0f || dist < nearest_dist) {
+ nearest = proj;
+ nearest_dist = dist;
+ }
+ }
+
+ return nearest;
+}
+
+float Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
+ // Brute force method
+
+ if (baked_cache_dirty)
+ _bake();
+
+ //validate//
+ int pc = baked_point_cache.size();
+ if (pc == 0) {
+ ERR_EXPLAIN("No points in Curve2D");
+ ERR_FAIL_COND_V(pc == 0, 0.0f);
+ }
+
+ if (pc == 1)
+ return 0.0f;
+
+ PoolVector2Array::Read r = baked_point_cache.read();
+
+ float nearest = 0.0f;
+ float nearest_dist = -1.0f;
+ float offset = 0.0f;
+
+ for (int i = 0; i < pc - 1; i++) {
+ Vector2 origin = r[i];
+ Vector2 direction = (r[i + 1] - origin) / bake_interval;
+
+ float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ Vector2 proj = origin + direction * d;
+
+ float dist = proj.distance_squared_to(p_to_point);
+
+ if (nearest_dist < 0.0f || dist < nearest_dist) {
+ nearest = offset + d;
+ nearest_dist = dist;
+ }
+
+ offset += bake_interval;
+ }
+
+ return nearest;
+}
+
Dictionary Curve2D::_get_data() const {
Dictionary dc;
@@ -908,13 +990,15 @@ void Curve2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_baked_length"), &Curve2D::get_baked_length);
ClassDB::bind_method(D_METHOD("interpolate_baked", "offset", "cubic"), &Curve2D::interpolate_baked, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_baked_points"), &Curve2D::get_baked_points);
+ ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Curve2D::get_closest_point);
+ ClassDB::bind_method(D_METHOD("get_closest_offset", "to_point"), &Curve2D::get_closest_offset);
ClassDB::bind_method(D_METHOD("tessellate", "max_stages", "tolerance_degrees"), &Curve2D::tessellate, DEFVAL(5), DEFVAL(4));
ClassDB::bind_method(D_METHOD("_get_data"), &Curve2D::_get_data);
ClassDB::bind_method(D_METHOD("_set_data"), &Curve2D::_set_data);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_interval", PROPERTY_HINT_RANGE, "0.01,512,0.01"), "set_bake_interval", "get_bake_interval");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
}
Curve2D::Curve2D() {
@@ -1275,6 +1359,87 @@ PoolRealArray Curve3D::get_baked_tilts() const {
return baked_tilt_cache;
}
+Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const {
+ // Brute force method
+
+ if (baked_cache_dirty)
+ _bake();
+
+ //validate//
+ int pc = baked_point_cache.size();
+ if (pc == 0) {
+ ERR_EXPLAIN("No points in Curve3D");
+ ERR_FAIL_COND_V(pc == 0, Vector3());
+ }
+
+ if (pc == 1)
+ return baked_point_cache.get(0);
+
+ PoolVector3Array::Read r = baked_point_cache.read();
+
+ Vector3 nearest;
+ float nearest_dist = -1.0f;
+
+ for (int i = 0; i < pc - 1; i++) {
+ Vector3 origin = r[i];
+ Vector3 direction = (r[i + 1] - origin) / bake_interval;
+
+ float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ Vector3 proj = origin + direction * d;
+
+ float dist = proj.distance_squared_to(p_to_point);
+
+ if (nearest_dist < 0.0f || dist < nearest_dist) {
+ nearest = proj;
+ nearest_dist = dist;
+ }
+ }
+
+ return nearest;
+}
+
+float Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
+ // Brute force method
+
+ if (baked_cache_dirty)
+ _bake();
+
+ //validate//
+ int pc = baked_point_cache.size();
+ if (pc == 0) {
+ ERR_EXPLAIN("No points in Curve3D");
+ ERR_FAIL_COND_V(pc == 0, 0.0f);
+ }
+
+ if (pc == 1)
+ return 0.0f;
+
+ PoolVector3Array::Read r = baked_point_cache.read();
+
+ float nearest = 0.0f;
+ float nearest_dist = -1.0f;
+ float offset = 0.0f;
+
+ for (int i = 0; i < pc - 1; i++) {
+ Vector3 origin = r[i];
+ Vector3 direction = (r[i + 1] - origin) / bake_interval;
+
+ float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ Vector3 proj = origin + direction * d;
+
+ float dist = proj.distance_squared_to(p_to_point);
+
+ if (nearest_dist < 0.0f || dist < nearest_dist) {
+ nearest = offset + d;
+ nearest_dist = dist;
+ }
+
+ offset += bake_interval;
+ }
+
+ return nearest;
+}
+
void Curve3D::set_bake_interval(float p_tolerance) {
bake_interval = p_tolerance;
@@ -1403,13 +1568,15 @@ void Curve3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("interpolate_baked", "offset", "cubic"), &Curve3D::interpolate_baked, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_baked_points"), &Curve3D::get_baked_points);
ClassDB::bind_method(D_METHOD("get_baked_tilts"), &Curve3D::get_baked_tilts);
+ ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Curve3D::get_closest_point);
+ ClassDB::bind_method(D_METHOD("get_closest_offset", "to_point"), &Curve3D::get_closest_offset);
ClassDB::bind_method(D_METHOD("tessellate", "max_stages", "tolerance_degrees"), &Curve3D::tessellate, DEFVAL(5), DEFVAL(4));
ClassDB::bind_method(D_METHOD("_get_data"), &Curve3D::_get_data);
ClassDB::bind_method(D_METHOD("_set_data"), &Curve3D::_set_data);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_interval", PROPERTY_HINT_RANGE, "0.01,512,0.01"), "set_bake_interval", "get_bake_interval");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
}
Curve3D::Curve3D() {
diff --git a/scene/resources/curve.h b/scene/resources/curve.h
index 4d421246bf..492eb05d1e 100644
--- a/scene/resources/curve.h
+++ b/scene/resources/curve.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef CURVE_H
#define CURVE_H
@@ -198,6 +199,8 @@ public:
float get_baked_length() const;
Vector2 interpolate_baked(float p_offset, bool p_cubic = false) const;
PoolVector2Array get_baked_points() const; //useful for going through
+ Vector2 get_closest_point(const Vector2 &p_to_point) const;
+ float get_closest_offset(const Vector2 &p_to_point) const;
PoolVector2Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display
@@ -267,6 +270,8 @@ public:
float interpolate_baked_tilt(float p_offset) const;
PoolVector3Array get_baked_points() const; //useful for going through
PoolRealArray get_baked_tilts() const; //useful for going through
+ Vector3 get_closest_point(const Vector3 &p_to_point) const;
+ float get_closest_offset(const Vector3 &p_to_point) const;
PoolVector3Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index b18583dfb1..5ac9344f31 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -415,6 +415,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_color", "Label", Color(1, 1, 1));
theme->set_color("font_color_shadow", "Label", Color(0, 0, 0, 0));
+ theme->set_color("font_outline_modulate", "Label", Color(1, 1, 1));
theme->set_constant("shadow_offset_x", "Label", 1 * scale);
theme->set_constant("shadow_offset_y", "Label", 1 * scale);
@@ -448,10 +449,10 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// TextEdit
- theme->set_stylebox("normal", "TextEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3));
+ theme->set_stylebox("normal", "TextEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3, 0, 0, 0, 0));
theme->set_stylebox("focus", "TextEdit", focus);
- theme->set_stylebox("read_only", "TextEdit", make_stylebox(tree_bg_disabled_png, 4, 4, 4, 4));
- theme->set_stylebox("completion", "TextEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3));
+ theme->set_stylebox("read_only", "TextEdit", make_stylebox(tree_bg_disabled_png, 4, 4, 4, 4, 0, 0, 0, 0));
+ theme->set_stylebox("completion", "TextEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3, 0, 0, 0, 0));
theme->set_icon("tab", "TextEdit", make_icon(tab_png));
@@ -582,6 +583,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("checked", "PopupMenu", make_icon(checked_png));
theme->set_icon("unchecked", "PopupMenu", make_icon(unchecked_png));
+ theme->set_icon("radio_checked", "PopupMenu", make_icon(radio_checked_png));
+ theme->set_icon("radio_unchecked", "PopupMenu", make_icon(radio_unchecked_png));
theme->set_icon("submenu", "PopupMenu", make_icon(submenu_png));
theme->set_font("font", "PopupMenu", default_font);
@@ -816,6 +819,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_color_selected", "RichTextLabel", font_color_selection);
theme->set_color("selection_color", "RichTextLabel", Color(0.1, 0.1, 1, 0.8));
+ theme->set_color("font_color_shadow", "RichTextLabel", Color(0, 0, 0, 0));
+
+ theme->set_constant("shadow_offset_x", "RichTextLabel", 1 * scale);
+ theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * scale);
+ theme->set_constant("shadow_as_outline", "RichTextLabel", 0 * scale);
+
theme->set_constant("line_separation", "RichTextLabel", 1 * scale);
theme->set_constant("table_hseparation", "RichTextLabel", 3 * scale);
theme->set_constant("table_vseparation", "RichTextLabel", 3 * scale);
@@ -880,7 +889,7 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
Ref<StyleBox> default_style;
Ref<Texture> default_icon;
- Ref<BitmapFont> default_font;
+ Ref<Font> default_font;
if (p_font.is_valid()) {
default_font = p_font;
} else if (p_hidpi) {
@@ -888,7 +897,7 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
} else {
default_font = make_font2(_lodpi_font_height, _lodpi_font_ascent, _lodpi_font_charcount, &_lodpi_font_charrects[0][0], _lodpi_font_kerning_pair_count, &_lodpi_font_kerning_pairs[0][0], _lodpi_font_img_width, _lodpi_font_img_height, _lodpi_font_img_data);
}
- Ref<BitmapFont> large_font = default_font;
+ Ref<Font> large_font = default_font;
fill_default_theme(t, default_font, large_font, default_icon, default_style, p_hidpi ? 2.0 : 1.0);
Theme::set_default(t);
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index d52002ad5c..f41a26a680 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -27,20 +27,19 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifdef FREETYPE_ENABLED
#include "dynamic_font.h"
#include "os/file_access.h"
#include "os/os.h"
-bool DynamicFontData::CacheID::operator<(CacheID right) const {
+#include FT_STROKER_H
- if (size < right.size)
- return true;
- if (mipmaps != right.mipmaps)
- return right.mipmaps;
- if (filter != right.filter)
- return right.filter;
- return false;
+#define __STDC_LIMIT_MACROS
+#include <stdint.h>
+
+bool DynamicFontData::CacheID::operator<(CacheID right) const {
+ return key < right.key;
}
Ref<DynamicFontAtSize> DynamicFontData::_get_dynamic_font_at_size(CacheID p_cache_id) {
@@ -85,6 +84,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");
}
@@ -92,6 +99,7 @@ void DynamicFontData::_bind_methods() {
DynamicFontData::DynamicFontData() {
force_autohinter = false;
+ hinting = DynamicFontData::HINTING_NORMAL;
font_mem = NULL;
font_mem_size = 0;
}
@@ -191,10 +199,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 / 64.0) / oversampling * scale_color_font;
+ descent = (-face->size->metrics.descender / 64.0) / oversampling * scale_color_font;
linegap = 0;
texture_flags = 0;
if (id.mipmaps)
@@ -202,8 +225,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;
}
@@ -224,18 +245,11 @@ float DynamicFontAtSize::get_descent() const {
return descent;
}
-Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const {
+const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFontAtSize::_find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const {
+ const Character *chr = char_map.getptr(p_char);
+ ERR_FAIL_COND_V(!chr, (Pair<const Character *, DynamicFontAtSize *>(NULL, NULL)));
- if (!valid)
- return Size2(1, 1);
- const_cast<DynamicFontAtSize *>(this)->_update_char(p_char);
-
- const Character *c = char_map.getptr(p_char);
- ERR_FAIL_COND_V(!c, Size2());
-
- Size2 ret(0, get_height());
-
- if (!c->found) {
+ if (!chr->found) {
//not found, try in fallbacks
for (int i = 0; i < p_fallbacks.size(); i++) {
@@ -245,53 +259,56 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const V
continue;
fb->_update_char(p_char);
- const Character *ch = fb->char_map.getptr(p_char);
- ERR_CONTINUE(!ch);
+ const Character *fallback_chr = fb->char_map.getptr(p_char);
+ ERR_CONTINUE(!fallback_chr);
- if (!ch->found)
+ if (!fallback_chr->found)
continue;
- c = ch;
- break;
+ return Pair<const Character *, DynamicFontAtSize *>(fallback_chr, fb);
}
- //not found, try 0xFFFD to display 'not found'.
- if (!c->found) {
-
- const_cast<DynamicFontAtSize *>(this)->_update_char(0xFFFD);
- c = char_map.getptr(0xFFFD);
- ERR_FAIL_COND_V(!c, Size2());
- }
+ //not found, try 0xFFFD to display 'not found'.
+ const_cast<DynamicFontAtSize *>(this)->_update_char(0xFFFD);
+ chr = char_map.getptr(0xFFFD);
+ ERR_FAIL_COND_V(!chr, (Pair<const Character *, DynamicFontAtSize *>(NULL, NULL)));
}
- if (c->found) {
- ret.x = c->advance;
- }
+ return Pair<const Character *, DynamicFontAtSize *>(chr, const_cast<DynamicFontAtSize *>(this));
+}
+
+float DynamicFontAtSize::_get_kerning_advance(const DynamicFontAtSize *font, CharType p_char, CharType p_next) const {
+ float advance = 0.0;
if (p_next) {
FT_Vector delta;
- FT_Get_Kerning(face, p_char, p_next, FT_KERNING_DEFAULT, &delta);
+ FT_Get_Kerning(font->face, p_char, p_next, FT_KERNING_DEFAULT, &delta);
+ advance = (delta.x / 64.0) / oversampling;
+ }
- if (delta.x == 0) {
- for (int i = 0; i < p_fallbacks.size(); i++) {
+ return advance;
+}
- DynamicFontAtSize *fb = const_cast<DynamicFontAtSize *>(p_fallbacks[i].ptr());
- if (!fb->valid)
- continue;
+Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const {
- FT_Get_Kerning(fb->face, p_char, p_next, FT_KERNING_DEFAULT, &delta);
+ if (!valid)
+ return Size2(1, 1);
+ const_cast<DynamicFontAtSize *>(this)->_update_char(p_char);
- if (delta.x == 0)
- continue;
+ Pair<const Character *, DynamicFontAtSize *> char_pair_with_font = _find_char_with_font(p_char, p_fallbacks);
+ const Character *ch = char_pair_with_font.first;
+ DynamicFontAtSize *font = char_pair_with_font.second;
+ ERR_FAIL_COND_V(!ch, Size2());
- ret.x += (delta.x >> 6) / oversampling;
- break;
- }
- } else {
- ret.x += (delta.x >> 6) / oversampling;
- }
+ Size2 ret(0, get_height());
+
+ if (ch->found) {
+ ret.x = ch->advance;
}
+ ret.x += _get_kerning_advance(font, p_char, p_next);
+ // ensures oversampled glyphs will have enough space when this value is used by clipping/wrapping algorithms
+ ret.x = Math::ceil(ret.x);
return ret;
}
@@ -305,92 +322,41 @@ void DynamicFontAtSize::set_texture_flags(uint32_t p_flags) {
}
}
-float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const {
+float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks, bool p_advance_only) const {
if (!valid)
return 0;
const_cast<DynamicFontAtSize *>(this)->_update_char(p_char);
- const Character *c = char_map.getptr(p_char);
-
- float advance = 0;
-
- if (!c->found) {
-
- //not found, try in fallbacks
- bool used_fallback = false;
+ Pair<const Character *, DynamicFontAtSize *> char_pair_with_font = _find_char_with_font(p_char, p_fallbacks);
+ const Character *ch = char_pair_with_font.first;
+ DynamicFontAtSize *font = char_pair_with_font.second;
- for (int i = 0; i < p_fallbacks.size(); i++) {
+ ERR_FAIL_COND_V(!ch, 0.0);
- DynamicFontAtSize *fb = const_cast<DynamicFontAtSize *>(p_fallbacks[i].ptr());
- if (!fb->valid)
- continue;
+ float advance = 0.0;
- fb->_update_char(p_char);
- const Character *ch = fb->char_map.getptr(p_char);
- ERR_CONTINUE(!ch);
-
- if (!ch->found)
- continue;
+ if (ch->found) {
+ ERR_FAIL_COND_V(ch->texture_idx < -1 || ch->texture_idx >= font->textures.size(), 0);
+ if (!p_advance_only && ch->texture_idx != -1) {
Point2 cpos = p_pos;
cpos.x += ch->h_align;
- cpos.y -= get_ascent();
+ cpos.y -= font->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);
- advance = ch->advance;
- used_fallback = true;
- break;
- }
- //not found, try 0xFFFD to display 'not found'.
-
- if (!used_fallback) {
-
- const_cast<DynamicFontAtSize *>(this)->_update_char(0xFFFD);
- c = char_map.getptr(0xFFFD);
+ Color modulate = p_modulate;
+ if (FT_HAS_COLOR(face)) {
+ modulate.r = modulate.g = modulate.b = 1.0;
+ }
+ RID texture = font->textures[ch->texture_idx].texture->get_rid();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size * Vector2(font->scale_color_font, font->scale_color_font)), texture, ch->rect_uv, modulate, false, RID(), false);
}
- }
- if (c->found) {
-
- 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_uv, p_modulate, false, RID(), false);
- advance = c->advance;
- //textures[c->texture_idx].texture->draw(p_canvas_item,Vector2());
+ advance = ch->advance;
}
- if (p_next) {
-
- FT_Vector delta;
- FT_Get_Kerning(face, p_char, p_next, FT_KERNING_DEFAULT, &delta);
-
- if (delta.x == 0) {
- for (int i = 0; i < p_fallbacks.size(); i++) {
-
- DynamicFontAtSize *fb = const_cast<DynamicFontAtSize *>(p_fallbacks[i].ptr());
- if (!fb->valid)
- continue;
-
- FT_Get_Kerning(fb->face, p_char, p_next, FT_KERNING_DEFAULT, &delta);
-
- if (delta.x == 0)
- continue;
-
- advance += (delta.x >> 6) / oversampling;
- break;
- }
- } else {
- advance += (delta.x >> 6) / oversampling;
- }
- }
+ advance += _get_kerning_advance(font, p_char, p_next);
return advance;
}
@@ -415,79 +381,37 @@ void DynamicFontAtSize::_ft_stream_close(FT_Stream stream) {
memdelete(f);
}
-void DynamicFontAtSize::_update_char(CharType p_char) {
-
- if (char_map.has(p_char))
- return;
-
- _THREAD_SAFE_METHOD_
-
- FT_GlyphSlot slot = face->glyph;
-
- if (FT_Get_Char_Index(face, p_char) == 0) {
- //not found
- Character ch;
- ch.texture_idx = -1;
- ch.advance = 0;
- ch.h_align = 0;
- ch.v_align = 0;
- ch.found = false;
-
- 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));
- if (!error) {
- 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;
- ch.h_align = 0;
- ch.v_align = 0;
- ch.found = false;
-
- char_map[p_char] = ch;
-
- return;
- }
-
- 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;
-
- int mw = w + rect_margin * 2;
- int mh = h + rect_margin * 2;
-
- if (mw > 4096 || mh > 4096) {
-
- ERR_FAIL_COND(mw > 4096);
- ERR_FAIL_COND(mh > 4096);
- }
+DynamicFontAtSize::Character DynamicFontAtSize::Character::not_found() {
+ Character ch;
+ ch.texture_idx = -1;
+ ch.advance = 0;
+ ch.h_align = 0;
+ ch.v_align = 0;
+ ch.found = false;
+ return ch;
+}
- //find a texture to fit this...
+DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyph(int p_color_size, Image::Format p_image_format, int p_width, int p_height) {
+ TexturePosition ret;
+ ret.index = -1;
+ ret.x = 0;
+ ret.y = 0;
- int tex_index = -1;
- int tex_x = 0;
- int tex_y = 0;
+ int mw = p_width;
+ int mh = p_height;
for (int i = 0; i < textures.size(); i++) {
CharTexture &ct = textures[i];
+ if (ct.texture->get_format() != p_image_format)
+ continue;
+
if (mw > ct.texture_size || mh > ct.texture_size) //too big for this texture
continue;
- tex_y = 0x7FFFFFFF;
- tex_x = 0;
+ ret.y = 0x7FFFFFFF;
+ ret.x = 0;
for (int j = 0; j < ct.texture_size - mw; j++) {
@@ -500,27 +424,27 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
max_y = y;
}
- if (max_y < tex_y) {
- tex_y = max_y;
- tex_x = j;
+ if (max_y < ret.y) {
+ ret.y = max_y;
+ ret.x = j;
}
}
- if (tex_y == 0x7FFFFFFF || tex_y + mh > ct.texture_size)
+ if (ret.y == 0x7FFFFFFF || ret.y + mh > ct.texture_size)
continue; //fail, could not fit it here
- tex_index = i;
+ ret.index = i;
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) {
+ if (ret.index == -1) {
//could not find texture to fit, create one
- tex_x = 0;
- tex_y = 0;
+ ret.x = 0;
+ ret.y = 0;
- int texsize = MAX(id.size * 8, 256);
+ int texsize = MAX(id.size * oversampling * 8, 256);
if (mw > texsize)
texsize = mw; //special case, adapt to it?
if (mh > texsize)
@@ -532,13 +456,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 * p_color_size); //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++) {
+ ERR_FAIL_COND_V(texsize * texsize * p_color_size > tex.imgdata.size(), ret);
+ for (int i = 0; i < texsize * texsize * p_color_size; i++) {
w[i] = 0;
}
}
@@ -547,12 +471,31 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
tex.offsets[i] = 0;
textures.push_back(tex);
- tex_index = textures.size() - 1;
+ ret.index = textures.size() - 1;
}
+ return ret;
+}
+
+DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap bitmap, int yofs, int xofs, float advance) {
+ int w = bitmap.width;
+ int h = bitmap.rows;
+
+ int mw = w + rect_margin * 2;
+ int mh = h + rect_margin * 2;
+
+ ERR_FAIL_COND_V(mw > 4096, Character::not_found());
+ ERR_FAIL_COND_V(mh > 4096, Character::not_found());
+
+ int color_size = bitmap.pixel_mode == FT_PIXEL_MODE_BGRA ? 4 : 2;
+ Image::Format require_format = color_size == 4 ? Image::FORMAT_RGBA8 : Image::FORMAT_LA8;
+
+ TexturePosition tex_pos = _find_texture_pos_for_glyph(color_size, require_format, mw, mh);
+ ERR_FAIL_COND_V(tex_pos.index < 0, Character::not_found());
+
//fit character in char texture
- CharTexture &tex = textures[tex_index];
+ CharTexture &tex = textures[tex_pos.index];
{
PoolVector<uint8_t>::Write wr = tex.imgdata.write();
@@ -560,23 +503,30 @@ 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;
- ERR_FAIL_COND(ofs >= tex.imgdata.size());
- switch (slot->bitmap.pixel_mode) {
+ int ofs = ((i + tex_pos.y + rect_margin) * tex.texture_size + j + tex_pos.x + rect_margin) * color_size;
+ ERR_FAIL_COND_V(ofs >= tex.imgdata.size(), Character::not_found());
+ switch (bitmap.pixel_mode) {
case FT_PIXEL_MODE_MONO: {
- int byte = i * slot->bitmap.pitch + (j >> 3);
+ int byte = i * bitmap.pitch + (j >> 3);
int bit = 1 << (7 - (j % 8));
wr[ofs + 0] = 255; //grayscale as 1
- wr[ofs + 1] = slot->bitmap.buffer[byte] & bit ? 255 : 0;
+ wr[ofs + 1] = bitmap.buffer[byte] & bit ? 255 : 0;
} break;
case FT_PIXEL_MODE_GRAY:
wr[ofs + 0] = 255; //grayscale as 1
- wr[ofs + 1] = slot->bitmap.buffer[i * slot->bitmap.pitch + j];
+ wr[ofs + 1] = bitmap.buffer[i * bitmap.pitch + j];
break;
- // TODO: FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_BGRA
+ case FT_PIXEL_MODE_BGRA: {
+ int ofs_color = i * bitmap.pitch + (j << 2);
+ wr[ofs + 2] = bitmap.buffer[ofs_color + 0];
+ wr[ofs + 1] = bitmap.buffer[ofs_color + 1];
+ wr[ofs + 0] = bitmap.buffer[ofs_color + 2];
+ wr[ofs + 3] = 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();
+ ERR_EXPLAIN("Font uses unsupported pixel format: " + itos(bitmap.pixel_mode));
+ ERR_FAIL_V(Character::not_found());
break;
}
}
@@ -586,7 +536,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();
@@ -598,41 +548,112 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
// update height array
- for (int k = tex_x; k < tex_x + mw; k++) {
-
- tex.offsets[k] = tex_y + mh;
+ for (int k = tex_pos.x; k < tex_pos.x + mw; k++) {
+ tex.offsets[k] = tex_pos.y + mh;
}
Character chr;
- chr.h_align = xofs / oversampling;
- chr.v_align = ascent - (yofs / oversampling); // + ascent - descent;
- chr.advance = advance / oversampling;
- chr.texture_idx = tex_index;
+ 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_pos.index;
chr.found = true;
- chr.rect_uv = Rect2(tex_x + rect_margin, tex_y + rect_margin, w, h);
+ chr.rect_uv = Rect2(tex_pos.x + rect_margin, tex_pos.y + rect_margin, w, h);
chr.rect = chr.rect_uv;
chr.rect.position /= oversampling;
- chr.rect.size /= oversampling;
+ chr.rect.size = chr.rect.size * scale_color_font / oversampling;
+ return chr;
+}
+
+DynamicFontAtSize::Character DynamicFontAtSize::_make_outline_char(CharType p_char) {
+ Character ret = Character::not_found();
+
+ if (FT_Load_Char(face, p_char, FT_LOAD_NO_BITMAP | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)) != 0)
+ return ret;
- //print_line("CHAR: "+String::chr(p_char)+" TEX INDEX: "+itos(tex_index)+" RECT: "+chr.rect+" X OFS: "+itos(xofs)+" Y OFS: "+itos(yofs));
+ FT_Stroker stroker;
+ if (FT_Stroker_New(library, &stroker) != 0)
+ return ret;
- char_map[p_char] = chr;
+ FT_Stroker_Set(stroker, (int)(id.outline_size * oversampling * 64.0), FT_STROKER_LINECAP_BUTT, FT_STROKER_LINEJOIN_ROUND, 0);
+ FT_Glyph glyph;
+ FT_BitmapGlyph glyph_bitmap;
+
+ if (FT_Get_Glyph(face->glyph, &glyph) != 0)
+ goto cleanup_stroker;
+ if (FT_Glyph_Stroke(&glyph, stroker, 1) != 0)
+ goto cleanup_glyph;
+ if (FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1) != 0)
+ goto cleanup_glyph;
+
+ glyph_bitmap = (FT_BitmapGlyph)glyph;
+ ret = _bitmap_to_character(glyph_bitmap->bitmap, glyph_bitmap->top, glyph_bitmap->left, glyph->advance.x / 65536.0);
+
+cleanup_glyph:
+ FT_Done_Glyph(glyph);
+cleanup_stroker:
+ FT_Stroker_Done(stroker);
+ return ret;
}
-bool DynamicFontAtSize::update_oversampling() {
- if (oversampling == font_oversampling)
- return false;
- if (!valid)
- return false;
+void DynamicFontAtSize::_update_char(CharType p_char) {
+
+ if (char_map.has(p_char))
+ return;
+
+ _THREAD_SAFE_METHOD_
+
+ Character character = Character::not_found();
+
+ FT_GlyphSlot slot = face->glyph;
+
+ if (FT_Get_Char_Index(face, p_char) == 0) {
+ char_map[p_char] = character;
+ return;
+ }
+
+ 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));
+ if (error) {
+ char_map[p_char] = character;
+ return;
+ }
+
+ if (id.outline_size > 0) {
+ character = _make_outline_char(p_char);
+ } else {
+ error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
+ if (!error)
+ character = _bitmap_to_character(slot->bitmap, slot->bitmap_top, slot->bitmap_left, slot->advance.x / 64.0);
+ }
+
+ char_map[p_char] = character;
+}
+
+void DynamicFontAtSize::update_oversampling() {
+ if (oversampling == font_oversampling || !valid)
+ return;
FT_Done_FreeType(library);
textures.clear();
char_map.clear();
oversampling = font_oversampling;
+ valid = false;
_load();
-
- return true;
}
DynamicFontAtSize::DynamicFontAtSize() {
@@ -644,14 +665,16 @@ DynamicFontAtSize::DynamicFontAtSize() {
linegap = 1;
texture_flags = 0;
oversampling = font_oversampling;
+ scale_color_font = 1;
}
DynamicFontAtSize::~DynamicFontAtSize() {
if (valid) {
FT_Done_FreeType(library);
- font->size_cache.erase(id);
}
+ font->size_cache.erase(id);
+ font.unref();
}
/////////////////////////
@@ -659,11 +682,27 @@ DynamicFontAtSize::~DynamicFontAtSize() {
void DynamicFont::_reload_cache() {
ERR_FAIL_COND(cache_id.size < 1);
- if (!data.is_valid())
+ if (!data.is_valid()) {
+ data_at_size.unref();
+ outline_data_at_size.unref();
+ fallback_data_at_size.resize(0);
+ fallback_outline_data_at_size.resize(0);
return;
+ }
+
data_at_size = data->_get_dynamic_font_at_size(cache_id);
+ if (outline_cache_id.outline_size > 0) {
+ outline_data_at_size = data->_get_dynamic_font_at_size(outline_cache_id);
+ fallback_outline_data_at_size.resize(fallback_data_at_size.size());
+ } else {
+ outline_data_at_size.unref();
+ fallback_outline_data_at_size.resize(0);
+ }
+
for (int i = 0; i < fallbacks.size(); i++) {
fallback_data_at_size[i] = fallbacks[i]->_get_dynamic_font_at_size(cache_id);
+ if (outline_cache_id.outline_size > 0)
+ fallback_outline_data_at_size[i] = fallbacks[i]->_get_dynamic_font_at_size(outline_cache_id);
}
emit_changed();
@@ -673,12 +712,10 @@ void DynamicFont::_reload_cache() {
void DynamicFont::set_font_data(const Ref<DynamicFontData> &p_data) {
data = p_data;
- if (data.is_valid())
- data_at_size = data->_get_dynamic_font_at_size(cache_id);
- else
- data_at_size = Ref<DynamicFontAtSize>();
+ _reload_cache();
emit_changed();
+ _change_notify();
}
Ref<DynamicFontData> DynamicFont::get_font_data() const {
@@ -691,6 +728,7 @@ void DynamicFont::set_size(int p_size) {
if (cache_id.size == p_size)
return;
cache_id.size = p_size;
+ outline_cache_id.size = p_size;
_reload_cache();
}
@@ -699,6 +737,30 @@ int DynamicFont::get_size() const {
return cache_id.size;
}
+void DynamicFont::set_outline_size(int p_size) {
+ if (outline_cache_id.outline_size == p_size)
+ return;
+ ERR_FAIL_COND(p_size < 0 || p_size > UINT8_MAX);
+ outline_cache_id.outline_size = p_size;
+ _reload_cache();
+}
+
+int DynamicFont::get_outline_size() const {
+ return outline_cache_id.outline_size;
+}
+
+void DynamicFont::set_outline_color(Color p_color) {
+ if (p_color != outline_color) {
+ outline_color = p_color;
+ emit_changed();
+ _change_notify();
+ }
+}
+
+Color DynamicFont::get_outline_color() const {
+ return outline_color;
+}
+
bool DynamicFont::get_use_mipmaps() const {
return cache_id.mipmaps;
@@ -709,6 +771,7 @@ void DynamicFont::set_use_mipmaps(bool p_enable) {
if (cache_id.mipmaps == p_enable)
return;
cache_id.mipmaps = p_enable;
+ outline_cache_id.mipmaps = p_enable;
_reload_cache();
}
@@ -722,9 +785,22 @@ void DynamicFont::set_use_filter(bool p_enable) {
if (cache_id.filter == p_enable)
return;
cache_id.filter = p_enable;
+ outline_cache_id.filter = 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) {
@@ -799,13 +875,24 @@ 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) const {
+bool DynamicFont::has_outline() const {
+ return outline_cache_id.outline_size > 0;
+}
+
+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 {
+ const Ref<DynamicFontAtSize> &font_at_size = p_outline && outline_cache_id.outline_size > 0 ? outline_data_at_size : data_at_size;
- if (!data_at_size.is_valid())
+ if (!font_at_size.is_valid())
return 0;
- return data_at_size->draw_char(p_canvas_item, p_pos, p_char, p_next, p_modulate, fallback_data_at_size) + spacing_char;
+ const Vector<Ref<DynamicFontAtSize> > &fallbacks = p_outline && outline_cache_id.outline_size > 0 ? fallback_outline_data_at_size : fallback_data_at_size;
+ Color color = p_outline && outline_cache_id.outline_size > 0 ? p_modulate * outline_color : p_modulate;
+
+ // If requested outline draw, but no outline is present, simply return advance without drawing anything
+ bool advance_only = p_outline && outline_cache_id.outline_size == 0;
+ return font_at_size->draw_char(p_canvas_item, p_pos, p_char, p_next, color, fallbacks, advance_only) + spacing_char;
}
+
void DynamicFont::set_fallback(int p_idx, const Ref<DynamicFontData> &p_data) {
ERR_FAIL_COND(p_data.is_null());
@@ -819,6 +906,8 @@ void DynamicFont::add_fallback(const Ref<DynamicFontData> &p_data) {
ERR_FAIL_COND(p_data.is_null());
fallbacks.push_back(p_data);
fallback_data_at_size.push_back(fallbacks[fallbacks.size() - 1]->_get_dynamic_font_at_size(cache_id)); //const..
+ if (outline_cache_id.outline_size > 0)
+ fallback_outline_data_at_size.push_back(fallbacks[fallbacks.size() - 1]->_get_dynamic_font_at_size(outline_cache_id));
_change_notify();
emit_changed();
@@ -903,6 +992,12 @@ void DynamicFont::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_size", "data"), &DynamicFont::set_size);
ClassDB::bind_method(D_METHOD("get_size"), &DynamicFont::get_size);
+ ClassDB::bind_method(D_METHOD("set_outline_size", "size"), &DynamicFont::set_outline_size);
+ ClassDB::bind_method(D_METHOD("get_outline_size"), &DynamicFont::get_outline_size);
+
+ ClassDB::bind_method(D_METHOD("set_outline_color", "color"), &DynamicFont::set_outline_color);
+ ClassDB::bind_method(D_METHOD("get_outline_color"), &DynamicFont::get_outline_color);
+
ClassDB::bind_method(D_METHOD("set_use_mipmaps", "enable"), &DynamicFont::set_use_mipmaps);
ClassDB::bind_method(D_METHOD("get_use_mipmaps"), &DynamicFont::get_use_mipmaps);
ClassDB::bind_method(D_METHOD("set_use_filter", "enable"), &DynamicFont::set_use_filter);
@@ -918,6 +1013,8 @@ void DynamicFont::_bind_methods() {
ADD_GROUP("Settings", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "size"), "set_size", "get_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size"), "set_outline_size", "get_outline_size");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_color"), "set_outline_color", "get_outline_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_mipmaps"), "set_use_mipmaps", "get_use_mipmaps");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_filter"), "set_use_filter", "get_use_filter");
ADD_GROUP("Extra Spacing", "extra_spacing");
@@ -945,6 +1042,7 @@ DynamicFont::DynamicFont() :
spacing_bottom = 0;
spacing_char = 0;
spacing_space = 0;
+ outline_color = Color(1, 1, 1);
if (dynamic_font_mutex)
dynamic_font_mutex->lock();
dynamic_fonts.add(&font_list);
@@ -972,14 +1070,27 @@ void DynamicFont::finish_dynamic_fonts() {
void DynamicFont::update_oversampling() {
+ Vector<Ref<DynamicFont> > changed;
+
+ if (dynamic_font_mutex)
+ dynamic_font_mutex->lock();
+
SelfList<DynamicFont> *E = dynamic_fonts.first();
while (E) {
- if (E->self()->data_at_size.is_valid() && E->self()->data_at_size->update_oversampling()) {
- E->self()->emit_changed();
+ if (E->self()->data_at_size.is_valid()) {
+ E->self()->data_at_size->update_oversampling();
+ changed.push_back(Ref<DynamicFont>(E->self()));
}
E = E->next();
}
+
+ if (dynamic_font_mutex)
+ dynamic_font_mutex->unlock();
+
+ for (int i = 0; i < changed.size(); i++) {
+ changed[i]->emit_changed();
+ }
}
/////////////////////////
diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h
index 1a890dd65d..f460bca2d4 100644
--- a/scene/resources/dynamic_font.h
+++ b/scene/resources/dynamic_font.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef DYNAMIC_FONT_H
#define DYNAMIC_FONT_H
@@ -34,6 +35,7 @@
#include "io/resource_loader.h"
#include "os/mutex.h"
#include "os/thread_safe.h"
+#include "pair.h"
#include "scene/resources/font.h"
#include <ft2build.h>
@@ -48,23 +50,35 @@ class DynamicFontData : public Resource {
public:
struct CacheID {
-
- int size;
- bool mipmaps;
- bool filter;
-
+ union {
+ struct {
+ uint32_t size : 16;
+ uint32_t outline_size : 8;
+ bool mipmaps : 1;
+ bool filter : 1;
+ };
+ uint32_t key;
+ };
bool operator<(CacheID right) const;
CacheID() {
- size = 16;
- mipmaps = false;
- filter = false;
+ key = 0;
}
};
+ 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;
@@ -88,6 +102,8 @@ public:
~DynamicFontData();
};
+VARIANT_ENUM_CAST(DynamicFontData::Hinting);
+
class DynamicFontAtSize : public Reference {
GDCLASS(DynamicFontAtSize, Reference)
@@ -103,6 +119,7 @@ class DynamicFontAtSize : public Reference {
float linegap;
float rect_margin;
float oversampling;
+ float scale_color_font;
uint32_t texture_flags;
@@ -132,8 +149,22 @@ class DynamicFontAtSize : public Reference {
texture_idx = 0;
v_align = 0;
}
+
+ static Character not_found();
};
+ struct TexturePosition {
+ int index;
+ int x;
+ int y;
+ };
+
+ const Pair<const Character *, DynamicFontAtSize *> _find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const;
+ Character _make_outline_char(CharType p_char);
+ float _get_kerning_advance(const DynamicFontAtSize *font, CharType p_char, CharType p_next) const;
+ TexturePosition _find_texture_pos_for_glyph(int p_color_size, Image::Format p_image_format, int p_width, int p_height);
+ Character _bitmap_to_character(FT_Bitmap bitmap, int yofs, int xofs, float advance);
+
static unsigned long _ft_stream_io(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count);
static void _ft_stream_close(FT_Stream stream);
@@ -158,10 +189,10 @@ public:
Size2 get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const;
- float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const;
+ float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks, bool p_advance_only = false) const;
void set_texture_flags(uint32_t p_flags);
- bool update_oversampling();
+ void update_oversampling();
DynamicFontAtSize();
~DynamicFontAtSize();
@@ -184,17 +215,23 @@ public:
private:
Ref<DynamicFontData> data;
Ref<DynamicFontAtSize> data_at_size;
+ Ref<DynamicFontAtSize> outline_data_at_size;
Vector<Ref<DynamicFontData> > fallbacks;
Vector<Ref<DynamicFontAtSize> > fallback_data_at_size;
+ Vector<Ref<DynamicFontAtSize> > fallback_outline_data_at_size;
DynamicFontData::CacheID cache_id;
+ DynamicFontData::CacheID outline_cache_id;
+
bool valid;
int spacing_top;
int spacing_bottom;
int spacing_char;
int spacing_space;
+ Color outline_color;
+
protected:
void _reload_cache();
@@ -211,6 +248,12 @@ public:
void set_size(int p_size);
int get_size() const;
+ void set_outline_size(int p_size);
+ int get_outline_size() const;
+
+ void set_outline_color(Color p_color);
+ Color get_outline_color() const;
+
bool get_use_mipmaps() const;
void set_use_mipmaps(bool p_enable);
@@ -235,7 +278,9 @@ public:
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)) const;
+ virtual bool has_outline() 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;
SelfList<DynamicFont> font_list;
diff --git a/scene/resources/dynamic_font_stb.cpp b/scene/resources/dynamic_font_stb.cpp
index 70495e9bbf..29f1106d16 100644
--- a/scene/resources/dynamic_font_stb.cpp
+++ b/scene/resources/dynamic_font_stb.cpp
@@ -27,6 +27,7 @@
/* 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
@@ -161,7 +162,7 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next) const {
return ret;
}
-float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate) const {
+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);
@@ -171,13 +172,15 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT
return 0;
}
- 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);
+ 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());
@@ -458,12 +461,12 @@ 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) const {
+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);
+ return data_at_size->draw_char(p_canvas_item, p_pos, p_char, p_next, p_modulate, p_outline);
}
DynamicFont::DynamicFont() {
diff --git a/scene/resources/dynamic_font_stb.h b/scene/resources/dynamic_font_stb.h
index 3d4ad4389c..feae29c0c2 100644
--- a/scene/resources/dynamic_font_stb.h
+++ b/scene/resources/dynamic_font_stb.h
@@ -27,6 +27,7 @@
/* 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
@@ -135,7 +136,7 @@ public:
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)) 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();
@@ -170,7 +171,7 @@ public:
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)) 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();
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 6216893667..3fab4d3cfc 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "environment.h"
#include "project_settings.h"
#include "servers/visual_server.h"
@@ -269,19 +270,19 @@ void Environment::_validate_property(PropertyInfo &property) const {
if (property.name == "background_sky" || property.name == "background_sky_custom_fov" || property.name == "ambient_light/sky_contribution") {
if (bg_mode != BG_SKY && bg_mode != BG_COLOR_SKY) {
- property.usage = PROPERTY_USAGE_NOEDITOR;
+ property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
}
}
if (property.name == "background_color") {
if (bg_mode != BG_COLOR && bg_mode != BG_COLOR_SKY) {
- property.usage = PROPERTY_USAGE_NOEDITOR;
+ property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
}
}
if (property.name == "background_canvas_max_layer") {
if (bg_mode != BG_CANVAS) {
- property.usage = PROPERTY_USAGE_NOEDITOR;
+ property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
}
}
@@ -304,7 +305,7 @@ void Environment::_validate_property(PropertyInfo &property) const {
String enabled = prefix + "enabled";
if (property.name.begins_with(prefix) && property.name != enabled && !bool(get(enabled))) {
- property.usage = PROPERTY_USAGE_NOEDITOR;
+ property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
return;
}
@@ -1218,7 +1219,7 @@ Environment::Environment() {
ssao_radius2 = 0;
ssao_intensity2 = 1;
ssao_bias = 0.01;
- ssao_direct_light_affect = false;
+ ssao_direct_light_affect = 0.0;
ssao_blur = SSAO_BLUR_3x3;
set_ssao_edge_sharpness(4);
set_ssao_quality(SSAO_QUALITY_LOW);
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index 9e2461a2ce..27fd57aa09 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef ENVIRONMENT_H
#define ENVIRONMENT_H
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 7b4bd273bd..0bae9d9b2d 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -27,16 +27,17 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "font.h"
#include "core/io/resource_loader.h"
#include "core/os/file_access.h"
+#include "method_bind_ext.gen.inc"
-void Font::draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, float p_width, const String &p_text, const Color &p_modulate) const {
-
+void Font::draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, float p_width, const String &p_text, const Color &p_modulate, const Color &p_outline_modulate) const {
float length = get_string_size(p_text).width;
if (length >= p_width) {
- draw(p_canvas_item, p_pos, p_text, p_modulate, p_width);
+ draw(p_canvas_item, p_pos, p_text, p_modulate, p_width, p_outline_modulate);
return;
}
@@ -55,13 +56,14 @@ void Font::draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, f
ERR_PRINT("Unknown halignment type");
} break;
}
- draw(p_canvas_item, p_pos + Point2(ofs, 0), p_text, p_modulate, p_width);
+ draw(p_canvas_item, p_pos + Point2(ofs, 0), p_text, p_modulate, p_width, p_outline_modulate);
}
-void Font::draw(RID p_canvas_item, const Point2 &p_pos, const String &p_text, const Color &p_modulate, int p_clip_w) const {
-
+void Font::draw(RID p_canvas_item, const Point2 &p_pos, const String &p_text, const Color &p_modulate, int p_clip_w, const Color &p_outline_modulate) const {
Vector2 ofs;
+ int chars_drawn = 0;
+ bool with_outline = has_outline();
for (int i = 0; i < p_text.length(); i++) {
int width = get_char_size(p_text[i]).width;
@@ -69,7 +71,15 @@ void Font::draw(RID p_canvas_item, const Point2 &p_pos, const String &p_text, co
if (p_clip_w >= 0 && (ofs.x + width) > p_clip_w)
break; //clip
- ofs.x += draw_char(p_canvas_item, p_pos + ofs, p_text[i], p_text[i + 1], p_modulate);
+ ofs.x += draw_char(p_canvas_item, p_pos + ofs, p_text[i], p_text[i + 1], with_outline ? p_outline_modulate : p_modulate, with_outline);
+ ++chars_drawn;
+ }
+
+ if (has_outline()) {
+ ofs = Vector2(0, 0);
+ for (int i = 0; i < chars_drawn; i++) {
+ ofs.x += draw_char(p_canvas_item, p_pos + ofs, p_text[i], p_text[i + 1], p_modulate, false);
+ }
}
}
@@ -80,13 +90,14 @@ void Font::update_changes() {
void Font::_bind_methods() {
- ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "string", "modulate", "clip_w"), &Font::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "string", "modulate", "clip_w", "outline_modulate"), &Font::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(-1), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("get_ascent"), &Font::get_ascent);
ClassDB::bind_method(D_METHOD("get_descent"), &Font::get_descent);
ClassDB::bind_method(D_METHOD("get_height"), &Font::get_height);
ClassDB::bind_method(D_METHOD("is_distance_field_hint"), &Font::is_distance_field_hint);
ClassDB::bind_method(D_METHOD("get_string_size", "string"), &Font::get_string_size);
- ClassDB::bind_method(D_METHOD("draw_char", "canvas_item", "position", "char", "next", "modulate"), &Font::draw_char, DEFVAL(-1), DEFVAL(Color(1, 1, 1)));
+ ClassDB::bind_method(D_METHOD("has_outline"), &Font::has_outline);
+ ClassDB::bind_method(D_METHOD("draw_char", "canvas_item", "position", "char", "next", "modulate", "outline"), &Font::draw_char, DEFVAL(-1), DEFVAL(Color(1, 1, 1)), DEFVAL(false));
ClassDB::bind_method(D_METHOD("update_changes"), &Font::update_changes);
}
@@ -493,23 +504,24 @@ Ref<BitmapFont> BitmapFont::get_fallback() const {
return fallback;
}
-float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate) const {
+float BitmapFont::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 Character *c = char_map.getptr(p_char);
if (!c) {
if (fallback.is_valid())
- return fallback->draw_char(p_canvas_item, p_pos, p_char, p_next, p_modulate);
+ return fallback->draw_char(p_canvas_item, p_pos, p_char, p_next, p_modulate, p_outline);
return 0;
}
- Point2 cpos = p_pos;
- cpos.x += c->h_align;
- cpos.y -= 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)
+ if (!p_outline && c->texture_idx != -1) {
+ Point2 cpos = p_pos;
+ cpos.x += c->h_align;
+ cpos.y -= ascent;
+ cpos.y += c->v_align;
VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, c->rect.size), textures[c->texture_idx]->get_rid(), c->rect, p_modulate, false, RID(), false);
+ }
return get_char_size(p_char, p_next).width;
}
@@ -576,9 +588,9 @@ void BitmapFont::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_fallback", "fallback"), &BitmapFont::set_fallback);
ClassDB::bind_method(D_METHOD("get_fallback"), &BitmapFont::get_fallback);
- ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "textures", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_textures", "_get_textures");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "chars", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_chars", "_get_chars");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "kernings", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_kernings", "_get_kernings");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "textures", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_textures", "_get_textures");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "chars", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_chars", "_get_chars");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "kernings", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_kernings", "_get_kernings");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "-1024,1024,1"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ascent", PROPERTY_HINT_RANGE, "-1024,1024,1"), "set_ascent", "get_ascent");
@@ -595,3 +607,42 @@ BitmapFont::~BitmapFont() {
clear();
}
+
+////////////
+
+RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error) {
+
+ if (r_error)
+ *r_error = ERR_FILE_CANT_OPEN;
+
+ Ref<BitmapFont> font;
+ font.instance();
+
+ Error err = font->create_from_fnt(p_path);
+
+ if (err) {
+ if (r_error)
+ *r_error = err;
+ return RES();
+ }
+
+ return font;
+}
+
+void ResourceFormatLoaderBMFont::get_recognized_extensions(List<String> *p_extensions) const {
+
+ p_extensions->push_back("fnt");
+}
+
+bool ResourceFormatLoaderBMFont::handles_type(const String &p_type) const {
+
+ return (p_type == "BitmapFont");
+}
+
+String ResourceFormatLoaderBMFont::get_resource_type(const String &p_path) const {
+
+ String el = p_path.get_extension().to_lower();
+ if (el == "fnt")
+ return "BitmapFont";
+ return "";
+}
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 5eaf82d6bc..4e295b6035 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef FONT_H
#define FONT_H
@@ -55,14 +56,55 @@ public:
virtual bool is_distance_field_hint() const = 0;
- void draw(RID p_canvas_item, const Point2 &p_pos, const String &p_text, const Color &p_modulate = Color(1, 1, 1), int p_clip_w = -1) const;
- void draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, float p_width, const String &p_text, const Color &p_modulate = Color(1, 1, 1)) 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)) const = 0;
+ void draw(RID p_canvas_item, const Point2 &p_pos, const String &p_text, const Color &p_modulate = Color(1, 1, 1), int p_clip_w = -1, const Color &p_outline_modulate = Color(1, 1, 1)) const;
+ void draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, float p_width, const String &p_text, const Color &p_modulate = Color(1, 1, 1), const Color &p_outline_modulate = Color(1, 1, 1)) const;
+
+ virtual bool has_outline() const { return false; }
+ 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 = 0;
void update_changes();
Font();
};
+// Helper class to that draws outlines immediately and draws characters in its destructor.
+class FontDrawer {
+ const Ref<Font> &font;
+ Color outline_color;
+ bool has_outline;
+
+ struct PendingDraw {
+ RID canvas_item;
+ Point2 pos;
+ CharType chr;
+ CharType next;
+ Color modulate;
+ };
+
+ Vector<PendingDraw> pending_draws;
+
+public:
+ FontDrawer(const Ref<Font> &p_font, const Color &p_outline_color) :
+ font(p_font),
+ outline_color(p_outline_color) {
+ has_outline = p_font->has_outline();
+ }
+
+ 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)) {
+ if (has_outline) {
+ PendingDraw draw = { p_canvas_item, p_pos, p_char, p_next, p_modulate };
+ pending_draws.push_back(draw);
+ }
+ return font->draw_char(p_canvas_item, p_pos, p_char, p_next, has_outline ? outline_color : p_modulate, has_outline);
+ }
+
+ ~FontDrawer() {
+ for (int i = 0; i < pending_draws.size(); ++i) {
+ const PendingDraw &draw = pending_draws[i];
+ font->draw_char(draw.canvas_item, draw.pos, draw.chr, draw.next, draw.modulate, false);
+ }
+ }
+};
+
class BitmapFont : public Font {
GDCLASS(BitmapFont, Font);
@@ -152,10 +194,18 @@ public:
void set_distance_field_hint(bool p_distance_field);
bool is_distance_field_hint() 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)) 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;
BitmapFont();
~BitmapFont();
};
+class ResourceFormatLoaderBMFont : public ResourceFormatLoader {
+public:
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual bool handles_type(const String &p_type) const;
+ virtual String get_resource_type(const String &p_path) const;
+};
+
#endif
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 4e3991b573..1282ce767a 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "material.h"
#include "scene/scene_string_names.h"
@@ -102,25 +103,19 @@ Material::~Material() {
bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
- if (p_name == SceneStringNames::get_singleton()->shader) {
- set_shader(p_value);
- return true;
- } else {
-
- if (shader.is_valid()) {
+ if (shader.is_valid()) {
- StringName pr = shader->remap_param(p_name);
- if (!pr) {
- String n = p_name;
- if (n.find("param/") == 0) { //backwards compatibility
- pr = n.substr(6, n.length());
- }
- }
- if (pr) {
- VisualServer::get_singleton()->material_set_param(_get_material(), pr, p_value);
- return true;
+ StringName pr = shader->remap_param(p_name);
+ if (!pr) {
+ String n = p_name;
+ if (n.find("param/") == 0) { //backwards compatibility
+ pr = n.substr(6, n.length());
}
}
+ if (pr) {
+ VisualServer::get_singleton()->material_set_param(_get_material(), pr, p_value);
+ return true;
+ }
}
return false;
@@ -128,20 +123,12 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
- if (p_name == SceneStringNames::get_singleton()->shader) {
-
- r_ret = get_shader();
- return true;
-
- } else {
-
- if (shader.is_valid()) {
+ if (shader.is_valid()) {
- StringName pr = shader->remap_param(p_name);
- if (pr) {
- r_ret = VisualServer::get_singleton()->material_get_param(_get_material(), pr);
- return true;
- }
+ StringName pr = shader->remap_param(p_name);
+ if (pr) {
+ r_ret = VisualServer::get_singleton()->material_get_param(_get_material(), pr);
+ return true;
}
}
@@ -150,8 +137,6 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "shader", PROPERTY_HINT_RESOURCE_TYPE, "Shader,ShaderGraph"));
-
if (!shader.is_null()) {
shader->get_param_list(p_list);
@@ -192,6 +177,8 @@ void ShaderMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_shader"), &ShaderMaterial::get_shader);
ClassDB::bind_method(D_METHOD("set_shader_param", "param", "value"), &ShaderMaterial::set_shader_param);
ClassDB::bind_method(D_METHOD("get_shader_param", "param"), &ShaderMaterial::get_shader_param);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shader", PROPERTY_HINT_RESOURCE_TYPE, "Shader"), "set_shader", "get_shader");
}
void ShaderMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
@@ -400,10 +387,12 @@ void SpatialMaterial::_update_shader() {
if (flags[FLAG_USE_VERTEX_LIGHTING]) {
code += ",vertex_lighting";
}
-
if (flags[FLAG_TRIPLANAR_USE_WORLD] && (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR])) {
code += ",world_vertex_coords";
}
+ if (flags[FLAG_DONT_RECEIVE_SHADOWS]) {
+ code += ",shadows_disabled";
+ }
code += ";\n";
code += "uniform vec4 albedo : hint_color;\n";
@@ -750,15 +739,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";
@@ -1492,9 +1484,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 {
@@ -1859,6 +1851,7 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_world_triplanar"), "set_flag", "get_flag", FLAG_TRIPLANAR_USE_WORLD);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_albedo_tex_force_srgb"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_do_not_receive_shadows"), "set_flag", "get_flag", FLAG_DONT_RECEIVE_SHADOWS);
ADD_GROUP("Vertex Color", "vertex_color");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_use_as_albedo"), "set_flag", "get_flag", FLAG_ALBEDO_FROM_VERTEX_COLOR);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_is_srgb"), "set_flag", "get_flag", FLAG_SRGB_VERTEX_COLOR);
@@ -2048,6 +2041,7 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_USE_ALPHA_SCISSOR);
BIND_ENUM_CONSTANT(FLAG_TRIPLANAR_USE_WORLD);
BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
+ BIND_ENUM_CONSTANT(FLAG_DONT_RECEIVE_SHADOWS);
BIND_ENUM_CONSTANT(FLAG_MAX);
BIND_ENUM_CONSTANT(DIFFUSE_BURLEY);
@@ -2140,7 +2134,7 @@ SpatialMaterial::SpatialMaterial() :
for (int i = 0; i < FLAG_MAX; i++) {
flags[i] = 0;
}
- diffuse_mode = DIFFUSE_LAMBERT;
+ diffuse_mode = DIFFUSE_BURLEY;
specular_mode = SPECULAR_SCHLICK_GGX;
for (int i = 0; i < FEATURE_MAX; i++) {
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 9ce1765e62..ce733bfb8d 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef MATERIAL_H
#define MATERIAL_H
@@ -187,6 +188,7 @@ public:
FLAG_EMISSION_ON_UV2,
FLAG_USE_ALPHA_SCISSOR,
FLAG_ALBEDO_TEXTURE_FORCE_SRGB,
+ FLAG_DONT_RECEIVE_SHADOWS,
FLAG_MAX
};
@@ -235,7 +237,7 @@ private:
uint64_t blend_mode : 2;
uint64_t depth_draw_mode : 2;
uint64_t cull_mode : 2;
- uint64_t flags : 14;
+ uint64_t flags : 15;
uint64_t detail_blend_mode : 2;
uint64_t diffuse_mode : 3;
uint64_t specular_mode : 2;
@@ -565,7 +567,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/mesh.cpp b/scene/resources/mesh.cpp
index dc726adf86..d87644381c 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "mesh.h"
#include "pair.h"
@@ -314,6 +315,8 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
}
}
+ ERR_FAIL_COND_V(arrays.size() != ARRAY_MAX, Ref<ArrayMesh>());
+
{
PoolVector<int>::Write ir;
PoolVector<int> indices = arrays[ARRAY_INDEX];
@@ -558,12 +561,6 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
return true;
}
- if (sname == "custom_aabb/custom_aabb") {
-
- set_custom_aabb(p_value);
- return true;
- }
-
if (!sname.begins_with("surfaces"))
return false;
@@ -672,11 +669,6 @@ bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const {
else if (what == "name")
r_ret = surface_get_name(idx);
return true;
- } else if (sname == "custom_aabb/custom_aabb") {
-
- r_ret = custom_aabb;
- return true;
-
} else if (!sname.begins_with("surfaces"))
return false;
@@ -727,13 +719,13 @@ void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const {
return;
if (blend_shapes.size()) {
- p_list->push_back(PropertyInfo(Variant::POOL_STRING_ARRAY, "blend_shape/names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::POOL_STRING_ARRAY, "blend_shape/names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::INT, "blend_shape/mode", PROPERTY_HINT_ENUM, "Normalized,Relative"));
}
for (int i = 0; i < surfaces.size(); i++) {
- p_list->push_back(PropertyInfo(Variant::DICTIONARY, "surfaces/" + itos(i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::DICTIONARY, "surfaces/" + itos(i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::STRING, "surface_" + itos(i + 1) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
if (surfaces[i].is_2d) {
p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,CanvasItemMaterial", PROPERTY_USAGE_EDITOR));
@@ -741,8 +733,6 @@ void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,SpatialMaterial", PROPERTY_USAGE_EDITOR));
}
}
-
- p_list->push_back(PropertyInfo(Variant::AABB, "custom_aabb/custom_aabb"));
}
void ArrayMesh::_recompute_aabb() {
@@ -922,6 +912,7 @@ void ArrayMesh::surface_set_material(int p_idx, const Ref<Material> &p_material)
VisualServer::get_singleton()->mesh_surface_set_material(mesh, p_idx, p_material.is_null() ? RID() : p_material->get_rid());
_change_notify("material");
+ emit_changed();
}
void ArrayMesh::surface_set_name(int p_idx, const String &p_name) {
@@ -929,6 +920,7 @@ void ArrayMesh::surface_set_name(int p_idx, const String &p_name) {
ERR_FAIL_INDEX(p_idx, surfaces.size());
surfaces[p_idx].name = p_name;
+ emit_changed();
}
String ArrayMesh::surface_get_name(int p_idx) const {
@@ -941,6 +933,7 @@ void ArrayMesh::surface_update_region(int p_surface, int p_offset, const PoolVec
ERR_FAIL_INDEX(p_surface, surfaces.size());
VS::get_singleton()->mesh_surface_update_region(mesh, p_surface, p_offset, p_data);
+ emit_changed();
}
void ArrayMesh::surface_set_custom_aabb(int p_idx, const AABB &p_aabb) {
@@ -948,6 +941,7 @@ void ArrayMesh::surface_set_custom_aabb(int p_idx, const AABB &p_aabb) {
ERR_FAIL_INDEX(p_idx, surfaces.size());
surfaces[p_idx].aabb = p_aabb;
// set custom aabb too?
+ emit_changed();
}
Ref<Material> ArrayMesh::surface_get_material(int p_idx) const {
@@ -996,6 +990,7 @@ void ArrayMesh::set_custom_aabb(const AABB &p_custom) {
custom_aabb = p_custom;
VS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb);
+ emit_changed();
}
AABB ArrayMesh::get_custom_aabb() const {
@@ -1279,12 +1274,17 @@ void ArrayMesh::_bind_methods() {
ClassDB::set_method_flags(get_class_static(), _scs_create("center_geometry"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ClassDB::bind_method(D_METHOD("regen_normalmaps"), &ArrayMesh::regen_normalmaps);
ClassDB::set_method_flags(get_class_static(), _scs_create("regen_normalmaps"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
+ ClassDB::bind_method(D_METHOD("lightmap_unwrap"), &ArrayMesh::lightmap_unwrap);
+ ClassDB::set_method_flags(get_class_static(), _scs_create("lightmap_unwrap"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ClassDB::bind_method(D_METHOD("get_faces"), &ArrayMesh::get_faces);
ClassDB::bind_method(D_METHOD("generate_triangle_mesh"), &ArrayMesh::generate_triangle_mesh);
ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &ArrayMesh::set_custom_aabb);
ClassDB::bind_method(D_METHOD("get_custom_aabb"), &ArrayMesh::get_custom_aabb);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative", PROPERTY_USAGE_NOEDITOR), "set_blend_shape_mode", "get_blend_shape_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb");
+
BIND_CONSTANT(NO_INDEX_ARRAY);
BIND_CONSTANT(ARRAY_WEIGHTS_SIZE);
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 98d9edd48b..e8b7ecaf9a 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef MESH_H
#define MESH_H
diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp
index 2854d45b52..8639b325c3 100644
--- a/scene/resources/mesh_data_tool.cpp
+++ b/scene/resources/mesh_data_tool.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "mesh_data_tool.h"
void MeshDataTool::clear() {
diff --git a/scene/resources/mesh_data_tool.h b/scene/resources/mesh_data_tool.h
index fde6e5a46e..f614b80c3b 100644
--- a/scene/resources/mesh_data_tool.h
+++ b/scene/resources/mesh_data_tool.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef MESH_DATA_TOOL_H
#define MESH_DATA_TOOL_H
diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp
index adf646f2d9..e1d3540fd1 100644
--- a/scene/resources/mesh_library.cpp
+++ b/scene/resources/mesh_library.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "mesh_library.h"
bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) {
diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h
index a0bcfec2b6..69719960e2 100644
--- a/scene/resources/mesh_library.h
+++ b/scene/resources/mesh_library.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef GRID_THEME_H
#define GRID_THEME_H
diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp
index a89b1c7342..4d0a14e3aa 100644
--- a/scene/resources/multimesh.cpp
+++ b/scene/resources/multimesh.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "multimesh.h"
#include "servers/visual_server.h"
@@ -210,8 +211,8 @@ void MultiMesh::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_format", PROPERTY_HINT_ENUM, "2D,3D"), "set_transform_format", "get_transform_format");
ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1"), "set_instance_count", "get_instance_count");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_transform_array", "_get_transform_array");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "color_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_color_array", "_get_color_array");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_transform_array", "_get_transform_array");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "color_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_color_array", "_get_color_array");
BIND_ENUM_CONSTANT(TRANSFORM_2D);
BIND_ENUM_CONSTANT(TRANSFORM_3D);
diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h
index f84d0c77c6..0875d6d06d 100644
--- a/scene/resources/multimesh.h
+++ b/scene/resources/multimesh.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef MULTIMESH_H
#define MULTIMESH_H
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 9dc29151d5..846f6e356e 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "packed_scene.h"
#include "core/core_string_names.h"
@@ -234,6 +235,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
if (p_edit_state == GEN_EDIT_STATE_MAIN) {
//for the main scene, use the resource as is
res->configure_for_local_scene(base, resources_local_to_scene);
+ resources_local_to_scene[res] = res;
} else {
//for instances, a copy must be made
@@ -243,13 +245,12 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
res = local_dupe;
value = local_dupe;
}
-
- //this here may reference nodes not iniialized so this line is commented and used after loading all nodes
- //res->setup_local_to_scene();
}
//must make a copy, because this res is local to scene
}
}
+ } else if (p_edit_state == GEN_EDIT_STATE_INSTANCE) {
+ value = value.duplicate(true); // Duplicate arrays and dictionaries for the editor
}
node->set(snames[nprops[j].name], value, &valid);
}
@@ -1120,7 +1121,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
uint32_t name_index = r[idx++];
nd.name = name_index & ((1 << NAME_INDEX_BITS) - 1);
nd.index = (name_index >> NAME_INDEX_BITS);
- nd.index--; //0 is invaild, stored as 1
+ nd.index--; //0 is invalid, stored as 1
nd.instance = r[idx++];
nd.properties.resize(r[idx++]);
for (int j = 0; j < nd.properties.size(); j++) {
@@ -1213,7 +1214,7 @@ Dictionary SceneState::get_bundled_scene() const {
rnodes.push_back(nd.owner);
rnodes.push_back(nd.type);
uint32_t name_index = nd.name;
- if (nd.index < (1 << (32 - NAME_INDEX_BITS)) - 1) { //save if less than 16k childs
+ if (nd.index < (1 << (32 - NAME_INDEX_BITS)) - 1) { //save if less than 16k children
name_index |= uint32_t(nd.index + 1) << NAME_INDEX_BITS; //for backwards compatibility, index 0 is no index
}
rnodes.push_back(name_index);
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index 01035863d9..278986eb62 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef PACKED_SCENE_H
#define PACKED_SCENE_H
diff --git a/scene/resources/plane_shape.cpp b/scene/resources/plane_shape.cpp
index 881ecc616e..4d38ebe090 100644
--- a/scene/resources/plane_shape.cpp
+++ b/scene/resources/plane_shape.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "plane_shape.h"
#include "servers/physics_server.h"
diff --git a/scene/resources/plane_shape.h b/scene/resources/plane_shape.h
index 3225a614e5..c24c9474fb 100644
--- a/scene/resources/plane_shape.h
+++ b/scene/resources/plane_shape.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef PLANE_SHAPE_H
#define PLANE_SHAPE_H
diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp
index f26ec5e0a8..6fea2e1a8e 100644
--- a/scene/resources/polygon_path_finder.cpp
+++ b/scene/resources/polygon_path_finder.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "polygon_path_finder.h"
#include "geometry.h"
@@ -588,7 +589,7 @@ void PolygonPathFinder::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_data"), &PolygonPathFinder::_set_data);
ClassDB::bind_method(D_METHOD("_get_data"), &PolygonPathFinder::_get_data);
- ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
}
PolygonPathFinder::PolygonPathFinder() {
diff --git a/scene/resources/polygon_path_finder.h b/scene/resources/polygon_path_finder.h
index 960e6739d6..19761c274c 100644
--- a/scene/resources/polygon_path_finder.h
+++ b/scene/resources/polygon_path_finder.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef POLYGON_PATH_FINDER_H
#define POLYGON_PATH_FINDER_H
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 94ce3590d7..e0562d9e4a 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -57,6 +57,31 @@ void PrimitiveMesh::_update() const {
}
}
+ if (flip_faces) {
+ PoolVector<Vector3> normals = arr[VS::ARRAY_NORMAL];
+ PoolVector<int> indices = arr[VS::ARRAY_INDEX];
+ if (normals.size() && indices.size()) {
+
+ {
+ int nc = normals.size();
+ PoolVector<Vector3>::Write w = normals.write();
+ for (int i = 0; i < nc; i++) {
+ w[i] = -w[i];
+ }
+ }
+
+ {
+ int ic = indices.size();
+ PoolVector<int>::Write w = indices.write();
+ for (int i = 0; i < ic; i += 3) {
+ SWAP(w[i + 0], w[i + 1]);
+ }
+ }
+ arr[VS::ARRAY_NORMAL] = normals;
+ arr[VS::ARRAY_INDEX] = indices;
+ }
+ }
+
// in with the new
VisualServer::get_singleton()->mesh_clear(mesh);
VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)primitive_type, arr);
@@ -65,6 +90,8 @@ void PrimitiveMesh::_update() const {
pending_request = false;
_clear_triangle_mesh();
+
+ const_cast<PrimitiveMesh *>(this)->emit_changed();
}
void PrimitiveMesh::_request_update() {
@@ -164,7 +191,15 @@ void PrimitiveMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_mesh_arrays"), &PrimitiveMesh::get_mesh_arrays);
+ ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &PrimitiveMesh::set_custom_aabb);
+ ClassDB::bind_method(D_METHOD("get_custom_aabb"), &PrimitiveMesh::get_custom_aabb);
+
+ ClassDB::bind_method(D_METHOD("set_flip_faces", "flip_faces"), &PrimitiveMesh::set_flip_faces);
+ ClassDB::bind_method(D_METHOD("get_flip_faces"), &PrimitiveMesh::get_flip_faces);
+
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_faces"), "set_flip_faces", "get_flip_faces");
}
void PrimitiveMesh::set_material(const Ref<Material> &p_material) {
@@ -185,7 +220,30 @@ Array PrimitiveMesh::get_mesh_arrays() const {
return surface_get_arrays(0);
}
+void PrimitiveMesh::set_custom_aabb(const AABB &p_custom) {
+
+ custom_aabb = p_custom;
+ VS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb);
+ emit_changed();
+}
+
+AABB PrimitiveMesh::get_custom_aabb() const {
+
+ return custom_aabb;
+}
+
+void PrimitiveMesh::set_flip_faces(bool p_enable) {
+ flip_faces = p_enable;
+ _request_update();
+}
+
+bool PrimitiveMesh::get_flip_faces() const {
+ return flip_faces;
+}
+
PrimitiveMesh::PrimitiveMesh() {
+
+ flip_faces = false;
// defaults
mesh = VisualServer::get_singleton()->mesh_create();
@@ -361,8 +419,8 @@ void CapsuleMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_rings", "rings"), &CapsuleMesh::set_rings);
ClassDB::bind_method(D_METHOD("get_rings"), &CapsuleMesh::get_rings);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_radius", "get_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "mid_height", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_mid_height", "get_mid_height");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "mid_height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001"), "set_mid_height", "get_mid_height");
ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1"), "set_radial_segments", "get_radial_segments");
ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1"), "set_rings", "get_rings");
}
@@ -823,9 +881,9 @@ void CylinderMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_rings", "rings"), &CylinderMesh::set_rings);
ClassDB::bind_method(D_METHOD("get_rings"), &CylinderMesh::get_rings);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "top_radius", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_top_radius", "get_top_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "bottom_radius", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_bottom_radius", "get_bottom_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "top_radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001"), "set_top_radius", "get_top_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "bottom_radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001"), "set_bottom_radius", "get_bottom_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1"), "set_radial_segments", "get_radial_segments");
ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1"), "set_rings", "get_rings");
}
@@ -1224,7 +1282,7 @@ void PrismMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &PrismMesh::get_subdivide_depth);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "left_to_right", PROPERTY_HINT_RANGE, "-2.0,2.0,0.1"), "set_left_to_right", "get_left_to_right");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_size", "get_size");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_width", "get_subdivide_width");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_height", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_height", "get_subdivide_height");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_depth", "get_subdivide_depth");
@@ -1441,8 +1499,8 @@ void SphereMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_is_hemisphere", "is_hemisphere"), &SphereMesh::set_is_hemisphere);
ClassDB::bind_method(D_METHOD("get_is_hemisphere"), &SphereMesh::get_is_hemisphere);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_radius", "get_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1"), "set_radial_segments", "get_radial_segments");
ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1"), "set_rings", "get_rings");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_hemisphere"), "set_is_hemisphere", "get_is_hemisphere");
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 2b7294141a..a91aa09ffe 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -39,7 +39,7 @@
@author Bastiaan Olij <mux213@gmail.com>
Base class for all the classes in this file, handles a number of code functions that are shared among all meshes.
- This class is set appart that it assumes a single surface is always generated for our mesh.
+ This class is set apart that it assumes a single surface is always generated for our mesh.
*/
class PrimitiveMesh : public Mesh {
@@ -48,8 +48,10 @@ class PrimitiveMesh : public Mesh {
private:
RID mesh;
mutable AABB aabb;
+ AABB custom_aabb;
Ref<Material> material;
+ bool flip_faces;
mutable bool pending_request;
void _update() const;
@@ -81,6 +83,12 @@ public:
Array get_mesh_arrays() const;
+ void set_custom_aabb(const AABB &p_custom);
+ AABB get_custom_aabb() const;
+
+ void set_flip_faces(bool p_enable);
+ bool get_flip_faces() const;
+
PrimitiveMesh();
~PrimitiveMesh();
};
@@ -189,7 +197,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 dfd7aee23a..a9dec3e87c 100644
--- a/scene/resources/ray_shape.cpp
+++ b/scene/resources/ray_shape.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "ray_shape.h"
#include "servers/physics_server.h"
@@ -42,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();
}
@@ -51,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 {
@@ -58,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 45fd8ea603..f11b2e7c3c 100644
--- a/scene/resources/ray_shape.h
+++ b/scene/resources/ray_shape.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef RAY_SHAPE_H
#define RAY_SHAPE_H
#include "scene/resources/shape.h"
@@ -35,6 +36,7 @@ class RayShape : public Shape {
GDCLASS(RayShape, Shape);
float length;
+ bool slips_on_slope;
protected:
static void _bind_methods();
@@ -45,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/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp
index 5c4c838e29..aeb22f6d0a 100644
--- a/scene/resources/rectangle_shape_2d.cpp
+++ b/scene/resources/rectangle_shape_2d.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "rectangle_shape_2d.h"
#include "servers/physics_2d_server.h"
diff --git a/scene/resources/rectangle_shape_2d.h b/scene/resources/rectangle_shape_2d.h
index 1e2a40d695..2d66d328fd 100644
--- a/scene/resources/rectangle_shape_2d.h
+++ b/scene/resources/rectangle_shape_2d.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef RECTANGLE_SHAPE_2D_H
#define RECTANGLE_SHAPE_2D_H
diff --git a/scene/resources/room.cpp b/scene/resources/room.cpp
index f46b074225..9493f8fbe6 100644
--- a/scene/resources/room.cpp
+++ b/scene/resources/room.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "room.h"
#include "servers/visual_server.h"
diff --git a/scene/resources/room.h b/scene/resources/room.h
index 367757fdb9..359d918665 100644
--- a/scene/resources/room.h
+++ b/scene/resources/room.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef ROOM_BOUNDS_H
#define ROOM_BOUNDS_H
diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp
index 9910fe8dfc..597866eb74 100644
--- a/scene/resources/scene_format_text.cpp
+++ b/scene/resources/scene_format_text.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "scene_format_text.h"
#include "core/io/resource_format_binary.h"
#include "os/dir_access.h"
@@ -1311,6 +1312,8 @@ Error ResourceFormatLoaderText::rename_dependencies(const String &p_path, const
return ria->rename_dependencies(f, p_path, p_map);
}
+ResourceFormatLoaderText *ResourceFormatLoaderText::singleton = NULL;
+
Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path, const String &p_dst_path) {
Error err;
@@ -1410,7 +1413,7 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
I = I->next();
}
- resource_set.insert(res); //saved after, so the childs it needs are available when loaded
+ resource_set.insert(res); //saved after, so the children it needs are available when loaded
saved_resources.push_back(res);
} break;
@@ -1442,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;
}
@@ -1503,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
@@ -1663,7 +1672,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
f->store_string(vars);
}
- f->store_line("]\n");
+ f->store_line("]");
for (int j = 0; j < state->get_node_property_count(i); j++) {
@@ -1673,10 +1682,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
f->store_string(_valprop(String(state->get_node_property_name(i, j))) + " = " + vars + "\n");
}
- if (state->get_node_property_count(i)) {
- //add space
- f->store_line(String());
- }
+ f->store_line(String());
}
for (int i = 0; i < state->get_connection_count(); i++) {
@@ -1699,14 +1705,12 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
f->store_string(" binds= " + vars);
}
- f->store_line("]\n");
+ f->store_line("]");
}
- f->store_line(String());
-
Vector<NodePath> editable_instances = state->get_editable_instances();
for (int i = 0; i < editable_instances.size(); i++) {
- f->store_line("[editable path=\"" + editable_instances[i].operator String() + "\"]");
+ f->store_line("\n[editable path=\"" + editable_instances[i].operator String() + "\"]");
}
}
diff --git a/scene/resources/scene_format_text.h b/scene/resources/scene_format_text.h
index 6782aff6fd..c28ded3d77 100644
--- a/scene/resources/scene_format_text.h
+++ b/scene/resources/scene_format_text.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef SCENE_FORMAT_TEXT_H
#define SCENE_FORMAT_TEXT_H
@@ -127,7 +128,9 @@ public:
};
class ResourceFormatLoaderText : public ResourceFormatLoader {
+
public:
+ static ResourceFormatLoaderText *singleton;
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
@@ -137,6 +140,8 @@ public:
virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map);
static Error convert_file_to_binary(const String &p_src_path, const String &p_dst_path);
+
+ ResourceFormatLoaderText() { singleton = this; }
};
class ResourceFormatSaverTextInstance {
diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp
index 346599b25a..58027c127d 100644
--- a/scene/resources/segment_shape_2d.cpp
+++ b/scene/resources/segment_shape_2d.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "segment_shape_2d.h"
#include "servers/physics_2d_server.h"
@@ -105,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();
}
@@ -139,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) {
@@ -152,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 39a71f61d5..700982ac0a 100644
--- a/scene/resources/segment_shape_2d.h
+++ b/scene/resources/segment_shape_2d.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef SEGMENT_SHAPE_2D_H
#define SEGMENT_SHAPE_2D_H
@@ -62,6 +63,7 @@ class RayShape2D : public Shape2D {
GDCLASS(RayShape2D, Shape2D);
real_t length;
+ bool slips_on_slope;
void _update_shape();
@@ -71,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/shader.cpp b/scene/resources/shader.cpp
index c33267d023..36740a307b 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "shader.h"
#include "os/file_access.h"
#include "scene/scene_string_names.h"
diff --git a/scene/resources/shader.h b/scene/resources/shader.h
index e9f5873588..248a6f0125 100644
--- a/scene/resources/shader.h
+++ b/scene/resources/shader.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef SHADER_H
#define SHADER_H
diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp
index 431150d1dd..070cc84863 100644
--- a/scene/resources/shader_graph.cpp
+++ b/scene/resources/shader_graph.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "shader_graph.h"
#include "scene/scene_string_names.h"
@@ -269,7 +270,7 @@ void ShaderGraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_data"),&ShaderGraph::_set_data);
ClassDB::bind_method(D_METHOD("_get_data"),&ShaderGraph::_get_data);
- ADD_PROPERTY( PropertyInfo(Variant::DICTIONARY,"_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR), "_set_data","_get_data");
+ ADD_PROPERTY( PropertyInfo(Variant::DICTIONARY,"_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data","_get_data");
//void get_connections(ShaderType p_which,List<Connection> *p_connections) const;
diff --git a/scene/resources/shader_graph.h b/scene/resources/shader_graph.h
index f9856158b9..e3a68f8572 100644
--- a/scene/resources/shader_graph.h
+++ b/scene/resources/shader_graph.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef SHADER_GRAPH_H
#define SHADER_GRAPH_H
diff --git a/scene/resources/shape.cpp b/scene/resources/shape.cpp
index edec89641f..418d8ce819 100644
--- a/scene/resources/shape.cpp
+++ b/scene/resources/shape.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "shape.h"
#include "os/os.h"
diff --git a/scene/resources/shape.h b/scene/resources/shape.h
index bdbc9ba1e4..ad87a69679 100644
--- a/scene/resources/shape.h
+++ b/scene/resources/shape.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef SHAPE_H
#define SHAPE_H
diff --git a/scene/resources/shape_2d.cpp b/scene/resources/shape_2d.cpp
index 15c8b6b748..0ca518e5bb 100644
--- a/scene/resources/shape_2d.cpp
+++ b/scene/resources/shape_2d.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "shape_2d.h"
#include "servers/physics_2d_server.h"
RID Shape2D::get_rid() const {
diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h
index 877a159aee..7eb0406bd8 100644
--- a/scene/resources/shape_2d.h
+++ b/scene/resources/shape_2d.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef SHAPE_2D_H
#define SHAPE_2D_H
@@ -44,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/shape_line_2d.cpp b/scene/resources/shape_line_2d.cpp
index 9548d35370..1a81eea6e5 100644
--- a/scene/resources/shape_line_2d.cpp
+++ b/scene/resources/shape_line_2d.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "shape_line_2d.h"
#include "servers/physics_2d_server.h"
#include "servers/visual_server.h"
diff --git a/scene/resources/shape_line_2d.h b/scene/resources/shape_line_2d.h
index fe6f2d675e..7d31941558 100644
--- a/scene/resources/shape_line_2d.h
+++ b/scene/resources/shape_line_2d.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef SHAPE_LINE_2D_H
#define SHAPE_LINE_2D_H
diff --git a/scene/resources/sky_box.cpp b/scene/resources/sky_box.cpp
index 42ed6f72fa..f2d5cb3516 100644
--- a/scene/resources/sky_box.cpp
+++ b/scene/resources/sky_box.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "sky_box.h"
#include "io/image_loader.h"
diff --git a/scene/resources/sky_box.h b/scene/resources/sky_box.h
index b62f9064c5..e561653a9e 100644
--- a/scene/resources/sky_box.h
+++ b/scene/resources/sky_box.h
@@ -27,8 +27,9 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef Sky_H
-#define Sky_H
+
+#ifndef SKY_BOX_H
+#define SKY_BOX_H
#include "os/thread.h"
#include "scene/resources/texture.h"
@@ -195,4 +196,4 @@ public:
VARIANT_ENUM_CAST(ProceduralSky::TextureSize)
-#endif // Sky_H
+#endif // SKY_BOX_H
diff --git a/scene/resources/space_2d.cpp b/scene/resources/space_2d.cpp
index e2661e83f5..062f4099db 100644
--- a/scene/resources/space_2d.cpp
+++ b/scene/resources/space_2d.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "space_2d.h"
RID Space2D::get_rid() const {
diff --git a/scene/resources/space_2d.h b/scene/resources/space_2d.h
index 3ed1e4199a..148285ac6d 100644
--- a/scene/resources/space_2d.h
+++ b/scene/resources/space_2d.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef SPACE_2D_H
#define SPACE_2D_H
diff --git a/scene/resources/sphere_shape.cpp b/scene/resources/sphere_shape.cpp
index c61749a598..d8ca1cf3f1 100644
--- a/scene/resources/sphere_shape.cpp
+++ b/scene/resources/sphere_shape.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "sphere_shape.h"
#include "servers/physics_server.h"
diff --git a/scene/resources/sphere_shape.h b/scene/resources/sphere_shape.h
index c1e0069941..5dd7daabc5 100644
--- a/scene/resources/sphere_shape.h
+++ b/scene/resources/sphere_shape.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef SPHERE_SHAPE_H
#define SPHERE_SHAPE_H
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 7c8007ff9c..7da65ac984 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "style_box.h"
#include <limits.h>
@@ -100,23 +101,27 @@ StyleBox::StyleBox() {
}
}
-void StyleBoxTexture::set_texture(RES p_texture) {
+void StyleBoxTexture::set_texture(Ref<Texture> p_texture) {
if (texture == p_texture)
return;
texture = p_texture;
- region_rect = Rect2(Point2(), texture->get_size());
+ if (p_texture.is_null()) {
+ region_rect = Rect2(0, 0, 0, 0);
+ } else {
+ region_rect = Rect2(Point2(), texture->get_size());
+ }
emit_signal("texture_changed");
emit_changed();
_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;
@@ -124,7 +129,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;
}
@@ -181,7 +186,7 @@ Size2 StyleBoxTexture::get_center_size() const {
if (texture.is_null())
return Size2();
- return texture->get_size() - get_minimum_size();
+ return region_rect.size - get_minimum_size();
}
void StyleBoxTexture::set_expand_margin_size(Margin p_expand_margin, float p_size) {
@@ -649,14 +654,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)
- int width = style_rect.size.width;
- int height = style_rect.size.height;
+ //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]);
@@ -911,6 +916,7 @@ void StyleBoxLine::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_vertical"), &StyleBoxLine::is_vertical);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "grow", PROPERTY_HINT_RANGE, "-300,300,1"), "set_grow", "get_grow");
ADD_PROPERTY(PropertyInfo(Variant::INT, "thickness", PROPERTY_HINT_RANGE, "0,10"), "set_thickness", "get_thickness");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "is_vertical");
}
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index bdaa04e492..c1d84fe19f 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef STYLE_BOX_H
#define STYLE_BOX_H
@@ -111,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/surface_tool.cpp b/scene/resources/surface_tool.cpp
index a2535d0ddb..5a42873d79 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "surface_tool.h"
#include "method_bind_ext.gen.inc"
@@ -860,7 +861,7 @@ void SurfaceTool::generate_tangents() {
}
}
-void SurfaceTool::generate_normals() {
+void SurfaceTool::generate_normals(bool p_flip) {
ERR_FAIL_COND(primitive != Mesh::PRIMITIVE_TRIANGLES);
@@ -886,7 +887,11 @@ void SurfaceTool::generate_normals() {
ERR_FAIL_COND(!v[2]);
E = v[2]->next();
- Vector3 normal = Plane(v[0]->get().vertex, v[1]->get().vertex, v[2]->get().vertex).normal;
+ Vector3 normal;
+ if (!p_flip)
+ normal = Plane(v[0]->get().vertex, v[1]->get().vertex, v[2]->get().vertex).normal;
+ else
+ normal = Plane(v[2]->get().vertex, v[1]->get().vertex, v[0]->get().vertex).normal;
if (smooth) {
@@ -979,7 +984,7 @@ void SurfaceTool::_bind_methods() {
ClassDB::bind_method(D_METHOD("index"), &SurfaceTool::index);
ClassDB::bind_method(D_METHOD("deindex"), &SurfaceTool::deindex);
- ClassDB::bind_method(D_METHOD("generate_normals"), &SurfaceTool::generate_normals);
+ ClassDB::bind_method(D_METHOD("generate_normals", "flip"), &SurfaceTool::generate_normals, DEFVAL(false));
ClassDB::bind_method(D_METHOD("generate_tangents"), &SurfaceTool::generate_tangents);
ClassDB::bind_method(D_METHOD("add_to_format", "flags"), &SurfaceTool::add_to_format);
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index d18c1fc263..459d399380 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef SURFACE_TOOL_H
#define SURFACE_TOOL_H
@@ -115,7 +116,7 @@ public:
void index();
void deindex();
- void generate_normals();
+ void generate_normals(bool p_flip = false);
void generate_tangents();
void add_to_format(int p_flags) { format |= p_flags; }
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index ea51a5ba8d..c0f6756fd1 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "texture.h"
#include "core/method_bind_ext.gen.inc"
#include "core/os/os.h"
@@ -75,10 +76,12 @@ void Texture::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "normal_map", "clip_uv"), &Texture::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_data"), &Texture::get_data);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic Linear,Convert to Linear,Mirrored Repeat,Video Surface"), "set_flags", "get_flags");
+
+ BIND_ENUM_CONSTANT(FLAGS_DEFAULT);
BIND_ENUM_CONSTANT(FLAG_MIPMAPS);
BIND_ENUM_CONSTANT(FLAG_REPEAT);
BIND_ENUM_CONSTANT(FLAG_FILTER);
- BIND_ENUM_CONSTANT(FLAGS_DEFAULT);
BIND_ENUM_CONSTANT(FLAG_ANISOTROPIC_FILTER);
BIND_ENUM_CONSTANT(FLAG_CONVERT_TO_LINEAR);
BIND_ENUM_CONSTANT(FLAG_MIRRORED_REPEAT);
@@ -120,10 +123,6 @@ bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
w = s.width;
h = s.height;
VisualServer::get_singleton()->texture_set_size_override(texture, w, h);
- } else if (p_name == "storage") {
- storage = Storage(p_value.operator int());
- } else if (p_name == "lossy_quality") {
- lossy_storage_quality = p_value;
} else if (p_name == "_data") {
_set_data(p_value);
} else
@@ -142,10 +141,6 @@ bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = flags;
else if (p_name == "size")
r_ret = Size2(w, h);
- else if (p_name == "storage")
- r_ret = storage;
- else if (p_name == "lossy_quality")
- r_ret = lossy_storage_quality;
else
return false;
@@ -164,8 +159,6 @@ void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, ""));
- p_list->push_back(PropertyInfo(Variant::INT, "storage", PROPERTY_HINT_ENUM, "Uncompressed,Compress Lossy,Compress Lossless"));
- p_list->push_back(PropertyInfo(Variant::REAL, "lossy_quality", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"));
}
void ImageTexture::_reload_hook(const RID &p_hook) {
@@ -362,6 +355,9 @@ void ImageTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_size_override", "size"), &ImageTexture::set_size_override);
ClassDB::bind_method(D_METHOD("_reload_hook", "rid"), &ImageTexture::_reload_hook);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "storage", PROPERTY_HINT_ENUM, "Uncompressed,Compress Lossy,Compress Lossless"), "set_storage", "get_storage");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "lossy_quality", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_lossy_storage_quality", "get_lossy_storage_quality");
+
BIND_ENUM_CONSTANT(STORAGE_RAW);
BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSY);
BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSLESS);
@@ -1132,7 +1128,7 @@ void LargeTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_data", "data"), &LargeTexture::_set_data);
ClassDB::bind_method(D_METHOD("_get_data"), &LargeTexture::_get_data);
- ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
}
void LargeTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
@@ -1283,8 +1279,6 @@ bool CubeMap::_set(const StringName &p_name, const Variant &p_value) {
set_side(SIDE_FRONT, p_value);
} else if (p_name == "side/back") {
set_side(SIDE_BACK, p_value);
- } else if (p_name == "flags") {
- set_flags(p_value);
} else if (p_name == "storage") {
storage = Storage(p_value.operator int());
} else if (p_name == "lossy_quality") {
@@ -1309,8 +1303,6 @@ bool CubeMap::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = get_side(SIDE_FRONT);
} else if (p_name == "side/back") {
r_ret = get_side(SIDE_BACK);
- } else if (p_name == "flags") {
- r_ret = flags;
} else if (p_name == "storage") {
r_ret = storage;
} else if (p_name == "lossy_quality") {
@@ -1330,7 +1322,6 @@ void CubeMap::_get_property_list(List<PropertyInfo> *p_list) const {
img_hint = PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS;
}
- p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "side/left", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "side/right", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "side/bottom", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
@@ -1352,6 +1343,7 @@ void CubeMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_lossy_storage_quality", "quality"), &CubeMap::set_lossy_storage_quality);
ClassDB::bind_method(D_METHOD("get_lossy_storage_quality"), &CubeMap::get_lossy_storage_quality);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter"), "set_flags", "get_flags");
ADD_PROPERTY(PropertyInfo(Variant::INT, "storage_mode", PROPERTY_HINT_ENUM, "Raw,Lossy Compressed,Lossless Compressed"), "set_storage", "get_storage");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "lossy_storage_quality"), "set_lossy_storage_quality", "get_lossy_storage_quality");
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 1b0754ad3b..93d7ec4ef9 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef TEXTURE_H
#define TEXTURE_H
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 7337c5ec4d..f903669fc7 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "theme.h"
#include "os/file_access.h"
#include "print_string.h"
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index 0d15a9a11e..c23f237c75 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef THEME_H
#define THEME_H
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 89de2de279..42d64376f5 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "tile_set.h"
#include "array.h"
@@ -56,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")
@@ -141,6 +142,8 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
tile_set_navigation_polygon(id, p_value);
else if (what == "navigation_offset")
tile_set_navigation_polygon_offset(id, p_value);
+ else if (what == "z_index")
+ tile_set_z_index(id, p_value);
else
return false;
@@ -173,8 +176,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")
@@ -211,7 +214,7 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
Vector3 v;
for (Map<Vector2, int>::Element *E = tile_map[id].autotile_data.priority_map.front(); E; E = E->next()) {
if (E->value() > 1) {
- //Dont save default value
+ //Don't save default value
v.x = E->key().x;
v.y = E->key().y;
v.z = E->value();
@@ -238,6 +241,8 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = tile_get_navigation_polygon(id);
else if (what == "navigation_offset")
r_ret = tile_get_navigation_polygon_offset(id);
+ else if (what == "z_index")
+ r_ret = tile_get_z_index(id);
else
return false;
@@ -257,16 +262,16 @@ 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 + "autotile/bitmask_mode", PROPERTY_HINT_ENUM, "2X2,3X3", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "autotile/icon_coordinate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "autotile/tile_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::INT, pre + "autotile/spacing", PROPERTY_HINT_RANGE, "0,256,1", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/bitmask_flags", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/occluder_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/navpoly_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/priority_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ 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/occluder_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/navpoly_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/priority_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "occluder_offset"));
p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "occluder", PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D"));
@@ -277,11 +282,11 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D", PROPERTY_USAGE_EDITOR));
p_list->push_back(PropertyInfo(Variant::BOOL, pre + "shape_one_way", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "shapes", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::INT, pre + "z_index", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1"));
}
}
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();
@@ -290,7 +295,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("");
@@ -308,6 +312,7 @@ void TileSet::tile_set_texture(int p_id, const Ref<Texture> &p_texture) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].texture = p_texture;
emit_changed();
+ _change_notify("texture");
}
Ref<Texture> TileSet::tile_get_texture(int p_id) const {
@@ -347,6 +352,7 @@ void TileSet::tile_set_modulate(int p_id, const Color &p_modulate) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].modulate = p_modulate;
emit_changed();
+ _change_notify("modulate");
}
Color TileSet::tile_get_modulate(int p_id) const {
@@ -373,6 +379,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 {
@@ -381,18 +388,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;
- _change_notify("");
+ tile_map[p_id].tile_mode = p_tile_mode;
emit_changed();
+ _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) {
@@ -532,6 +538,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 {
@@ -746,6 +753,19 @@ Vector<TileSet::ShapeData> TileSet::tile_get_shapes(int p_id) const {
return tile_map[p_id].shapes_data;
}
+int TileSet::tile_get_z_index(int p_id) const {
+
+ ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
+ return tile_map[p_id].z_index;
+}
+
+void TileSet::tile_set_z_index(int p_id, int p_z_index) {
+
+ ERR_FAIL_COND(!tile_map.has(p_id));
+ tile_map[p_id].z_index = p_z_index;
+ emit_changed();
+}
+
void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
ERR_FAIL_COND(!tile_map.has(p_id));
@@ -917,6 +937,8 @@ void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("tile_get_shape_count", "id"), &TileSet::tile_get_shape_count);
ClassDB::bind_method(D_METHOD("tile_set_shapes", "id", "shapes"), &TileSet::_tile_set_shapes);
ClassDB::bind_method(D_METHOD("tile_get_shapes", "id"), &TileSet::_tile_get_shapes);
+ ClassDB::bind_method(D_METHOD("tile_set_tile_mode", "id", "tilemode"), &TileSet::tile_set_tile_mode);
+ ClassDB::bind_method(D_METHOD("tile_get_tile_mode", "id"), &TileSet::tile_get_tile_mode);
ClassDB::bind_method(D_METHOD("tile_set_navigation_polygon", "id", "navigation_polygon"), &TileSet::tile_set_navigation_polygon);
ClassDB::bind_method(D_METHOD("tile_get_navigation_polygon", "id"), &TileSet::tile_get_navigation_polygon);
ClassDB::bind_method(D_METHOD("tile_set_navigation_polygon_offset", "id", "navigation_polygon_offset"), &TileSet::tile_set_navigation_polygon_offset);
@@ -925,6 +947,8 @@ void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("tile_get_light_occluder", "id"), &TileSet::tile_get_light_occluder);
ClassDB::bind_method(D_METHOD("tile_set_occluder_offset", "id", "occluder_offset"), &TileSet::tile_set_occluder_offset);
ClassDB::bind_method(D_METHOD("tile_get_occluder_offset", "id"), &TileSet::tile_get_occluder_offset);
+ ClassDB::bind_method(D_METHOD("tile_set_z_index", "id", "z_index"), &TileSet::tile_set_z_index);
+ ClassDB::bind_method(D_METHOD("tile_get_z_index", "id"), &TileSet::tile_get_z_index);
ClassDB::bind_method(D_METHOD("remove_tile", "id"), &TileSet::remove_tile);
ClassDB::bind_method(D_METHOD("clear"), &TileSet::clear);
@@ -946,6 +970,10 @@ void TileSet::_bind_methods() {
BIND_ENUM_CONSTANT(BIND_BOTTOMLEFT);
BIND_ENUM_CONSTANT(BIND_BOTTOM);
BIND_ENUM_CONSTANT(BIND_BOTTOMRIGHT);
+
+ BIND_ENUM_CONSTANT(SINGLE_TILE);
+ BIND_ENUM_CONSTANT(AUTO_TILE);
+ BIND_ENUM_CONSTANT(ANIMATED_TILE);
}
TileSet::TileSet() {
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index e7e5c06d34..d5704ac9a0 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef TILE_SET_H
#define TILE_SET_H
@@ -70,6 +71,12 @@ public:
BIND_BOTTOMRIGHT = 256
};
+ enum TileMode {
+ SINGLE_TILE,
+ AUTO_TILE,
+ ANIMATED_TILE
+ };
+
struct AutotileData {
BitmaskMode bitmask_mode;
int spacing;
@@ -83,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;
}
@@ -103,13 +111,15 @@ private:
Ref<NavigationPolygon> navigation_polygon;
Ref<ShaderMaterial> material;
Color modulate;
- bool is_autotile;
+ TileMode tile_mode;
AutotileData autotile_data;
+ int z_index;
// Default modulate for back-compat
explicit TileData() :
+ tile_mode(SINGLE_TILE),
modulate(1, 1, 1),
- is_autotile(false) {}
+ z_index(0) {}
};
Map<int, TileData> tile_map;
@@ -145,8 +155,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;
@@ -212,6 +222,9 @@ public:
Ref<NavigationPolygon> autotile_get_navigation_polygon(int p_id, const Vector2 &p_coord) const;
const Map<Vector2, Ref<NavigationPolygon> > &autotile_get_navigation_map(int p_id) const;
+ void tile_set_z_index(int p_id, int p_z_index);
+ int tile_get_z_index(int p_id) const;
+
void remove_tile(int p_id);
bool has_tile(int p_id) const;
@@ -230,5 +243,6 @@ public:
VARIANT_ENUM_CAST(TileSet::AutotileBindings);
VARIANT_ENUM_CAST(TileSet::BitmaskMode);
+VARIANT_ENUM_CAST(TileSet::TileMode);
#endif // TILE_SET_H
diff --git a/scene/resources/video_stream.cpp b/scene/resources/video_stream.cpp
index ddedc1a37e..3cd8cbae77 100644
--- a/scene/resources/video_stream.cpp
+++ b/scene/resources/video_stream.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "video_stream.h"
void VideoStreamPlayback::_bind_methods(){
diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h
index bd5bf54d0a..0d25d9d687 100644
--- a/scene/resources/video_stream.h
+++ b/scene/resources/video_stream.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef VIDEO_STREAM_H
#define VIDEO_STREAM_H
diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp
index 57f567bc3c..82183d24e7 100644
--- a/scene/resources/world.cpp
+++ b/scene/resources/world.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "world.h"
#include "camera_matrix.h"
@@ -317,6 +318,9 @@ void World::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World::get_direct_space_state);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment");
+ ADD_PROPERTY(PropertyInfo(Variant::_RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
+ ADD_PROPERTY(PropertyInfo(Variant::_RID, "scenario", PROPERTY_HINT_NONE, "", 0), "", "get_scenario");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState", 0), "", "get_direct_space_state");
}
World::World() {
diff --git a/scene/resources/world.h b/scene/resources/world.h
index 19b8bd03a6..54bdf25784 100644
--- a/scene/resources/world.h
+++ b/scene/resources/world.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef WORLD_H
#define WORLD_H
diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp
index 1f75c43d75..bed6ffd1bd 100644
--- a/scene/resources/world_2d.cpp
+++ b/scene/resources/world_2d.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "world_2d.h"
#include "servers/physics_2d_server.h"
#include "servers/visual_server.h"
@@ -372,6 +373,10 @@ void World2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_space"), &World2D::get_space);
ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World2D::get_direct_space_state);
+
+ ADD_PROPERTY(PropertyInfo(Variant::_RID, "canvas", PROPERTY_HINT_NONE, "", 0), "", "get_canvas");
+ ADD_PROPERTY(PropertyInfo(Variant::_RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "Physics2DDirectSpaceState", 0), "", "get_direct_space_state");
}
Physics2DDirectSpaceState *World2D::get_direct_space_state() {
diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h
index 84fa00e6cd..59f34e32f2 100644
--- a/scene/resources/world_2d.h
+++ b/scene/resources/world_2d.h
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef WORLD_2D_H
#define WORLD_2D_H