diff options
Diffstat (limited to 'scene')
31 files changed, 759 insertions, 89 deletions
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index fce21f6001..a5c455ce64 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -216,6 +216,119 @@ void Area2D::_body_inout(int p_status,const RID& p_body, int p_instance, int p_b } + +void Area2D::_area_enter_tree(ObjectID p_id) { + + Object *obj = ObjectDB::get_instance(p_id); + Node *node = obj ? obj->cast_to<Node>() : NULL; + ERR_FAIL_COND(!node); + + Map<ObjectID,AreaState>::Element *E=area_map.find(p_id); + ERR_FAIL_COND(!E); + ERR_FAIL_COND(E->get().in_tree); + + E->get().in_tree=true; + emit_signal(SceneStringNames::get_singleton()->area_enter,node); + for(int i=0;i<E->get().shapes.size();i++) { + + emit_signal(SceneStringNames::get_singleton()->area_enter_shape,p_id,node,E->get().shapes[i].area_shape,E->get().shapes[i].self_shape); + } + +} + +void Area2D::_area_exit_tree(ObjectID p_id) { + + Object *obj = ObjectDB::get_instance(p_id); + Node *node = obj ? obj->cast_to<Node>() : NULL; + ERR_FAIL_COND(!node); + Map<ObjectID,AreaState>::Element *E=area_map.find(p_id); + ERR_FAIL_COND(!E); + ERR_FAIL_COND(!E->get().in_tree); + E->get().in_tree=false; + emit_signal(SceneStringNames::get_singleton()->area_exit,node); + for(int i=0;i<E->get().shapes.size();i++) { + + emit_signal(SceneStringNames::get_singleton()->area_exit_shape,p_id,node,E->get().shapes[i].area_shape,E->get().shapes[i].self_shape); + } + +} + +void Area2D::_area_inout(int p_status,const RID& p_area, int p_instance, int p_area_shape,int p_self_shape) { + + bool area_in = p_status==Physics2DServer::AREA_BODY_ADDED; + ObjectID objid=p_instance; + + Object *obj = ObjectDB::get_instance(objid); + Node *node = obj ? obj->cast_to<Node>() : NULL; + + Map<ObjectID,AreaState>::Element *E=area_map.find(objid); + + ERR_FAIL_COND(!area_in && !E); + + locked=true; + + if (area_in) { + if (!E) { + + E = area_map.insert(objid,AreaState()); + E->get().rc=0; + E->get().in_tree=node && node->is_inside_tree(); + if (node) { + node->connect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_area_enter_tree,make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_area_exit_tree,make_binds(objid)); + if (E->get().in_tree) { + emit_signal(SceneStringNames::get_singleton()->area_enter,node); + } + } + + } + E->get().rc++; + if (node) + E->get().shapes.insert(AreaShapePair(p_area_shape,p_self_shape)); + + + if (!node || E->get().in_tree) { + emit_signal(SceneStringNames::get_singleton()->area_enter_shape,objid,node,p_area_shape,p_self_shape); + } + + } else { + + E->get().rc--; + + if (node) + E->get().shapes.erase(AreaShapePair(p_area_shape,p_self_shape)); + + bool eraseit=false; + + if (E->get().rc==0) { + + if (node) { + node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_area_enter_tree); + node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_area_exit_tree); + if (E->get().in_tree) + emit_signal(SceneStringNames::get_singleton()->area_exit,obj); + + } + + eraseit=true; + + } + if (!node || E->get().in_tree) { + emit_signal(SceneStringNames::get_singleton()->area_exit_shape,objid,obj,p_area_shape,p_self_shape); + } + + if (eraseit) + area_map.erase(E); + + } + + locked=false; + + +} + + + void Area2D::_clear_monitoring() { if (locked) { @@ -223,27 +336,56 @@ void Area2D::_clear_monitoring() { } ERR_FAIL_COND(locked); - Map<ObjectID,BodyState> bmcopy = body_map; - body_map.clear(); - //disconnect all monitored stuff + { + Map<ObjectID,BodyState> bmcopy = body_map; + body_map.clear(); + //disconnect all monitored stuff - for (Map<ObjectID,BodyState>::Element *E=bmcopy.front();E;E=E->next()) { + for (Map<ObjectID,BodyState>::Element *E=bmcopy.front();E;E=E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); - Node *node = obj ? obj->cast_to<Node>() : NULL; - ERR_CONTINUE(!node); - if (!E->get().in_tree) - continue; + Object *obj = ObjectDB::get_instance(E->key()); + Node *node = obj ? obj->cast_to<Node>() : NULL; + ERR_CONTINUE(!node); + if (!E->get().in_tree) + continue; - for(int i=0;i<E->get().shapes.size();i++) { + for(int i=0;i<E->get().shapes.size();i++) { - emit_signal(SceneStringNames::get_singleton()->body_exit_shape,E->key(),node,E->get().shapes[i].body_shape,E->get().shapes[i].area_shape); + emit_signal(SceneStringNames::get_singleton()->body_exit_shape,E->key(),node,E->get().shapes[i].body_shape,E->get().shapes[i].area_shape); + } + + emit_signal(SceneStringNames::get_singleton()->body_exit,obj); + + node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_body_enter_tree); + node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_body_exit_tree); } - emit_signal(SceneStringNames::get_singleton()->body_exit,obj); + } - node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_body_exit_tree); + { + + Map<ObjectID,AreaState> bmcopy = area_map; + area_map.clear(); + //disconnect all monitored stuff + + for (Map<ObjectID,AreaState>::Element *E=bmcopy.front();E;E=E->next()) { + + Object *obj = ObjectDB::get_instance(E->key()); + Node *node = obj ? obj->cast_to<Node>() : NULL; + ERR_CONTINUE(!node); + if (!E->get().in_tree) + continue; + + for(int i=0;i<E->get().shapes.size();i++) { + + emit_signal(SceneStringNames::get_singleton()->area_exit_shape,E->key(),node,E->get().shapes[i].area_shape,E->get().shapes[i].self_shape); + } + + emit_signal(SceneStringNames::get_singleton()->area_exit,obj); + + node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_area_enter_tree); + node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_area_exit_tree); + } } } @@ -276,8 +418,10 @@ void Area2D::set_enable_monitoring(bool p_enable) { if (monitoring) { Physics2DServer::get_singleton()->area_set_monitor_callback(get_rid(),this,"_body_inout"); + Physics2DServer::get_singleton()->area_set_area_monitor_callback(get_rid(),this,"_area_inout"); } else { Physics2DServer::get_singleton()->area_set_monitor_callback(get_rid(),NULL,StringName()); + Physics2DServer::get_singleton()->area_set_area_monitor_callback(get_rid(),NULL,StringName()); _clear_monitoring(); } @@ -288,6 +432,26 @@ bool Area2D::is_monitoring_enabled() const { return monitoring; } +void Area2D::set_monitorable(bool p_enable) { + + if (locked) { + ERR_EXPLAIN("This function can't be used during the in/out signal."); + } + ERR_FAIL_COND(locked); + + if (p_enable==monitorable) + return; + + monitorable=p_enable; + + Physics2DServer::get_singleton()->area_set_monitorable(get_rid(),monitorable); +} + +bool Area2D::is_monitorable() const { + + return monitorable; +} + Array Area2D::get_overlapping_bodies() const { ERR_FAIL_COND_V(!monitoring,Array()); @@ -307,12 +471,56 @@ Array Area2D::get_overlapping_bodies() const { return ret; } +Array Area2D::get_overlapping_areas() const { + + ERR_FAIL_COND_V(!monitoring,Array()); + Array ret; + ret.resize(area_map.size()); + int idx=0; + for (const Map<ObjectID,AreaState>::Element *E=area_map.front();E;E=E->next()) { + Object *obj = ObjectDB::get_instance(E->key()); + if (!obj) { + ret.resize( ret.size() -1 ); //ops + } else { + ret[idx++]=obj; + } + + } + + return ret; +} + +bool Area2D::overlaps_area(Node* p_area) const { + + ERR_FAIL_NULL_V(p_area,false); + const Map<ObjectID,AreaState>::Element *E=area_map.find(p_area->get_instance_ID()); + if (!E) + return false; + return E->get().in_tree; + + + +} + +bool Area2D::overlaps_body(Node* p_body) const{ + + ERR_FAIL_NULL_V(p_body,false); + const Map<ObjectID,BodyState>::Element *E=body_map.find(p_body->get_instance_ID()); + if (!E) + return false; + return E->get().in_tree; + +} + void Area2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("_body_enter_tree","id"),&Area2D::_body_enter_tree); ObjectTypeDB::bind_method(_MD("_body_exit_tree","id"),&Area2D::_body_exit_tree); + ObjectTypeDB::bind_method(_MD("_area_enter_tree","id"),&Area2D::_area_enter_tree); + ObjectTypeDB::bind_method(_MD("_area_exit_tree","id"),&Area2D::_area_exit_tree); + ObjectTypeDB::bind_method(_MD("set_space_override_mode","enable"),&Area2D::set_space_override_mode); ObjectTypeDB::bind_method(_MD("get_space_override_mode"),&Area2D::get_space_override_mode); @@ -337,15 +545,29 @@ void Area2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_enable_monitoring","enable"),&Area2D::set_enable_monitoring); ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"),&Area2D::is_monitoring_enabled); + ObjectTypeDB::bind_method(_MD("set_monitorable","enable"),&Area2D::set_monitorable); + ObjectTypeDB::bind_method(_MD("is_monitorable"),&Area2D::is_monitorable); + ObjectTypeDB::bind_method(_MD("get_overlapping_bodies"),&Area2D::get_overlapping_bodies); + ObjectTypeDB::bind_method(_MD("get_overlapping_areas"),&Area2D::get_overlapping_areas); + + ObjectTypeDB::bind_method(_MD("overlaps_body:PhysicsBody2D","body"),&Area2D::overlaps_body); + ObjectTypeDB::bind_method(_MD("overlaps_area:Area2D","area"),&Area2D::overlaps_area); ObjectTypeDB::bind_method(_MD("_body_inout"),&Area2D::_body_inout); + ObjectTypeDB::bind_method(_MD("_area_inout"),&Area2D::_area_inout); + + + ADD_SIGNAL( MethodInfo("body_enter_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body",PROPERTY_HINT_RESOURCE_TYPE,"PhysicsBody2D"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"area_shape"))); + ADD_SIGNAL( MethodInfo("body_exit_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body",PROPERTY_HINT_RESOURCE_TYPE,"PhysicsBody2D"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"area_shape"))); + ADD_SIGNAL( MethodInfo("body_enter",PropertyInfo(Variant::OBJECT,"body",PROPERTY_HINT_RESOURCE_TYPE,"PhysicsBody2D"))); + ADD_SIGNAL( MethodInfo("body_exit",PropertyInfo(Variant::OBJECT,"body",PROPERTY_HINT_RESOURCE_TYPE,"PhysicsBody2D"))); + ADD_SIGNAL( MethodInfo("area_enter_shape",PropertyInfo(Variant::INT,"area_id"),PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area2D"),PropertyInfo(Variant::INT,"area_shape"),PropertyInfo(Variant::INT,"area_shape"))); + ADD_SIGNAL( MethodInfo("area_exit_shape",PropertyInfo(Variant::INT,"area_id"),PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area2D"),PropertyInfo(Variant::INT,"area_shape"),PropertyInfo(Variant::INT,"area_shape"))); + ADD_SIGNAL( MethodInfo("area_enter",PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area2D"))); + ADD_SIGNAL( MethodInfo("area_exit",PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area2D"))); - ADD_SIGNAL( MethodInfo("body_enter_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"area_shape"))); - ADD_SIGNAL( MethodInfo("body_exit_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"area_shape"))); - ADD_SIGNAL( MethodInfo("body_enter",PropertyInfo(Variant::OBJECT,"body"))); - ADD_SIGNAL( MethodInfo("body_exit",PropertyInfo(Variant::OBJECT,"body"))); ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"space_override",PROPERTY_HINT_ENUM,"Disabled,Combine,Replace"),_SCS("set_space_override_mode"),_SCS("get_space_override_mode")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"gravity_point"),_SCS("set_gravity_is_point"),_SCS("is_gravity_a_point")); @@ -355,6 +577,7 @@ void Area2D::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::REAL,"angular_damp",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_angular_damp"),_SCS("get_angular_damp")); ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable")); } @@ -369,7 +592,9 @@ Area2D::Area2D() : CollisionObject2D(Physics2DServer::get_singleton()->area_crea locked=false; priority=0; monitoring=false; + monitorable=false; set_enable_monitoring(true); + set_monitorable(true); } diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index f770e88a19..6a6c757e0c 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -53,6 +53,7 @@ private: real_t angular_damp; int priority; bool monitoring; + bool monitorable; bool locked; void _body_inout(int p_status,const RID& p_body, int p_instance, int p_body_shape,int p_area_shape); @@ -84,6 +85,36 @@ private: Map<ObjectID,BodyState> body_map; + + + void _area_inout(int p_status,const RID& p_area, int p_instance, int p_area_shape,int p_self_shape); + + void _area_enter_tree(ObjectID p_id); + void _area_exit_tree(ObjectID p_id); + + struct AreaShapePair { + + int area_shape; + int self_shape; + bool operator<(const AreaShapePair& p_sp) const { + if (area_shape==p_sp.area_shape) + return self_shape < p_sp.self_shape; + else + return area_shape < p_sp.area_shape; + } + + AreaShapePair() {} + AreaShapePair(int p_bs, int p_as) { area_shape=p_bs; self_shape=p_as; } + }; + + struct AreaState { + + int rc; + bool in_tree; + VSet<AreaShapePair> shapes; + }; + + Map<ObjectID,AreaState> area_map; void _clear_monitoring(); @@ -117,8 +148,14 @@ public: void set_enable_monitoring(bool p_enable); bool is_monitoring_enabled() const; + void set_monitorable(bool p_enable); + bool is_monitorable() const; + Array get_overlapping_bodies() const; //function for script + Array get_overlapping_areas() const; //function for script + bool overlaps_area(Node* p_area) const; + bool overlaps_body(Node* p_body) const; Area2D(); ~Area2D(); diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 436b77a1ac..c3ff03d8f4 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -943,7 +943,67 @@ Ref<CanvasItemMaterial> 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 0c7be261ab..c43642a8ec 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 3b859d9366..a883fee103 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<PropertyInfo> *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 4a529ce062..393973ce90 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<PropertyInfo> *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<Shape2D>& p_shape, const Matrix32& p_transform=Matrix32()); int get_shape_count() const; void set_shape(int p_shape_idx, const Ref<Shape2D>& 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/light_2d.cpp b/scene/2d/light_2d.cpp index 8f6907798f..4abb7e5436 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -23,7 +23,7 @@ Rect2 Light2D::get_item_rect() const { Size2i s; - s = texture->get_size()*scale; + s = texture->get_size()*_scale; Point2i ofs=texture_offset; ofs-=s/2; @@ -96,18 +96,18 @@ float Light2D::get_height() const { return height; } -void Light2D::set_scale( float p_scale) { +void Light2D::set_texture_scale( float p_scale) { - scale=p_scale; - VS::get_singleton()->canvas_light_set_scale(canvas_light,scale); + _scale=p_scale; + VS::get_singleton()->canvas_light_set_scale(canvas_light,_scale); item_rect_changed(); } -float Light2D::get_scale() const { +float Light2D::get_texture_scale() const { - return scale; + return _scale; } void Light2D::set_z_range_min( int p_min_z) { @@ -260,8 +260,8 @@ void Light2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_height","height"),&Light2D::set_height); ObjectTypeDB::bind_method(_MD("get_height"),&Light2D::get_height); - ObjectTypeDB::bind_method(_MD("set_scale","scale"),&Light2D::set_scale); - ObjectTypeDB::bind_method(_MD("get_scale"),&Light2D::get_scale); + ObjectTypeDB::bind_method(_MD("set_texture_scale","texture_scale"),&Light2D::set_texture_scale); + ObjectTypeDB::bind_method(_MD("get_texture_scale"),&Light2D::get_texture_scale); ObjectTypeDB::bind_method(_MD("set_z_range_min","z"),&Light2D::set_z_range_min); @@ -298,7 +298,7 @@ void Light2D::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled")); ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture")); ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"offset"),_SCS("set_texture_offset"),_SCS("get_texture_offset")); - ADD_PROPERTY( PropertyInfo(Variant::REAL,"scale",PROPERTY_HINT_RANGE,"0.01,4096,0.01"),_SCS("set_scale"),_SCS("get_scale")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"scale",PROPERTY_HINT_RANGE,"0.01,4096,0.01"),_SCS("set_texture_scale"),_SCS("get_texture_scale")); ADD_PROPERTY( PropertyInfo(Variant::COLOR,"color"),_SCS("set_color"),_SCS("get_color")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"subtract"),_SCS("set_subtract_mode"),_SCS("get_subtract_mode")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"range/height"),_SCS("set_height"),_SCS("get_height")); @@ -322,7 +322,7 @@ Light2D::Light2D() { shadow=false; color=Color(1,1,1); height=0; - scale=1.0; + _scale=1.0; z_min=-1024; z_max=1024; layer_min=0; diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index 6eb6ad5237..6cfb055fa9 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -12,7 +12,7 @@ private: bool shadow; Color color; float height; - float scale; + float _scale; int z_min; int z_max; int layer_min; @@ -51,8 +51,8 @@ public: void set_height( float p_height); float get_height() const; - void set_scale( float p_scale); - float get_scale() const; + void set_texture_scale( float p_scale); + float get_texture_scale() const; void set_z_range_min( int p_min_z); int get_z_range_min() const; diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 36b6b220b3..0b098f0cad 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -65,7 +65,7 @@ void Node2D::edit_set_state(const Variant& p_state) { pos = state[0]; angle = state[1]; - scale = state[2]; + _scale = state[2]; _update_transform(); _change_notify("transform/rot"); _change_notify("transform/scale"); @@ -93,11 +93,11 @@ void Node2D::edit_set_rect(const Rect2& p_edit_rect) { Point2 new_pos = p_edit_rect.pos + p_edit_rect.size*zero_offset;//p_edit_rect.pos - r.pos; Matrix32 postxf; - postxf.set_rotation_and_scale(angle,scale); + postxf.set_rotation_and_scale(angle,_scale); new_pos = postxf.xform(new_pos); pos+=new_pos; - scale*=new_scale; + _scale*=new_scale; _update_transform(); _change_notify("transform/scale"); @@ -118,14 +118,14 @@ void Node2D::_update_xform_values() { pos=_mat.elements[2]; angle=_mat.get_rotation(); - scale=_mat.get_scale(); + _scale=_mat.get_scale(); _xform_dirty=false; } void Node2D::_update_transform() { Matrix32 mat(angle,pos); - _mat.set_rotation_and_scale(angle,scale); + _mat.set_rotation_and_scale(angle,_scale); _mat.elements[2]=pos; VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(),_mat); @@ -161,11 +161,11 @@ void Node2D::set_scale(const Size2& p_scale) { if (_xform_dirty) ((Node2D*)this)->_update_xform_values(); - scale=p_scale; - if (scale.x==0) - scale.x=CMP_EPSILON; - if (scale.y==0) - scale.y=CMP_EPSILON; + _scale=p_scale; + if (_scale.x==0) + _scale.x=CMP_EPSILON; + if (_scale.y==0) + _scale.y=CMP_EPSILON; _update_transform(); _change_notify("transform/scale"); @@ -187,7 +187,7 @@ Size2 Node2D::get_scale() const { if (_xform_dirty) ((Node2D*)this)->_update_xform_values(); - return scale; + return _scale; } void Node2D::_set_rotd(float p_angle) { @@ -224,11 +224,27 @@ Rect2 Node2D::get_item_rect() const { return Rect2(Point2(-32,-32),Size2(64,64)); } -void Node2D::rotate(float p_degrees) { +void Node2D::rotate(float p_radians) { - set_rot( get_rot() + p_degrees); + set_rot( get_rot() + p_radians); } +void Node2D::translate(const Vector2& p_amount) { + + set_pos( get_pos() + p_amount ); +} + +void Node2D::global_translate(const Vector2& p_amount) { + + set_global_pos( get_global_pos() + p_amount ); +} + +void Node2D::scale(const Vector2& p_amount) { + + set_scale( get_scale() * p_amount ); +} + + void Node2D::move_x(float p_delta,bool p_scaled){ Matrix32 t = get_transform(); @@ -345,9 +361,12 @@ void Node2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_rot"),&Node2D::get_rot); ObjectTypeDB::bind_method(_MD("get_scale"),&Node2D::get_scale); - ObjectTypeDB::bind_method(_MD("rotate","degrees"),&Node2D::rotate); + ObjectTypeDB::bind_method(_MD("rotate","radians"),&Node2D::rotate); ObjectTypeDB::bind_method(_MD("move_local_x","delta","scaled"),&Node2D::move_x,DEFVAL(false)); ObjectTypeDB::bind_method(_MD("move_local_y","delta","scaled"),&Node2D::move_y,DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("translate","offset"),&Node2D::translate); + ObjectTypeDB::bind_method(_MD("global_translate","offset"),&Node2D::global_translate); + ObjectTypeDB::bind_method(_MD("scale","ratio"),&Node2D::scale); ObjectTypeDB::bind_method(_MD("set_global_pos","pos"),&Node2D::set_global_pos); ObjectTypeDB::bind_method(_MD("get_global_pos"),&Node2D::get_global_pos); @@ -379,7 +398,7 @@ Node2D::Node2D() { angle=0; - scale=Vector2(1,1); + _scale=Vector2(1,1); _xform_dirty=false; z=0; z_relative=true; diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index 7b059008c2..39a1061195 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -37,7 +37,7 @@ class Node2D : public CanvasItem { Point2 pos; float angle; - Size2 scale; + Size2 _scale; int z; bool z_relative; @@ -72,9 +72,12 @@ public: void set_rot(float p_angle); void set_scale(const Size2& p_scale); - void rotate(float p_degrees); + void rotate(float p_radians); void move_x(float p_delta,bool p_scaled=false); void move_y(float p_delta,bool p_scaled=false); + void translate(const Vector2& p_amount); + void global_translate(const Vector2& p_amount); + void scale(const Vector2& p_amount); Point2 get_pos() const; float get_rot() const; @@ -96,6 +99,7 @@ public: Matrix32 get_relative_transform(const Node *p_parent) const; + Matrix32 get_transform() const; Node2D(); diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 6f18325212..22dd0f01d0 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/3d/camera.cpp b/scene/3d/camera.cpp index 1109139180..db69182ca0 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -680,8 +680,6 @@ void Camera::_bind_methods() { ObjectTypeDB::bind_method( _MD("get_projection"),&Camera::get_projection ); ObjectTypeDB::bind_method( _MD("set_visible_layers","mask"),&Camera::set_visible_layers ); ObjectTypeDB::bind_method( _MD("get_visible_layers"),&Camera::get_visible_layers ); - ObjectTypeDB::bind_method( _MD("look_at","target","up"),&Camera::look_at ); - ObjectTypeDB::bind_method( _MD("look_at_from_pos","pos","target","up"),&Camera::look_at_from_pos ); ObjectTypeDB::bind_method(_MD("set_environment","env:Environment"),&Camera::set_environment); ObjectTypeDB::bind_method(_MD("get_environment:Environment"),&Camera::get_environment); ObjectTypeDB::bind_method(_MD("set_keep_aspect_mode","mode"),&Camera::set_keep_aspect_mode); @@ -752,22 +750,6 @@ Vector<Plane> Camera::get_frustum() const { -void Camera::look_at(const Vector3& p_target, const Vector3& p_up_normal) { - - Transform lookat; - lookat.origin=get_camera_transform().origin; - lookat=lookat.looking_at(p_target,p_up_normal); - set_global_transform(lookat); -} - -void Camera::look_at_from_pos(const Vector3& p_pos,const Vector3& p_target, const Vector3& p_up_normal) { - - Transform lookat; - lookat.origin=p_pos; - lookat=lookat.looking_at(p_target,p_up_normal); - set_global_transform(lookat); - -} void Camera::set_v_offset(float p_offset) { diff --git a/scene/3d/camera.h b/scene/3d/camera.h index 950688dfda..de03282021 100644 --- a/scene/3d/camera.h +++ b/scene/3d/camera.h @@ -139,8 +139,6 @@ public: void set_keep_aspect_mode(KeepAspect p_aspect); KeepAspect get_keep_aspect_mode() const; - void look_at(const Vector3& p_target, const Vector3& p_up_normal); - void look_at_from_pos(const Vector3& p_pos,const Vector3& p_target, const Vector3& p_up_normal); void set_v_offset(float p_offset); float get_v_offset() const; diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp index a5b009823c..6e11855543 100644 --- a/scene/3d/spatial.cpp +++ b/scene/3d/spatial.cpp @@ -593,6 +593,97 @@ bool Spatial::_is_visible_() const { return !is_hidden(); } +void Spatial::rotate(const Vector3& p_normal,float p_radians) { + + Transform t =get_transform(); + t.basis.rotate(p_normal,p_radians); + set_transform(t); +} + +void Spatial::rotate_x(float p_radians) { + + Transform t =get_transform(); + t.basis.rotate(Vector3(1,0,0),p_radians); + set_transform(t); + +} + +void Spatial::rotate_y(float p_radians){ + + Transform t =get_transform(); + t.basis.rotate(Vector3(0,1,0),p_radians); + set_transform(t); + +} +void Spatial::rotate_z(float p_radians){ + + Transform t =get_transform(); + t.basis.rotate(Vector3(0,0,1),p_radians); + set_transform(t); + +} + +void Spatial::translate(const Vector3& p_offset){ + + Transform t =get_transform(); + t.origin+=p_offset; + set_transform(t); + +} +void Spatial::scale(const Vector3& p_ratio){ + + Transform t =get_transform(); + t.basis.scale(p_ratio); + set_transform(t); + +} +void Spatial::global_rotate(const Vector3& p_normal,float p_radians){ + + Matrix3 rotation(p_normal,p_radians); + Transform t = get_global_transform(); + t.basis= rotation * t.basis; + set_global_transform(t); + +} +void Spatial::global_translate(const Vector3& p_offset){ + Transform t = get_global_transform(); + t.origin+=p_offset; + set_global_transform(t); + +} + +void Spatial::orthonormalize() { + + Transform t = get_transform(); + t.orthonormalize(); + set_transform(t); + +} + +void Spatial::set_identity() { + + set_transform(Transform()); + +} + + +void Spatial::look_at(const Vector3& p_target, const Vector3& p_up_normal) { + + Transform lookat; + lookat.origin=get_global_transform().origin; + lookat=lookat.looking_at(p_target,p_up_normal); + set_global_transform(lookat); +} + +void Spatial::look_at_from_pos(const Vector3& p_pos,const Vector3& p_target, const Vector3& p_up_normal) { + + Transform lookat; + lookat.origin=p_pos; + lookat=lookat.looking_at(p_target,p_up_normal); + set_global_transform(lookat); + +} + void Spatial::_bind_methods() { @@ -633,6 +724,28 @@ void Spatial::_bind_methods() { ObjectTypeDB::bind_method(_MD("_set_visible_"), &Spatial::_set_visible_); ObjectTypeDB::bind_method(_MD("_is_visible_"), &Spatial::_is_visible_); + void rotate(const Vector3& p_normal,float p_radians); + void rotate_x(float p_radians); + void rotate_y(float p_radians); + void rotate_z(float p_radians); + void translate(const Vector3& p_offset); + void scale(const Vector3& p_ratio); + void global_rotate(const Vector3& p_normal,float p_radians); + void global_translate(const Vector3& p_offset); + + ObjectTypeDB::bind_method( _MD("rotate","normal","radians"),&Spatial::rotate ); + ObjectTypeDB::bind_method( _MD("global_rotate","normal","radians"),&Spatial::global_rotate ); + ObjectTypeDB::bind_method( _MD("rotate_x","radians"),&Spatial::rotate_x ); + ObjectTypeDB::bind_method( _MD("rotate_y","radians"),&Spatial::rotate_y ); + ObjectTypeDB::bind_method( _MD("rotate_z","radians"),&Spatial::rotate_z ); + ObjectTypeDB::bind_method( _MD("translate","offset"),&Spatial::translate ); + ObjectTypeDB::bind_method( _MD("global_translate","offset"),&Spatial::global_translate ); + ObjectTypeDB::bind_method( _MD("orthonormalize"),&Spatial::orthonormalize ); + ObjectTypeDB::bind_method( _MD("set_identity"),&Spatial::set_identity ); + + ObjectTypeDB::bind_method( _MD("look_at","target","up"),&Spatial::look_at ); + ObjectTypeDB::bind_method( _MD("look_at_from_pos","pos","target","up"),&Spatial::look_at_from_pos ); + BIND_CONSTANT( NOTIFICATION_TRANSFORM_CHANGED ); BIND_CONSTANT( NOTIFICATION_ENTER_WORLD ); BIND_CONSTANT( NOTIFICATION_EXIT_WORLD ); diff --git a/scene/3d/spatial.h b/scene/3d/spatial.h index 49ecf5779b..f2cde8f1e6 100644 --- a/scene/3d/spatial.h +++ b/scene/3d/spatial.h @@ -167,6 +167,21 @@ public: Transform get_relative_transform(const Node *p_parent) const; + void rotate(const Vector3& p_normal,float p_radians); + void rotate_x(float p_radians); + void rotate_y(float p_radians); + void rotate_z(float p_radians); + void translate(const Vector3& p_offset); + void scale(const Vector3& p_ratio); + void global_rotate(const Vector3& p_normal,float p_radians); + void global_translate(const Vector3& p_offset); + + void look_at(const Vector3& p_target, const Vector3& p_up_normal); + void look_at_from_pos(const Vector3& p_pos,const Vector3& p_target, const Vector3& p_up_normal); + + void orthonormalize(); + void set_identity(); + void show(); void hide(); bool is_visible() const; diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 193649c815..d944b804a5 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -352,6 +352,7 @@ void ColorPickerButton::set_color(const Color& p_color){ picker->set_color(p_color); + update(); } Color ColorPickerButton::get_color() const{ diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index fbcfdb69bb..47f862a58d 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -29,6 +29,8 @@ #include "file_dialog.h" #include "scene/gui/label.h" #include "print_string.h" +#include "os/keyboard.h" +#include "tools/editor/editor_settings.h" FileDialog::GetIconFunc FileDialog::get_icon_func=NULL; @@ -278,13 +280,20 @@ void FileDialog::update_file_list() { List<String> dirs; bool isdir; + bool ishidden; + bool show_hidden = EditorSettings::get_singleton()->get("file_dialog/show_hidden_files"); String item; + while ((item=dir_access->get_next(&isdir))!="") { - - if (!isdir) - files.push_back(item); - else - dirs.push_back(item); + + ishidden = dir_access->current_is_hidden(); + + if (show_hidden || !ishidden) { + if (!isdir) + files.push_back(item); + else + dirs.push_back(item); + } } dirs.sort_custom<NoCaseComparator>(); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index d2e1e7f0b9..892e4c9bc7 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -72,6 +72,7 @@ void Label::_notification(int p_what) { if (clip && !autowrap) VisualServer::get_singleton()->canvas_item_set_clip(get_canvas_item(),true); + if (word_cache_dirty) regenerate_word_cache(); @@ -87,7 +88,8 @@ void Label::_notification(int p_what) { bool use_outlinde = get_constant("shadow_as_outline"); Point2 shadow_ofs(get_constant("shadow_offset_x"),get_constant("shadow_offset_y")); - + VisualServer::get_singleton()->canvas_item_set_distance_field_mode(get_canvas_item(),font.is_valid() && font->is_distance_field_hint()); + int font_h = font->get_height(); int line_from=(int)get_val(); // + p_exposed.pos.y / font_h; int lines_visible = size.y/font_h; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 8855627bb4..e0bf4587bc 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1345,7 +1345,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { return; } - if (k.scancode==KEY_HOME) { + if (k.scancode==KEY_HOME && completion_index>0) { completion_index=0; completion_current=completion_options[completion_index]; @@ -1354,7 +1354,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { return; } - if (k.scancode==KEY_END) { + if (k.scancode==KEY_END && completion_index<completion_options.size()-1) { completion_index=completion_options.size()-1; completion_current=completion_options[completion_index]; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 02e009866f..ee400ae6d5 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 { @@ -104,8 +104,10 @@ void Viewport::_update_stretch_transform() { stretch_transform.scale(scale); stretch_transform.elements[2]=size_override_margin*scale; + } else { + stretch_transform=Matrix32(); } @@ -355,11 +357,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 +395,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<RID>(),0xFFFFFFFF,0xFFFFFFFF); + for(int i=0;i<rc;i++) { + + if (res[i].collider) { + CollisionObject2D *co=res[i].collider->cast_to<CollisionObject2D>(); + if (co) { + + Map<ObjectID,uint64_t>::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<Map<ObjectID,uint64_t>::Element*> to_erase; + + for (Map<ObjectID,uint64_t>::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<CollisionObject2D>(); + 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 +556,9 @@ void Viewport::_notification(int p_what) { _test_new_mouseover(new_collider); } - - } #endif + } + } } break; @@ -1021,8 +1078,9 @@ Matrix32 Viewport::_get_input_pre_xform() const { ERR_FAIL_COND_V(to_screen_rect.size.x==0,pre_xf); ERR_FAIL_COND_V(to_screen_rect.size.y==0,pre_xf); - pre_xf.scale(rect.size/to_screen_rect.size); + pre_xf.elements[2]=-to_screen_rect.pos; + pre_xf.scale(rect.size/to_screen_rect.size); } else { pre_xf.elements[2]=-rect.pos; @@ -1086,6 +1144,7 @@ void Viewport::_make_input_local(InputEvent& ev) { } break; } + } diff --git a/scene/main/viewport.h b/scene/main/viewport.h index d2a22401bd..14f4f68217 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<ObjectID,uint64_t> physics_2d_mouseover; void _update_rect(); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 3c4bc3ac75..1e3b9772ee 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -108,13 +108,14 @@ void Environment::_bind_methods() { ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"fxaa/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_FXAA); - ADD_PROPERTY( PropertyInfo(Variant::INT,"background/mode",PROPERTY_HINT_ENUM,"Keep,Default Color,Color,Texture,Cubemap,Texture RGBE,Cubemap RGBE"),_SCS("set_background"),_SCS("get_background")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"background/mode",PROPERTY_HINT_ENUM,"Keep,Default Color,Color,Texture,Cubemap,Canvas"),_SCS("set_background"),_SCS("get_background")); ADD_PROPERTYI( PropertyInfo(Variant::COLOR,"background/color"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_COLOR); ADD_PROPERTYI( PropertyInfo(Variant::OBJECT,"background/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_TEXTURE); ADD_PROPERTYI( PropertyInfo(Variant::OBJECT,"background/cubemap",PROPERTY_HINT_RESOURCE_TYPE,"CubeMap"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_CUBEMAP); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"background/energy",PROPERTY_HINT_RANGE,"0,128,0.01"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_ENERGY); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"background/scale",PROPERTY_HINT_RANGE,"0.001,16,0.001"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_SCALE); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"background/glow",PROPERTY_HINT_RANGE,"0.00,8,0.01"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_GLOW); + ADD_PROPERTYI( PropertyInfo(Variant::INT,"background/canvas_max_layer"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_CANVAS_MAX_LAYER); ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"glow/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_GLOW); ADD_PROPERTYI( PropertyInfo(Variant::INT,"glow/blur_passes",PROPERTY_HINT_RANGE,"1,4,1"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLUR_PASSES); @@ -182,10 +183,10 @@ void Environment::_bind_methods() { BIND_CONSTANT( BG_COLOR ); BIND_CONSTANT( BG_TEXTURE ); BIND_CONSTANT( BG_CUBEMAP ); - BIND_CONSTANT( BG_TEXTURE_RGBE ); - BIND_CONSTANT( BG_CUBEMAP_RGBE ); + BIND_CONSTANT( BG_CANVAS ); BIND_CONSTANT( BG_MAX ); + BIND_CONSTANT( BG_PARAM_CANVAS_MAX_LAYER ); BIND_CONSTANT( BG_PARAM_COLOR ); BIND_CONSTANT( BG_PARAM_TEXTURE ); BIND_CONSTANT( BG_PARAM_CUBEMAP ); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index a9e2f422b9..d672a898d5 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -44,14 +44,14 @@ public: BG_COLOR=VS::ENV_BG_COLOR, BG_TEXTURE=VS::ENV_BG_TEXTURE, BG_CUBEMAP=VS::ENV_BG_CUBEMAP, - BG_TEXTURE_RGBE=VS::ENV_BG_TEXTURE_RGBE, - BG_CUBEMAP_RGBE=VS::ENV_BG_CUBEMAP_RGBE, + BG_CANVAS=VS::ENV_BG_CANVAS, BG_MAX=VS::ENV_BG_MAX }; enum BGParam { - BG_PARAM_COLOR=VS::ENV_BG_PARAM_COLOR, + BG_PARAM_CANVAS_MAX_LAYER=VS::ENV_BG_PARAM_CANVAS_MAX_LAYER, + BG_PARAM_COLOR=VS::ENV_BG_PARAM_COLOR, BG_PARAM_TEXTURE=VS::ENV_BG_PARAM_TEXTURE, BG_PARAM_CUBEMAP=VS::ENV_BG_PARAM_CUBEMAP, BG_PARAM_ENERGY=VS::ENV_BG_PARAM_ENERGY, diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 49ee3ee017..79316f0019 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -398,6 +398,17 @@ int Font::get_kerning_pair(CharType p_A,CharType p_B) const { return 0; } +void Font::set_distance_field_hint(bool p_distance_field) { + + distance_field_hint=p_distance_field; + emit_changed(); +} + +bool Font::is_distance_field_hint() const{ + + return distance_field_hint; +} + void Font::clear() { @@ -406,6 +417,7 @@ void Font::clear() { char_map.clear(); textures.clear(); kerning_map.clear(); + distance_field_hint=false; } Size2 Font::get_string_size(const String& p_string) const { @@ -511,9 +523,16 @@ 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); + ObjectTypeDB::bind_method(_MD("set_distance_field_hint","enable"),&Font::set_distance_field_hint); + ObjectTypeDB::bind_method(_MD("is_distance_field_hint"),&Font::is_distance_field_hint); + ObjectTypeDB::bind_method(_MD("clear"),&Font::clear); ObjectTypeDB::bind_method(_MD("draw","canvas_item","pos","string","modulate","clip_w"),&Font::draw,DEFVAL(Color(1,1,1)),DEFVAL(-1)); @@ -535,12 +554,14 @@ void Font::_bind_methods() { ADD_PROPERTY( PropertyInfo( Variant::REAL, "height", PROPERTY_HINT_RANGE,"-1024,1024,1" ), _SCS("set_height"), _SCS("get_height") ); ADD_PROPERTY( PropertyInfo( Variant::REAL, "ascent", PROPERTY_HINT_RANGE,"-1024,1024,1" ), _SCS("set_ascent"), _SCS("get_ascent") ); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "distance_field" ), _SCS("set_distance_field_hint"), _SCS("is_distance_field_hint") ); } Font::Font() { clear(); + } diff --git a/scene/resources/font.h b/scene/resources/font.h index a64ec1ef7a..498bc6863a 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -75,6 +75,7 @@ private: float height; float ascent; + bool distance_field_hint; void _set_chars(const DVector<int>& p_chars); DVector<int> _get_chars() const; @@ -116,6 +117,9 @@ public: Size2 get_string_size(const String& p_string) const; void clear(); + + void set_distance_field_hint(bool p_distance_field); + bool is_distance_field_hint() const; void draw(RID p_canvas_item, const Point2& p_pos, const String& p_text,const Color& p_modulate=Color(1,1,1),int p_clip_w=-1) const; void draw_halign(RID p_canvas_item, const Point2& p_pos, HAlign p_align,float p_width,const String& p_text,const Color& p_modulate=Color(1,1,1)) const; diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp index 880a3a32e3..30cf58bdd8 100644 --- a/scene/resources/world.cpp +++ b/scene/resources/world.cpp @@ -307,6 +307,11 @@ Ref<Environment> World::get_environment() const { } +PhysicsDirectSpaceState *World::get_direct_space_state() { + + return PhysicsServer::get_singleton()->space_get_direct_state(space); +} + void World::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_space"),&World::get_space); @@ -314,6 +319,7 @@ void World::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_sound_space"),&World::get_sound_space); ObjectTypeDB::bind_method(_MD("set_environment","env:Environment"),&World::set_environment); ObjectTypeDB::bind_method(_MD("get_environment:Environment"),&World::get_environment); + ObjectTypeDB::bind_method(_MD("get_direct_space_state:PhysicsDirectSpaceState"),&World::get_direct_space_state); ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"environment",PROPERTY_HINT_RESOURCE_TYPE,"Environment"),_SCS("set_environment"),_SCS("get_environment")); } diff --git a/scene/resources/world.h b/scene/resources/world.h index 60b3b99ab0..b10cadd6e0 100644 --- a/scene/resources/world.h +++ b/scene/resources/world.h @@ -75,6 +75,8 @@ public: void set_environment(const Ref<Environment>& p_environment); Ref<Environment> get_environment() const; + PhysicsDirectSpaceState *get_direct_space_state(); + World(); ~World(); diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index 0dd6a3d5e7..43a7af4bfd 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -352,8 +352,17 @@ void World2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_canvas"),&World2D::get_canvas); ObjectTypeDB::bind_method(_MD("get_space"),&World2D::get_space); ObjectTypeDB::bind_method(_MD("get_sound_space"),&World2D::get_sound_space); + + ObjectTypeDB::bind_method(_MD("get_direct_space_state:Physics2DDirectSpaceState"),&World2D::get_direct_space_state); + +} + +Physics2DDirectSpaceState *World2D::get_direct_space_state() { + + return Physics2DServer::get_singleton()->space_get_direct_state(space); } + World2D::World2D() { canvas = VisualServer::get_singleton()->canvas_create(); diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h index 3feb23495d..865ec28fe9 100644 --- a/scene/resources/world_2d.h +++ b/scene/resources/world_2d.h @@ -30,7 +30,7 @@ #define WORLD_2D_H #include "resource.h" - +#include "servers/physics_2d_server.h" class SpatialIndexer2D; class VisibilityNotifier2D; @@ -68,6 +68,8 @@ public: RID get_space(); RID get_sound_space(); + Physics2DDirectSpaceState *get_direct_space_state(); + World2D(); ~World2D(); }; diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index c30ff0044e..d4159f0946 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -64,6 +64,9 @@ SceneStringNames::SceneStringNames() { body_exit_shape = StaticCString::create("body_exit_shape"); body_exit = StaticCString::create("body_exit"); + area_enter_shape = StaticCString::create("area_enter_shape"); + area_exit_shape = StaticCString::create("area_exit_shape"); + idle=StaticCString::create("idle"); iteration=StaticCString::create("iteration"); @@ -103,6 +106,9 @@ SceneStringNames::SceneStringNames() { _body_enter_tree = StaticCString::create("_body_enter_tree"); _body_exit_tree = StaticCString::create("_body_exit_tree"); + _area_enter_tree = StaticCString::create("_area_enter_tree"); + _area_exit_tree = StaticCString::create("_area_exit_tree"); + _input_event=StaticCString::create("_input_event"); changed=StaticCString::create("changed"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 184cbe347b..aa29ef57dc 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -83,6 +83,10 @@ public: StringName body_exit_shape; StringName body_exit; + StringName area_enter_shape; + StringName area_exit_shape; + + StringName _get_gizmo_geometry; StringName _can_gizmo_scale; @@ -124,6 +128,9 @@ public: StringName _body_enter_tree; StringName _body_exit_tree; + StringName _area_enter_tree; + StringName _area_exit_tree; + StringName changed; StringName _shader_changed; |