diff options
Diffstat (limited to 'scene/resources')
32 files changed, 1057 insertions, 287 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 8192074c17..4544549f94 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -77,6 +77,8 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { track_set_interpolation_loop_wrap(track, p_value); else if (what == "imported") track_set_imported(track, p_value); + else if (what == "enabled") + track_set_enabled(track, p_value); else if (what == "keys" || what == "key_values") { if (track_get_type(track) == TYPE_TRANSFORM) { @@ -247,6 +249,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { r_ret = track_get_interpolation_loop_wrap(track); else if (what == "imported") r_ret = track_is_imported(track); + else if (what == "enabled") + r_ret = track_is_enabled(track); else if (what == "keys") { if (track_get_type(track) == TYPE_TRANSFORM) { @@ -391,6 +395,7 @@ void Animation::_get_property_list(List<PropertyInfo> *p_list) const { 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)); } } @@ -1575,6 +1580,19 @@ bool Animation::track_is_imported(int p_track) const { return tracks[p_track]->imported; } +void Animation::track_set_enabled(int p_track, bool p_enabled) { + + ERR_FAIL_INDEX(p_track, tracks.size()); + tracks[p_track]->enabled = p_enabled; + emit_changed(); +} + +bool Animation::track_is_enabled(int p_track) const { + + ERR_FAIL_INDEX_V(p_track, tracks.size(), false); + return tracks[p_track]->enabled; +} + void Animation::track_move_down(int p_track) { if (p_track > 0 && p_track < tracks.size()) { @@ -1595,6 +1613,22 @@ float Animation::get_step() const { return step; } +void Animation::copy_track(int src_track, Ref<Animation> p_to_animation) { + ERR_FAIL_COND(p_to_animation.is_null()); + ERR_FAIL_INDEX(src_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)); + } +} + void Animation::_bind_methods() { ClassDB::bind_method(D_METHOD("add_track", "type", "at_position"), &Animation::add_track, DEFVAL(-1)); @@ -1611,6 +1645,9 @@ void Animation::_bind_methods() { ClassDB::bind_method(D_METHOD("track_set_imported", "idx", "imported"), &Animation::track_set_imported); ClassDB::bind_method(D_METHOD("track_is_imported", "idx"), &Animation::track_is_imported); + ClassDB::bind_method(D_METHOD("track_set_enabled", "idx", "enabled"), &Animation::track_set_enabled); + ClassDB::bind_method(D_METHOD("track_is_enabled", "idx"), &Animation::track_is_enabled); + ClassDB::bind_method(D_METHOD("transform_track_insert_key", "idx", "time", "location", "rotation", "scale"), &Animation::transform_track_insert_key); ClassDB::bind_method(D_METHOD("track_insert_key", "idx", "time", "key", "transition"), &Animation::track_insert_key, DEFVAL(1)); ClassDB::bind_method(D_METHOD("track_remove_key", "idx", "key_idx"), &Animation::track_remove_key); @@ -1650,6 +1687,7 @@ void Animation::_bind_methods() { ClassDB::bind_method(D_METHOD("get_step"), &Animation::get_step); ClassDB::bind_method(D_METHOD("clear"), &Animation::clear); + ClassDB::bind_method(D_METHOD("copy_track", "track", "to_animation"), &Animation::copy_track); BIND_ENUM_CONSTANT(TYPE_VALUE); BIND_ENUM_CONSTANT(TYPE_TRANSFORM); diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 6235e161a3..1f468b29b5 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -67,10 +67,12 @@ private: bool loop_wrap; NodePath path; // path to something bool imported; + bool enabled; Track() { interpolation = INTERPOLATION_LINEAR; imported = false; loop_wrap = true; + enabled = true; } virtual ~Track() {} }; @@ -239,6 +241,9 @@ public: void track_set_imported(int p_track, bool p_imported); bool track_is_imported(int p_track) const; + void track_set_enabled(int p_track, bool p_enabled); + bool track_is_enabled(int p_track) const; + int transform_track_insert_key(int p_track, float p_time, const Vector3 p_loc, const Quat &p_rot = Quat(), const Vector3 &p_scale = Vector3()); void track_insert_key(int p_track, float p_time, const Variant &p_key, float p_transition = 1); void track_set_key_transition(int p_track, int p_key_idx, float p_transition); @@ -269,6 +274,8 @@ public: Vector<Variant> method_track_get_params(int p_track, int p_key_idx) const; StringName method_track_get_name(int p_track, int p_key_idx) const; + void copy_track(int p_track, Ref<Animation> p_to_animation); + void set_length(float p_length); float get_length() const; diff --git a/scene/resources/box_shape.cpp b/scene/resources/box_shape.cpp index 4b9843f3f5..858e19c9a6 100644 --- a/scene/resources/box_shape.cpp +++ b/scene/resources/box_shape.cpp @@ -73,8 +73,8 @@ void BoxShape::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents"), "set_extents", "get_extents"); } -BoxShape::BoxShape() - : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_BOX)) { +BoxShape::BoxShape() : + Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_BOX)) { set_extents(Vector3(1, 1, 1)); } diff --git a/scene/resources/capsule_shape.cpp b/scene/resources/capsule_shape.cpp index e11b98f82e..f0eb8232e5 100644 --- a/scene/resources/capsule_shape.cpp +++ b/scene/resources/capsule_shape.cpp @@ -113,8 +113,8 @@ void CapsuleShape::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_height", "get_height"); } -CapsuleShape::CapsuleShape() - : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CAPSULE)) { +CapsuleShape::CapsuleShape() : + Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CAPSULE)) { radius = 1.0; height = 1.0; diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp index 912150b939..3caf12feb8 100644 --- a/scene/resources/capsule_shape_2d.cpp +++ b/scene/resources/capsule_shape_2d.cpp @@ -97,8 +97,8 @@ void CapsuleShape2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "height"), "set_height", "get_height"); } -CapsuleShape2D::CapsuleShape2D() - : Shape2D(Physics2DServer::get_singleton()->capsule_shape_create()) { +CapsuleShape2D::CapsuleShape2D() : + Shape2D(Physics2DServer::get_singleton()->capsule_shape_create()) { radius = 10; height = 20; diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp index 287bde4bfb..bff3ed4d67 100644 --- a/scene/resources/circle_shape_2d.cpp +++ b/scene/resources/circle_shape_2d.cpp @@ -76,8 +76,8 @@ void CircleShape2D::draw(const RID &p_to_rid, const Color &p_color) { VisualServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col); } -CircleShape2D::CircleShape2D() - : Shape2D(Physics2DServer::get_singleton()->circle_shape_create()) { +CircleShape2D::CircleShape2D() : + Shape2D(Physics2DServer::get_singleton()->circle_shape_create()) { radius = 10; _update_shape(); diff --git a/scene/resources/concave_polygon_shape.cpp b/scene/resources/concave_polygon_shape.cpp index 6ae4fde85e..1c48f0c30b 100644 --- a/scene/resources/concave_polygon_shape.cpp +++ b/scene/resources/concave_polygon_shape.cpp @@ -106,8 +106,8 @@ void ConcavePolygonShape::_bind_methods() { ClassDB::bind_method(D_METHOD("get_faces"), &ConcavePolygonShape::get_faces); } -ConcavePolygonShape::ConcavePolygonShape() - : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON)) { +ConcavePolygonShape::ConcavePolygonShape() : + Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON)) { //set_planes(Vector3(1,1,1)); } diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp index bb91e33ec2..e90046fd28 100644 --- a/scene/resources/concave_polygon_shape_2d.cpp +++ b/scene/resources/concave_polygon_shape_2d.cpp @@ -84,6 +84,6 @@ void ConcavePolygonShape2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "segments"), "set_segments", "get_segments"); } -ConcavePolygonShape2D::ConcavePolygonShape2D() - : Shape2D(Physics2DServer::get_singleton()->concave_polygon_shape_create()) { +ConcavePolygonShape2D::ConcavePolygonShape2D() : + Shape2D(Physics2DServer::get_singleton()->concave_polygon_shape_create()) { } diff --git a/scene/resources/convex_polygon_shape.cpp b/scene/resources/convex_polygon_shape.cpp index bba52bd5ff..31c4ea55e9 100644 --- a/scene/resources/convex_polygon_shape.cpp +++ b/scene/resources/convex_polygon_shape.cpp @@ -81,8 +81,8 @@ void ConvexPolygonShape::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "points"), "set_points", "get_points"); } -ConvexPolygonShape::ConvexPolygonShape() - : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON)) { +ConvexPolygonShape::ConvexPolygonShape() : + Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON)) { //set_points(Vector3(1,1,1)); } diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp index a76b6a7cf4..9c25b6b467 100644 --- a/scene/resources/convex_polygon_shape_2d.cpp +++ b/scene/resources/convex_polygon_shape_2d.cpp @@ -86,8 +86,8 @@ Rect2 ConvexPolygonShape2D::get_rect() const { return rect; } -ConvexPolygonShape2D::ConvexPolygonShape2D() - : Shape2D(Physics2DServer::get_singleton()->convex_polygon_shape_create()) { +ConvexPolygonShape2D::ConvexPolygonShape2D() : + Shape2D(Physics2DServer::get_singleton()->convex_polygon_shape_create()) { int pcount = 3; for (int i = 0; i < pcount; i++) diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index c5feecd7c4..f4e6c5e247 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -257,6 +257,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // LinkButton + theme->set_stylebox("focus", "LinkButton", focus); + theme->set_font("font", "LinkButton", default_font); theme->set_color("font_color", "LinkButton", control_font_color); @@ -348,15 +350,15 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // CheckBox Ref<StyleBox> cbx_empty = memnew(StyleBoxEmpty); - cbx_empty->set_default_margin(MARGIN_LEFT, 22 * scale); + cbx_empty->set_default_margin(MARGIN_LEFT, 4 * scale); cbx_empty->set_default_margin(MARGIN_RIGHT, 4 * scale); cbx_empty->set_default_margin(MARGIN_TOP, 4 * scale); - cbx_empty->set_default_margin(MARGIN_BOTTOM, 5 * scale); + cbx_empty->set_default_margin(MARGIN_BOTTOM, 4 * scale); Ref<StyleBox> cbx_focus = focus; cbx_focus->set_default_margin(MARGIN_LEFT, 4 * scale); - cbx_focus->set_default_margin(MARGIN_RIGHT, 22 * scale); + cbx_focus->set_default_margin(MARGIN_RIGHT, 4 * scale); cbx_focus->set_default_margin(MARGIN_TOP, 4 * scale); - cbx_focus->set_default_margin(MARGIN_BOTTOM, 5 * scale); + cbx_focus->set_default_margin(MARGIN_BOTTOM, 4 * scale); theme->set_stylebox("normal", "CheckBox", cbx_empty); theme->set_stylebox("pressed", "CheckBox", cbx_empty); @@ -383,7 +385,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<StyleBox> cb_empty = memnew(StyleBoxEmpty); cb_empty->set_default_margin(MARGIN_LEFT, 6 * scale); - cb_empty->set_default_margin(MARGIN_RIGHT, 70 * scale); + cb_empty->set_default_margin(MARGIN_RIGHT, 6 * scale); cb_empty->set_default_margin(MARGIN_TOP, 4 * scale); cb_empty->set_default_margin(MARGIN_BOTTOM, 4 * scale); @@ -448,6 +450,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("normal", "TextEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3)); 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_icon("tab", "TextEdit", make_icon(tab_png)); @@ -465,6 +468,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("selection_color", "TextEdit", font_color_selection); theme->set_color("mark_color", "TextEdit", Color(1.0, 0.4, 0.4, 0.4)); theme->set_color("breakpoint_color", "TextEdit", Color(0.8, 0.8, 0.4, 0.2)); + theme->set_color("code_folding_color", "TextEdit", Color(0.8, 0.8, 0.8, 0.8)); theme->set_color("current_line_color", "TextEdit", Color(0.25, 0.25, 0.26, 0.8)); theme->set_color("caret_color", "TextEdit", control_font_color); theme->set_color("caret_background_color", "TextEdit", Color::html("000000")); diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 255bb4c6dd..c6b37cad5a 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -410,6 +410,10 @@ static const unsigned char tree_bg_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x4, 0x3, 0x0, 0x0, 0x0, 0x7f, 0x1c, 0xd2, 0x8e, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2a, 0x50, 0x4c, 0x54, 0x45, 0x17, 0x16, 0x1a, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x21, 0x1f, 0x25, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x1d, 0x1c, 0x21, 0x1d, 0x1c, 0x21, 0x24, 0x22, 0x29, 0x28, 0x26, 0x2d, 0x28, 0x26, 0x2e, 0x2b, 0x2a, 0x31, 0x2c, 0x2a, 0x32, 0xff, 0xff, 0xff, 0xb9, 0x11, 0x56, 0x3e, 0x0, 0x0, 0x0, 0x8, 0x74, 0x52, 0x4e, 0x53, 0x6f, 0xef, 0xf7, 0xf7, 0xf0, 0xf9, 0xf1, 0xee, 0xcf, 0x21, 0xd2, 0xdf, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xd, 0xf6, 0xb4, 0x61, 0xf5, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x2d, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x36, 0x36, 0x12, 0x60, 0xf0, 0x98, 0xb5, 0x6a, 0x65, 0xb, 0x43, 0xe4, 0x9e, 0x33, 0xa7, 0xa7, 0x32, 0x58, 0x9d, 0x39, 0x73, 0x66, 0x31, 0x16, 0x12, 0x22, 0xb, 0x52, 0xd9, 0xc6, 0xc0, 0x2, 0xd4, 0x55, 0x0, 0x0, 0xc, 0x14, 0x1a, 0x90, 0x55, 0x1a, 0xec, 0xdb, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; +static const unsigned char tree_bg_disabled_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x8, 0x4, 0x0, 0x0, 0x0, 0x27, 0x3b, 0x7, 0x36, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x64, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x95, 0xce, 0x31, 0x12, 0x2, 0x21, 0x10, 0x44, 0xd1, 0x3f, 0x40, 0xa1, 0x44, 0xa6, 0x46, 0xde, 0x63, 0x4f, 0xe5, 0x15, 0x38, 0xb2, 0xd6, 0x6, 0xb0, 0xc8, 0x30, 0x6, 0x96, 0xac, 0x56, 0x99, 0xf8, 0xb3, 0x7e, 0x51, 0xcb, 0xf9, 0x1a, 0xb3, 0x3f, 0xa, 0xaf, 0xc, 0xad, 0x2d, 0xcb, 0xe5, 0x76, 0x38, 0x5, 0x76, 0xec, 0x6c, 0xf7, 0xe0, 0x53, 0xe0, 0x13, 0xa1, 0x27, 0x27, 0x43, 0x26, 0x81, 0x20, 0xc8, 0x70, 0xfc, 0xe8, 0xf, 0x34, 0x67, 0xd8, 0x9c, 0x86, 0x61, 0x2e, 0x68, 0xe9, 0x91, 0xaf, 0x4b, 0x5a, 0x7d, 0x2a, 0x2c, 0x3, 0xed, 0xef, 0x1e, 0x6b, 0xcb, 0x4f, 0xa6, 0x66, 0x2b, 0x25, 0x6, 0x1, 0x37, 0x40, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; + static const unsigned char tree_bg_focus_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x6, 0x0, 0x0, 0x0, 0x73, 0x7a, 0x7a, 0xf4, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xdb, 0xb, 0x4, 0x12, 0x2d, 0x3a, 0xb5, 0x1b, 0x14, 0x49, 0x0, 0x0, 0x2, 0xd9, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xc5, 0x57, 0x31, 0x8e, 0x14, 0x31, 0x10, 0xac, 0xea, 0x3d, 0x11, 0x91, 0xdf, 0x49, 0xf7, 0xf, 0x78, 0x1, 0xf, 0x40, 0x84, 0x44, 0x10, 0xf2, 0x20, 0x42, 0x62, 0x12, 0xc4, 0x3, 0x78, 0x1, 0xff, 0x21, 0x42, 0xb8, 0x8a, 0xc0, 0x1e, 0x4f, 0xdb, 0xe3, 0xb9, 0xbb, 0x45, 0x20, 0x7c, 0x1a, 0xdd, 0x8c, 0xec, 0xed, 0xae, 0xae, 0xea, 0xee, 0xe9, 0xe1, 0xfd, 0xed, 0xdd, 0xb, 0x0, 0xdf, 0xf1, 0x7f, 0xd6, 0x4b, 0xde, 0xdf, 0xde, 0xf9, 0xcb, 0xeb, 0x9f, 0xff, 0xc5, 0xfb, 0x9b, 0xaf, 0xcf, 0x70, 0xb3, 0x3d, 0x3c, 0xff, 0xf0, 0xd, 0x24, 0x11, 0x71, 0x1, 0x49, 0x90, 0x4, 0x0, 0x4, 0xd3, 0x2f, 0xb6, 0x7b, 0xf, 0xff, 0x86, 0x2d, 0x8c, 0x47, 0x60, 0x1b, 0x0, 0x61, 0x1b, 0xb6, 0x21, 0x15, 0xd8, 0xc6, 0x8f, 0x8f, 0xaf, 0x0, 0x60, 0x7, 0x0, 0xa2, 0x2, 0x20, 0x11, 0x41, 0x30, 0xa2, 0x2, 0xc1, 0xb5, 0x0, 0x8c, 0x79, 0xd9, 0x80, 0x24, 0x48, 0x0, 0x48, 0x28, 0x9d, 0xb9, 0xd9, 0xd, 0xb0, 0x31, 0x40, 0x5c, 0x2e, 0x1, 0x46, 0x0, 0xd, 0xd0, 0xb6, 0xef, 0x35, 0x8e, 0x13, 0x6, 0xbc, 0x33, 0x60, 0xa3, 0x9a, 0x11, 0x6c, 0x82, 0xe6, 0xa, 0x0, 0x86, 0xe8, 0x2f, 0x71, 0xa9, 0xf7, 0x9c, 0x4d, 0x1f, 0x69, 0x5e, 0x1, 0xd8, 0xa3, 0x37, 0xa4, 0xa, 0x27, 0x1a, 0x13, 0x79, 0x25, 0x9, 0xaa, 0xe3, 0xd8, 0x9c, 0x5f, 0xea, 0x7d, 0x67, 0x80, 0xd7, 0x31, 0x20, 0xab, 0x3, 0x20, 0x5, 0x20, 0x2a, 0x13, 0x41, 0x40, 0x2b, 0x0, 0x76, 0x22, 0xb9, 0xb1, 0xd1, 0x92, 0x91, 0x5d, 0x86, 0xf3, 0x35, 0xef, 0x5, 0xa3, 0x25, 0x60, 0xd, 0x6e, 0x66, 0xe5, 0x0, 0xc0, 0xa8, 0x54, 0x1, 0x6, 0xe9, 0x16, 0x9f, 0x4f, 0xdc, 0x1c, 0x13, 0xed, 0xb1, 0x55, 0x31, 0x78, 0x70, 0x8e, 0xca, 0xcb, 0x8e, 0x6a, 0xbe, 0x56, 0x88, 0x67, 0x38, 0xdb, 0x75, 0x58, 0x76, 0xdf, 0x1b, 0x6c, 0x7a, 0xc, 0x6c, 0x90, 0x0, 0xfd, 0xe0, 0xe8, 0x98, 0xe4, 0x4, 0xe2, 0x69, 0xc, 0xe4, 0x40, 0xaa, 0xf9, 0x63, 0x70, 0xbb, 0x4, 0x16, 0x9c, 0x12, 0xa7, 0x3e, 0xe7, 0x38, 0xb3, 0x4, 0x2b, 0x6f, 0xc7, 0x23, 0xbb, 0xc3, 0x66, 0xdb, 0x38, 0x7, 0x0, 0xcf, 0x32, 0x34, 0xb6, 0x52, 0xb4, 0x3c, 0xf7, 0x35, 0x10, 0xd9, 0xf7, 0x6, 0x56, 0x93, 0x4, 0x4b, 0x0, 0x43, 0x28, 0xf9, 0x4a, 0x3d, 0x6e, 0xb0, 0x3e, 0x9, 0x31, 0xa9, 0x62, 0xd6, 0xc4, 0x36, 0x9c, 0xf2, 0xd9, 0xbd, 0x41, 0x2d, 0x24, 0x68, 0xc7, 0x1f, 0x62, 0x60, 0x6a, 0xc1, 0x7f, 0x95, 0x81, 0xaa, 0x13, 0x61, 0x9, 0xa6, 0xf6, 0x1c, 0x30, 0x17, 0x11, 0x6f, 0x48, 0x12, 0x3b, 0xf3, 0x7b, 0xc2, 0xeb, 0xca, 0x92, 0xb7, 0x72, 0x5f, 0x31, 0x90, 0x11, 0x4e, 0x48, 0xb3, 0x13, 0xa6, 0xcc, 0x3e, 0x51, 0x60, 0x91, 0x53, 0x55, 0x87, 0xf3, 0x2a, 0x98, 0xff, 0x7c, 0x6c, 0x1a, 0xf9, 0xec, 0xda, 0xeb, 0x94, 0x13, 0x43, 0xdd, 0x3f, 0x2a, 0x41, 0xd2, 0xb, 0x27, 0x65, 0xe8, 0x13, 0x20, 0x29, 0x3f, 0xc6, 0x7c, 0x48, 0x65, 0x8, 0x41, 0xda, 0xa4, 0xd5, 0x11, 0xc0, 0x2a, 0x61, 0xce, 0x18, 0x58, 0xd2, 0xbe, 0x98, 0x48, 0x96, 0xdd, 0xf5, 0xbc, 0x11, 0x65, 0xb6, 0x12, 0x55, 0xcb, 0xde, 0xb3, 0x78, 0x27, 0x78, 0xdc, 0xcb, 0x72, 0xe6, 0xd7, 0x8a, 0x27, 0xe6, 0x52, 0x1f, 0x10, 0xe0, 0xb8, 0x92, 0x81, 0xb4, 0x3f, 0x1, 0x1d, 0xed, 0x6c, 0xd4, 0xef, 0x12, 0x2f, 0x73, 0xa0, 0xe, 0xf, 0x42, 0x24, 0x20, 0xf, 0x91, 0xbf, 0x6e, 0x44, 0xfb, 0xde, 0xa1, 0x4, 0xa5, 0x7, 0xaa, 0xa0, 0x23, 0xad, 0xd4, 0x4b, 0xaa, 0x73, 0x0, 0xb7, 0xa1, 0x82, 0x87, 0x46, 0x74, 0x9a, 0xf, 0x48, 0x5d, 0xb3, 0xd, 0xa2, 0xb0, 0x96, 0xe5, 0x7d, 0xc8, 0x81, 0x19, 0xf1, 0x36, 0x2b, 0xba, 0xbd, 0x5e, 0xb3, 0xb7, 0x55, 0x12, 0x76, 0x90, 0xc4, 0x3a, 0x1, 0xa7, 0x66, 0xbc, 0x3, 0x90, 0xe0, 0x8, 0xc8, 0x42, 0x29, 0xa5, 0x7b, 0xa2, 0x63, 0x9f, 0x88, 0x26, 0xa, 0x9c, 0x85, 0x6f, 0x7b, 0x2b, 0x0, 0x92, 0x51, 0x4a, 0x81, 0x5c, 0x2a, 0xcb, 0x2a, 0x47, 0x0, 0xb0, 0x2b, 0x8, 0x11, 0x62, 0x20, 0x58, 0x20, 0x47, 0x77, 0x5a, 0xe5, 0x98, 0x43, 0x3f, 0x2, 0xd8, 0xc1, 0xa5, 0x39, 0x40, 0x82, 0xb5, 0xd9, 0xd7, 0x5a, 0x2, 0x59, 0x80, 0x9, 0x8a, 0x0, 0x7f, 0x1, 0x8, 0x44, 0x8, 0x64, 0xe0, 0xe8, 0x6e, 0x4b, 0xb4, 0x87, 0xa6, 0xc4, 0x3d, 0x17, 0x24, 0xa3, 0xa8, 0xc0, 0x32, 0x8a, 0xea, 0x33, 0x67, 0x0, 0x6e, 0xc, 0x94, 0x5e, 0xe2, 0x46, 0x11, 0x3a, 0x0, 0x82, 0x57, 0x1, 0x98, 0xbf, 0xb, 0xa4, 0xf6, 0x55, 0xd4, 0x2a, 0xe1, 0x0, 0x40, 0xf5, 0xf3, 0xa5, 0xd3, 0x16, 0x6a, 0xb4, 0xa7, 0x19, 0xfa, 0x4f, 0x18, 0xe8, 0x2c, 0x34, 0xfb, 0x92, 0x20, 0xbb, 0xf, 0xa3, 0x1d, 0xc0, 0xcd, 0xe7, 0xb7, 0x83, 0xf9, 0xf2, 0x24, 0xd3, 0xd7, 0xaf, 0x40, 0x9a, 0x84, 0x1, 0xf0, 0xfe, 0xf6, 0xee, 0x1d, 0x80, 0x4f, 0xff, 0xc8, 0xdf, 0x63, 0xeb, 0xfd, 0x6f, 0x3, 0x74, 0x35, 0xa7, 0x2a, 0xf0, 0x17, 0xed, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; diff --git a/scene/resources/default_theme/tree_bg_disabled.png b/scene/resources/default_theme/tree_bg_disabled.png Binary files differnew file mode 100644 index 0000000000..a0fa505e4c --- /dev/null +++ b/scene/resources/default_theme/tree_bg_disabled.png diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 15710f4c14..326320c60f 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -215,6 +215,13 @@ bool ShaderMaterial::_can_do_next_pass() const { return shader.is_valid() && shader->get_mode() == Shader::MODE_SPATIAL; } +Shader::Mode ShaderMaterial::get_shader_mode() const { + if (shader.is_valid()) + return shader->get_mode(); + else + return Shader::MODE_SPATIAL; +} + ShaderMaterial::ShaderMaterial() { } @@ -638,7 +645,7 @@ void SpatialMaterial::_update_shader() { code += "\tvec2 base_uv = UV;\n"; } - if ((features[FEATURE_DETAIL] && detail_uv == DETAIL_UV_2) || (features[FEATURE_AMBIENT_OCCLUSION] && flags[FLAG_AO_ON_UV2])) { + if ((features[FEATURE_DETAIL] && detail_uv == DETAIL_UV_2) || (features[FEATURE_AMBIENT_OCCLUSION] && flags[FLAG_AO_ON_UV2]) || (features[FEATURE_EMISSION] && flags[FLAG_EMISSION_ON_UV2])) { code += "\tvec2 base_uv2 = UV2;\n"; } @@ -722,11 +729,20 @@ void SpatialMaterial::_update_shader() { } if (features[FEATURE_EMISSION]) { - if (flags[FLAG_UV1_USE_TRIPLANAR]) { - code += "\tvec3 emission_tex = triplanar_texture(texture_emission,uv1_power_normal,uv1_triplanar_pos).rgb;\n"; + if (flags[FLAG_EMISSION_ON_UV2]) { + if (flags[FLAG_UV2_USE_TRIPLANAR]) { + code += "\tvec3 emission_tex = triplanar_texture(texture_emission,uv2_power_normal,uv2_triplanar_pos).rgb;\n"; + } else { + code += "\tvec3 emission_tex = texture(texture_emission,base_uv2).rgb;\n"; + } } else { - code += "\tvec3 emission_tex = texture(texture_emission,base_uv).rgb;\n"; + if (flags[FLAG_UV1_USE_TRIPLANAR]) { + code += "\tvec3 emission_tex = triplanar_texture(texture_emission,uv1_power_normal,uv1_triplanar_pos).rgb;\n"; + } else { + code += "\tvec3 emission_tex = texture(texture_emission,base_uv).rgb;\n"; + } } + if (emission_op == EMISSION_OP_ADD) { code += "\tEMISSION = (emission.rgb+emission_tex)*emission_energy;\n"; } else { @@ -1662,6 +1678,11 @@ RID SpatialMaterial::get_shader_rid() const { return shader_map[current_key].shader; } +Shader::Mode SpatialMaterial::get_shader_mode() const { + + return Shader::MODE_SPATIAL; +} + void SpatialMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo); @@ -1880,6 +1901,7 @@ void SpatialMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR, "emission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_emission", "get_emission"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_emission_energy", "get_emission_energy"); ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_operator", PROPERTY_HINT_ENUM, "Add,Multiply"), "set_emission_operator", "get_emission_operator"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "emission_on_uv2"), "set_flag", "get_flag", FLAG_EMISSION_ON_UV2); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "emission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION); ADD_GROUP("NormalMap", "normal_"); @@ -2022,6 +2044,7 @@ void SpatialMaterial::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_UV1_USE_TRIPLANAR); BIND_ENUM_CONSTANT(FLAG_UV2_USE_TRIPLANAR); BIND_ENUM_CONSTANT(FLAG_AO_ON_UV2); + BIND_ENUM_CONSTANT(FLAG_EMISSION_ON_UV2); BIND_ENUM_CONSTANT(FLAG_USE_ALPHA_SCISSOR); BIND_ENUM_CONSTANT(FLAG_TRIPLANAR_USE_WORLD); BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_FORCE_SRGB); @@ -2054,8 +2077,8 @@ void SpatialMaterial::_bind_methods() { BIND_ENUM_CONSTANT(EMISSION_OP_MULTIPLY); } -SpatialMaterial::SpatialMaterial() - : element(this) { +SpatialMaterial::SpatialMaterial() : + element(this) { //initialize to right values set_albedo(Color(1.0, 1.0, 1.0, 1.0)); diff --git a/scene/resources/material.h b/scene/resources/material.h index 374ec853dc..d5c3ef83e2 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -69,6 +69,8 @@ public: int get_render_priority() const; virtual RID get_rid() const; + + virtual Shader::Mode get_shader_mode() const = 0; Material(); virtual ~Material(); }; @@ -96,6 +98,8 @@ public: void set_shader_param(const StringName &p_param, const Variant &p_value); Variant get_shader_param(const StringName &p_param) const; + virtual Shader::Mode get_shader_mode() const; + ShaderMaterial(); ~ShaderMaterial(); }; @@ -180,6 +184,7 @@ public: FLAG_UV2_USE_TRIPLANAR, FLAG_TRIPLANAR_USE_WORLD, FLAG_AO_ON_UV2, + FLAG_EMISSION_ON_UV2, FLAG_USE_ALPHA_SCISSOR, FLAG_ALBEDO_TEXTURE_FORCE_SRGB, FLAG_MAX @@ -230,7 +235,7 @@ private: uint64_t blend_mode : 2; uint64_t depth_draw_mode : 2; uint64_t cull_mode : 2; - uint64_t flags : 13; + uint64_t flags : 14; uint64_t detail_blend_mode : 2; uint64_t diffuse_mode : 3; uint64_t specular_mode : 2; @@ -600,6 +605,8 @@ public: RID get_shader_rid() const; + virtual Shader::Mode get_shader_mode() const; + SpatialMaterial(); virtual ~SpatialMaterial(); }; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 0a886c25b1..bb33962be6 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -28,10 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "mesh.h" + +#include "pair.h" #include "scene/resources/concave_polygon_shape.h" #include "scene/resources/convex_polygon_shape.h" #include "surface_tool.h" +#include <stdlib.h> + void Mesh::_clear_triangle_mesh() const { triangle_mesh.unref(); @@ -413,8 +417,21 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { return newmesh; } +void Mesh::set_lightmap_size_hint(const Vector2 &p_size) { + lightmap_size_hint = p_size; +} + +Size2 Mesh::get_lightmap_size_hint() const { + return lightmap_size_hint; +} + void Mesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_lightmap_size_hint", "size"), &Mesh::set_lightmap_size_hint); + ClassDB::bind_method(D_METHOD("get_lightmap_size_hint"), &Mesh::get_lightmap_size_hint); + + ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint"); + BIND_ENUM_CONSTANT(PRIMITIVE_POINTS); BIND_ENUM_CONSTANT(PRIMITIVE_LINES); BIND_ENUM_CONSTANT(PRIMITIVE_LINE_STRIP); @@ -1035,6 +1052,202 @@ void ArrayMesh::regen_normalmaps() { } } +//dirty hack +bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) = NULL; + +struct ArrayMeshLightmapSurface { + + Ref<Material> material; + Vector<SurfaceTool::Vertex> vertices; + Mesh::PrimitiveType primitive; + uint32_t format; +}; + +Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) { + + ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED); + ERR_EXPLAIN("Can't unwrap mesh with blend shapes"); + ERR_FAIL_COND_V(blend_shapes.size() != 0, ERR_UNAVAILABLE); + + Vector<float> vertices; + Vector<float> normals; + Vector<int> indices; + Vector<int> face_materials; + Vector<float> uv; + Vector<Pair<int, int> > uv_index; + + Vector<ArrayMeshLightmapSurface> surfaces; + for (int i = 0; i < get_surface_count(); i++) { + ArrayMeshLightmapSurface s; + s.primitive = surface_get_primitive_type(i); + + if (s.primitive != Mesh::PRIMITIVE_TRIANGLES) { + ERR_EXPLAIN("Only triangles are supported for lightmap unwrap"); + ERR_FAIL_V(ERR_UNAVAILABLE); + } + s.format = surface_get_format(i); + if (!(s.format & ARRAY_FORMAT_NORMAL)) { + ERR_EXPLAIN("Normals are required for lightmap unwrap"); + ERR_FAIL_V(ERR_UNAVAILABLE); + } + + Array arrays = surface_get_arrays(i); + s.material = surface_get_material(i); + s.vertices = SurfaceTool::create_vertex_array_from_triangle_arrays(arrays); + + PoolVector<Vector3> rvertices = arrays[Mesh::ARRAY_VERTEX]; + int vc = rvertices.size(); + PoolVector<Vector3>::Read r = rvertices.read(); + + PoolVector<Vector3> rnormals = arrays[Mesh::ARRAY_NORMAL]; + PoolVector<Vector3>::Read rn = rnormals.read(); + + int vertex_ofs = vertices.size() / 3; + + vertices.resize((vertex_ofs + vc) * 3); + normals.resize((vertex_ofs + vc) * 3); + uv_index.resize(vertex_ofs + vc); + + for (int j = 0; j < vc; j++) { + + Vector3 v = p_base_transform.xform(r[j]); + + vertices[(j + vertex_ofs) * 3 + 0] = v.x; + vertices[(j + vertex_ofs) * 3 + 1] = v.y; + vertices[(j + vertex_ofs) * 3 + 2] = v.z; + normals[(j + vertex_ofs) * 3 + 0] = rn[j].x; + normals[(j + vertex_ofs) * 3 + 1] = rn[j].y; + normals[(j + vertex_ofs) * 3 + 2] = rn[j].z; + uv_index[j + vertex_ofs] = Pair<int, int>(i, j); + } + + PoolVector<int> rindices = arrays[Mesh::ARRAY_INDEX]; + int ic = rindices.size(); + + if (ic == 0) { + + for (int j = 0; j < vc / 3; j++) { + if (Face3(r[j * 3 + 0], r[j * 3 + 1], r[j * 3 + 2]).is_degenerate()) + continue; + + indices.push_back(vertex_ofs + j * 3 + 0); + indices.push_back(vertex_ofs + j * 3 + 1); + indices.push_back(vertex_ofs + j * 3 + 2); + face_materials.push_back(i); + } + + } else { + PoolVector<int>::Read ri = rindices.read(); + + for (int j = 0; j < ic / 3; j++) { + if (Face3(r[ri[j * 3 + 0]], r[ri[j * 3 + 1]], r[ri[j * 3 + 2]]).is_degenerate()) + continue; + indices.push_back(vertex_ofs + ri[j * 3 + 0]); + indices.push_back(vertex_ofs + ri[j * 3 + 1]); + indices.push_back(vertex_ofs + ri[j * 3 + 2]); + face_materials.push_back(i); + } + } + + surfaces.push_back(s); + } + + //unwrap + + float *gen_uvs; + int *gen_vertices; + int *gen_indices; + int gen_vertex_count; + int gen_index_count; + int size_x; + int size_y; + + bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), face_materials.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y); + + if (!ok) { + return ERR_CANT_CREATE; + } + + //remove surfaces + while (get_surface_count()) { + surface_remove(0); + } + + //create surfacetools for each surface.. + Vector<Ref<SurfaceTool> > surfaces_tools; + + for (int i = 0; i < surfaces.size(); i++) { + Ref<SurfaceTool> st; + st.instance(); + st->begin(Mesh::PRIMITIVE_TRIANGLES); + st->set_material(surfaces[i].material); + surfaces_tools.push_back(st); //stay there + } + + print_line("gen indices: " + itos(gen_index_count)); + //go through all indices + for (int i = 0; i < gen_index_count; i += 3) { + + ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_index.size(), ERR_BUG); + ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_index.size(), ERR_BUG); + ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_index.size(), ERR_BUG); + + ERR_FAIL_COND_V(uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 1]]].first || uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG); + + int surface = uv_index[gen_vertices[gen_indices[i + 0]]].first; + + for (int j = 0; j < 3; j++) { + + int vertex_idx = gen_vertices[gen_indices[i + j]]; + + SurfaceTool::Vertex v = surfaces[surface].vertices[uv_index[gen_vertices[gen_indices[i + j]]].second]; + + if (surfaces[surface].format & ARRAY_FORMAT_COLOR) { + surfaces_tools[surface]->add_color(v.color); + } + if (surfaces[surface].format & ARRAY_FORMAT_TEX_UV) { + surfaces_tools[surface]->add_uv(v.uv); + } + if (surfaces[surface].format & ARRAY_FORMAT_NORMAL) { + surfaces_tools[surface]->add_normal(v.normal); + } + if (surfaces[surface].format & ARRAY_FORMAT_TANGENT) { + Plane t; + t.normal = v.tangent; + t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1; + surfaces_tools[surface]->add_tangent(t); + } + if (surfaces[surface].format & ARRAY_FORMAT_BONES) { + surfaces_tools[surface]->add_bones(v.bones); + } + if (surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) { + surfaces_tools[surface]->add_weights(v.weights); + } + + Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]); + surfaces_tools[surface]->add_uv2(uv2); + + surfaces_tools[surface]->add_vertex(v.vertex); + } + } + + //free stuff + ::free(gen_vertices); + ::free(gen_indices); + ::free(gen_uvs); + + //generate surfaces + + for (int i = 0; i < surfaces_tools.size(); i++) { + surfaces_tools[i]->index(); + surfaces_tools[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), surfaces[i].format); + } + + set_lightmap_size_hint(Size2(size_x, size_y)); + + return OK; +} + void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index b85a6a84af..ea38ebf2ff 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -43,6 +43,8 @@ class Mesh : public Resource { GDCLASS(Mesh, Resource); mutable Ref<TriangleMesh> triangle_mesh; //cached + Size2 lightmap_size_hint; + protected: void _clear_triangle_mesh() const; @@ -138,6 +140,9 @@ public: virtual AABB get_aabb() const = 0; + void set_lightmap_size_hint(const Vector2 &p_size); + Size2 get_lightmap_size_hint() const; + Mesh(); }; @@ -216,6 +221,8 @@ public: void center_geometry(); void regen_normalmaps(); + Error lightmap_unwrap(const Transform &p_base_transform = Transform(), float p_texel_size = 0.05); + virtual void reload_from_file(); ArrayMesh(); diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 06829089be..3a5cb7da2e 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -177,7 +177,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { node = Object::cast_to<Node>(obj); } else { - print_line("wtf class is disabled for: " + itos(n.type)); + print_line("Class is disabled for: " + itos(n.type)); print_line("name: " + String(snames[n.type])); } diff --git a/scene/resources/plane_shape.cpp b/scene/resources/plane_shape.cpp index 2b1e890a5d..2eb2ceff24 100644 --- a/scene/resources/plane_shape.cpp +++ b/scene/resources/plane_shape.cpp @@ -86,8 +86,8 @@ void PlaneShape::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::PLANE, "plane"), "set_plane", "get_plane"); } -PlaneShape::PlaneShape() - : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_PLANE)) { +PlaneShape::PlaneShape() : + Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_PLANE)) { set_plane(Plane(0, 1, 0, 0)); } diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 3b80db291c..2e8f9cbb33 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -164,7 +164,7 @@ void PrimitiveMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("get_mesh_arrays"), &PrimitiveMesh::get_mesh_arrays); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material", "get_material"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material"); } void PrimitiveMesh::set_material(const Ref<Material> &p_material) { diff --git a/scene/resources/ray_shape.cpp b/scene/resources/ray_shape.cpp index ccce7660c6..b03a81b6bd 100644 --- a/scene/resources/ray_shape.cpp +++ b/scene/resources/ray_shape.cpp @@ -66,8 +66,8 @@ void RayShape::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_length", "get_length"); } -RayShape::RayShape() - : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_RAY)) { +RayShape::RayShape() : + Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_RAY)) { set_length(1.0); } diff --git a/scene/resources/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp index 69dbb76744..202024aa96 100644 --- a/scene/resources/rectangle_shape_2d.cpp +++ b/scene/resources/rectangle_shape_2d.cpp @@ -66,8 +66,8 @@ void RectangleShape2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "extents"), "set_extents", "get_extents"); } -RectangleShape2D::RectangleShape2D() - : Shape2D(Physics2DServer::get_singleton()->rectangle_shape_create()) { +RectangleShape2D::RectangleShape2D() : + Shape2D(Physics2DServer::get_singleton()->rectangle_shape_create()) { extents = Vector2(10, 10); _update_shape(); diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp index fe23fbf6b3..aebbb5b562 100644 --- a/scene/resources/scene_format_text.cpp +++ b/scene/resources/scene_format_text.cpp @@ -28,7 +28,7 @@ /* 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" #include "project_settings.h" #include "version.h" @@ -53,6 +53,60 @@ Ref<Resource> ResourceInteractiveLoaderText::get_resource() { return resource; } +Error ResourceInteractiveLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { + + VariantParser::Token token; + VariantParser::get_token(p_stream, token, line, r_err_str); + if (token.type != VariantParser::TK_NUMBER) { + r_err_str = "Expected number (sub-resource index)"; + return ERR_PARSE_ERROR; + } + + int index = token.value; + + if (!p_data->resource_map.has(index)) { + Ref<DummyResource> dr; + dr.instance(); + dr->set_subindex(index); + p_data->resource_map[index] = dr; + p_data->resource_set.insert(dr); + } + + r_res = p_data->resource_map[index]; + + VariantParser::get_token(p_stream, token, line, r_err_str); + if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) { + r_err_str = "Expected ')'"; + return ERR_PARSE_ERROR; + } + + return OK; +} + +Error ResourceInteractiveLoaderText::_parse_ext_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { + + VariantParser::Token token; + VariantParser::get_token(p_stream, token, line, r_err_str); + if (token.type != VariantParser::TK_NUMBER) { + r_err_str = "Expected number (sub-resource index)"; + return ERR_PARSE_ERROR; + } + + int id = token.value; + + ERR_FAIL_COND_V(!p_data->rev_external_resources.has(id), ERR_PARSE_ERROR); + + r_res = p_data->rev_external_resources[id]; + + VariantParser::get_token(p_stream, token, line, r_err_str); + if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) { + r_err_str = "Expected ')'"; + return ERR_PARSE_ERROR; + } + + return OK; +} + Error ResourceInteractiveLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { VariantParser::Token token; @@ -131,6 +185,203 @@ Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream * return OK; } +Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::ResourceParser &parser) { + Ref<PackedScene> packed_scene; + packed_scene.instance(); + + while (true) { + + if (next_tag.name == "node") { + + int parent = -1; + int owner = -1; + int type = -1; + int name = -1; + int instance = -1; + //int base_scene=-1; + + if (next_tag.fields.has("name")) { + name = packed_scene->get_state()->add_name(next_tag.fields["name"]); + } + + if (next_tag.fields.has("parent")) { + NodePath np = next_tag.fields["parent"]; + np.prepend_period(); //compatible to how it manages paths internally + parent = packed_scene->get_state()->add_node_path(np); + } + + if (next_tag.fields.has("type")) { + type = packed_scene->get_state()->add_name(next_tag.fields["type"]); + } else { + type = SceneState::TYPE_INSTANCED; //no type? assume this was instanced + } + + if (next_tag.fields.has("instance")) { + + instance = packed_scene->get_state()->add_value(next_tag.fields["instance"]); + + if (packed_scene->get_state()->get_node_count() == 0 && parent == -1) { + packed_scene->get_state()->set_base_scene(instance); + instance = -1; + } + } + + if (next_tag.fields.has("instance_placeholder")) { + + String path = next_tag.fields["instance_placeholder"]; + + int path_v = packed_scene->get_state()->add_value(path); + + if (packed_scene->get_state()->get_node_count() == 0) { + error = ERR_FILE_CORRUPT; + error_text = "Instance Placeholder can't be used for inheritance."; + _printerr(); + return Ref<PackedScene>(); + } + + instance = path_v | SceneState::FLAG_INSTANCE_IS_PLACEHOLDER; + } + + if (next_tag.fields.has("owner")) { + owner = packed_scene->get_state()->add_node_path(next_tag.fields["owner"]); + } else { + if (parent != -1 && !(type == SceneState::TYPE_INSTANCED && instance == -1)) + owner = 0; //if no owner, owner is root + } + + int node_id = packed_scene->get_state()->add_node(parent, owner, type, name, instance); + + if (next_tag.fields.has("groups")) { + + Array groups = next_tag.fields["groups"]; + for (int i = 0; i < groups.size(); i++) { + packed_scene->get_state()->add_node_group(node_id, packed_scene->get_state()->add_name(groups[i])); + } + } + + while (true) { + + String assign; + Variant value; + + error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &parser); + + if (error) { + if (error != ERR_FILE_EOF) { + _printerr(); + return Ref<PackedScene>(); + } else { + return packed_scene; + } + } + + if (assign != String()) { + int nameidx = packed_scene->get_state()->add_name(assign); + int valueidx = packed_scene->get_state()->add_value(value); + packed_scene->get_state()->add_node_property(node_id, nameidx, valueidx); + //it's assignment + } else if (next_tag.name != String()) { + break; + } + } + } else if (next_tag.name == "connection") { + + if (!next_tag.fields.has("from")) { + error = ERR_FILE_CORRUPT; + error_text = "missing 'from' field fron connection tag"; + return Ref<PackedScene>(); + } + + if (!next_tag.fields.has("to")) { + error = ERR_FILE_CORRUPT; + error_text = "missing 'to' field fron connection tag"; + return Ref<PackedScene>(); + } + + if (!next_tag.fields.has("signal")) { + error = ERR_FILE_CORRUPT; + error_text = "missing 'signal' field fron connection tag"; + return Ref<PackedScene>(); + } + + if (!next_tag.fields.has("method")) { + error = ERR_FILE_CORRUPT; + error_text = "missing 'method' field fron connection tag"; + return Ref<PackedScene>(); + } + + NodePath from = next_tag.fields["from"]; + NodePath to = next_tag.fields["to"]; + StringName method = next_tag.fields["method"]; + StringName signal = next_tag.fields["signal"]; + int flags = CONNECT_PERSIST; + Array binds; + + if (next_tag.fields.has("flags")) { + flags = next_tag.fields["flags"]; + } + + if (next_tag.fields.has("binds")) { + binds = next_tag.fields["binds"]; + } + + Vector<int> bind_ints; + for (int i = 0; i < binds.size(); i++) { + bind_ints.push_back(packed_scene->get_state()->add_value(binds[i])); + } + + packed_scene->get_state()->add_connection( + packed_scene->get_state()->add_node_path(from.simplified()), + packed_scene->get_state()->add_node_path(to.simplified()), + packed_scene->get_state()->add_name(signal), + packed_scene->get_state()->add_name(method), + flags, + bind_ints); + + error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &parser); + + if (error) { + if (error != ERR_FILE_EOF) { + _printerr(); + return Ref<PackedScene>(); + } else { + return packed_scene; + } + } + } else if (next_tag.name == "editable") { + + if (!next_tag.fields.has("path")) { + error = ERR_FILE_CORRUPT; + error_text = "missing 'path' field fron connection tag"; + _printerr(); + return Ref<PackedScene>(); + } + + NodePath path = next_tag.fields["path"]; + + packed_scene->get_state()->add_editable_instance(path.simplified()); + + error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &parser); + + if (error) { + if (error != ERR_FILE_EOF) { + _printerr(); + return Ref<PackedScene>(); + } else { + return packed_scene; + } + } + } else { + + error = ERR_FILE_CORRUPT; + _printerr(); + return Ref<PackedScene>(); + } + } + + return packed_scene; +} + Error ResourceInteractiveLoaderText::poll() { if (error != OK) @@ -364,231 +615,21 @@ Error ResourceInteractiveLoaderText::poll() { return error; } - /* - int add_name(const StringName& p_name); - int add_value(const Variant& p_value); - int add_node_path(const NodePath& p_path); - int add_node(int p_parent,int p_owner,int p_type,int p_name, int p_instance); - void add_node_property(int p_node,int p_name,int p_value); - void add_node_group(int p_node,int p_group); - void set_base_scene(int p_idx); - void add_connection(int p_from,int p_to, int p_signal, int p_method, int p_flags,const Vector<int>& p_binds); - void add_editable_instance(const NodePath& p_path); - - */ - - int parent = -1; - int owner = -1; - int type = -1; - int name = -1; - int instance = -1; - //int base_scene=-1; - - if (next_tag.fields.has("name")) { - name = packed_scene->get_state()->add_name(next_tag.fields["name"]); - } - - if (next_tag.fields.has("parent")) { - NodePath np = next_tag.fields["parent"]; - np.prepend_period(); //compatible to how it manages paths internally - parent = packed_scene->get_state()->add_node_path(np); - } - - if (next_tag.fields.has("type")) { - type = packed_scene->get_state()->add_name(next_tag.fields["type"]); - } else { - type = SceneState::TYPE_INSTANCED; //no type? assume this was instanced - } - - if (next_tag.fields.has("instance")) { - - instance = packed_scene->get_state()->add_value(next_tag.fields["instance"]); - - if (packed_scene->get_state()->get_node_count() == 0 && parent == -1) { - packed_scene->get_state()->set_base_scene(instance); - instance = -1; - } - } - - if (next_tag.fields.has("instance_placeholder")) { - - String path = next_tag.fields["instance_placeholder"]; - - int path_v = packed_scene->get_state()->add_value(path); - - if (packed_scene->get_state()->get_node_count() == 0) { - error = ERR_FILE_CORRUPT; - error_text = "Instance Placeholder can't be used for inheritance."; - _printerr(); - return error; - } - - instance = path_v | SceneState::FLAG_INSTANCE_IS_PLACEHOLDER; - } - - if (next_tag.fields.has("owner")) { - owner = packed_scene->get_state()->add_node_path(next_tag.fields["owner"]); - } else { - if (parent != -1 && !(type == SceneState::TYPE_INSTANCED && instance == -1)) - owner = 0; //if no owner, owner is root - } - - int node_id = packed_scene->get_state()->add_node(parent, owner, type, name, instance); - - if (next_tag.fields.has("groups")) { - - Array groups = next_tag.fields["groups"]; - for (int i = 0; i < groups.size(); i++) { - packed_scene->get_state()->add_node_group(node_id, packed_scene->get_state()->add_name(groups[i])); - } - } - - while (true) { - - String assign; - Variant value; - - error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &rp); - - if (error) { - if (error != ERR_FILE_EOF) { - _printerr(); - } else { - resource = packed_scene; - if (!ResourceCache::has(res_path)) { - packed_scene->set_path(res_path); - } - } - return error; - } - - if (assign != String()) { - int nameidx = packed_scene->get_state()->add_name(assign); - int valueidx = packed_scene->get_state()->add_value(value); - packed_scene->get_state()->add_node_property(node_id, nameidx, valueidx); - //it's assignment - } else if (next_tag.name != String()) { - - error = OK; - return error; - } else { - - resource = packed_scene; - error = ERR_FILE_EOF; - return error; - } - } - - return OK; - - } else if (next_tag.name == "connection") { - - if (!is_scene) { - - error_text += "found the 'connection' tag on a resource file!"; - _printerr(); - error = ERR_FILE_CORRUPT; - return error; - } - - if (!next_tag.fields.has("from")) { - error = ERR_FILE_CORRUPT; - error_text = "missing 'from' field fron connection tag"; - return error; - } - - if (!next_tag.fields.has("to")) { - error = ERR_FILE_CORRUPT; - error_text = "missing 'to' field fron connection tag"; - return error; - } - - if (!next_tag.fields.has("signal")) { - error = ERR_FILE_CORRUPT; - error_text = "missing 'signal' field fron connection tag"; - return error; - } - - if (!next_tag.fields.has("method")) { - error = ERR_FILE_CORRUPT; - error_text = "missing 'method' field fron connection tag"; - return error; - } - - NodePath from = next_tag.fields["from"]; - NodePath to = next_tag.fields["to"]; - StringName method = next_tag.fields["method"]; - StringName signal = next_tag.fields["signal"]; - int flags = CONNECT_PERSIST; - Array binds; - - if (next_tag.fields.has("flags")) { - flags = next_tag.fields["flags"]; - } - - if (next_tag.fields.has("binds")) { - binds = next_tag.fields["binds"]; - } - - Vector<int> bind_ints; - for (int i = 0; i < binds.size(); i++) { - bind_ints.push_back(packed_scene->get_state()->add_value(binds[i])); - } - - packed_scene->get_state()->add_connection( - packed_scene->get_state()->add_node_path(from.simplified()), - packed_scene->get_state()->add_node_path(to.simplified()), - packed_scene->get_state()->add_name(signal), - packed_scene->get_state()->add_name(method), - flags, - bind_ints); - - error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp); - - if (error) { - if (error != ERR_FILE_EOF) { - _printerr(); - } else { - resource = packed_scene; - } - } - - return error; - } else if (next_tag.name == "editable") { + Ref<PackedScene> packed_scene = _parse_node_tag(rp); - if (!is_scene) { - - error_text += "found the 'editable' tag on a resource file!"; - _printerr(); - error = ERR_FILE_CORRUPT; + if (!packed_scene.is_valid()) return error; - } - if (!next_tag.fields.has("path")) { - error = ERR_FILE_CORRUPT; - error_text = "missing 'path' field fron connection tag"; - _printerr(); - return error; + error = OK; + //get it here + resource = packed_scene; + if (!ResourceCache::has(res_path)) { + packed_scene->set_path(res_path); } - NodePath path = next_tag.fields["path"]; - - packed_scene->get_state()->add_editable_instance(path.simplified()); - - error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp); - - if (error) { - if (error != ERR_FILE_EOF) { - _printerr(); - } else { - resource = packed_scene; - } - } - - return error; + return ERR_FILE_EOF; } else { - error_text += "Unknown tag in file: " + next_tag.name; _printerr(); error = ERR_FILE_CORRUPT; @@ -804,7 +845,6 @@ void ResourceInteractiveLoaderText::open(FileAccess *p_f, bool p_skip_first_tag) if (tag.name == "gd_scene") { is_scene = true; - packed_scene.instance(); } else if (tag.name == "gd_resource") { if (!tag.fields.has("type")) { @@ -846,6 +886,281 @@ void ResourceInteractiveLoaderText::open(FileAccess *p_f, bool p_skip_first_tag) rp.userdata = this; } +static void bs_save_unicode_string(FileAccess *f, const String &p_string, bool p_bit_on_len = false) { + + CharString utf8 = p_string.utf8(); + if (p_bit_on_len) { + f->store_32(utf8.length() + 1 | 0x80000000); + } else { + f->store_32(utf8.length() + 1); + } + f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1); +} + +Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) { + + if (error) + return error; + + FileAccessRef wf = FileAccess::open(p_path, FileAccess::WRITE); + if (!wf) { + return ERR_CANT_OPEN; + } + + //save header compressed + static const uint8_t header[4] = { 'R', 'S', 'R', 'C' }; + wf->store_buffer(header, 4); + + wf->store_32(0); //endianness, little endian + wf->store_32(0); //64 bits file, false for now + wf->store_32(VERSION_MAJOR); + wf->store_32(VERSION_MINOR); + static const int save_format_version = 3; //use format version 3 for saving + wf->store_32(save_format_version); + + bs_save_unicode_string(wf.f, is_scene ? "PackedScene" : resource_type); + wf->store_64(0); //offset to import metadata, this is no longer used + for (int i = 0; i < 14; i++) + wf->store_32(0); // reserved + + wf->store_32(0); //string table size, will not be in use + size_t ext_res_count_pos = wf->get_position(); + + wf->store_32(0); //zero ext resources, still parsing them + + //go with external resources + + DummyReadData dummy_read; + VariantParser::ResourceParser rp; + rp.ext_func = _parse_ext_resource_dummys; + rp.sub_func = _parse_sub_resource_dummys; + rp.userdata = &dummy_read; + + while (next_tag.name == "ext_resource") { + + if (!next_tag.fields.has("path")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'path' in external resource tag"; + _printerr(); + return error; + } + + if (!next_tag.fields.has("type")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'type' in external resource tag"; + _printerr(); + return error; + } + + if (!next_tag.fields.has("id")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'id' in external resource tag"; + _printerr(); + return error; + } + + String path = next_tag.fields["path"]; + String type = next_tag.fields["type"]; + int index = next_tag.fields["id"]; + + bs_save_unicode_string(wf.f, type); + bs_save_unicode_string(wf.f, path); + + int lindex = dummy_read.external_resources.size(); + Ref<DummyResource> dr; + dr.instance(); + dr->set_path("res://dummy" + itos(lindex)); //anything is good to detect it for saving as external + dummy_read.external_resources[dr] = lindex; + dummy_read.rev_external_resources[index] = dr; + + error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp); + + if (error) { + _printerr(); + return error; + } + } + + // save external resource table + wf->seek(ext_res_count_pos); + wf->store_32(dummy_read.external_resources.size()); + wf->seek_end(); + + //now, save resources to a separate file, for now + + size_t sub_res_count_pos = wf->get_position(); + wf->store_32(0); //zero sub resources, still parsing them + + String temp_file = p_path + ".temp"; + FileAccessRef wf2 = FileAccess::open(temp_file, FileAccess::WRITE); + if (!wf2) { + return ERR_CANT_OPEN; + } + + Vector<size_t> local_offsets; + Vector<size_t> local_pointers_pos; + + while (next_tag.name == "sub_resource" || next_tag.name == "resource") { + + String type; + int id = -1; + bool main_res; + + if (next_tag.name == "sub_resource") { + if (!next_tag.fields.has("type")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'type' in external resource tag"; + _printerr(); + return error; + } + + if (!next_tag.fields.has("id")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'index' in external resource tag"; + _printerr(); + return error; + } + + type = next_tag.fields["type"]; + id = next_tag.fields["id"]; + main_res = false; + } else { + type = res_type; + id = 0; //used for last anyway + main_res = true; + } + + local_offsets.push_back(wf2->get_position()); + + bs_save_unicode_string(wf, "local://" + itos(id)); + local_pointers_pos.push_back(wf->get_position()); + wf->store_64(0); //temp local offset + + bs_save_unicode_string(wf2, type); + size_t propcount_ofs = wf2->get_position(); + wf2->store_32(0); + + int prop_count = 0; + + while (true) { + + String assign; + Variant value; + + error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &rp); + + if (error) { + if (main_res && error == ERR_FILE_EOF) { + next_tag.name = ""; //exit + break; + } + + _printerr(); + return error; + } + + if (assign != String()) { + + Map<StringName, int> empty_string_map; //unused + bs_save_unicode_string(wf2, assign, true); + ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_set, dummy_read.external_resources, empty_string_map); + prop_count++; + + } else if (next_tag.name != String()) { + + error = OK; + break; + } else { + error = ERR_FILE_CORRUPT; + error_text = "Premature end of file while parsing [sub_resource]"; + _printerr(); + return error; + } + } + + wf2->seek(propcount_ofs); + wf2->store_32(prop_count); + wf2->seek_end(); + } + + if (next_tag.name == "node") { + //this is a node, must save one more! + + if (!is_scene) { + + error_text += "found the 'node' tag on a resource file!"; + _printerr(); + error = ERR_FILE_CORRUPT; + return error; + } + + Ref<PackedScene> packed_scene = _parse_node_tag(rp); + + if (!packed_scene.is_valid()) + return error; + + error = OK; + //get it here + List<PropertyInfo> props; + packed_scene->get_property_list(&props); + + bs_save_unicode_string(wf, "local://0"); + local_pointers_pos.push_back(wf->get_position()); + wf->store_64(0); //temp local offset + + local_offsets.push_back(wf2->get_position()); + bs_save_unicode_string(wf2, "PackedScene"); + size_t propcount_ofs = wf2->get_position(); + wf2->store_32(0); + + int prop_count = 0; + + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) + continue; + + String name = E->get().name; + Variant value = packed_scene->get(name); + + Map<StringName, int> empty_string_map; //unused + bs_save_unicode_string(wf2, name, true); + ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_set, dummy_read.external_resources, empty_string_map); + prop_count++; + } + + wf2->seek(propcount_ofs); + wf2->store_32(prop_count); + wf2->seek_end(); + } + + wf2->close(); + + size_t offset_from = wf->get_position(); + wf->seek(sub_res_count_pos); //plus one because the saved one + wf->store_32(local_offsets.size()); + + for (int i = 0; i < local_offsets.size(); i++) { + wf->seek(local_pointers_pos[i]); + wf->store_64(local_offsets[i] + offset_from); + } + + wf->seek_end(); + + Vector<uint8_t> data = FileAccess::get_file_as_array(temp_file); + wf->store_buffer(data.ptr(), data.size()); + { + DirAccessRef dar = DirAccess::open(temp_file.get_base_dir()); + dar->remove(temp_file); + } + + wf->store_buffer((const uint8_t *)"RSRC", 4); //magic at end + + wf->close(); + + return OK; +} + String ResourceInteractiveLoaderText::recognize(FileAccess *p_f) { error = OK; @@ -991,6 +1306,25 @@ Error ResourceFormatLoaderText::rename_dependencies(const String &p_path, const return ria->rename_dependencies(f, p_path, p_map); } +Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path, const String &p_dst_path) { + + Error err; + FileAccess *f = FileAccess::open(p_src_path, FileAccess::READ, &err); + + if (err != OK) { + + ERR_FAIL_COND_V(err != OK, ERR_CANT_OPEN); + } + + Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText); + String path = p_src_path; + ria->local_path = ProjectSettings::get_singleton()->localize_path(path); + ria->res_path = ria->local_path; + //ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); + ria->open(f); + return ria->save_as_binary(f, p_dst_path); +} + /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ diff --git a/scene/resources/scene_format_text.h b/scene/resources/scene_format_text.h index a72a62037c..5d3c2004c1 100644 --- a/scene/resources/scene_format_text.h +++ b/scene/resources/scene_format_text.h @@ -78,9 +78,26 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader { Error _parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str); Error _parse_ext_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str); - VariantParser::ResourceParser rp; + // for converter + class DummyResource : public Resource { + public: + }; - Ref<PackedScene> packed_scene; + struct DummyReadData { + + Map<RES, int> external_resources; + Map<int, RES> rev_external_resources; + Set<RES> resource_set; + Map<int, RES> resource_map; + }; + + static Error _parse_sub_resource_dummys(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return _parse_sub_resource_dummy((DummyReadData *)(p_self), p_stream, r_res, line, r_err_str); } + static Error _parse_ext_resource_dummys(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return _parse_ext_resource_dummy((DummyReadData *)(p_self), p_stream, r_res, line, r_err_str); } + + static Error _parse_sub_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str); + static Error _parse_ext_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str); + + VariantParser::ResourceParser rp; friend class ResourceFormatLoaderText; @@ -89,6 +106,8 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader { RES resource; + Ref<PackedScene> _parse_node_tag(VariantParser::ResourceParser &parser); + public: virtual void set_local_path(const String &p_local_path); virtual Ref<Resource> get_resource(); @@ -102,6 +121,7 @@ public: void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types); Error rename_dependencies(FileAccess *p_f, const String &p_path, const Map<String, String> &p_map); + Error save_as_binary(FileAccess *p_f, const String &p_path); ResourceInteractiveLoaderText(); ~ResourceInteractiveLoaderText(); }; @@ -115,6 +135,8 @@ public: virtual String get_resource_type(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); 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); }; class ResourceFormatSaverTextInstance { diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp index 7c7ec0d112..e8ef448e23 100644 --- a/scene/resources/segment_shape_2d.cpp +++ b/scene/resources/segment_shape_2d.cpp @@ -86,8 +86,8 @@ void SegmentShape2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "b"), "set_b", "get_b"); } -SegmentShape2D::SegmentShape2D() - : Shape2D(Physics2DServer::get_singleton()->segment_shape_create()) { +SegmentShape2D::SegmentShape2D() : + Shape2D(Physics2DServer::get_singleton()->segment_shape_create()) { a = Vector2(); b = Vector2(0, 10); @@ -145,8 +145,8 @@ real_t RayShape2D::get_length() const { return length; } -RayShape2D::RayShape2D() - : Shape2D(Physics2DServer::get_singleton()->ray_shape_create()) { +RayShape2D::RayShape2D() : + Shape2D(Physics2DServer::get_singleton()->ray_shape_create()) { length = 20; _update_shape(); diff --git a/scene/resources/shape_line_2d.cpp b/scene/resources/shape_line_2d.cpp index d046ce876c..512ff3bc56 100644 --- a/scene/resources/shape_line_2d.cpp +++ b/scene/resources/shape_line_2d.cpp @@ -95,8 +95,8 @@ void LineShape2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "d"), "set_d", "get_d"); } -LineShape2D::LineShape2D() - : Shape2D(Physics2DServer::get_singleton()->line_shape_create()) { +LineShape2D::LineShape2D() : + Shape2D(Physics2DServer::get_singleton()->line_shape_create()) { normal = Vector2(0, -1); d = 0; diff --git a/scene/resources/sky_box.cpp b/scene/resources/sky_box.cpp index 2ef20f67f5..a2c3f1f111 100644 --- a/scene/resources/sky_box.cpp +++ b/scene/resources/sky_box.cpp @@ -180,7 +180,7 @@ Ref<Image> ProceduralSky::_generate_sky() { normal.normalize(); - float v_angle = Math::acos(normal.y); + float v_angle = Math::acos(CLAMP(normal.y, -1.0, 1.0)); Color color; @@ -193,7 +193,7 @@ Ref<Image> ProceduralSky::_generate_sky() { float c = v_angle / (Math_PI * 0.5); color = sky_horizon_linear.linear_interpolate(sky_top_linear, Math::ease(1.0 - c, sky_curve)); - float sun_angle = Math::rad2deg(Math::acos(sun.dot(normal))); + float sun_angle = Math::rad2deg(Math::acos(CLAMP(sun.dot(normal), -1.0, 1.0))); if (sun_angle < sun_angle_min) { color = color.blend(sun_color); diff --git a/scene/resources/sphere_shape.cpp b/scene/resources/sphere_shape.cpp index 00203c2b4b..042988dcd3 100644 --- a/scene/resources/sphere_shape.cpp +++ b/scene/resources/sphere_shape.cpp @@ -80,8 +80,8 @@ void SphereShape::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_radius", "get_radius"); } -SphereShape::SphereShape() - : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_SPHERE)) { +SphereShape::SphereShape() : + Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_SPHERE)) { set_radius(1.0); } diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index bf89e704bc..d8600e041d 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -101,6 +101,7 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) { vtx.color = last_color; vtx.normal = last_normal; vtx.uv = last_uv; + vtx.uv2 = last_uv2; vtx.weights = last_weights; vtx.bones = last_bones; vtx.tangent = last_tangent.normal; @@ -401,7 +402,7 @@ Array SurfaceTool::commit_to_arrays() { return a; } -Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) { +Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing, uint32_t p_flags) { Ref<ArrayMesh> mesh; if (p_existing.is_valid()) @@ -418,7 +419,7 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) { Array a = commit_to_arrays(); - mesh->add_surface_from_arrays(primitive, a); + mesh->add_surface_from_arrays(primitive, a, Array(), p_flags); if (material.is_valid()) mesh->surface_set_material(surface, material); @@ -482,6 +483,113 @@ void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List< _create_list_from_arrays(arr, r_vertex, r_index, lformat); } +Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays) { + + Vector<SurfaceTool::Vertex> ret; + + PoolVector<Vector3> varr = p_arrays[VS::ARRAY_VERTEX]; + PoolVector<Vector3> narr = p_arrays[VS::ARRAY_NORMAL]; + PoolVector<float> tarr = p_arrays[VS::ARRAY_TANGENT]; + PoolVector<Color> carr = p_arrays[VS::ARRAY_COLOR]; + PoolVector<Vector2> uvarr = p_arrays[VS::ARRAY_TEX_UV]; + PoolVector<Vector2> uv2arr = p_arrays[VS::ARRAY_TEX_UV2]; + PoolVector<int> barr = p_arrays[VS::ARRAY_BONES]; + PoolVector<float> warr = p_arrays[VS::ARRAY_WEIGHTS]; + + int vc = varr.size(); + + if (vc == 0) + return ret; + int lformat = 0; + + PoolVector<Vector3>::Read rv; + if (varr.size()) { + lformat |= VS::ARRAY_FORMAT_VERTEX; + rv = varr.read(); + } + PoolVector<Vector3>::Read rn; + if (narr.size()) { + lformat |= VS::ARRAY_FORMAT_NORMAL; + rn = narr.read(); + } + PoolVector<float>::Read rt; + if (tarr.size()) { + lformat |= VS::ARRAY_FORMAT_TANGENT; + rt = tarr.read(); + } + PoolVector<Color>::Read rc; + if (carr.size()) { + lformat |= VS::ARRAY_FORMAT_COLOR; + rc = carr.read(); + } + + PoolVector<Vector2>::Read ruv; + if (uvarr.size()) { + lformat |= VS::ARRAY_FORMAT_TEX_UV; + ruv = uvarr.read(); + } + + PoolVector<Vector2>::Read ruv2; + if (uv2arr.size()) { + lformat |= VS::ARRAY_FORMAT_TEX_UV2; + ruv2 = uv2arr.read(); + } + + PoolVector<int>::Read rb; + if (barr.size()) { + lformat |= VS::ARRAY_FORMAT_BONES; + rb = barr.read(); + } + + PoolVector<float>::Read rw; + if (warr.size()) { + lformat |= VS::ARRAY_FORMAT_WEIGHTS; + rw = warr.read(); + } + + for (int i = 0; i < vc; i++) { + + Vertex v; + if (lformat & VS::ARRAY_FORMAT_VERTEX) + v.vertex = varr[i]; + if (lformat & VS::ARRAY_FORMAT_NORMAL) + v.normal = narr[i]; + if (lformat & VS::ARRAY_FORMAT_TANGENT) { + Plane p(tarr[i * 4 + 0], tarr[i * 4 + 1], tarr[i * 4 + 2], tarr[i * 4 + 3]); + v.tangent = p.normal; + v.binormal = p.normal.cross(v.tangent).normalized() * p.d; + } + if (lformat & VS::ARRAY_FORMAT_COLOR) + v.color = carr[i]; + if (lformat & VS::ARRAY_FORMAT_TEX_UV) + v.uv = uvarr[i]; + if (lformat & VS::ARRAY_FORMAT_TEX_UV2) + v.uv2 = uv2arr[i]; + if (lformat & VS::ARRAY_FORMAT_BONES) { + Vector<int> b; + b.resize(4); + b[0] = barr[i * 4 + 0]; + b[1] = barr[i * 4 + 1]; + b[2] = barr[i * 4 + 2]; + b[3] = barr[i * 4 + 3]; + v.bones = b; + } + if (lformat & VS::ARRAY_FORMAT_WEIGHTS) { + Vector<float> w; + w.resize(4); + w[0] = warr[i * 4 + 0]; + w[1] = warr[i * 4 + 1]; + w[2] = warr[i * 4 + 2]; + w[3] = warr[i * 4 + 3]; + v.weights = w; + } + + ret.push_back(v); + } + + return ret; +} + void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) { PoolVector<Vector3> varr = arr[VS::ARRAY_VERTEX]; @@ -882,7 +990,7 @@ void SurfaceTool::_bind_methods() { ClassDB::bind_method(D_METHOD("create_from", "existing", "surface"), &SurfaceTool::create_from); ClassDB::bind_method(D_METHOD("append_from", "existing", "surface", "transform"), &SurfaceTool::append_from); - ClassDB::bind_method(D_METHOD("commit", "existing"), &SurfaceTool::commit, DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("commit", "existing", "flags"), &SurfaceTool::commit, DEFVAL(Variant()), DEFVAL(Mesh::ARRAY_COMPRESS_DEFAULT)); } SurfaceTool::SurfaceTool() { diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index cdaac643de..b180ffe260 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -127,10 +127,11 @@ public: List<Vertex> &get_vertex_array() { return vertex_array; } void create_from_triangle_arrays(const Array &p_arrays); + static Vector<Vertex> create_vertex_array_from_triangle_arrays(const Array &p_arrays); Array commit_to_arrays(); void create_from(const Ref<Mesh> &p_existing, int p_surface); void append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform); - Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>()); + Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>(), uint32_t p_flags = Mesh::ARRAY_COMPRESS_DEFAULT); SurfaceTool(); }; diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 6fab597d2b..bd6b917d4e 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -83,7 +83,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { } } } else if (what == "occluder_map") { - tile_map[id].autotile_data.ocludder_map.clear(); + tile_map[id].autotile_data.occluder_map.clear(); Array p = p_value; Vector2 last_coord; while (p.size() > 0) { @@ -194,7 +194,7 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const { r_ret = p; } else if (what == "occluder_map") { Array p; - for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = tile_map[id].autotile_data.ocludder_map.front(); E; E = E->next()) { + for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = tile_map[id].autotile_data.occluder_map.front(); E; E = E->next()) { p.push_back(E->key()); p.push_back(E->value()); } @@ -643,20 +643,20 @@ Ref<OccluderPolygon2D> TileSet::tile_get_light_occluder(int p_id) const { void TileSet::autotile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder, const Vector2 &p_coord) { ERR_FAIL_COND(!tile_map.has(p_id)); if (p_light_occluder.is_null()) { - if (tile_map[p_id].autotile_data.ocludder_map.has(p_coord)) { - tile_map[p_id].autotile_data.ocludder_map.erase(p_coord); + if (tile_map[p_id].autotile_data.occluder_map.has(p_coord)) { + tile_map[p_id].autotile_data.occluder_map.erase(p_coord); } } else { - tile_map[p_id].autotile_data.ocludder_map[p_coord] = p_light_occluder; + tile_map[p_id].autotile_data.occluder_map[p_coord] = p_light_occluder; } } Ref<OccluderPolygon2D> TileSet::autotile_get_light_occluder(int p_id, const Vector2 &p_coord) const { ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<OccluderPolygon2D>()); - if (!tile_map[p_id].autotile_data.ocludder_map.has(p_coord)) { + if (!tile_map[p_id].autotile_data.occluder_map.has(p_coord)) { return Ref<OccluderPolygon2D>(); } else { - return tile_map[p_id].autotile_data.ocludder_map[p_coord]; + return tile_map[p_id].autotile_data.occluder_map[p_coord]; } } @@ -688,7 +688,7 @@ const Map<Vector2, Ref<OccluderPolygon2D> > &TileSet::autotile_get_light_oclusio static Map<Vector2, Ref<OccluderPolygon2D> > dummy; ERR_FAIL_COND_V(!tile_map.has(p_id), dummy); - return tile_map[p_id].autotile_data.ocludder_map; + return tile_map[p_id].autotile_data.occluder_map; } void TileSet::autotile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon, const Vector2 &p_coord) { @@ -932,8 +932,8 @@ void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("find_tile_by_name", "name"), &TileSet::find_tile_by_name); ClassDB::bind_method(D_METHOD("get_tiles_ids"), &TileSet::_get_tiles_ids); - BIND_VMETHOD(MethodInfo("_is_tile_bound", PropertyInfo(Variant::INT, "drawn_id"), PropertyInfo(Variant::INT, "neighbor_id"))); - BIND_VMETHOD(MethodInfo("_forward_subtile_selection", PropertyInfo(Variant::INT, "autotile_id"), PropertyInfo(Variant::INT, "bitmask"), PropertyInfo(Variant::OBJECT, "tilemap", PROPERTY_HINT_NONE, "TileMap"), PropertyInfo(Variant::VECTOR2, "tile_location"))); + BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_tile_bound", PropertyInfo(Variant::INT, "drawn_id"), PropertyInfo(Variant::INT, "neighbor_id"))); + BIND_VMETHOD(MethodInfo(Variant::VECTOR2, "_forward_subtile_selection", PropertyInfo(Variant::INT, "autotile_id"), PropertyInfo(Variant::INT, "bitmask"), PropertyInfo(Variant::OBJECT, "tilemap", PROPERTY_HINT_NONE, "TileMap"), PropertyInfo(Variant::VECTOR2, "tile_location"))); BIND_ENUM_CONSTANT(BITMASK_2X2); BIND_ENUM_CONSTANT(BITMASK_3X3); diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 18b62c778d..deac583f62 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -76,13 +76,14 @@ public: Size2 size; Vector2 icon_coord; Map<Vector2, uint16_t> flags; - Map<Vector2, Ref<OccluderPolygon2D> > ocludder_map; + Map<Vector2, Ref<OccluderPolygon2D> > occluder_map; Map<Vector2, Ref<NavigationPolygon> > navpoly_map; Map<Vector2, int> priority_map; // Default size to prevent invalid value - explicit AutotileData() - : size(64, 64), icon_coord(0, 0) { + explicit AutotileData() : + size(64, 64), + icon_coord(0, 0) { bitmask_mode = BITMASK_2X2; } }; @@ -106,8 +107,9 @@ private: AutotileData autotile_data; // Default modulate for back-compat - explicit TileData() - : modulate(1, 1, 1), is_autotile(false) {} + explicit TileData() : + modulate(1, 1, 1), + is_autotile(false) {} }; Map<int, TileData> tile_map; |