diff options
Diffstat (limited to 'scene/2d')
| -rw-r--r-- | scene/2d/canvas_item.cpp | 11 | ||||
| -rw-r--r-- | scene/2d/canvas_item.h | 4 | ||||
| -rw-r--r-- | scene/2d/physics_body_2d.cpp | 50 | ||||
| -rw-r--r-- | scene/2d/physics_body_2d.h | 4 | ||||
| -rw-r--r-- | scene/2d/ray_cast_2d.cpp | 36 | ||||
| -rw-r--r-- | scene/2d/ray_cast_2d.h | 4 |
6 files changed, 83 insertions, 26 deletions
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/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 75fa6054ad..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 @@ -1228,29 +1233,38 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { -Vector2 KinematicBody2D::move_and_slide(const Vector2& p_linear_velocity,const Vector2& p_floor_direction,int p_max_bounces) { +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 = p_linear_velocity*get_fixed_process_delta_time(); + 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(motion!=Vector2() && p_max_bounces) { + 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 { @@ -1271,6 +1285,8 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2& p_linear_velocity,const V } p_max_bounces--; + if (motion==Vector2()) + break; } return lv; @@ -1298,11 +1314,11 @@ 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); } @@ -1367,9 +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","max_bounces"),&KinematicBody2D::move_and_slide,DEFVAL(Vector2(0,0)),DEFVAL(4)); + 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); diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 387267cd09..ea29d873bd 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -319,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; @@ -335,7 +335,7 @@ 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),int p_max_bounces=4); + 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; 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; |