summaryrefslogtreecommitdiff
path: root/scene/2d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d')
-rw-r--r--scene/2d/camera_2d.cpp50
-rw-r--r--scene/2d/camera_2d.h4
-rw-r--r--scene/2d/canvas_item.cpp11
-rw-r--r--scene/2d/canvas_item.h4
-rw-r--r--scene/2d/node_2d.cpp53
-rw-r--r--scene/2d/node_2d.h6
-rw-r--r--scene/2d/physics_body_2d.cpp119
-rw-r--r--scene/2d/physics_body_2d.h15
-rw-r--r--scene/2d/ray_cast_2d.cpp36
-rw-r--r--scene/2d/ray_cast_2d.h4
-rw-r--r--scene/2d/visibility_notifier_2d.cpp6
11 files changed, 279 insertions, 29 deletions
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index f98a50e3e0..e576aa10e0 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -29,6 +29,8 @@
#include "camera_2d.h"
#include "scene/scene_string_names.h"
#include "servers/visual_server.h"
+#include "core/math/math_funcs.h"
+#include <editor/editor_node.h>
void Camera2D::_update_scroll() {
@@ -114,7 +116,25 @@ Matrix32 Camera2D::get_camera_transform() {
camera_pos=new_camera_pos;
}
-
+ Point2 screen_offset = (anchor_mode==ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom) : Point2());
+ Rect2 screen_rect(-screen_offset+camera_pos,screen_size*zoom);
+
+ if (offset!=Vector2())
+ screen_rect.pos+=offset;
+
+ if (limit_smoothing_enabled) {
+ if (screen_rect.pos.x < limit[MARGIN_LEFT])
+ camera_pos.x -= screen_rect.pos.x - limit[MARGIN_LEFT];
+
+ if (screen_rect.pos.x + screen_rect.size.x > limit[MARGIN_RIGHT])
+ camera_pos.x -= screen_rect.pos.x + screen_rect.size.x - limit[MARGIN_RIGHT];
+
+ if (screen_rect.pos.y + screen_rect.size.y > limit[MARGIN_BOTTOM])
+ camera_pos.y -= screen_rect.pos.y + screen_rect.size.y - limit[MARGIN_BOTTOM];
+
+ if (screen_rect.pos.y < limit[MARGIN_TOP])
+ camera_pos.y -= screen_rect.pos.y - limit[MARGIN_TOP];
+ }
if (smoothing_enabled && !get_tree()->is_editor_hint()) {
@@ -144,19 +164,19 @@ Matrix32 Camera2D::get_camera_transform() {
}
Rect2 screen_rect(-screen_offset+ret_camera_pos,screen_size*zoom);
+ if (screen_rect.pos.x < limit[MARGIN_LEFT])
+ screen_rect.pos.x = limit[MARGIN_LEFT];
+
if (screen_rect.pos.x + screen_rect.size.x > limit[MARGIN_RIGHT])
screen_rect.pos.x = limit[MARGIN_RIGHT] - screen_rect.size.x;
if (screen_rect.pos.y + screen_rect.size.y > limit[MARGIN_BOTTOM])
screen_rect.pos.y = limit[MARGIN_BOTTOM] - screen_rect.size.y;
-
- if (screen_rect.pos.x < limit[MARGIN_LEFT])
- screen_rect.pos.x=limit[MARGIN_LEFT];
-
if (screen_rect.pos.y < limit[MARGIN_TOP])
screen_rect.pos.y =limit[MARGIN_TOP];
-
+
+
if (offset!=Vector2()) {
screen_rect.pos+=offset;
@@ -382,6 +402,17 @@ int Camera2D::get_limit(Margin p_margin) const{
}
+void Camera2D::set_limit_smoothing_enabled(bool enable) {
+
+ limit_smoothing_enabled = enable;
+ _update_scroll();
+}
+
+bool Camera2D::is_limit_smoothing_enabled() const{
+
+ return limit_smoothing_enabled;
+}
+
void Camera2D::set_drag_margin(Margin p_margin,float p_drag_margin) {
ERR_FAIL_INDEX(p_margin,4);
@@ -536,13 +567,15 @@ void Camera2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_update_scroll"),&Camera2D::_update_scroll);
-
ObjectTypeDB::bind_method(_MD("_set_current","current"),&Camera2D::_set_current);
ObjectTypeDB::bind_method(_MD("is_current"),&Camera2D::is_current);
ObjectTypeDB::bind_method(_MD("set_limit","margin","limit"),&Camera2D::set_limit);
ObjectTypeDB::bind_method(_MD("get_limit","margin"),&Camera2D::get_limit);
+ ObjectTypeDB::bind_method(_MD("set_limit_smoothing_enabled","limit_smoothing_enabled"),&Camera2D::set_limit_smoothing_enabled);
+ ObjectTypeDB::bind_method(_MD("is_limit_smoothing_enabled"),&Camera2D::is_limit_smoothing_enabled);
+
ObjectTypeDB::bind_method(_MD("set_v_drag_enabled","enabled"),&Camera2D::set_v_drag_enabled);
ObjectTypeDB::bind_method(_MD("is_v_drag_enabled"),&Camera2D::is_v_drag_enabled);
@@ -587,6 +620,7 @@ void Camera2D::_bind_methods() {
ADD_PROPERTYI( PropertyInfo(Variant::INT,"limit/top"),_SCS("set_limit"),_SCS("get_limit"),MARGIN_TOP);
ADD_PROPERTYI( PropertyInfo(Variant::INT,"limit/right"),_SCS("set_limit"),_SCS("get_limit"),MARGIN_RIGHT);
ADD_PROPERTYI( PropertyInfo(Variant::INT,"limit/bottom"),_SCS("set_limit"),_SCS("get_limit"),MARGIN_BOTTOM);
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL,"limit/smoothed"),_SCS("set_limit_smoothing_enabled"),_SCS("is_limit_smoothing_enabled") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"drag_margin/h_enabled"),_SCS("set_h_drag_enabled"),_SCS("is_h_drag_enabled") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"drag_margin/v_enabled"),_SCS("set_v_drag_enabled"),_SCS("is_v_drag_enabled") );
@@ -619,6 +653,7 @@ Camera2D::Camera2D() {
limit[MARGIN_TOP]=-10000000;
limit[MARGIN_RIGHT]=10000000;
limit[MARGIN_BOTTOM]=10000000;
+
drag_margin[MARGIN_LEFT]=0.2;
drag_margin[MARGIN_TOP]=0.2;
drag_margin[MARGIN_RIGHT]=0.2;
@@ -626,6 +661,7 @@ Camera2D::Camera2D() {
camera_pos=Vector2();
first=true;
smoothing_enabled=false;
+ limit_smoothing_enabled=false;
smoothing=5.0;
zoom = Vector2(1, 1);
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index b3f55d798d..9f3e4254bb 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -61,6 +61,7 @@ protected:
float smoothing;
bool smoothing_enabled;
int limit[4];
+ bool limit_smoothing_enabled;
float drag_margin[4];
bool h_drag_enabled;
@@ -68,7 +69,6 @@ protected:
float h_ofs;
float v_ofs;
-
Point2 camera_screen_center;
void _update_scroll();
@@ -95,6 +95,8 @@ public:
void set_limit(Margin p_margin,int p_limit);
int get_limit(Margin p_margin) const;
+ void set_limit_smoothing_enabled(bool enable);
+ bool is_limit_smoothing_enabled() const;
void set_h_drag_enabled(bool p_enabled);
bool is_h_drag_enabled() const;
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index eb4f457975..ed1d606ba8 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -650,21 +650,22 @@ int CanvasItem::get_light_mask() const{
}
-void CanvasItem::item_rect_changed() {
+void CanvasItem::item_rect_changed(bool p_size_changed) {
- update();
+ if (p_size_changed)
+ update();
emit_signal(SceneStringNames::get_singleton()->item_rect_changed);
}
-void CanvasItem::draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width) {
+void CanvasItem::draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width,bool p_antialiased) {
if (!drawing) {
ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL();
}
- VisualServer::get_singleton()->canvas_item_add_line(canvas_item,p_from,p_to,p_color,p_width);
+ VisualServer::get_singleton()->canvas_item_add_line(canvas_item,p_from,p_to,p_color,p_width,p_antialiased);
}
void CanvasItem::draw_rect(const Rect2& p_rect, const Color& p_color) {
@@ -1028,7 +1029,7 @@ void CanvasItem::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_is_on_top"),&CanvasItem::_is_on_top);
//ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform);
- ObjectTypeDB::bind_method(_MD("draw_line","from","to","color","width"),&CanvasItem::draw_line,DEFVAL(1.0));
+ ObjectTypeDB::bind_method(_MD("draw_line","from","to","color","width","antialiased"),&CanvasItem::draw_line,DEFVAL(1.0),DEFVAL(false));
ObjectTypeDB::bind_method(_MD("draw_rect","rect","color"),&CanvasItem::draw_rect);
ObjectTypeDB::bind_method(_MD("draw_circle","pos","radius","color"),&CanvasItem::draw_circle);
ObjectTypeDB::bind_method(_MD("draw_texture","texture:Texture","pos","modulate"),&CanvasItem::draw_texture,DEFVAL(Color(1,1,1,1)));
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index b894310ce2..7849a66185 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -157,7 +157,7 @@ protected:
_FORCE_INLINE_ void _notify_transform() { if (!is_inside_tree()) return; _notify_transform(this); if (!block_transform_notify && notify_local_transform) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); }
- void item_rect_changed();
+ void item_rect_changed(bool p_size_changed=true);
void _notification(int p_what);
static void _bind_methods();
@@ -207,7 +207,7 @@ public:
/* DRAWING API */
- void draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0);
+ void draw_line(const Point2& p_from, const Point2& p_to, const Color& p_color, float p_width=1.0, bool p_antialiased=false);
void draw_rect(const Rect2& p_rect, const Color& p_color);
void draw_circle(const Point2& p_pos, float p_radius, const Color& p_color);
void draw_texture(const Ref<Texture>& p_texture, const Point2& p_pos, const Color &p_modulate=Color(1,1,1,1));
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index 134e0153b3..df43e8e373 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -295,6 +295,53 @@ void Node2D::set_global_pos(const Point2& p_pos) {
}
}
+
+float Node2D::get_global_rot() const {
+
+ return get_global_transform().get_rotation();
+}
+
+void Node2D::set_global_rot(float p_radians) {
+
+ CanvasItem *pi = get_parent_item();
+ if (pi) {
+ const float parent_global_rot = pi->get_global_transform().get_rotation();
+ set_rot(p_radians - parent_global_rot);
+ } else {
+ set_rot(p_radians);
+ }
+}
+
+
+float Node2D::get_global_rotd() const {
+
+ return Math::rad2deg(get_global_rot());
+}
+
+void Node2D::set_global_rotd(float p_degrees) {
+
+ set_global_rot(Math::deg2rad(p_degrees));
+}
+
+
+Size2 Node2D::get_global_scale() const {
+
+ return get_global_transform().get_scale();
+}
+
+void Node2D::set_global_scale(const Size2& p_scale) {
+
+ CanvasItem *pi = get_parent_item();
+ if (pi) {
+ const Size2 parent_global_scale = pi->get_global_transform().get_scale();
+ set_scale(p_scale - parent_global_scale);
+ } else {
+ set_scale(p_scale);
+ }
+
+}
+
+
void Node2D::set_transform(const Matrix32& p_transform) {
_mat=p_transform;
@@ -398,6 +445,12 @@ void Node2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_global_pos","pos"),&Node2D::set_global_pos);
ObjectTypeDB::bind_method(_MD("get_global_pos"),&Node2D::get_global_pos);
+ ObjectTypeDB::bind_method(_MD("set_global_rot","radians"),&Node2D::set_global_rot);
+ ObjectTypeDB::bind_method(_MD("get_global_rot"),&Node2D::get_global_rot);
+ ObjectTypeDB::bind_method(_MD("set_global_rotd","degrees"),&Node2D::set_global_rotd);
+ ObjectTypeDB::bind_method(_MD("get_global_rotd"),&Node2D::get_global_rotd);
+ ObjectTypeDB::bind_method(_MD("set_global_scale","scale"),&Node2D::set_global_scale);
+ ObjectTypeDB::bind_method(_MD("get_global_scale"),&Node2D::get_global_scale);
ObjectTypeDB::bind_method(_MD("set_transform","xform"),&Node2D::set_transform);
ObjectTypeDB::bind_method(_MD("set_global_transform","xform"),&Node2D::set_global_transform);
diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h
index b0c628fd94..aa8d0ef33c 100644
--- a/scene/2d/node_2d.h
+++ b/scene/2d/node_2d.h
@@ -87,11 +87,17 @@ public:
Size2 get_scale() const;
Point2 get_global_pos() const;
+ float get_global_rot() const;
+ float get_global_rotd() const;
+ Size2 get_global_scale() const;
virtual Rect2 get_item_rect() const;
void set_transform(const Matrix32& p_transform);
void set_global_transform(const Matrix32& p_transform);
void set_global_pos(const Point2& p_pos);
+ void set_global_rot(float p_radians);
+ void set_global_rotd(float p_degrees);
+ void set_global_scale(const Size2& p_scale);
void set_z(int p_z);
int get_z() const;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 26c4ea385f..0c5c353766 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -436,7 +436,7 @@ bool RigidBody2D::_test_motion(const Vector2& p_motion,float p_margin,const Ref<
Physics2DServer::MotionResult *r=NULL;
if (p_result.is_valid())
r=p_result->get_result_ptr();
- return Physics2DServer::get_singleton()->body_test_motion(get_rid(),p_motion,p_margin,r);
+ return Physics2DServer::get_singleton()->body_test_motion(get_rid(),get_global_transform(),p_motion,p_margin,r);
}
@@ -1057,8 +1057,10 @@ Vector2 KinematicBody2D::get_travel() const {
Vector2 KinematicBody2D::move(const Vector2& p_motion) {
#if 1
+
+ Matrix32 gt = get_global_transform();
Physics2DServer::MotionResult result;
- colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(),p_motion,margin,&result);
+ colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(),gt,p_motion,margin,&result);
collider_metadata=result.collider_metadata;
collider_shape=result.collider_shape;
@@ -1067,10 +1069,12 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
normal=result.collision_normal;
collider=result.collider_id;
- Matrix32 gt = get_global_transform();
+
gt.elements[2]+=result.motion;
set_global_transform(gt);
travel=result.motion;
+
+
return result.remainder;
#else
@@ -1081,7 +1085,6 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
//this took about a week to get right..
//but is it right? who knows at this point..
-
colliding=false;
ERR_FAIL_COND_V(!is_inside_tree(),Vector2());
Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(get_world_2d()->get_space());
@@ -1099,17 +1102,15 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
bool collided=false;
uint32_t mask=0;
- if (collide_static)
+ if (true)
mask|=Physics2DDirectSpaceState::TYPE_MASK_STATIC_BODY;
- if (collide_kinematic)
+ if (true)
mask|=Physics2DDirectSpaceState::TYPE_MASK_KINEMATIC_BODY;
- if (collide_rigid)
+ if (true)
mask|=Physics2DDirectSpaceState::TYPE_MASK_RIGID_BODY;
- if (collide_character)
+ if (true)
mask|=Physics2DDirectSpaceState::TYPE_MASK_CHARACTER_BODY;
-// print_line("motion: "+p_motion+" margin: "+rtos(margin));
-
//print_line("margin: "+rtos(margin));
do {
@@ -1145,6 +1146,8 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
break;
}
+
+
Matrix32 gt = get_global_transform();
gt.elements[2]+=recover_motion;
set_global_transform(gt);
@@ -1191,6 +1194,8 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
if (safe>=1) {
//not collided
colliding=false;
+
+
} else {
//it collided, let's get the rest info in unsafe advance
@@ -1226,16 +1231,94 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
#endif
}
+
+
+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) {
+
+ Vector2 motion = (move_and_slide_floor_velocity+p_linear_velocity)*get_fixed_process_delta_time();
+ Vector2 lv = p_linear_velocity;
+
+ move_and_slide_on_floor=false;
+ move_and_slide_on_ceiling=false;
+ move_and_slide_on_wall=false;
+ move_and_slide_colliders.clear();
+ move_and_slide_floor_velocity=Vector2();
+
+ while(p_max_bounces) {
+
+ motion=move(motion);
+
+ if (is_colliding()) {
+
+
+ if (p_floor_direction==Vector2()) {
+ //all is a wall
+ move_and_slide_on_wall=true;
+ } else {
+ if ( get_collision_normal().dot(p_floor_direction) > Math::cos(Math::deg2rad(45))) { //floor
+
+
+ move_and_slide_on_floor=true;
+ move_and_slide_floor_velocity=get_collider_velocity();
+
+ if (get_travel().length()<1 && ABS((lv.x-move_and_slide_floor_velocity.x))<p_slope_stop_min_velocity) {
+ revert_motion();
+ return Vector2();
+ }
+ } else if ( get_collision_normal().dot(p_floor_direction) < Math::cos(Math::deg2rad(45))) { //ceiling
+ move_and_slide_on_ceiling=true;
+ } else {
+ move_and_slide_on_wall=true;
+ }
+
+ }
+
+ motion=get_collision_normal().slide(motion);
+ lv=get_collision_normal().slide(lv);
+ Variant collider = _get_collider();
+ if (collider.get_type()!=Variant::NIL) {
+ move_and_slide_colliders.push_back(collider);
+ }
+
+ } else {
+ break;
+ }
+
+ p_max_bounces--;
+ if (motion==Vector2())
+ break;
+ }
+
+ return lv;
+}
+
+bool KinematicBody2D::is_move_and_slide_on_floor() const {
+
+ return move_and_slide_on_floor;
+}
+bool KinematicBody2D::is_move_and_slide_on_wall() const{
+
+ return move_and_slide_on_wall;
+}
+bool KinematicBody2D::is_move_and_slide_on_ceiling() const{
+
+ return move_and_slide_on_ceiling;
+}
+Array KinematicBody2D::get_move_and_slide_colliders() const{
+
+ return move_and_slide_colliders;
+}
+
Vector2 KinematicBody2D::move_to(const Vector2& p_position) {
return move(p_position-get_global_pos());
}
-bool KinematicBody2D::test_move(const Vector2& p_motion) {
+bool KinematicBody2D::test_move(const Matrix32& p_from,const Vector2& p_motion) {
ERR_FAIL_COND_V(!is_inside_tree(),false);
- return Physics2DServer::get_singleton()->body_test_motion(get_rid(),p_motion,margin);
+ return Physics2DServer::get_singleton()->body_test_motion(get_rid(),p_from,p_motion,margin);
}
@@ -1300,8 +1383,9 @@ void KinematicBody2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("move","rel_vec"),&KinematicBody2D::move);
ObjectTypeDB::bind_method(_MD("move_to","position"),&KinematicBody2D::move_to);
+ ObjectTypeDB::bind_method(_MD("move_and_slide","linear_velocity","floor_normal","slope_stop_min_velocity","max_bounces"),&KinematicBody2D::move_and_slide,DEFVAL(Vector2(0,0)),DEFVAL(5),DEFVAL(4));
- ObjectTypeDB::bind_method(_MD("test_move","rel_vec"),&KinematicBody2D::test_move);
+ ObjectTypeDB::bind_method(_MD("test_move","from","rel_vec"),&KinematicBody2D::test_move);
ObjectTypeDB::bind_method(_MD("get_travel"),&KinematicBody2D::get_travel);
ObjectTypeDB::bind_method(_MD("revert_motion"),&KinematicBody2D::revert_motion);
@@ -1313,6 +1397,10 @@ void KinematicBody2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_collider:Object"),&KinematicBody2D::_get_collider);
ObjectTypeDB::bind_method(_MD("get_collider_shape"),&KinematicBody2D::get_collider_shape);
ObjectTypeDB::bind_method(_MD("get_collider_metadata:Variant"),&KinematicBody2D::get_collider_metadata);
+ ObjectTypeDB::bind_method(_MD("get_move_and_slide_colliders"),&KinematicBody2D::get_move_and_slide_colliders);
+ ObjectTypeDB::bind_method(_MD("is_move_and_slide_on_floor"),&KinematicBody2D::is_move_and_slide_on_floor);
+ ObjectTypeDB::bind_method(_MD("is_move_and_slide_on_ceiling"),&KinematicBody2D::is_move_and_slide_on_ceiling);
+ ObjectTypeDB::bind_method(_MD("is_move_and_slide_on_wall"),&KinematicBody2D::is_move_and_slide_on_wall);
ObjectTypeDB::bind_method(_MD("set_collision_margin","pixels"),&KinematicBody2D::set_collision_margin);
ObjectTypeDB::bind_method(_MD("get_collision_margin","pixels"),&KinematicBody2D::get_collision_margin);
@@ -1330,6 +1418,11 @@ KinematicBody2D::KinematicBody2D() : PhysicsBody2D(Physics2DServer::BODY_MODE_KI
collider_shape=0;
margin=0.08;
+
+ move_and_slide_on_floor=false;
+ move_and_slide_on_ceiling=false;
+ move_and_slide_on_wall=false;
+
}
KinematicBody2D::~KinematicBody2D() {
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 5af65bff33..ea29d873bd 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -302,6 +302,12 @@ class KinematicBody2D : public PhysicsBody2D {
Variant collider_metadata;
Vector2 travel;
+ Vector2 move_and_slide_floor_velocity;
+ bool move_and_slide_on_floor;
+ bool move_and_slide_on_ceiling;
+ bool move_and_slide_on_wall;
+ Array move_and_slide_colliders;
+
Variant _get_collider() const;
_FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const;
@@ -313,7 +319,7 @@ public:
Vector2 move(const Vector2& p_motion);
Vector2 move_to(const Vector2& p_position);
- bool test_move(const Vector2& p_motion);
+ bool test_move(const Matrix32 &p_from, const Vector2& p_motion);
bool is_colliding() const;
Vector2 get_travel() const;
@@ -329,6 +335,13 @@ public:
void set_collision_margin(float p_margin);
float get_collision_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);
+ bool is_move_and_slide_on_floor() const;
+ bool is_move_and_slide_on_wall() const;
+ bool is_move_and_slide_on_ceiling() const;
+ Array get_move_and_slide_colliders() const;
+
+
KinematicBody2D();
~KinematicBody2D();
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 6cda52fa4e..b5d62adfb4 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -29,6 +29,7 @@
#include "ray_cast_2d.h"
#include "servers/physics_2d_server.h"
#include "collision_object_2d.h"
+#include "physics_body_2d.h"
void RayCast2D::set_cast_to(const Vector2& p_point) {
@@ -106,6 +107,30 @@ bool RayCast2D::is_enabled() const {
return enabled;
}
+void RayCast2D::set_exclude_parent_body(bool p_exclude_parent_body) {
+
+ if (exclude_parent_body==p_exclude_parent_body)
+ return;
+
+ exclude_parent_body=p_exclude_parent_body;
+
+ if (!is_inside_tree())
+ return;
+
+
+
+ if (get_parent()->cast_to<PhysicsBody2D>()) {
+ if (exclude_parent_body)
+ exclude.insert( get_parent()->cast_to<PhysicsBody2D>()->get_rid() );
+ else
+ exclude.erase( get_parent()->cast_to<PhysicsBody2D>()->get_rid() );
+ }
+}
+
+bool RayCast2D::get_exclude_parent_body() const{
+
+ return exclude_parent_body;
+}
void RayCast2D::_notification(int p_what) {
@@ -118,6 +143,12 @@ void RayCast2D::_notification(int p_what) {
else
set_fixed_process(false);
+ if (get_parent()->cast_to<PhysicsBody2D>()) {
+ if (exclude_parent_body)
+ exclude.insert( get_parent()->cast_to<PhysicsBody2D>()->get_rid() );
+ else
+ exclude.erase( get_parent()->cast_to<PhysicsBody2D>()->get_rid() );
+ }
} break;
case NOTIFICATION_EXIT_TREE: {
@@ -254,7 +285,11 @@ void RayCast2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_type_mask","mask"),&RayCast2D::set_type_mask);
ObjectTypeDB::bind_method(_MD("get_type_mask"),&RayCast2D::get_type_mask);
+ ObjectTypeDB::bind_method(_MD("set_exclude_parent_body","mask"),&RayCast2D::set_exclude_parent_body);
+ ObjectTypeDB::bind_method(_MD("get_exclude_parent_body"),&RayCast2D::get_exclude_parent_body);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL,"exclude_parent"),_SCS("set_exclude_parent_body"),_SCS("get_exclude_parent_body"));
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"cast_to"),_SCS("set_cast_to"),_SCS("get_cast_to"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"layer_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"type_mask",PROPERTY_HINT_FLAGS,"Static,Kinematic,Rigid,Character,Area"),_SCS("set_type_mask"),_SCS("get_type_mask"));
@@ -269,4 +304,5 @@ RayCast2D::RayCast2D() {
layer_mask=1;
type_mask=Physics2DDirectSpaceState::TYPE_MASK_COLLISION;
cast_to=Vector2(0,50);
+ exclude_parent_body=true;
}
diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h
index 54ec42c53e..e1caa8b63e 100644
--- a/scene/2d/ray_cast_2d.h
+++ b/scene/2d/ray_cast_2d.h
@@ -45,6 +45,7 @@ class RayCast2D : public Node2D {
Set<RID> exclude;
uint32_t layer_mask;
uint32_t type_mask;
+ bool exclude_parent_body;
Vector2 cast_to;
@@ -66,6 +67,9 @@ public:
void set_type_mask(uint32_t p_mask);
uint32_t get_type_mask() const;
+ void set_exclude_parent_body(bool p_exclude_parent_body);
+ bool get_exclude_parent_body() const;
+
bool is_colliding() const;
Object *get_collider() const;
int get_collider_shape() const;
diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp
index 5411950976..852bc187d2 100644
--- a/scene/2d/visibility_notifier_2d.cpp
+++ b/scene/2d/visibility_notifier_2d.cpp
@@ -40,6 +40,9 @@ void VisibilityNotifier2D::_enter_viewport(Viewport* p_viewport) {
ERR_FAIL_COND(viewports.has(p_viewport));
viewports.insert(p_viewport);
+ if (is_inside_tree() && get_tree()->is_editor_hint())
+ return;
+
if (viewports.size()==1) {
emit_signal(SceneStringNames::get_singleton()->enter_screen);
@@ -54,6 +57,9 @@ void VisibilityNotifier2D::_exit_viewport(Viewport* p_viewport){
ERR_FAIL_COND(!viewports.has(p_viewport));
viewports.erase(p_viewport);
+ if (is_inside_tree() && get_tree()->is_editor_hint())
+ return;
+
emit_signal(SceneStringNames::get_singleton()->exit_viewport,p_viewport);
if (viewports.size()==0) {
emit_signal(SceneStringNames::get_singleton()->exit_screen);