diff options
Diffstat (limited to 'scene/2d')
-rw-r--r-- | scene/2d/audio_stream_player_2d.cpp | 58 | ||||
-rw-r--r-- | scene/2d/collision_polygon_2d.cpp | 3 | ||||
-rw-r--r-- | scene/2d/light_2d.cpp | 7 | ||||
-rw-r--r-- | scene/2d/line_2d.cpp | 15 | ||||
-rw-r--r-- | scene/2d/line_2d.h | 19 | ||||
-rw-r--r-- | scene/2d/line_builder.cpp | 52 | ||||
-rw-r--r-- | scene/2d/line_builder.h | 27 | ||||
-rw-r--r-- | scene/2d/physics_body_2d.cpp | 224 | ||||
-rw-r--r-- | scene/2d/physics_body_2d.h | 52 | ||||
-rw-r--r-- | scene/2d/screen_button.cpp | 3 |
10 files changed, 259 insertions, 201 deletions
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index d2a8e3315a..b6abe90035 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -57,52 +57,32 @@ void AudioStreamPlayer2D::_mix_audio() { AudioFrame vol_inc = (current.vol - prev_outputs[i].vol) / float(buffer_size); AudioFrame vol = current.vol; - switch (AudioServer::get_singleton()->get_speaker_mode()) { + int cc = AudioServer::get_singleton()->get_channel_count(); - case AudioServer::SPEAKER_MODE_STEREO: { - AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 0); + if (cc == 1) { + AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 0); - for (int j = 0; j < buffer_size; j++) { + for (int j = 0; j < buffer_size; j++) { - target[j] += buffer[j] * vol; - vol += vol_inc; - } - - } break; - case AudioServer::SPEAKER_SURROUND_51: { - - AudioFrame *targets[2] = { - AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 1), - AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 2), - }; - - for (int j = 0; j < buffer_size; j++) { - - AudioFrame frame = buffer[j] * vol; - targets[0][j] += frame; - targets[1][j] += frame; - vol += vol_inc; - } + target[j] += buffer[j] * vol; + vol += vol_inc; + } - } break; - case AudioServer::SPEAKER_SURROUND_71: { + } else { + AudioFrame *targets[4]; - AudioFrame *targets[3] = { - AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 1), - AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 2), - AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 3) - }; + for (int k = 0; k < cc; k++) { + targets[k] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k); + } - for (int j = 0; j < buffer_size; j++) { + for (int j = 0; j < buffer_size; j++) { - AudioFrame frame = buffer[j] * vol; - targets[0][j] += frame; - targets[1][j] += frame; - targets[2][j] += frame; - vol += vol_inc; + AudioFrame frame = buffer[j] * vol; + for (int k = 0; k < cc; k++) { + targets[k][j] += frame; } - - } break; + vol += vol_inc; + } } prev_outputs[i] = current; @@ -439,7 +419,7 @@ void AudioStreamPlayer2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "play", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_RANGE, "1,65536,1"), "set_max_distance", "get_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation", PROPERTY_HINT_EXP_EASING), "set_attenuation", "get_attenuation"); diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index e2764a6e8d..a840744c78 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -302,6 +302,9 @@ void CollisionPolygon2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "one_way_collision"), "set_one_way_collision", "is_one_way_collision_enabled"); + + BIND_ENUM_CONSTANT(BUILD_SOLIDS); + BIND_ENUM_CONSTANT(BUILD_SEGMENTS); } CollisionPolygon2D::CollisionPolygon2D() { diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 1bca2c6f37..516acefe2a 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -443,6 +443,13 @@ void Light2D::_bind_methods() { BIND_ENUM_CONSTANT(MODE_SUB); BIND_ENUM_CONSTANT(MODE_MIX); BIND_ENUM_CONSTANT(MODE_MASK); + + BIND_ENUM_CONSTANT(SHADOW_FILTER_NONE); + BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF3); + BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF5); + BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF7); + BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF9); + BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF13); } Light2D::Light2D() { diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index c87a9a5b1e..d8cef5b937 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -28,13 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "line_2d.h" +#include "line_builder.h" #include "core_string_names.h" // Needed so we can bind functions -VARIANT_ENUM_CAST(LineJointMode) -VARIANT_ENUM_CAST(LineCapMode) -VARIANT_ENUM_CAST(LineTextureMode) +VARIANT_ENUM_CAST(Line2D::LineJointMode) +VARIANT_ENUM_CAST(Line2D::LineCapMode) +VARIANT_ENUM_CAST(Line2D::LineTextureMode) Line2D::Line2D() : Node2D() { @@ -134,7 +135,7 @@ void Line2D::set_texture_mode(const LineTextureMode mode) { update(); } -LineTextureMode Line2D::get_texture_mode() const { +Line2D::LineTextureMode Line2D::get_texture_mode() const { return _texture_mode; } @@ -143,7 +144,7 @@ void Line2D::set_joint_mode(LineJointMode mode) { update(); } -LineJointMode Line2D::get_joint_mode() const { +Line2D::LineJointMode Line2D::get_joint_mode() const { return _joint_mode; } @@ -152,7 +153,7 @@ void Line2D::set_begin_cap_mode(LineCapMode mode) { update(); } -LineCapMode Line2D::get_begin_cap_mode() const { +Line2D::LineCapMode Line2D::get_begin_cap_mode() const { return _begin_cap_mode; } @@ -161,7 +162,7 @@ void Line2D::set_end_cap_mode(LineCapMode mode) { update(); } -LineCapMode Line2D::get_end_cap_mode() const { +Line2D::LineCapMode Line2D::get_end_cap_mode() const { return _end_cap_mode; } diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h index 017ccf13ff..36aadfd265 100644 --- a/scene/2d/line_2d.h +++ b/scene/2d/line_2d.h @@ -30,7 +30,6 @@ #ifndef LINE2D_H #define LINE2D_H -#include "line_builder.h" #include "node_2d.h" class Line2D : public Node2D { @@ -38,6 +37,24 @@ class Line2D : public Node2D { GDCLASS(Line2D, Node2D) public: + enum LineJointMode { + LINE_JOINT_SHARP = 0, + LINE_JOINT_BEVEL, + LINE_JOINT_ROUND + }; + + enum LineCapMode { + LINE_CAP_NONE = 0, + LINE_CAP_BOX, + LINE_CAP_ROUND + }; + + enum LineTextureMode { + LINE_TEXTURE_NONE = 0, + LINE_TEXTURE_TILE + // TODO STRETCH mode + }; + Line2D(); void set_points(const PoolVector<Vector2> &p_points); diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp index 53db30e3ce..4873c47827 100644 --- a/scene/2d/line_builder.cpp +++ b/scene/2d/line_builder.cpp @@ -92,14 +92,14 @@ static inline Vector2 interpolate(const Rect2 &r, const Vector2 &v) { //---------------------------------------------------------------------------- LineBuilder::LineBuilder() { - joint_mode = LINE_JOINT_SHARP; + joint_mode = Line2D::LINE_JOINT_SHARP; width = 10; default_color = Color(0.4, 0.5, 1); gradient = NULL; sharp_limit = 2.f; round_precision = 8; - begin_cap_mode = LINE_CAP_NONE; - end_cap_mode = LINE_CAP_NONE; + begin_cap_mode = Line2D::LINE_CAP_NONE; + end_cap_mode = Line2D::LINE_CAP_NONE; _interpolate_color = false; _last_index[0] = 0; @@ -141,7 +141,7 @@ void LineBuilder::build() { float current_distance1 = 0.f; float total_distance = 0.f; _interpolate_color = gradient != NULL; - bool distance_required = _interpolate_color || texture_mode == LINE_TEXTURE_TILE; + bool distance_required = _interpolate_color || texture_mode == Line2D::LINE_TEXTURE_TILE; if (distance_required) total_distance = calculate_total_distance(points); if (_interpolate_color) @@ -153,7 +153,7 @@ void LineBuilder::build() { float uvx1 = 0.f; // Begin cap - if (begin_cap_mode == LINE_CAP_BOX) { + if (begin_cap_mode == Line2D::LINE_CAP_BOX) { // Push back first vertices a little bit pos_up0 -= f0 * hw; pos_down0 -= f0 * hw; @@ -161,8 +161,8 @@ void LineBuilder::build() { total_distance += width; current_distance0 += hw; current_distance1 = current_distance0; - } else if (begin_cap_mode == LINE_CAP_ROUND) { - if (texture_mode == LINE_TEXTURE_TILE) { + } else if (begin_cap_mode == Line2D::LINE_CAP_ROUND) { + if (texture_mode == Line2D::LINE_TEXTURE_TILE) { uvx0 = 0.5f; } new_arc(pos0, pos_up0 - pos0, -Math_PI, color0, Rect2(0.f, 0.f, 1.f, 1.f)); @@ -247,15 +247,15 @@ void LineBuilder::build() { corner_pos_down = corner_pos_in; } - LineJointMode current_joint_mode = joint_mode; + Line2D::LineJointMode current_joint_mode = joint_mode; Vector2 pos_up1, pos_down1; if (intersection_result == SEGMENT_INTERSECT) { // Fallback on bevel if sharp angle is too high (because it would produce very long miters) - if (current_joint_mode == LINE_JOINT_SHARP && corner_pos_out.distance_squared_to(pos1) / hw_sq > sharp_limit_sq) { - current_joint_mode = LINE_JOINT_BEVEL; + if (current_joint_mode == Line2D::LINE_JOINT_SHARP && corner_pos_out.distance_squared_to(pos1) / hw_sq > sharp_limit_sq) { + current_joint_mode = Line2D::LINE_JOINT_BEVEL; } - if (current_joint_mode == LINE_JOINT_SHARP) { + if (current_joint_mode == Line2D::LINE_JOINT_SHARP) { // In this case, we won't create joint geometry, // The previous and next line quads will directly share an edge. pos_up1 = corner_pos_up; @@ -284,7 +284,7 @@ void LineBuilder::build() { if (_interpolate_color) { color1 = gradient->get_color_at_offset(current_distance1 / total_distance); } - if (texture_mode == LINE_TEXTURE_TILE) { + if (texture_mode == Line2D::LINE_TEXTURE_TILE) { uvx0 = current_distance0 / width; uvx1 = current_distance1 / width; } @@ -298,7 +298,7 @@ void LineBuilder::build() { pos0 = pos1; current_distance0 = current_distance1; if (intersection_result == SEGMENT_INTERSECT) { - if (current_joint_mode == LINE_JOINT_SHARP) { + if (current_joint_mode == Line2D::LINE_JOINT_SHARP) { pos_up0 = pos_up1; pos_down0 = pos_down1; } else { @@ -317,7 +317,7 @@ void LineBuilder::build() { // From this point, bu0 and bd0 concern the next segment // Add joint geometry - if (current_joint_mode != LINE_JOINT_SHARP) { + if (current_joint_mode != Line2D::LINE_JOINT_SHARP) { /* ________________ cbegin * / \ @@ -337,9 +337,9 @@ void LineBuilder::build() { cend = pos_up0; } - if (current_joint_mode == LINE_JOINT_BEVEL) { + if (current_joint_mode == Line2D::LINE_JOINT_BEVEL) { strip_add_tri(cend, orientation); - } else if (current_joint_mode == LINE_JOINT_ROUND) { + } else if (current_joint_mode == Line2D::LINE_JOINT_ROUND) { Vector2 vbegin = cbegin - pos1; Vector2 vend = cend - pos1; strip_add_arc(pos1, vbegin.angle_to(vend), orientation); @@ -360,7 +360,7 @@ void LineBuilder::build() { Vector2 pos_down1 = pos1 - u0 * hw; // End cap (box) - if (end_cap_mode == LINE_CAP_BOX) { + if (end_cap_mode == Line2D::LINE_CAP_BOX) { pos_up1 += f0 * hw; pos_down1 += f0 * hw; } @@ -371,14 +371,14 @@ void LineBuilder::build() { if (_interpolate_color) { color1 = gradient->get_color(gradient->get_points_count() - 1); } - if (texture_mode == LINE_TEXTURE_TILE) { + if (texture_mode == Line2D::LINE_TEXTURE_TILE) { uvx1 = current_distance1 / width; } strip_add_quad(pos_up1, pos_down1, color1, uvx1); // End cap (round) - if (end_cap_mode == LINE_CAP_ROUND) { + if (end_cap_mode == Line2D::LINE_CAP_ROUND) { // Note: color is not used in case we don't interpolate... Color color = _interpolate_color ? gradient->get_color(gradient->get_points_count() - 1) : Color(0, 0, 0); new_arc(pos1, pos_up1 - pos1, Math_PI, color, Rect2(uvx1 - 0.5f, 0.f, 1.f, 1.f)); @@ -396,7 +396,7 @@ void LineBuilder::strip_begin(Vector2 up, Vector2 down, Color color, float uvx) colors.push_back(color); } - if (texture_mode != LINE_TEXTURE_NONE) { + if (texture_mode != Line2D::LINE_TEXTURE_NONE) { uvs.push_back(Vector2(uvx, 0.f)); uvs.push_back(Vector2(uvx, 1.f)); } @@ -420,7 +420,7 @@ void LineBuilder::strip_new_quad(Vector2 up, Vector2 down, Color color, float uv colors.push_back(color); } - if (texture_mode != LINE_TEXTURE_NONE) { + if (texture_mode != Line2D::LINE_TEXTURE_NONE) { uvs.push_back(uvs[_last_index[UP]]); uvs.push_back(uvs[_last_index[DOWN]]); uvs.push_back(Vector2(uvx, UP)); @@ -449,7 +449,7 @@ void LineBuilder::strip_add_quad(Vector2 up, Vector2 down, Color color, float uv colors.push_back(color); } - if (texture_mode != LINE_TEXTURE_NONE) { + if (texture_mode != Line2D::LINE_TEXTURE_NONE) { uvs.push_back(Vector2(uvx, 0.f)); uvs.push_back(Vector2(uvx, 1.f)); } @@ -476,7 +476,7 @@ void LineBuilder::strip_add_tri(Vector2 up, Orientation orientation) { Orientation opposite_orientation = orientation == UP ? DOWN : UP; - if (texture_mode != LINE_TEXTURE_NONE) { + if (texture_mode != Line2D::LINE_TEXTURE_NONE) { // UVs are just one slice of the texture all along // (otherwise we can't share the bottom vertice) uvs.push_back(uvs[_last_index[opposite_orientation]]); @@ -541,7 +541,7 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col vertices.push_back(center); if (_interpolate_color) colors.push_back(color); - if (texture_mode != LINE_TEXTURE_NONE) + if (texture_mode != Line2D::LINE_TEXTURE_NONE) uvs.push_back(interpolate(uv_rect, Vector2(0.5f, 0.5f))); // Arc vertices @@ -552,7 +552,7 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col vertices.push_back(rpos); if (_interpolate_color) colors.push_back(color); - if (texture_mode != LINE_TEXTURE_NONE) { + if (texture_mode != Line2D::LINE_TEXTURE_NONE) { Vector2 tsc = Vector2(Math::cos(tt), Math::sin(tt)); uvs.push_back(interpolate(uv_rect, 0.5f * (tsc + Vector2(1.f, 1.f)))); tt += angle_step; @@ -565,7 +565,7 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col vertices.push_back(rpos); if (_interpolate_color) colors.push_back(color); - if (texture_mode != LINE_TEXTURE_NONE) { + if (texture_mode != Line2D::LINE_TEXTURE_NONE) { tt = tt_begin + angle_delta; Vector2 tsc = Vector2(Math::cos(tt), Math::sin(tt)); uvs.push_back(interpolate(uv_rect, 0.5f * (tsc + Vector2(1.f, 1.f)))); diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h index 227e0abd08..f12fbf6f82 100644 --- a/scene/2d/line_builder.h +++ b/scene/2d/line_builder.h @@ -31,39 +31,22 @@ #define LINE_BUILDER_H #include "color.h" +#include "line_2d.h" #include "math_2d.h" #include "scene/resources/color_ramp.h" -enum LineJointMode { - LINE_JOINT_SHARP = 0, - LINE_JOINT_BEVEL, - LINE_JOINT_ROUND -}; - -enum LineCapMode { - LINE_CAP_NONE = 0, - LINE_CAP_BOX, - LINE_CAP_ROUND -}; - -enum LineTextureMode { - LINE_TEXTURE_NONE = 0, - LINE_TEXTURE_TILE - // TODO STRETCH mode -}; - class LineBuilder { public: // TODO Move in a struct and reference it // Input Vector<Vector2> points; - LineJointMode joint_mode; - LineCapMode begin_cap_mode; - LineCapMode end_cap_mode; + Line2D::LineJointMode joint_mode; + Line2D::LineCapMode begin_cap_mode; + Line2D::LineCapMode end_cap_mode; float width; Color default_color; Gradient *gradient; - LineTextureMode texture_mode; + Line2D::LineTextureMode texture_mode; float sharp_limit; int round_precision; // TODO offset_joints option (offers alternative implementation of round joints) diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index b1eb2ba267..c6cd3677cd 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -955,35 +955,25 @@ RigidBody2D::~RigidBody2D() { ////////////////////////// -Dictionary KinematicBody2D::_move(const Vector2 &p_motion) { +Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion) { Collision col; - if (move(p_motion, col)) { - Dictionary d; - d["position"] = col.collision; - d["normal"] = col.normal; - d["local_shape"] = col.local_shape; - d["travel"] = col.travel; - d["remainder"] = col.remainder; - d["collider_id"] = col.collider; - d["collider_velocity"] = col.collider_vel; - if (col.collider) { - d["collider"] = ObjectDB::get_instance(col.collider); - } else { - d["collider"] = Variant(); - } - d["collider_shape_index"] = col.collider_shape; - d["collider_metadata"] = col.collider_metadata; + if (move_and_collide(p_motion, col)) { + if (motion_cache.is_null()) { + motion_cache.instance(); + motion_cache->owner = this; + } - return d; + motion_cache->collision = col; - } else { - return Dictionary(); + return motion_cache; } + + return Ref<KinematicCollision2D>(); } -bool KinematicBody2D::move(const Vector2 &p_motion, Collision &r_collision) { +bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, Collision &r_collision) { Transform2D gt = get_global_transform(); Physics2DServer::MotionResult result; @@ -1007,7 +997,7 @@ bool KinematicBody2D::move(const Vector2 &p_motion, Collision &r_collision) { return colliding; } -Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_bounces, float p_floor_max_angle) { +Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) { Vector2 motion = (floor_velocity + p_linear_velocity) * get_fixed_process_delta_time(); Vector2 lv = p_linear_velocity; @@ -1018,11 +1008,11 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const colliders.clear(); floor_velocity = Vector2(); - while (p_max_bounces) { + while (p_max_slides) { Collision collision; - bool collided = move(motion, collision); + bool collided = move_and_collide(motion, collision); if (collided) { @@ -1060,7 +1050,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const break; } - p_max_bounces--; + p_max_slides--; if (motion == Vector2()) break; } @@ -1103,75 +1093,35 @@ float KinematicBody2D::get_safe_margin() const { return margin; } -int KinematicBody2D::get_collision_count() const { +int KinematicBody2D::get_slide_count() const { return colliders.size(); } -Vector2 KinematicBody2D::get_collision_position(int p_collision) const { - - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2()); - return colliders[p_collision].collision; -} -Vector2 KinematicBody2D::get_collision_normal(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2()); - return colliders[p_collision].normal; +KinematicBody2D::Collision KinematicBody2D::get_slide_collision(int p_bounce) const { + ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Collision()); + return colliders[p_bounce]; } -Vector2 KinematicBody2D::get_collision_travel(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2()); - return colliders[p_collision].travel; -} -Vector2 KinematicBody2D::get_collision_remainder(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2()); - return colliders[p_collision].remainder; -} -Object *KinematicBody2D::get_collision_local_shape(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL); - uint32_t owner = shape_find_owner(colliders[p_collision].local_shape); - return shape_owner_get_owner(owner); -} -Object *KinematicBody2D::get_collision_collider(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL); +Ref<KinematicCollision2D> KinematicBody2D::_get_slide_collision(int p_bounce) { - if (colliders[p_collision].collider) { - return ObjectDB::get_instance(colliders[p_collision].collider); + ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision2D>()); + if (p_bounce >= slide_colliders.size()) { + slide_colliders.resize(p_bounce + 1); } - return NULL; -} -ObjectID KinematicBody2D::get_collision_collider_id(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), 0); - - return colliders[p_collision].collider; -} -Object *KinematicBody2D::get_collision_collider_shape(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL); - Object *collider = get_collision_collider(p_collision); - CollisionObject2D *obj2d = Object::cast_to<CollisionObject2D>(collider); - if (obj2d) { - uint32_t owner = shape_find_owner(colliders[p_collision].collider_shape); - return obj2d->shape_owner_get_owner(owner); + if (slide_colliders[p_bounce].is_null()) { + slide_colliders[p_bounce].instance(); + slide_colliders[p_bounce]->owner = this; } - return NULL; -} -int KinematicBody2D::get_collision_collider_shape_index(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), -1); - return colliders[p_collision].collider_shape; -} -Vector2 KinematicBody2D::get_collision_collider_velocity(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2()); - return colliders[p_collision].collider_vel; -} -Variant KinematicBody2D::get_collision_collider_metadata(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Variant()); - return colliders[p_collision].collider_metadata; + slide_colliders[p_bounce]->collision = colliders[p_bounce]; + return slide_colliders[p_bounce]; } void KinematicBody2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("move", "rel_vec"), &KinematicBody2D::_move); + ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec"), &KinematicBody2D::_move); ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45))); ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec"), &KinematicBody2D::test_move); @@ -1184,18 +1134,8 @@ void KinematicBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody2D::set_safe_margin); ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody2D::get_safe_margin); - ClassDB::bind_method(D_METHOD("get_collision_count"), &KinematicBody2D::get_collision_count); - ClassDB::bind_method(D_METHOD("get_collision_position", "collision"), &KinematicBody2D::get_collision_position); - ClassDB::bind_method(D_METHOD("get_collision_normal", "collision"), &KinematicBody2D::get_collision_normal); - ClassDB::bind_method(D_METHOD("get_collision_travel", "collision"), &KinematicBody2D::get_collision_travel); - ClassDB::bind_method(D_METHOD("get_collision_remainder", "collision"), &KinematicBody2D::get_collision_remainder); - ClassDB::bind_method(D_METHOD("get_collision_local_shape", "collision"), &KinematicBody2D::get_collision_local_shape); - ClassDB::bind_method(D_METHOD("get_collision_collider", "collision"), &KinematicBody2D::get_collision_collider); - ClassDB::bind_method(D_METHOD("get_collision_collider_id", "collision"), &KinematicBody2D::get_collision_collider_id); - ClassDB::bind_method(D_METHOD("get_collision_collider_shape", "collision"), &KinematicBody2D::get_collision_collider_shape); - ClassDB::bind_method(D_METHOD("get_collision_collider_shape_index", "collision"), &KinematicBody2D::get_collision_collider_shape_index); - ClassDB::bind_method(D_METHOD("get_collision_collider_velocity", "collision"), &KinematicBody2D::get_collision_collider_velocity); - ClassDB::bind_method(D_METHOD("get_collision_collider_metadata", "collision"), &KinematicBody2D::get_collision_collider_metadata); + ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody2D::get_slide_count); + ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody2D::_get_slide_collision); ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); } @@ -1210,4 +1150,106 @@ KinematicBody2D::KinematicBody2D() on_wall = false; } KinematicBody2D::~KinematicBody2D() { + if (motion_cache.is_valid()) { + motion_cache->owner = NULL; + } + + for (int i = 0; i < slide_colliders.size(); i++) { + if (slide_colliders[i].is_valid()) { + slide_colliders[i]->owner = NULL; + } + } +} + +//////////////////////// + +Vector2 KinematicCollision2D::get_position() const { + + return collision.collision; +} +Vector2 KinematicCollision2D::get_normal() const { + return collision.normal; +} +Vector2 KinematicCollision2D::get_travel() const { + return collision.travel; +} +Vector2 KinematicCollision2D::get_remainder() const { + return collision.remainder; +} +Object *KinematicCollision2D::get_local_shape() const { + ERR_FAIL_COND_V(!owner, NULL); + uint32_t ownerid = owner->shape_find_owner(collision.local_shape); + return owner->shape_owner_get_owner(ownerid); +} + +Object *KinematicCollision2D::get_collider() const { + + if (collision.collider) { + return ObjectDB::get_instance(collision.collider); + } + + return NULL; +} +ObjectID KinematicCollision2D::get_collider_id() const { + + return collision.collider; +} +Object *KinematicCollision2D::get_collider_shape() const { + + Object *collider = get_collider(); + if (collider) { + CollisionObject2D *obj2d = Object::cast_to<CollisionObject2D>(collider); + if (obj2d) { + uint32_t ownerid = obj2d->shape_find_owner(collision.collider_shape); + return obj2d->shape_owner_get_owner(ownerid); + } + } + + return NULL; +} +int KinematicCollision2D::get_collider_shape_index() const { + + return collision.collider_shape; +} +Vector2 KinematicCollision2D::get_collider_velocity() const { + + return collision.collider_vel; +} +Variant KinematicCollision2D::get_collider_metadata() const { + + return Variant(); +} + +void KinematicCollision2D::_bind_methods() { + + ClassDB::bind_method(D_METHOD("get_position"), &KinematicCollision2D::get_position); + ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision2D::get_normal); + ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision2D::get_travel); + ClassDB::bind_method(D_METHOD("get_remainder"), &KinematicCollision2D::get_remainder); + ClassDB::bind_method(D_METHOD("get_local_shape"), &KinematicCollision2D::get_local_shape); + ClassDB::bind_method(D_METHOD("get_collider"), &KinematicCollision2D::get_collider); + ClassDB::bind_method(D_METHOD("get_collider_id"), &KinematicCollision2D::get_collider_id); + ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicCollision2D::get_collider_shape); + ClassDB::bind_method(D_METHOD("get_collider_shape_index"), &KinematicCollision2D::get_collider_shape_index); + ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicCollision2D::get_collider_velocity); + ClassDB::bind_method(D_METHOD("get_collider_metadata"), &KinematicCollision2D::get_collider_metadata); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "", "get_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "normal"), "", "get_normal"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "travel"), "", "get_travel"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "remainder"), "", "get_remainder"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "local_shape"), "", "get_local_shape"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_collider"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id"), "", "get_collider_id"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider_shape"), "", "get_collider_shape"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape_index"), "", "get_collider_shape_index"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "collider_velocity"), "", "get_collider_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_collider_metadata"); +} + +KinematicCollision2D::KinematicCollision2D() { + collision.collider = 0; + collision.collider_shape = 0; + collision.local_shape = 0; + owner = NULL; } diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 1a4b0c0f5c..b82771a8f4 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -34,6 +34,8 @@ #include "servers/physics_2d_server.h" #include "vset.h" +class KinematicCollision2D; + class PhysicsBody2D : public CollisionObject2D { GDCLASS(PhysicsBody2D, CollisionObject2D); @@ -288,42 +290,62 @@ private: bool on_ceiling; bool on_wall; Vector<Collision> colliders; + Vector<Ref<KinematicCollision2D> > slide_colliders; + Ref<KinematicCollision2D> motion_cache; _FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const; - Dictionary _move(const Vector2 &p_motion); + Ref<KinematicCollision2D> _move(const Vector2 &p_motion); + Ref<KinematicCollision2D> _get_slide_collision(int p_bounce); protected: static void _bind_methods(); public: - bool move(const Vector2 &p_motion, Collision &r_collision); + bool move_and_collide(const Vector2 &p_motion, Collision &r_collision); bool test_move(const Transform2D &p_from, const Vector2 &p_motion); void set_safe_margin(float p_margin); float get_safe_margin() const; - Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), float p_slope_stop_min_velocity = 5, int p_max_bounces = 4, float p_floor_max_angle = Math::deg2rad((float)45)); + Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), float p_slope_stop_min_velocity = 5, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45)); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; Vector2 get_floor_velocity() const; - int get_collision_count() const; - Vector2 get_collision_position(int p_collision) const; - Vector2 get_collision_normal(int p_collision) const; - Vector2 get_collision_travel(int p_collision) const; - Vector2 get_collision_remainder(int p_collision) const; - Object *get_collision_local_shape(int p_collision) const; - Object *get_collision_collider(int p_collision) const; - ObjectID get_collision_collider_id(int p_collision) const; - Object *get_collision_collider_shape(int p_collision) const; - int get_collision_collider_shape_index(int p_collision) const; - Vector2 get_collision_collider_velocity(int p_collision) const; - Variant get_collision_collider_metadata(int p_collision) const; + int get_slide_count() const; + Collision get_slide_collision(int p_bounce) const; KinematicBody2D(); ~KinematicBody2D(); }; +class KinematicCollision2D : public Reference { + + GDCLASS(KinematicCollision2D, Reference); + + KinematicBody2D *owner; + friend class KinematicBody2D; + KinematicBody2D::Collision collision; + +protected: + static void _bind_methods(); + +public: + Vector2 get_position() const; + Vector2 get_normal() const; + Vector2 get_travel() const; + Vector2 get_remainder() const; + Object *get_local_shape() const; + Object *get_collider() const; + ObjectID get_collider_id() const; + Object *get_collider_shape() const; + int get_collider_shape_index() const; + Vector2 get_collider_velocity() const; + Variant get_collider_metadata() const; + + KinematicCollision2D(); +}; + #endif // PHYSICS_BODY_2D_H diff --git a/scene/2d/screen_button.cpp b/scene/2d/screen_button.cpp index c9bf6675d2..bf7c5a3ba4 100644 --- a/scene/2d/screen_button.cpp +++ b/scene/2d/screen_button.cpp @@ -399,6 +399,9 @@ void TouchScreenButton::_bind_methods() { ADD_SIGNAL(MethodInfo("pressed")); ADD_SIGNAL(MethodInfo("released")); + + BIND_ENUM_CONSTANT(VISIBILITY_ALWAYS); + BIND_ENUM_CONSTANT(VISIBILITY_TOUCHSCREEN_ONLY); } TouchScreenButton::TouchScreenButton() { |