From a969e2e6f17d6810771e9c9c31551d57e5d1efdb Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 17 Mar 2015 00:45:25 -0300 Subject: Area2D can now detect overlap with other areas this should make everything simpler, specially for newcomers to Godot --- servers/physics_2d/area_2d_sw.cpp | 71 ++++++++++++++++++++++++++++- servers/physics_2d/area_2d_sw.h | 34 ++++++++++++++ servers/physics_2d/area_pair_2d_sw.cpp | 69 ++++++++++++++++++++++++++++ servers/physics_2d/area_pair_2d_sw.h | 18 ++++++++ servers/physics_2d/physics_2d_server_sw.cpp | 18 ++++++++ servers/physics_2d/physics_2d_server_sw.h | 3 +- servers/physics_2d/space_2d_sw.cpp | 15 ++++-- 7 files changed, 222 insertions(+), 6 deletions(-) (limited to 'servers/physics_2d') diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp index 2e911288a..65f3b80dd 100644 --- a/servers/physics_2d/area_2d_sw.cpp +++ b/servers/physics_2d/area_2d_sw.cpp @@ -31,6 +31,7 @@ #include "body_2d_sw.h" Area2DSW::BodyKey::BodyKey(Body2DSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape) { rid=p_body->get_self(); instance_id=p_body->get_instance_id(); body_shape=p_body_shape; area_shape=p_area_shape; } +Area2DSW::BodyKey::BodyKey(Area2DSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape) { rid=p_body->get_self(); instance_id=p_body->get_instance_id(); body_shape=p_body_shape; area_shape=p_area_shape; } void Area2DSW::_shapes_changed() { @@ -57,6 +58,7 @@ void Area2DSW::set_space(Space2DSW *p_space) { } monitored_bodies.clear(); + monitored_areas.clear(); _set_space(p_space); } @@ -76,11 +78,31 @@ void Area2DSW::set_monitor_callback(ObjectID p_id, const StringName& p_method) { monitor_callback_method=p_method; monitored_bodies.clear(); + monitored_areas.clear(); _shape_changed(); } +void Area2DSW::set_area_monitor_callback(ObjectID p_id, const StringName& p_method) { + + + if (p_id==area_monitor_callback_id) { + area_monitor_callback_method=p_method; + return; + } + + _unregister_shapes(); + + area_monitor_callback_id=p_id; + area_monitor_callback_method=p_method; + + monitored_bodies.clear(); + monitored_areas.clear(); + + _shape_changed(); + +} void Area2DSW::set_space_override_mode(Physics2DServer::AreaSpaceOverrideMode p_mode) { @@ -134,6 +156,15 @@ void Area2DSW::_queue_monitor_update() { } +void Area2DSW::set_monitorable(bool p_monitorable) { + + if (monitorable==p_monitorable) + return; + + monitorable=p_monitorable; + _set_static(!monitorable); +} + void Area2DSW::call_queries() { if (monitor_callback_id && !monitored_bodies.empty()) { @@ -170,13 +201,49 @@ void Area2DSW::call_queries() { monitored_bodies.clear(); + if (area_monitor_callback_id && !monitored_areas.empty()) { + + + Variant res[5]; + Variant *resptr[5]; + for(int i=0;i<5;i++) + resptr[i]=&res[i]; + + Object *obj = ObjectDB::get_instance(area_monitor_callback_id); + if (!obj) { + monitored_areas.clear(); + area_monitor_callback_id=0; + return; + } + + + + for (Map::Element *E=monitored_areas.front();E;E=E->next()) { + + if (E->get().state==0) + continue; //nothing happened + + res[0]=E->get().state>0 ? Physics2DServer::AREA_BODY_ADDED : Physics2DServer::AREA_BODY_REMOVED; + res[1]=E->key().rid; + res[2]=E->key().instance_id; + res[3]=E->key().body_shape; + res[4]=E->key().area_shape; + + + Variant::CallError ce; + obj->call(area_monitor_callback_method,(const Variant**)resptr,5,ce); + } + } + + monitored_areas.clear(); + //get_space()->area_remove_from_monitor_query_list(&monitor_query_list); } Area2DSW::Area2DSW() : CollisionObject2DSW(TYPE_AREA), monitor_query_list(this), moved_list(this) { - _set_static(true); //areas are never active + _set_static(true); //areas are not active by default space_override_mode=Physics2DServer::AREA_SPACE_OVERRIDE_DISABLED; gravity=9.80665; gravity_vector=Vector2(0,-1); @@ -187,6 +254,8 @@ Area2DSW::Area2DSW() : CollisionObject2DSW(TYPE_AREA), monitor_query_list(this), linear_damp=0.1; priority=0; monitor_callback_id=0; + area_monitor_callback_id=0; + monitorable=false; } diff --git a/servers/physics_2d/area_2d_sw.h b/servers/physics_2d/area_2d_sw.h index d94b2f9cc..26b7b2516 100644 --- a/servers/physics_2d/area_2d_sw.h +++ b/servers/physics_2d/area_2d_sw.h @@ -50,10 +50,14 @@ class Area2DSW : public CollisionObject2DSW{ float linear_damp; float angular_damp; int priority; + bool monitorable; ObjectID monitor_callback_id; StringName monitor_callback_method; + ObjectID area_monitor_callback_id; + StringName area_monitor_callback_method; + SelfList monitor_query_list; SelfList moved_list; @@ -80,6 +84,7 @@ class Area2DSW : public CollisionObject2DSW{ _FORCE_INLINE_ BodyKey() {} BodyKey(Body2DSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape); + BodyKey(Area2DSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape); }; struct BodyState { @@ -91,6 +96,7 @@ class Area2DSW : public CollisionObject2DSW{ }; Map monitored_bodies; + Map monitored_areas; //virtual void shape_changed_notify(Shape2DSW *p_shape); //virtual void shape_deleted_notify(Shape2DSW *p_shape); @@ -108,9 +114,16 @@ public: void set_monitor_callback(ObjectID p_id, const StringName& p_method); _FORCE_INLINE_ bool has_monitor_callback() const { return monitor_callback_id; } + void set_area_monitor_callback(ObjectID p_id, const StringName& p_method); + _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id; } + + _FORCE_INLINE_ void add_body_to_query(Body2DSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape); _FORCE_INLINE_ void remove_body_from_query(Body2DSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape); + _FORCE_INLINE_ void add_area_to_query(Area2DSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape); + _FORCE_INLINE_ void remove_area_from_query(Area2DSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape); + void set_param(Physics2DServer::AreaParameter p_param, const Variant& p_value); Variant get_param(Physics2DServer::AreaParameter p_param) const; @@ -142,6 +155,9 @@ public: _FORCE_INLINE_ void remove_constraint( Constraint2DSW* p_constraint) { constraints.erase(p_constraint); } _FORCE_INLINE_ const Set& get_constraints() const { return constraints; } + void set_monitorable(bool p_monitorable); + _FORCE_INLINE_ bool is_monitorable() const { return monitorable; } + void set_transform(const Matrix32& p_transform); void set_space(Space2DSW *p_space); @@ -168,6 +184,24 @@ void Area2DSW::remove_body_from_query(Body2DSW *p_body, uint32_t p_body_shape,ui _queue_monitor_update(); } +void Area2DSW::add_area_to_query(Area2DSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape) { + + + BodyKey bk(p_area,p_area_shape,p_self_shape); + monitored_areas[bk].inc(); + if (!monitor_query_list.in_list()) + _queue_monitor_update(); + + +} +void Area2DSW::remove_area_from_query(Area2DSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape) { + + + BodyKey bk(p_area,p_area_shape,p_self_shape); + monitored_areas[bk].dec(); + if (!monitor_query_list.in_list()) + _queue_monitor_update(); +} diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp index 1c7f73db5..ed2e34c97 100644 --- a/servers/physics_2d/area_pair_2d_sw.cpp +++ b/servers/physics_2d/area_pair_2d_sw.cpp @@ -94,3 +94,72 @@ AreaPair2DSW::~AreaPair2DSW() { body->remove_constraint(this); area->remove_constraint(this); } + + +////////////////////////////////// + + + +bool Area2Pair2DSW::setup(float p_step) { + + bool result = CollisionSolver2DSW::solve(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),Vector2(),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),Vector2(),NULL,this); + + if (result!=colliding) { + + if (result) { + + if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) + area_b->add_area_to_query(area_a,shape_a,shape_b); + + if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) + area_a->add_area_to_query(area_b,shape_b,shape_a); + + } else { + + if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) + area_b->remove_area_from_query(area_a,shape_a,shape_b); + + if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) + area_a->remove_area_from_query(area_b,shape_b,shape_a); + } + + colliding=result; + + } + + return false; //never do any post solving +} + +void Area2Pair2DSW::solve(float p_step) { + + +} + + +Area2Pair2DSW::Area2Pair2DSW(Area2DSW *p_area_a,int p_shape_a, Area2DSW *p_area_b,int p_shape_b) { + + + area_a=p_area_a; + area_b=p_area_b; + shape_a=p_shape_a; + shape_b=p_shape_b; + colliding=false; + area_a->add_constraint(this); + area_b->add_constraint(this); + +} + +Area2Pair2DSW::~Area2Pair2DSW() { + + if (colliding) { + + if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) + area_b->remove_area_from_query(area_a,shape_a,shape_b); + + if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) + area_a->remove_area_from_query(area_b,shape_b,shape_a); + } + + area_a->remove_constraint(this); + area_b->remove_constraint(this); +} diff --git a/servers/physics_2d/area_pair_2d_sw.h b/servers/physics_2d/area_pair_2d_sw.h index 5dad8c7a1..575490b10 100644 --- a/servers/physics_2d/area_pair_2d_sw.h +++ b/servers/physics_2d/area_pair_2d_sw.h @@ -49,5 +49,23 @@ public: ~AreaPair2DSW(); }; + +class Area2Pair2DSW : public Constraint2DSW { + + Area2DSW *area_a; + Area2DSW *area_b; + int shape_a; + int shape_b; + bool colliding; +public: + + bool setup(float p_step); + void solve(float p_step); + + Area2Pair2DSW(Area2DSW *p_area_a,int p_shape_a, Area2DSW *p_area_b,int p_shape_b); + ~Area2Pair2DSW(); +}; + + #endif // AREA_PAIR_2D_SW_H diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index be4995505..0a02a9568 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -463,6 +463,16 @@ Matrix32 Physics2DServerSW::area_get_transform(RID p_area) const { return area->get_transform(); }; +void Physics2DServerSW::area_set_monitorable(RID p_area,bool p_monitorable) { + + Area2DSW *area = area_owner.get(p_area); + ERR_FAIL_COND(!area); + + area->set_monitorable(p_monitorable); + +} + + void Physics2DServerSW::area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method) { Area2DSW *area = area_owner.get(p_area); @@ -473,6 +483,14 @@ void Physics2DServerSW::area_set_monitor_callback(RID p_area,Object *p_receiver, } +void Physics2DServerSW::area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method) { + + + Area2DSW *area = area_owner.get(p_area); + ERR_FAIL_COND(!area); + + area->set_area_monitor_callback(p_receiver?p_receiver->get_instance_ID():0,p_method); +} /* BODY API */ diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index e9c499aaf..eba5845e5 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -133,9 +133,10 @@ public: virtual Variant area_get_param(RID p_parea,AreaParameter p_param) const; virtual Matrix32 area_get_transform(RID p_area) const; + virtual void area_set_monitorable(RID p_area,bool p_monitorable); virtual void area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method); - + virtual void area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method); /* BODY API */ diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index f2ed74ffb..9523e8bf8 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -527,13 +527,20 @@ void* Space2DSW::_broadphase_pair(CollisionObject2DSW *A,int p_subindex_A,Collis if (type_A==CollisionObject2DSW::TYPE_AREA) { - ERR_FAIL_COND_V(type_B!=CollisionObject2DSW::TYPE_BODY,NULL); Area2DSW *area=static_cast(A); - Body2DSW *body=static_cast(B); + if (type_B==CollisionObject2DSW::TYPE_AREA) { + + Area2DSW *area_b=static_cast(B); + Area2Pair2DSW *area2_pair = memnew(Area2Pair2DSW(area_b,p_subindex_B,area,p_subindex_A) ); + return area2_pair; + } else { + + Body2DSW *body=static_cast(B); + AreaPair2DSW *area_pair = memnew(AreaPair2DSW(body,p_subindex_B,area,p_subindex_A) ); + return area_pair; + } - AreaPair2DSW *area_pair = memnew(AreaPair2DSW(body,p_subindex_B,area,p_subindex_A) ); - return area_pair; } else { -- cgit v1.2.3-70-g09d2 From c6c72a3c37a44964ec8e6b3353f78635bf588eab Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 22 Mar 2015 01:46:18 -0300 Subject: input events on Area2D is now supported also added a demo showing how this works --- demos/2d/area_input/box_area.png | Bin 0 -> 1246 bytes demos/2d/area_input/circle_area.png | Bin 0 -> 3030 bytes demos/2d/area_input/engine.cfg | 4 ++ demos/2d/area_input/input.gd | 20 ++++++++ demos/2d/area_input/input.scn | Bin 0 -> 2886 bytes scene/2d/canvas_item.cpp | 62 ++++++++++++++++++++++ scene/2d/canvas_item.h | 1 + scene/2d/collision_object_2d.cpp | 71 ++++++++++++++++++++++++++ scene/2d/collision_object_2d.h | 12 +++++ scene/2d/physics_body_2d.cpp | 1 + scene/main/viewport.cpp | 65 +++++++++++++++++++++-- scene/main/viewport.h | 1 + scene/resources/font.cpp | 4 ++ servers/physics/space_sw.cpp | 2 +- servers/physics_2d/collision_object_2d_sw.cpp | 1 + servers/physics_2d/collision_object_2d_sw.h | 4 ++ servers/physics_2d/physics_2d_server_sw.cpp | 15 ++++++ servers/physics_2d/physics_2d_server_sw.h | 5 ++ servers/physics_2d/shape_2d_sw.cpp | 63 +++++++++++++++++++++++ servers/physics_2d/shape_2d_sw.h | 10 ++++ servers/physics_2d/space_2d_sw.cpp | 51 ++++++++++++++++++ servers/physics_2d/space_2d_sw.h | 1 + servers/physics_2d_server.h | 5 ++ 23 files changed, 392 insertions(+), 6 deletions(-) create mode 100644 demos/2d/area_input/box_area.png create mode 100644 demos/2d/area_input/circle_area.png create mode 100644 demos/2d/area_input/engine.cfg create mode 100644 demos/2d/area_input/input.gd create mode 100644 demos/2d/area_input/input.scn (limited to 'servers/physics_2d') diff --git a/demos/2d/area_input/box_area.png b/demos/2d/area_input/box_area.png new file mode 100644 index 000000000..ba7c37f7d Binary files /dev/null and b/demos/2d/area_input/box_area.png differ diff --git a/demos/2d/area_input/circle_area.png b/demos/2d/area_input/circle_area.png new file mode 100644 index 000000000..3cc24c8a0 Binary files /dev/null and b/demos/2d/area_input/circle_area.png differ diff --git a/demos/2d/area_input/engine.cfg b/demos/2d/area_input/engine.cfg new file mode 100644 index 000000000..3227e9278 --- /dev/null +++ b/demos/2d/area_input/engine.cfg @@ -0,0 +1,4 @@ +[application] + +name="Area 2D Input Events" +main_scene="res://input.scn" diff --git a/demos/2d/area_input/input.gd b/demos/2d/area_input/input.gd new file mode 100644 index 000000000..acecd095e --- /dev/null +++ b/demos/2d/area_input/input.gd @@ -0,0 +1,20 @@ + +extends Area2D + +# member variables here, example: +# var a=2 +# var b="textvar" + +#virtual from CollisionObject2D (also available as signal) +func _input_event(viewport, event, shape_idx): + #convert event to local coordinates + if (event.type==InputEvent.MOUSE_MOTION): + event = make_input_local( event ) + get_node("label").set_text(str(event.pos)) + +#virtual from CollisionObject2D (also available as signal) +func _mouse_exit(): + get_node("label").set_text("") + + + diff --git a/demos/2d/area_input/input.scn b/demos/2d/area_input/input.scn new file mode 100644 index 000000000..0bb3a1883 Binary files /dev/null and b/demos/2d/area_input/input.scn differ diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 436b77a1a..c3ff03d8f 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -943,7 +943,67 @@ Ref CanvasItem::get_material() const{ } +InputEvent CanvasItem::make_input_local(const InputEvent& p_event) const { + ERR_FAIL_COND_V(!is_inside_tree(),p_event); + + InputEvent ev = p_event; + + Matrix32 local_matrix = (get_canvas_transform() * get_global_transform()).affine_inverse(); + + switch(ev.type) { + + case InputEvent::MOUSE_BUTTON: { + + Vector2 g = local_matrix.xform(Vector2(ev.mouse_button.global_x,ev.mouse_button.global_y)); + Vector2 l = local_matrix.xform(Vector2(ev.mouse_button.x,ev.mouse_button.y)); + ev.mouse_button.x=l.x; + ev.mouse_button.y=l.y; + ev.mouse_button.global_x=g.x; + ev.mouse_button.global_y=g.y; + + } break; + case InputEvent::MOUSE_MOTION: { + + Vector2 g = local_matrix.xform(Vector2(ev.mouse_motion.global_x,ev.mouse_motion.global_y)); + Vector2 l = local_matrix.xform(Vector2(ev.mouse_motion.x,ev.mouse_motion.y)); + Vector2 r = local_matrix.basis_xform(Vector2(ev.mouse_motion.relative_x,ev.mouse_motion.relative_y)); + Vector2 s = local_matrix.basis_xform(Vector2(ev.mouse_motion.speed_x,ev.mouse_motion.speed_y)); + ev.mouse_motion.x=l.x; + ev.mouse_motion.y=l.y; + ev.mouse_motion.global_x=g.x; + ev.mouse_motion.global_y=g.y; + ev.mouse_motion.relative_x=r.x; + ev.mouse_motion.relative_y=r.y; + ev.mouse_motion.speed_x=s.x; + ev.mouse_motion.speed_y=s.y; + + } break; + case InputEvent::SCREEN_TOUCH: { + + + Vector2 t = local_matrix.xform(Vector2(ev.screen_touch.x,ev.screen_touch.y)); + ev.screen_touch.x=t.x; + ev.screen_touch.y=t.y; + + } break; + case InputEvent::SCREEN_DRAG: { + + + Vector2 t = local_matrix.xform(Vector2(ev.screen_drag.x,ev.screen_drag.y)); + Vector2 r = local_matrix.basis_xform(Vector2(ev.screen_drag.relative_x,ev.screen_drag.relative_y)); + Vector2 s = local_matrix.basis_xform(Vector2(ev.screen_drag.speed_x,ev.screen_drag.speed_y)); + ev.screen_drag.x=t.x; + ev.screen_drag.y=t.y; + ev.screen_drag.relative_x=r.x; + ev.screen_drag.relative_y=r.y; + ev.screen_drag.speed_x=s.x; + ev.screen_drag.speed_y=s.y; + } break; + } + + return ev; +} void CanvasItem::_bind_methods() { @@ -1021,6 +1081,8 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_use_parent_material","enable"),&CanvasItem::set_use_parent_material); ObjectTypeDB::bind_method(_MD("get_use_parent_material"),&CanvasItem::get_use_parent_material); + ObjectTypeDB::bind_method(_MD("make_input_local","event"),&CanvasItem::make_input_local); + BIND_VMETHOD(MethodInfo("_draw")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/visible"), _SCS("_set_visible_"),_SCS("_is_visible_") ); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 0c7be261a..c43642a8e 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -249,6 +249,7 @@ public: void set_use_parent_material(bool p_use_parent_material); bool get_use_parent_material() const; + InputEvent make_input_local(const InputEvent& pevent) const; CanvasItem(); ~CanvasItem(); diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index 3b859d936..a883fee10 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -28,6 +28,7 @@ /*************************************************************************/ #include "collision_object_2d.h" #include "servers/physics_2d_server.h" +#include "scene/scene_string_names.h" void CollisionObject2D::_update_shapes_from_children() { @@ -58,9 +59,15 @@ void CollisionObject2D::_notification(int p_what) { } else Physics2DServer::get_singleton()->body_set_space(rid,space); + _update_pickable(); + //get space } + case NOTIFICATION_VISIBILITY_CHANGED: { + + _update_pickable(); + } break; case NOTIFICATION_TRANSFORM_CHANGED: { if (area) @@ -166,6 +173,57 @@ void CollisionObject2D::_get_property_list( List *p_list) const { } } + +void CollisionObject2D::set_pickable(bool p_enabled) { + + if (pickable==p_enabled) + return; + + pickable=p_enabled; + _update_pickable(); +} + +bool CollisionObject2D::is_pickable() const { + + return pickable; +} + +void CollisionObject2D::_input_event(Node *p_viewport, const InputEvent& p_input_event, int p_shape) { + + if (get_script_instance()) { + get_script_instance()->call(SceneStringNames::get_singleton()->_input_event,p_viewport,p_input_event,p_shape); + } + emit_signal(SceneStringNames::get_singleton()->input_event,p_viewport,p_input_event,p_shape); +} + +void CollisionObject2D::_mouse_enter() { + + if (get_script_instance()) { + get_script_instance()->call(SceneStringNames::get_singleton()->_mouse_enter); + } + emit_signal(SceneStringNames::get_singleton()->mouse_enter); +} + + +void CollisionObject2D::_mouse_exit() { + + if (get_script_instance()) { + get_script_instance()->call(SceneStringNames::get_singleton()->_mouse_exit); + } + emit_signal(SceneStringNames::get_singleton()->mouse_exit); + +} + +void CollisionObject2D::_update_pickable() { + if (!is_inside_tree()) + return; + bool pickable = this->pickable && is_inside_tree() && is_visible(); + if (area) + Physics2DServer::get_singleton()->area_set_pickable(rid,pickable); + else + Physics2DServer::get_singleton()->body_set_pickable(rid,pickable); +} + void CollisionObject2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("add_shape","shape:Shape2D","transform"),&CollisionObject2D::add_shape,DEFVAL(Matrix32())); @@ -180,6 +238,17 @@ void CollisionObject2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("clear_shapes"),&CollisionObject2D::clear_shapes); ObjectTypeDB::bind_method(_MD("get_rid"),&CollisionObject2D::get_rid); + ObjectTypeDB::bind_method(_MD("set_pickable","enabled"),&CollisionObject2D::set_pickable); + ObjectTypeDB::bind_method(_MD("is_pickable"),&CollisionObject2D::is_pickable); + + BIND_VMETHOD( MethodInfo("_input_event",PropertyInfo(Variant::OBJECT,"viewport"),PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::INT,"shape_idx"))); + + ADD_SIGNAL( MethodInfo("input_event",PropertyInfo(Variant::OBJECT,"viewport"),PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::INT,"shape_idx"))); + ADD_SIGNAL( MethodInfo("mouse_enter")); + ADD_SIGNAL( MethodInfo("mouse_exit")); + + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"input/pickable"),_SCS("set_pickable"),_SCS("is_pickable")); + } @@ -262,7 +331,9 @@ CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) { rid=p_rid; area=p_area; + pickable=true; if (p_area) { + Physics2DServer::get_singleton()->area_attach_object_instance_ID(rid,get_instance_ID()); } else { Physics2DServer::get_singleton()->body_attach_object_instance_ID(rid,get_instance_ID()); diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h index 4a529ce06..393973ce9 100644 --- a/scene/2d/collision_object_2d.h +++ b/scene/2d/collision_object_2d.h @@ -38,6 +38,7 @@ class CollisionObject2D : public Node2D { bool area; RID rid; + bool pickable; struct ShapeData { Matrix32 xform; @@ -66,9 +67,17 @@ protected: bool _get(const StringName& p_name,Variant &r_ret) const; void _get_property_list( List *p_list) const; static void _bind_methods(); + + void _update_pickable(); +friend class Viewport; + void _input_event(Node *p_viewport, const InputEvent& p_input_event, int p_shape); + void _mouse_enter(); + void _mouse_exit(); + public: + void add_shape(const Ref& p_shape, const Matrix32& p_transform=Matrix32()); int get_shape_count() const; void set_shape(int p_shape_idx, const Ref& p_shape); @@ -80,6 +89,9 @@ public: void remove_shape(int p_shape_idx); void clear_shapes(); + void set_pickable(bool p_enabled); + bool is_pickable() const; + _FORCE_INLINE_ RID get_rid() const { return rid; } CollisionObject2D(); diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 6f1832521..22dd0f01d 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -98,6 +98,7 @@ PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject mask=1; set_one_way_collision_max_depth(0); + set_pickable(false); } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 02e009866..18b8b46d9 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -30,7 +30,7 @@ #include "os/os.h" #include "scene/3d/spatial.h" #include "os/input.h" - +#include "servers/physics_2d_server.h" //#include "scene/3d/camera.h" #include "servers/spatial_sound_server.h" @@ -40,7 +40,7 @@ #include "scene/3d/spatial_indexer.h" #include "scene/3d/collision_object.h" - +#include "scene/2d/collision_object_2d.h" int RenderTargetTexture::get_width() const { @@ -355,11 +355,12 @@ void Viewport::_notification(int p_what) { case NOTIFICATION_FIXED_PROCESS: { if (physics_object_picking) { -#ifndef _3D_DISABLED + Vector2 last_pos(1e20,1e20); CollisionObject *last_object; ObjectID last_id=0; PhysicsDirectSpaceState::RayResult result; + Physics2DDirectSpaceState *ss2d=Physics2DServer::get_singleton()->space_get_direct_state(find_world_2d()->get_space()); bool motion_tested=false; @@ -392,6 +393,60 @@ void Viewport::_notification(int p_what) { } + if (ss2d) { + //send to 2D + + + uint64_t frame = get_tree()->get_frame(); + + Vector2 point = get_canvas_transform().affine_inverse().xform(pos); + Physics2DDirectSpaceState::ShapeResult res[64]; + int rc = ss2d->intersect_point(point,res,64,Set(),0xFFFFFFFF,0xFFFFFFFF); + for(int i=0;icast_to(); + if (co) { + + Map::Element *E=physics_2d_mouseover.find(res[i].collider_id); + if (!E) { + E=physics_2d_mouseover.insert(res[i].collider_id,frame); + co->_mouse_enter(); + } else { + E->get()=frame; + } + + co->_input_event(this,ev,res[i].shape); + } + } + } + + List::Element*> to_erase; + + for (Map::Element*E=physics_2d_mouseover.front();E;E=E->next()) { + if (E->get()!=frame) { + Object *o=ObjectDB::get_instance(E->key()); + if (o) { + + CollisionObject2D *co=o->cast_to(); + if (co) { + co->_mouse_exit(); + } + } + to_erase.push_back(E); + } + } + + while(to_erase.size()) { + physics_2d_mouseover.erase(to_erase.front()->get()); + to_erase.pop_front(); + } + + } + + + +#ifndef _3D_DISABLED bool captured=false; if (physics_object_capture!=0) { @@ -499,9 +554,9 @@ void Viewport::_notification(int p_what) { _test_new_mouseover(new_collider); } - - } #endif + } + } } break; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index d2a22401b..14f4f6821 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -124,6 +124,7 @@ friend class RenderTargetTexture; ObjectID physics_object_over; Vector2 physics_last_mousepos; void _test_new_mouseover(ObjectID new_collider); + Map physics_2d_mouseover; void _update_rect(); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 24d413ed6..79316f001 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -523,6 +523,10 @@ void Font::_bind_methods() { ObjectTypeDB::bind_method(_MD("add_texture","texture:Texture"),&Font::add_texture); ObjectTypeDB::bind_method(_MD("add_char","character","texture","rect","align","advance"),&Font::add_char,DEFVAL(Point2()),DEFVAL(-1)); + + ObjectTypeDB::bind_method(_MD("get_texture_count"),&Font::get_texture_count); + ObjectTypeDB::bind_method(_MD("get_texture:Texture","idx"),&Font::get_texture); + ObjectTypeDB::bind_method(_MD("get_char_size","char","next"),&Font::get_char_size,DEFVAL(0)); ObjectTypeDB::bind_method(_MD("get_string_size","string"),&Font::get_string_size); diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index 4e8b60b86..3fc34889f 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -77,7 +77,7 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3& p_from, const Vecto if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask)) continue; - if (!(static_cast(space->intersection_query_results[i])->is_ray_pickable())) + if (!(static_cast(space->intersection_query_results[i])->is_ray_pickable())) continue; if (p_exclude.has( space->intersection_query_results[i]->get_self())) diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp index d0443f811..eefc598b3 100644 --- a/servers/physics_2d/collision_object_2d_sw.cpp +++ b/servers/physics_2d/collision_object_2d_sw.cpp @@ -228,4 +228,5 @@ CollisionObject2DSW::CollisionObject2DSW(Type p_type) { instance_id=0; user_mask=0; layer_mask=1; + pickable=true; } diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h index 00ad36124..0c9123787 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/collision_object_2d_sw.h @@ -47,6 +47,7 @@ private: Type type; RID self; ObjectID instance_id; + bool pickable; struct Shape { @@ -129,6 +130,9 @@ public: _FORCE_INLINE_ bool is_static() const { return _static; } + void set_pickable(bool p_pickable) { pickable=p_pickable; } + _FORCE_INLINE_ bool is_pickable() const { return pickable; } + virtual ~CollisionObject2DSW() {} }; diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index 0a02a9568..883acd020 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -463,6 +463,14 @@ Matrix32 Physics2DServerSW::area_get_transform(RID p_area) const { return area->get_transform(); }; +void Physics2DServerSW::area_set_pickable(RID p_area,bool p_pickable) { + + Area2DSW *area = area_owner.get(p_area); + ERR_FAIL_COND(!area); + area->set_pickable(p_pickable); + +} + void Physics2DServerSW::area_set_monitorable(RID p_area,bool p_monitorable) { Area2DSW *area = area_owner.get(p_area); @@ -943,6 +951,13 @@ bool Physics2DServerSW::body_collide_shape(RID p_body, int p_body_shape, RID p_s } +void Physics2DServerSW::body_set_pickable(RID p_body,bool p_pickable) { + + Body2DSW *body = body_owner.get(p_body); + ERR_FAIL_COND(!body); + body->set_pickable(p_pickable); + +} /* JOINT API */ diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index eba5845e5..58fc4eeb3 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -138,6 +138,9 @@ public: virtual void area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method); virtual void area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method); + virtual void area_set_pickable(RID p_area,bool p_pickable); + + /* BODY API */ // create a body of a given type @@ -218,6 +221,8 @@ public: virtual void body_set_force_integration_callback(RID p_body,Object *p_receiver,const StringName& p_method,const Variant& p_udata=Variant()); virtual bool body_collide_shape(RID p_body, int p_body_shape,RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,Vector2 *r_results,int p_result_max,int &r_result_count); + virtual void body_set_pickable(RID p_body,bool p_pickable); + /* JOINT API */ virtual void joint_set_param(RID p_joint, JointParam p_param, real_t p_value); diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index ed63870a1..9a4b52d56 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -106,6 +106,11 @@ void LineShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_supports,int r_amount=0; } +bool LineShape2DSW::contains_point(const Vector2& p_point) const { + + return normal.dot(p_point) < d; +} + bool LineShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const { Vector2 segment= p_begin - p_end; @@ -175,6 +180,11 @@ void RayShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_supports,int } +bool RayShape2DSW::contains_point(const Vector2& p_point) const { + + return false; +} + bool RayShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const { return false; //rays can't be intersected @@ -223,6 +233,11 @@ void SegmentShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_supports, } +bool SegmentShape2DSW::contains_point(const Vector2& p_point) const { + + return false; +} + bool SegmentShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const { if (!Geometry::segment_intersects_segment_2d(p_begin,p_end,a,b,&r_point)) @@ -288,6 +303,13 @@ void CircleShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_supports,i } + +bool CircleShape2DSW::contains_point(const Vector2& p_point) const { + + return p_point.length_squared() < radius*radius; +} + + bool CircleShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const { @@ -375,6 +397,11 @@ void RectangleShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_support } +bool RectangleShape2DSW::contains_point(const Vector2& p_point) const { + + return Math::abs(p_point.x)0) + out=true; + else + in=true; + } + + return (in && !out) || (!in && out); +} + + bool ConvexPolygonShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const { Vector2 n = (p_end-p_begin).normalized(); @@ -734,6 +791,12 @@ void ConcavePolygonShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_su } +bool ConcavePolygonShape2DSW::contains_point(const Vector2& p_point) const { + + return false; //sorry +} + + bool ConcavePolygonShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const{ uint32_t* stack = (uint32_t*)alloca(sizeof(int)*bvh_depth); diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/shape_2d_sw.h index 931491efd..05ea5b21c 100644 --- a/servers/physics_2d/shape_2d_sw.h +++ b/servers/physics_2d/shape_2d_sw.h @@ -78,6 +78,8 @@ public: virtual bool is_concave() const { return false; } + virtual bool contains_point(const Vector2& p_point) const=0; + virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const=0; virtual void project_range_castv(const Vector2& p_cast, const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const=0; virtual Vector2 get_support(const Vector2& p_normal) const; @@ -171,6 +173,7 @@ public: virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); } virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const; + virtual bool contains_point(const Vector2& p_point) const; virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const; virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const; @@ -213,6 +216,7 @@ public: virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); } virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const; + virtual bool contains_point(const Vector2& p_point) const; virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const; virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const; @@ -260,6 +264,7 @@ public: virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); } virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const; + virtual bool contains_point(const Vector2& p_point) const; virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const; virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const; @@ -297,6 +302,7 @@ public: virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); } virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const; + virtual bool contains_point(const Vector2& p_point) const; virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const; virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const; @@ -336,6 +342,7 @@ public: virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); } virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const; + virtual bool contains_point(const Vector2& p_point) const; virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const; virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const; @@ -423,6 +430,7 @@ public: virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); } virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const; + virtual bool contains_point(const Vector2& p_point) const; virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const; virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const; @@ -485,6 +493,7 @@ public: virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); } virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const; + virtual bool contains_point(const Vector2& p_point) const; virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const; virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const; @@ -572,6 +581,7 @@ public: virtual void project_range(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { /*project_range(p_normal,p_transform,r_min,r_max);*/ } virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const; + virtual bool contains_point(const Vector2& p_point) const; virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const; virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const { return 0; } diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 9523e8bf8..5aaf9a761 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -45,6 +45,57 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_objec } + +int Physics2DDirectSpaceStateSW::intersect_point(const Vector2& p_point,ShapeResult *r_results,int p_result_max,const Set& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) { + + if (p_result_max<=0) + return 0; + + Rect2 aabb; + aabb.pos=p_point-Vector2(0.00001,0.00001); + aabb.size=Vector2(0.00002,0.00002); + + int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); + + int cc=0; + + for(int i=0;iintersection_query_results[i],p_layer_mask,p_object_type_mask)) + continue; + + if (p_exclude.has( space->intersection_query_results[i]->get_self())) + continue; + + const CollisionObject2DSW *col_obj=space->intersection_query_results[i]; + + if (!col_obj->is_pickable()) + continue; + + int shape_idx=space->intersection_query_subindex_results[i]; + + Shape2DSW * shape = col_obj->get_shape(shape_idx); + + Vector2 local_point = (col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).affine_inverse().xform(p_point); + + if (!shape->contains_point(local_point)) + continue; + + r_results[cc].collider_id=col_obj->get_instance_id(); + if (r_results[cc].collider_id!=0) + r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id); + r_results[cc].rid=col_obj->get_self(); + r_results[cc].shape=shape_idx; + r_results[cc].metadata=col_obj->get_shape_metadata(shape_idx); + + cc++; + } + + return cc; + + +} + bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2& p_from, const Vector2& p_to,RayResult &r_result,const Set& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) { diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h index 7977b1906..05b55fe80 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/space_2d_sw.h @@ -46,6 +46,7 @@ public: Space2DSW *space; + virtual int intersect_point(const Vector2& p_point,ShapeResult *r_results,int p_result_max,const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); virtual bool intersect_ray(const Vector2& p_from, const Vector2& p_to,RayResult &r_result,const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); virtual int intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); virtual bool cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index 1fb47fc1d..657e5ce44 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -181,6 +181,8 @@ public: }; + virtual int intersect_point(const Vector2& p_point,ShapeResult *r_results,int p_result_max,const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0; + virtual int intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0; virtual bool cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0; @@ -342,6 +344,7 @@ public: virtual Matrix32 area_get_transform(RID p_area) const=0; virtual void area_set_monitorable(RID p_area,bool p_monitorable)=0; + virtual void area_set_pickable(RID p_area,bool p_pickable)=0; virtual void area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method)=0; virtual void area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method)=0; @@ -462,6 +465,8 @@ public: virtual bool body_collide_shape(RID p_body, int p_body_shape,RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,Vector2 *r_results,int p_result_max,int &r_result_count)=0; + virtual void body_set_pickable(RID p_body,bool p_pickable)=0; + /* JOINT API */ enum JointType { -- cgit v1.2.3-70-g09d2 From e9f94ce8d2cc6805e74fffdf733e6dc5b5c530f5 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 22 Mar 2015 15:11:19 -0300 Subject: fix area center of gravity --- servers/physics/body_sw.cpp | 2 +- servers/physics_2d/body_2d_sw.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'servers/physics_2d') diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp index 725a440b5..c7c20a8bd 100644 --- a/servers/physics/body_sw.cpp +++ b/servers/physics/body_sw.cpp @@ -358,7 +358,7 @@ void BodySW::_compute_area_gravity(const AreaSW *p_area) { if (p_area->is_gravity_point()) { - gravity = (p_area->get_gravity_vector() - get_transform().get_origin()).normalized() * p_area->get_gravity(); + gravity = (p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin()).normalized() * p_area->get_gravity(); } else { gravity = p_area->get_gravity_vector() * p_area->get_gravity(); diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp index 1cfe9a6ab..06d466ace 100644 --- a/servers/physics_2d/body_2d_sw.cpp +++ b/servers/physics_2d/body_2d_sw.cpp @@ -379,7 +379,7 @@ void Body2DSW::_compute_area_gravity(const Area2DSW *p_area) { if (p_area->is_gravity_point()) { - gravity = (p_area->get_transform().get_origin()+p_area->get_gravity_vector() - get_transform().get_origin()).normalized() * p_area->get_gravity(); + gravity = (p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin()).normalized() * p_area->get_gravity(); } else { gravity = p_area->get_gravity_vector() * p_area->get_gravity(); -- cgit v1.2.3-70-g09d2