diff options
Diffstat (limited to 'scene/2d')
34 files changed, 977 insertions, 211 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 316dffb3f9..2fcfc18429 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -27,7 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "animated_sprite.h" - +#include "scene/scene_string_names.h" void AnimatedSprite::edit_set_pivot(const Point2& p_pivot) { set_offset(p_pivot); @@ -207,7 +207,7 @@ void AnimatedSprite::set_frame(int p_frame) { frame=p_frame; update(); _change_notify("frame"); - + emit_signal(SceneStringNames::get_singleton()->frame_changed); } int AnimatedSprite::get_frame() const { @@ -233,6 +233,7 @@ void AnimatedSprite::set_offset(const Point2& p_offset) { offset=p_offset; update(); item_rect_changed(); + _change_notify("offset"); } Point2 AnimatedSprite::get_offset() const { @@ -325,6 +326,8 @@ void AnimatedSprite::_bind_methods() { ObjectTypeDB::bind_method(_MD("_res_changed"),&AnimatedSprite::_res_changed); + ADD_SIGNAL(MethodInfo("frame_changed")); + ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "frames",PROPERTY_HINT_RESOURCE_TYPE,"SpriteFrames"), _SCS("set_sprite_frames"),_SCS("get_sprite_frames")); ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "frame"), _SCS("set_frame"),_SCS("get_frame")); ADD_PROPERTY( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered")); diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index ad228662e4..fce21f6001 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -73,14 +73,25 @@ real_t Area2D::get_gravity() const{ return gravity; } -void Area2D::set_density(real_t p_density){ +void Area2D::set_linear_damp(real_t p_linear_damp){ - density=p_density; - Physics2DServer::get_singleton()->area_set_param(get_rid(),Physics2DServer::AREA_PARAM_DENSITY,p_density); + linear_damp=p_linear_damp; + Physics2DServer::get_singleton()->area_set_param(get_rid(),Physics2DServer::AREA_PARAM_LINEAR_DAMP,p_linear_damp); } -real_t Area2D::get_density() const{ +real_t Area2D::get_linear_damp() const{ - return density; + return linear_damp; +} + +void Area2D::set_angular_damp(real_t p_angular_damp){ + + angular_damp=p_angular_damp; + Physics2DServer::get_singleton()->area_set_param(get_rid(),Physics2DServer::AREA_PARAM_ANGULAR_DAMP,p_angular_damp); +} + +real_t Area2D::get_angular_damp() const{ + + return angular_damp; } void Area2D::set_priority(real_t p_priority){ @@ -94,7 +105,7 @@ real_t Area2D::get_priority() const{ } -void Area2D::_body_enter_scene(ObjectID p_id) { +void Area2D::_body_enter_tree(ObjectID p_id) { Object *obj = ObjectDB::get_instance(p_id); Node *node = obj ? obj->cast_to<Node>() : NULL; @@ -102,9 +113,9 @@ void Area2D::_body_enter_scene(ObjectID p_id) { Map<ObjectID,BodyState>::Element *E=body_map.find(p_id); ERR_FAIL_COND(!E); - ERR_FAIL_COND(E->get().in_scene); + ERR_FAIL_COND(E->get().in_tree); - E->get().in_scene=true; + E->get().in_tree=true; emit_signal(SceneStringNames::get_singleton()->body_enter,node); for(int i=0;i<E->get().shapes.size();i++) { @@ -113,15 +124,15 @@ void Area2D::_body_enter_scene(ObjectID p_id) { } -void Area2D::_body_exit_scene(ObjectID p_id) { +void Area2D::_body_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,BodyState>::Element *E=body_map.find(p_id); ERR_FAIL_COND(!E); - ERR_FAIL_COND(!E->get().in_scene); - E->get().in_scene=false; + ERR_FAIL_COND(!E->get().in_tree); + E->get().in_tree=false; emit_signal(SceneStringNames::get_singleton()->body_exit,node); for(int i=0;i<E->get().shapes.size();i++) { @@ -142,16 +153,18 @@ void Area2D::_body_inout(int p_status,const RID& p_body, int p_instance, int p_b ERR_FAIL_COND(!body_in && !E); + locked=true; + if (body_in) { if (!E) { E = body_map.insert(objid,BodyState()); E->get().rc=0; - E->get().in_scene=node && node->is_inside_scene(); + E->get().in_tree=node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->enter_scene,this,SceneStringNames::get_singleton()->_body_enter_scene,make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->exit_scene,this,SceneStringNames::get_singleton()->_body_exit_scene,make_binds(objid)); - if (E->get().in_scene) { + node->connect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_body_enter_tree,make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_body_exit_tree,make_binds(objid)); + if (E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->body_enter,node); } } @@ -162,7 +175,7 @@ void Area2D::_body_inout(int p_status,const RID& p_body, int p_instance, int p_b E->get().shapes.insert(ShapePair(p_body_shape,p_area_shape)); - if (E->get().in_scene) { + if (!node || E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->body_enter_shape,objid,node,p_body_shape,p_area_shape); } @@ -178,9 +191,9 @@ void Area2D::_body_inout(int p_status,const RID& p_body, int p_instance, int p_b if (E->get().rc==0) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->enter_scene,this,SceneStringNames::get_singleton()->_body_enter_scene); - node->disconnect(SceneStringNames::get_singleton()->exit_scene,this,SceneStringNames::get_singleton()->_body_exit_scene); - if (E->get().in_scene) + 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); + if (E->get().in_tree) emit_signal(SceneStringNames::get_singleton()->body_exit,obj); } @@ -188,7 +201,7 @@ void Area2D::_body_inout(int p_status,const RID& p_body, int p_instance, int p_b eraseit=true; } - if (node && E->get().in_scene) { + if (!node || E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->body_exit_shape,objid,obj,p_body_shape,p_area_shape); } @@ -197,11 +210,18 @@ void Area2D::_body_inout(int p_status,const RID& p_body, int p_instance, int p_b } + locked=false; + + } void Area2D::_clear_monitoring() { + if (locked) { + ERR_EXPLAIN("This function can't be used during the in/out signal."); + } + ERR_FAIL_COND(locked); Map<ObjectID,BodyState> bmcopy = body_map; body_map.clear(); @@ -212,7 +232,7 @@ void Area2D::_clear_monitoring() { Object *obj = ObjectDB::get_instance(E->key()); Node *node = obj ? obj->cast_to<Node>() : NULL; ERR_CONTINUE(!node); - if (!E->get().in_scene) + if (!E->get().in_tree) continue; for(int i=0;i<E->get().shapes.size();i++) { @@ -222,8 +242,8 @@ void Area2D::_clear_monitoring() { emit_signal(SceneStringNames::get_singleton()->body_exit,obj); - node->disconnect(SceneStringNames::get_singleton()->enter_scene,this,SceneStringNames::get_singleton()->_body_enter_scene); - node->disconnect(SceneStringNames::get_singleton()->exit_scene,this,SceneStringNames::get_singleton()->_body_exit_scene); + 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); } } @@ -232,7 +252,7 @@ void Area2D::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_EXIT_SCENE: { + case NOTIFICATION_EXIT_TREE: { _clear_monitoring(); } break; @@ -243,6 +263,11 @@ void Area2D::_notification(int p_what) { void Area2D::set_enable_monitoring(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==monitoring) return; @@ -263,11 +288,30 @@ bool Area2D::is_monitoring_enabled() const { return monitoring; } +Array Area2D::get_overlapping_bodies() const { + + ERR_FAIL_COND_V(!monitoring,Array()); + Array ret; + ret.resize(body_map.size()); + int idx=0; + for (const Map<ObjectID,BodyState>::Element *E=body_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; +} + void Area2D::_bind_methods() { - ObjectTypeDB::bind_method(_MD("_body_enter_scene","id"),&Area2D::_body_enter_scene); - ObjectTypeDB::bind_method(_MD("_body_exit_scene","id"),&Area2D::_body_exit_scene); + 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("set_space_override_mode","enable"),&Area2D::set_space_override_mode); ObjectTypeDB::bind_method(_MD("get_space_override_mode"),&Area2D::get_space_override_mode); @@ -281,8 +325,11 @@ void Area2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_gravity","gravity"),&Area2D::set_gravity); ObjectTypeDB::bind_method(_MD("get_gravity"),&Area2D::get_gravity); - ObjectTypeDB::bind_method(_MD("set_density","density"),&Area2D::set_density); - ObjectTypeDB::bind_method(_MD("get_density"),&Area2D::get_density); + ObjectTypeDB::bind_method(_MD("set_linear_damp","linear_damp"),&Area2D::set_linear_damp); + ObjectTypeDB::bind_method(_MD("get_linear_damp"),&Area2D::get_linear_damp); + + ObjectTypeDB::bind_method(_MD("set_angular_damp","angular_damp"),&Area2D::set_angular_damp); + ObjectTypeDB::bind_method(_MD("get_angular_damp"),&Area2D::get_angular_damp); ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area2D::set_priority); ObjectTypeDB::bind_method(_MD("get_priority"),&Area2D::get_priority); @@ -290,6 +337,8 @@ 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("get_overlapping_bodies"),&Area2D::get_overlapping_bodies); + ObjectTypeDB::bind_method(_MD("_body_inout"),&Area2D::_body_inout); @@ -302,7 +351,8 @@ void Area2D::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::BOOL,"gravity_point"),_SCS("set_gravity_is_point"),_SCS("is_gravity_a_point")); ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"gravity_vec"),_SCS("set_gravity_vector"),_SCS("get_gravity_vector")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity",PROPERTY_HINT_RANGE,"-1024,1024,0.01"),_SCS("set_gravity"),_SCS("get_gravity")); - ADD_PROPERTY( PropertyInfo(Variant::REAL,"density",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_density"),_SCS("get_density")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"linear_damp",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_linear_damp"),_SCS("get_linear_damp")); + 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")); @@ -314,7 +364,9 @@ Area2D::Area2D() : CollisionObject2D(Physics2DServer::get_singleton()->area_crea set_gravity(98);; set_gravity_vector(Vector2(0,1)); gravity_is_point=false; - density=0.1; + linear_damp=0.1; + angular_damp=1; + locked=false; priority=0; monitoring=false; set_enable_monitoring(true); diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index b4c8edf138..f770e88a19 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -49,14 +49,16 @@ private: Vector2 gravity_vec; real_t gravity; bool gravity_is_point; - real_t density; + real_t linear_damp; + real_t angular_damp; int priority; bool monitoring; + bool locked; void _body_inout(int p_status,const RID& p_body, int p_instance, int p_body_shape,int p_area_shape); - void _body_enter_scene(ObjectID p_id); - void _body_exit_scene(ObjectID p_id); + void _body_enter_tree(ObjectID p_id); + void _body_exit_tree(ObjectID p_id); struct ShapePair { @@ -76,7 +78,7 @@ private: struct BodyState { int rc; - bool in_scene; + bool in_tree; VSet<ShapePair> shapes; }; @@ -103,8 +105,11 @@ public: void set_gravity(real_t p_gravity); real_t get_gravity() const; - void set_density(real_t p_density); - real_t get_density() const; + void set_linear_damp(real_t p_linear_damp); + real_t get_linear_damp() const; + + void set_angular_damp(real_t p_angular_damp); + real_t get_angular_damp() const; void set_priority(real_t p_priority); real_t get_priority() const; @@ -112,6 +117,8 @@ public: void set_enable_monitoring(bool p_enable); bool is_monitoring_enabled() const; + Array get_overlapping_bodies() const; //function for script + Area2D(); ~Area2D(); diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index fe6c9637e0..b3897010bf 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -33,10 +33,10 @@ void Camera2D::_update_scroll() { - if (!is_inside_scene()) + if (!is_inside_tree()) return; - if (get_scene()->is_editor_hint()) { + if (get_tree()->is_editor_hint()) { update(); //will just be drawn return; } @@ -48,7 +48,7 @@ void Camera2D::_update_scroll() { if (viewport) { viewport->set_canvas_transform( xform ); } - get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,group_name,"_camera_moved",xform); + get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,group_name,"_camera_moved",xform); }; } @@ -67,7 +67,7 @@ Vector2 Camera2D::get_zoom() const { Matrix32 Camera2D::get_camera_transform() { - if (!get_scene()) + if (!get_tree()) return Matrix32(); Size2 screen_size = get_viewport_rect().size; @@ -213,7 +213,7 @@ void Camera2D::_notification(int p_what) { _update_scroll(); } break; - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { viewport = NULL; Node *n=this; @@ -239,7 +239,7 @@ void Camera2D::_notification(int p_what) { } break; - case NOTIFICATION_EXIT_SCENE: { + case NOTIFICATION_EXIT_TREE: { if (is_current()) { if (viewport) { @@ -316,10 +316,10 @@ bool Camera2D::is_current() const { void Camera2D::make_current() { - if (!is_inside_scene()) { + if (!is_inside_tree()) { current=true; } else { - get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,group_name,"_make_current",this); + get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,group_name,"_make_current",this); } } diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index d66f100b3f..ae857bbce9 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -38,7 +38,7 @@ bool CanvasItem::is_visible() const { - if (!is_inside_scene()) + if (!is_inside_tree()) return false; const CanvasItem *p=this; @@ -92,7 +92,7 @@ void CanvasItem::show() { hidden=false; VisualServer::get_singleton()->canvas_item_set_visible(canvas_item,true); - if (!is_inside_scene()) + if (!is_inside_tree()) return; if (is_visible()) { @@ -106,11 +106,11 @@ void CanvasItem::hide() { if (hidden) return; - bool propagate=is_inside_scene() && is_visible(); + bool propagate=is_inside_tree() && is_visible(); hidden=true; VisualServer::get_singleton()->canvas_item_set_visible(canvas_item,false); - if (!is_inside_scene()) + if (!is_inside_tree()) return; if (propagate) _propagate_visibility_changed(false); @@ -147,7 +147,7 @@ void CanvasItem::_update_callback() { - if (!is_inside_scene()) { + if (!is_inside_tree()) { pending_update=false; return; } @@ -225,7 +225,7 @@ void CanvasItem::_sort_children() { pending_children_sort=false; - if (!is_inside_scene()) + if (!is_inside_tree()) return; for(int i=0;i<get_child_count();i++) { @@ -243,7 +243,7 @@ void CanvasItem::_sort_children() { void CanvasItem::_raise_self() { - if (!is_inside_scene()) + if (!is_inside_tree()) return; VisualServer::get_singleton()->canvas_item_raise(canvas_item); @@ -283,7 +283,7 @@ void CanvasItem::_enter_canvas() { group = "root_canvas"+itos(canvas.get_id()); add_to_group(group); - get_scene()->call_group(SceneMainLoop::GROUP_CALL_UNIQUE,group,"_raise_self"); + get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE,group,"_raise_self"); } else { @@ -313,7 +313,7 @@ void CanvasItem::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { first_draw=true; pending_children_sort=false; @@ -324,14 +324,14 @@ void CanvasItem::_notification(int p_what) { } _enter_canvas(); if (!block_transform_notify && !xform_change.in_list()) { - get_scene()->xform_change_list.add(&xform_change); + get_tree()->xform_change_list.add(&xform_change); } } break; case NOTIFICATION_MOVED_IN_PARENT: { if (group!="") { - get_scene()->call_group(SceneMainLoop::GROUP_CALL_UNIQUE,group,"_raise_self"); + get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE,group,"_raise_self"); } else { CanvasItem *p = get_parent_item(); ERR_FAIL_COND(!p); @@ -340,9 +340,9 @@ void CanvasItem::_notification(int p_what) { } break; - case NOTIFICATION_EXIT_SCENE: { + case NOTIFICATION_EXIT_TREE: { if (xform_change.in_list()) - get_scene()->xform_change_list.remove(&xform_change); + get_tree()->xform_change_list.remove(&xform_change); _exit_canvas(); if (C) { get_parent()->cast_to<CanvasItem>()->children_items.erase(C); @@ -379,7 +379,7 @@ bool CanvasItem::_is_visible_() const { void CanvasItem::update() { - if (!is_inside_scene()) + if (!is_inside_tree()) return; if (pending_update) return; @@ -406,7 +406,7 @@ void CanvasItem::set_as_toplevel(bool p_toplevel) { if (toplevel==p_toplevel) return; - if (!is_inside_scene()) { + if (!is_inside_tree()) { toplevel=p_toplevel; return; } @@ -630,8 +630,8 @@ void CanvasItem::_notify_transform(CanvasItem *p_node) { if (!p_node->xform_change.in_list()) { if (!p_node->block_transform_notify) { - if (p_node->is_inside_scene()) - get_scene()->xform_change_list.add(&p_node->xform_change); + if (p_node->is_inside_tree()) + get_tree()->xform_change_list.add(&p_node->xform_change); } } @@ -648,13 +648,13 @@ void CanvasItem::_notify_transform(CanvasItem *p_node) { Rect2 CanvasItem::get_viewport_rect() const { - ERR_FAIL_COND_V(!is_inside_scene(),Rect2()); + ERR_FAIL_COND_V(!is_inside_tree(),Rect2()); return get_viewport()->get_visible_rect(); } RID CanvasItem::get_canvas() const { - ERR_FAIL_COND_V(!is_inside_scene(),RID()); + ERR_FAIL_COND_V(!is_inside_tree(),RID()); if (canvas_layer) return canvas_layer->get_world_2d()->get_canvas(); @@ -677,7 +677,7 @@ CanvasItem *CanvasItem::get_toplevel() const { Ref<World2D> CanvasItem::get_world_2d() const { - ERR_FAIL_COND_V(!is_inside_scene(),Ref<World2D>()); + ERR_FAIL_COND_V(!is_inside_tree(),Ref<World2D>()); CanvasItem *tl=get_toplevel(); @@ -693,7 +693,7 @@ Ref<World2D> CanvasItem::get_world_2d() const { RID CanvasItem::get_viewport_rid() const { - ERR_FAIL_COND_V(!is_inside_scene(),RID()); + ERR_FAIL_COND_V(!is_inside_tree(),RID()); return get_viewport()->get_viewport(); } @@ -720,6 +720,95 @@ bool CanvasItem::is_draw_behind_parent_enabled() const{ return behind; } +void CanvasItem::set_shader(const Ref<Shader>& p_shader) { + + ERR_FAIL_COND(p_shader.is_valid() && p_shader->get_mode()!=Shader::MODE_CANVAS_ITEM); + +#ifdef TOOLS_ENABLED + + if (shader.is_valid()) { + shader->disconnect("changed",this,"_shader_changed"); + } +#endif + shader=p_shader; + +#ifdef TOOLS_ENABLED + + if (shader.is_valid()) { + shader->connect("changed",this,"_shader_changed"); + } +#endif + + RID rid; + if (shader.is_valid()) + rid=shader->get_rid(); + VS::get_singleton()->canvas_item_set_shader(canvas_item,rid); + _change_notify(); //properties for shader exposed +} + +void CanvasItem::set_use_parent_shader(bool p_use_parent_shader) { + + use_parent_shader=p_use_parent_shader; + VS::get_singleton()->canvas_item_set_use_parent_shader(canvas_item,p_use_parent_shader); +} + +bool CanvasItem::get_use_parent_shader() const{ + + return use_parent_shader; +} + +Ref<Shader> CanvasItem::get_shader() const{ + + return shader; +} + +void CanvasItem::set_shader_param(const StringName& p_param,const Variant& p_value) { + + VS::get_singleton()->canvas_item_set_shader_param(canvas_item,p_param,p_value); +} + +Variant CanvasItem::get_shader_param(const StringName& p_param) const { + + return VS::get_singleton()->canvas_item_get_shader_param(canvas_item,p_param); +} + +bool CanvasItem::_set(const StringName& p_name, const Variant& p_value) { + + if (shader.is_valid()) { + StringName pr = shader->remap_param(p_name); + if (pr) { + set_shader_param(pr,p_value); + return true; + } + } + return false; +} + +bool CanvasItem::_get(const StringName& p_name,Variant &r_ret) const{ + + if (shader.is_valid()) { + StringName pr = shader->remap_param(p_name); + if (pr) { + r_ret=get_shader_param(pr); + return true; + } + } + return false; + +} +void CanvasItem::_get_property_list( List<PropertyInfo> *p_list) const{ + + if (shader.is_valid()) { + shader->get_param_list(p_list); + } +} + +#ifdef TOOLS_ENABLED +void CanvasItem::_shader_changed() { + + _change_notify(); +} +#endif void CanvasItem::_bind_methods() { @@ -761,7 +850,9 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("_set_on_top","on_top"),&CanvasItem::_set_on_top); ObjectTypeDB::bind_method(_MD("_is_on_top"),&CanvasItem::_is_on_top); - +#ifdef TOOLS_ENABLED + ObjectTypeDB::bind_method(_MD("_shader_changed"),&CanvasItem::_shader_changed); +#endif //ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform); ObjectTypeDB::bind_method(_MD("draw_line","from","to","color","width"),&CanvasItem::draw_line,DEFVAL(1.0)); @@ -786,15 +877,22 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_world_2d"),&CanvasItem::get_world_2d); //ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasItem::get_viewport); + ObjectTypeDB::bind_method(_MD("set_shader","shader"),&CanvasItem::set_shader); + ObjectTypeDB::bind_method(_MD("get_shader"),&CanvasItem::get_shader); + ObjectTypeDB::bind_method(_MD("set_use_parent_shader","enable"),&CanvasItem::set_use_parent_shader); + ObjectTypeDB::bind_method(_MD("get_use_parent_shader"),&CanvasItem::get_use_parent_shader); + BIND_VMETHOD(MethodInfo("_draw")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/visible"), _SCS("_set_visible_"),_SCS("_is_visible_") ); ADD_PROPERTY( PropertyInfo(Variant::REAL,"visibility/opacity",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_opacity"),_SCS("get_opacity") ); ADD_PROPERTY( PropertyInfo(Variant::REAL,"visibility/self_opacity",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_self_opacity"),_SCS("get_self_opacity") ); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/behind_parent"), _SCS("set_draw_behind_parent"),_SCS("is_draw_behind_parent_enabled") ); + ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"visibility/behind_parent"), _SCS("set_draw_behind_parent"),_SCS("is_draw_behind_parent_enabled") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/on_top",PROPERTY_HINT_NONE,"",0), _SCS("_set_on_top"),_SCS("_is_on_top") ); //compatibility ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,PMAlpha"), _SCS("set_blend_mode"),_SCS("get_blend_mode") ); + ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"shader/shader",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemShader,CanvasItemShaderGraph"), _SCS("set_shader"),_SCS("get_shader") ); + ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"shader/use_parent"), _SCS("set_use_parent_shader"),_SCS("get_use_parent_shader") ); //exporting these two things doesn't really make much sense i think //ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transform/toplevel"), _SCS("set_as_toplevel"),_SCS("is_set_as_toplevel") ); //ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),_SCS("set_transform_notify"),_SCS("is_transform_notify_enabled")); @@ -824,7 +922,7 @@ void CanvasItem::_bind_methods() { Matrix32 CanvasItem::get_canvas_transform() const { - ERR_FAIL_COND_V(!is_inside_scene(),Matrix32()); + ERR_FAIL_COND_V(!is_inside_tree(),Matrix32()); if (canvas_layer) return canvas_layer->get_transform(); @@ -835,7 +933,7 @@ Matrix32 CanvasItem::get_canvas_transform() const { Matrix32 CanvasItem::get_viewport_transform() const { - ERR_FAIL_COND_V(!is_inside_scene(),Matrix32()); + ERR_FAIL_COND_V(!is_inside_tree(),Matrix32()); if (canvas_layer) { @@ -871,6 +969,7 @@ CanvasItem::CanvasItem() : xform_change(this) { block_transform_notify=false; // viewport=NULL; canvas_layer=NULL; + use_parent_shader; global_invalid=true; C=NULL; diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 604eef0527..ed3ade9df2 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -32,6 +32,7 @@ #include "scene/main/node.h" #include "scene/resources/texture.h" #include "scene/main/scene_main_loop.h" +#include "scene/resources/shader.h" class CanvasLayer; class Viewport; @@ -80,6 +81,9 @@ private: bool block_transform_notify; bool behind; + bool use_parent_shader; + Ref<Shader> shader; + mutable Matrix32 global_transform; mutable bool global_invalid; @@ -99,8 +103,9 @@ private: void _queue_sort_children(); void _sort_children(); - - +#ifdef TOOLS_ENABLED + void _shader_changed(); +#endif void _notify_transform(CanvasItem *p_node); void _set_on_top(bool p_on_top) { set_draw_behind_parent(!p_on_top); } @@ -108,9 +113,12 @@ private: protected: + bool _set(const StringName& p_name, const Variant& p_value); + bool _get(const StringName& p_name,Variant &r_ret) const; + void _get_property_list( List<PropertyInfo> *p_list) const; - _FORCE_INLINE_ void _notify_transform() { if (!is_inside_scene()) return; _notify_transform(this); if (!block_transform_notify) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); } + _FORCE_INLINE_ void _notify_transform() { if (!is_inside_tree()) return; _notify_transform(this); if (!block_transform_notify) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); } void item_rect_changed(); @@ -120,7 +128,7 @@ public: enum { - NOTIFICATION_TRANSFORM_CHANGED=SceneMainLoop::NOTIFICATION_TRANSFORM_CHANGED, //unique + NOTIFICATION_TRANSFORM_CHANGED=SceneTree::NOTIFICATION_TRANSFORM_CHANGED, //unique NOTIFICATION_DRAW=30, NOTIFICATION_VISIBILITY_CHANGED=31, NOTIFICATION_ENTER_CANVAS=32, @@ -204,7 +212,14 @@ public: RID get_canvas() const; Ref<World2D> get_world_2d() const; + void set_shader(const Ref<Shader>& p_shader); + Ref<Shader> get_shader() const; + + void set_use_parent_shader(bool p_use_parent_shader); + bool get_use_parent_shader() const; + void set_shader_param(const StringName& p_param,const Variant& p_value); + Variant get_shader_param(const StringName& p_param) const; CanvasItem(); ~CanvasItem(); diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index e5d9872a28..3b859d9366 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -45,7 +45,7 @@ void CollisionObject2D::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { if (area) Physics2DServer::get_singleton()->area_set_transform(rid,get_global_transform()); @@ -69,7 +69,7 @@ void CollisionObject2D::_notification(int p_what) { Physics2DServer::get_singleton()->body_set_state(rid,Physics2DServer::BODY_STATE_TRANSFORM,get_global_transform()); } break; - case NOTIFICATION_EXIT_SCENE: { + case NOTIFICATION_EXIT_TREE: { if (area) { Physics2DServer::get_singleton()->area_set_space(rid,RID()); @@ -156,13 +156,13 @@ bool CollisionObject2D::_get(const StringName& p_name,Variant &r_ret) const { void CollisionObject2D::_get_property_list( List<PropertyInfo> *p_list) const { - p_list->push_back( PropertyInfo(Variant::INT,"shape_count",PROPERTY_HINT_RANGE,"0,256,1",PROPERTY_USAGE_NOEDITOR) ); + p_list->push_back( PropertyInfo(Variant::INT,"shape_count",PROPERTY_HINT_RANGE,"0,256,1",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) ); for(int i=0;i<shapes.size();i++) { String path="shapes/"+itos(i)+"/"; - p_list->push_back( PropertyInfo(Variant::OBJECT,path+"shape",PROPERTY_HINT_RESOURCE_TYPE,"Shape2D",PROPERTY_USAGE_NOEDITOR) ); - p_list->push_back( PropertyInfo(Variant::TRANSFORM,path+"transform",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) ); - p_list->push_back( PropertyInfo(Variant::BOOL,path+"trigger",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) ); + p_list->push_back( PropertyInfo(Variant::OBJECT,path+"shape",PROPERTY_HINT_RESOURCE_TYPE,"Shape2D",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) ); + p_list->push_back( PropertyInfo(Variant::TRANSFORM,path+"transform",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) ); + p_list->push_back( PropertyInfo(Variant::BOOL,path+"trigger",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) ); } } diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index ef63286697..1c0be60764 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -41,7 +41,6 @@ void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) { bool solids=build_mode==BUILD_SOLIDS; - if (solids) { //here comes the sun, lalalala @@ -51,6 +50,8 @@ void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) { Ref<ConvexPolygonShape2D> convex = memnew( ConvexPolygonShape2D ); convex->set_points(decomp[i]); co->add_shape(convex,get_transform()); + if (trigger) + co->set_shape_as_trigger(co->get_shape_count()-1,true); } @@ -71,6 +72,8 @@ void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) { concave->set_segments(segments); co->add_shape(concave,get_transform()); + if (trigger) + co->set_shape_as_trigger(co->get_shape_count()-1,true); } @@ -95,7 +98,7 @@ void CollisionPolygon2D::_notification(int p_what) { switch(p_what) { case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { - if (!is_inside_scene()) + if (!is_inside_tree()) break; _update_parent(); @@ -166,6 +169,18 @@ Rect2 CollisionPolygon2D::get_item_rect() const { return aabb; } +void CollisionPolygon2D::set_trigger(bool p_trigger) { + + trigger=p_trigger; + _update_parent(); +} + +bool CollisionPolygon2D::is_trigger() const{ + + return trigger; +} + + void CollisionPolygon2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("_add_to_collision_object"),&CollisionPolygon2D::_add_to_collision_object); @@ -175,14 +190,19 @@ void CollisionPolygon2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_build_mode"),&CollisionPolygon2D::set_build_mode); ObjectTypeDB::bind_method(_MD("get_build_mode"),&CollisionPolygon2D::get_build_mode); + ObjectTypeDB::bind_method(_MD("set_trigger"),&CollisionPolygon2D::set_trigger); + ObjectTypeDB::bind_method(_MD("is_trigger"),&CollisionPolygon2D::is_trigger); + ADD_PROPERTY( PropertyInfo(Variant::INT,"build_mode",PROPERTY_HINT_ENUM,"Solids,Segments"),_SCS("set_build_mode"),_SCS("get_build_mode")); ADD_PROPERTY( PropertyInfo(Variant::VECTOR2_ARRAY,"polygon"),_SCS("set_polygon"),_SCS("get_polygon")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"trigger"),_SCS("set_trigger"),_SCS("is_trigger")); } CollisionPolygon2D::CollisionPolygon2D() { aabb=Rect2(-10,-10,20,20); build_mode=BUILD_SOLIDS; + trigger=false; } diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index 09c2060088..b8e27b6fb4 100644 --- a/scene/2d/collision_polygon_2d.h +++ b/scene/2d/collision_polygon_2d.h @@ -50,6 +50,7 @@ protected: Rect2 aabb; BuildMode build_mode; Vector<Point2> polygon; + bool trigger; void _add_to_collision_object(Object *p_obj); void _update_parent(); @@ -60,6 +61,9 @@ protected: static void _bind_methods(); public: + void set_trigger(bool p_trigger); + bool is_trigger() const; + void set_build_mode(BuildMode p_mode); BuildMode get_build_mode() const; diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index 3f068f4ccc..9f35ade322 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -72,12 +72,12 @@ void CollisionShape2D::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { unparenting=false; } break; case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { - if (!is_inside_scene()) + if (!is_inside_tree()) break; _update_parent(); diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index 0e673ff791..e706ad658a 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -32,7 +32,7 @@ void Joint2D::_update_joint() { - if (!is_inside_scene()) + if (!is_inside_tree()) return; if (joint.is_valid()) { @@ -86,7 +86,7 @@ void Joint2D::_notification(int p_what) { case NOTIFICATION_READY: { _update_joint(); } break; - case NOTIFICATION_EXIT_SCENE: { + case NOTIFICATION_EXIT_TREE: { if (joint.is_valid()) { Physics2DServer::get_singleton()->free(joint); @@ -145,7 +145,7 @@ void PinJoint2D::_notification(int p_what) { switch(p_what) { case NOTIFICATION_DRAW: { - if (is_inside_scene() && get_scene()->is_editor_hint()) { + if (is_inside_tree() && get_tree()->is_editor_hint()) { draw_line(Point2(-10,0),Point2(+10,0),Color(0.7,0.6,0.0,0.5),3); draw_line(Point2(0,-10),Point2(0,+10),Color(0.7,0.6,0.0,0.5),3); @@ -197,7 +197,7 @@ void GrooveJoint2D::_notification(int p_what) { switch(p_what) { case NOTIFICATION_DRAW: { - if (is_inside_scene() && get_scene()->is_editor_hint()) { + if (is_inside_tree() && get_tree()->is_editor_hint()) { draw_line(Point2(-10,0),Point2(+10,0),Color(0.7,0.6,0.0,0.5),3); draw_line(Point2(-10,length),Point2(+10,length),Color(0.7,0.6,0.0,0.5),3); @@ -291,7 +291,7 @@ void DampedSpringJoint2D::_notification(int p_what) { switch(p_what) { case NOTIFICATION_DRAW: { - if (is_inside_scene() && get_scene()->is_editor_hint()) { + if (is_inside_tree() && get_tree()->is_editor_hint()) { draw_line(Point2(-10,0),Point2(+10,0),Color(0.7,0.6,0.0,0.5),3); draw_line(Point2(-10,length),Point2(+10,length),Color(0.7,0.6,0.0,0.5),3); diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 4c00db2429..8b4196ee7f 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -130,7 +130,7 @@ void Node2D::_update_transform() { VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(),_mat); - if (!is_inside_scene()) + if (!is_inside_tree()) return; @@ -272,7 +272,7 @@ void Node2D::set_transform(const Matrix32& p_transform) { VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(),_mat); - if (!is_inside_scene()) + if (!is_inside_tree()) return; _notify_transform(); @@ -289,6 +289,35 @@ void Node2D::set_global_transform(const Matrix32& p_transform) { } +void Node2D::set_z(int p_z) { + + ERR_FAIL_COND(p_z<VS::CANVAS_ITEM_Z_MIN); + ERR_FAIL_COND(p_z>VS::CANVAS_ITEM_Z_MAX); + z=p_z; + VS::get_singleton()->canvas_item_set_z(get_canvas_item(),z); + +} + +void Node2D::set_z_as_relative(bool p_enabled) { + + if (z_relative==p_enabled) + return; + z_relative=p_enabled; + VS::get_singleton()->canvas_item_set_z_as_relative_to_parent(get_canvas_item(),p_enabled); +} + +bool Node2D::is_z_relative() const { + + return z_relative; +} + + +int Node2D::get_z() const{ + + return z; +} + + void Node2D::_bind_methods() { @@ -308,18 +337,25 @@ void Node2D::_bind_methods() { 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("set_global_pos","pos"),&Node2D::set_global_pos); ObjectTypeDB::bind_method(_MD("get_global_pos"),&Node2D::get_global_pos); - ObjectTypeDB::bind_method(_MD("set_global_pos"),&Node2D::set_global_pos); ObjectTypeDB::bind_method(_MD("set_transform","xform"),&Node2D::set_transform); ObjectTypeDB::bind_method(_MD("set_global_transform","xform"),&Node2D::set_global_transform); + ObjectTypeDB::bind_method(_MD("set_z","z"),&Node2D::set_z); + ObjectTypeDB::bind_method(_MD("get_z"),&Node2D::get_z); + + ObjectTypeDB::bind_method(_MD("set_z_as_relative","enable"),&Node2D::set_z_as_relative); + ObjectTypeDB::bind_method(_MD("is_z_relative"),&Node2D::is_z_relative); + ObjectTypeDB::bind_method(_MD("edit_set_pivot"),&Node2D::edit_set_pivot); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/pos"),_SCS("set_pos"),_SCS("get_pos")); ADD_PROPERTY(PropertyInfo(Variant::REAL,"transform/rot",PROPERTY_HINT_RANGE,"-1440,1440,0.1"),_SCS("_set_rotd"),_SCS("_get_rotd")); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/scale"),_SCS("set_scale"),_SCS("get_scale")); - + ADD_PROPERTY(PropertyInfo(Variant::INT,"z/z",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z"),_SCS("get_z")); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"z/relative"),_SCS("set_z_as_relative"),_SCS("is_z_relative")); } @@ -331,6 +367,8 @@ Node2D::Node2D() { angle=0; 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 582c56fa9b..61b8c829d6 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -38,6 +38,8 @@ class Node2D : public CanvasItem { Point2 pos; float angle; Size2 scale; + int z; + bool z_relative; Matrix32 _mat; @@ -85,6 +87,11 @@ public: void set_global_transform(const Matrix32& p_transform); void set_global_pos(const Point2& p_pos); + void set_z(int p_z); + int get_z() const; + + void set_z_as_relative(bool p_enabled); + bool is_z_relative() const; Matrix32 get_transform() const; diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp index 55607bd4eb..df37285f9d 100644 --- a/scene/2d/parallax_background.cpp +++ b/scene/2d/parallax_background.cpp @@ -36,13 +36,13 @@ void ParallaxBackground::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { group_name = "__cameras_"+itos(get_viewport().get_id()); add_to_group(group_name); } break; - case NOTIFICATION_EXIT_SCENE: { + case NOTIFICATION_EXIT_TREE: { remove_from_group(group_name); } break; @@ -78,7 +78,7 @@ void ParallaxBackground::set_scroll_offset(const Point2& p_ofs) { void ParallaxBackground::_update_scroll() { - if (!is_inside_scene()) + if (!is_inside_tree()) return; Vector2 ofs = base_offset+offset*base_scale; diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index 2cda51dccb..a0913ab50c 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -74,7 +74,7 @@ void ParallaxLayer::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { orig_offset=get_pos(); orig_scale=get_scale(); @@ -85,9 +85,9 @@ void ParallaxLayer::_notification(int p_what) { void ParallaxLayer::set_base_offset_and_scale(const Point2& p_offset,float p_scale) { - if (!is_inside_scene()) + if (!is_inside_tree()) return; - if (get_scene()->is_editor_hint()) + if (get_tree()->is_editor_hint()) return; Point2 new_ofs = ((orig_offset+p_offset)*motion_scale)*p_scale; diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index ded86702ef..6e2cf5954b 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -34,14 +34,14 @@ void ParticleAttractor2D::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { _update_owner(); } break; case NOTIFICATION_DRAW: { - if (!get_scene()->is_editor_hint()) + if (!get_tree()->is_editor_hint()) return; Vector2 pv; @@ -58,7 +58,7 @@ void ParticleAttractor2D::_notification(int p_what) { } } break; - case NOTIFICATION_EXIT_SCENE: { + case NOTIFICATION_EXIT_TREE: { if (owner) { _set_owner(NULL); } @@ -76,7 +76,7 @@ void ParticleAttractor2D::_owner_exited() { void ParticleAttractor2D::_update_owner() { - if (!is_inside_scene() || !has_node(path)) { + if (!is_inside_tree() || !has_node(path)) { _set_owner(NULL); return; } @@ -98,7 +98,7 @@ void ParticleAttractor2D::_set_owner(Particles2D* p_owner) { return; if (owner) { - owner->disconnect("exit_scene",this,"_owner_exited"); + owner->disconnect("exit_tree",this,"_owner_exited"); owner->attractors.erase(this); owner=NULL; } @@ -106,7 +106,7 @@ void ParticleAttractor2D::_set_owner(Particles2D* p_owner) { if (owner) { - owner->connect("exit_scene",this,"_owner_exited",varray(),CONNECT_ONESHOT); + owner->connect("exit_tree",this,"_owner_exited",varray(),CONNECT_ONESHOT); owner->attractors.insert(this); } } @@ -355,6 +355,8 @@ void Particles2D::_process_particles(float p_delta) { p.rot=Math::deg2rad(param[PARAM_INITIAL_ANGLE]+param[PARAM_INITIAL_ANGLE]*randomness[PARAM_INITIAL_ANGLE]*_rand_from_seed(&rand_seed)); active_count++; + p.frame=Math::fmod(param[PARAM_ANIM_INITIAL_POS]+randomness[PARAM_ANIM_INITIAL_POS]*_rand_from_seed(&rand_seed),1.0); + } else { @@ -426,6 +428,8 @@ void Particles2D::_process_particles(float p_delta) { p.pos+=p.velocity*frame_time; p.rot+=Math::lerp(param[PARAM_SPIN_VELOCITY],param[PARAM_SPIN_VELOCITY]*randomness[PARAM_SPIN_VELOCITY]*_rand_from_seed(&rand_seed),randomness[PARAM_SPIN_VELOCITY])*frame_time; + float anim_spd=param[PARAM_ANIM_SPEED_SCALE]+param[PARAM_ANIM_SPEED_SCALE]*randomness[PARAM_ANIM_SPEED_SCALE]*_rand_from_seed(&rand_seed); + p.frame=Math::fposmod(p.frame+(frame_time/lifetime)*anim_spd,1.0); active_count++; @@ -457,7 +461,7 @@ void Particles2D::_notification(int p_what) { _process_particles( get_process_delta_time() ); } break; - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { float ppt=preprocess; while(ppt>0) { @@ -474,9 +478,13 @@ void Particles2D::_notification(int p_what) { RID ci=get_canvas_item(); Size2 size(1,1); Point2 center; + int total_frames=1; if (!texture.is_null()) { size=texture->get_size(); + size.x/=h_frames; + size.y/=v_frames; + total_frames=h_frames*v_frames; } @@ -507,7 +515,13 @@ void Particles2D::_notification(int p_what) { } - for(int i=0;i<particle_count;i++) { + int start_particle = (int)(time * (float)particle_count / lifetime); + + for (int id=0;id<particle_count;++id) { + int i = start_particle + id; + if (i >= particle_count) { + i -= particle_count; + } Particle &p=pdata[i]; if (!p.active) @@ -606,7 +620,17 @@ void Particles2D::_notification(int p_what) { if (texrid.is_valid()) { - texture->draw(ci,Point2(),color); + Rect2 src_rect; + src_rect.size=size; + + if (total_frames>1) { + int frame = Math::fast_ftoi(Math::floor(p.frame*total_frames)) % total_frames; + src_rect.pos.x = size.x * (frame%h_frames); + src_rect.pos.y = size.y * (frame/h_frames); + } + + + texture->draw_rect_region(ci,Rect2(Point2(),size),src_rect,color); //VisualServer::get_singleton()->canvas_item_add_texture_rect(ci,r,texrid,false,color); } else { VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2(),size),color); @@ -636,7 +660,9 @@ static const char* _particlesframe_property_names[Particles2D::PARAM_MAX]={ "params/initial_angle", "params/initial_size", "params/final_size", - "params/hue_variation" + "params/hue_variation", + "params/anim_speed_scale", + "params/anim_initial_pos", }; static const char* _particlesframe_property_rnames[Particles2D::PARAM_MAX]={ @@ -653,7 +679,9 @@ static const char* _particlesframe_property_rnames[Particles2D::PARAM_MAX]={ "randomness/initial_angle", "randomness/initial_size", "randomness/final_size", - "randomness/hue_variation" + "randomness/hue_variation", + "randomness/anim_speed_scale", + "randomness/anim_initial_pos", }; static const char* _particlesframe_property_ranges[Particles2D::PARAM_MAX]={ @@ -670,7 +698,9 @@ static const char* _particlesframe_property_ranges[Particles2D::PARAM_MAX]={ "0,360,0.01", "0,1024,0.01", "0,1024,0.01", - "0,1,0.01" + "0,1,0.01", + "0,128,0.01", + "0,1,0.01", }; @@ -903,6 +933,28 @@ bool Particles2D::is_flipped_v() const{ return flip_v; } +void Particles2D::set_h_frames(int p_frames) { + + ERR_FAIL_COND(p_frames<1); + h_frames=p_frames; +} + +int Particles2D::get_h_frames() const{ + + return h_frames; +} + +void Particles2D::set_v_frames(int p_frames){ + + ERR_FAIL_COND(p_frames<1); + v_frames=p_frames; +} +int Particles2D::get_v_frames() const{ + + return v_frames; +} + + void Particles2D::set_emission_points(const DVector<Vector2>& p_points) { @@ -952,6 +1004,12 @@ void Particles2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_flip_v","enable"),&Particles2D::set_flip_v); ObjectTypeDB::bind_method(_MD("is_flipped_v"),&Particles2D::is_flipped_v); + ObjectTypeDB::bind_method(_MD("set_h_frames","enable"),&Particles2D::set_h_frames); + ObjectTypeDB::bind_method(_MD("get_h_frames"),&Particles2D::get_h_frames); + + ObjectTypeDB::bind_method(_MD("set_v_frames","enable"),&Particles2D::set_v_frames); + ObjectTypeDB::bind_method(_MD("get_v_frames"),&Particles2D::get_v_frames); + ObjectTypeDB::bind_method(_MD("set_emission_half_extents","extents"),&Particles2D::set_emission_half_extents); ObjectTypeDB::bind_method(_MD("get_emission_half_extents"),&Particles2D::get_emission_half_extents); @@ -991,6 +1049,9 @@ void Particles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL,"config/flip_h"),_SCS("set_flip_h"),_SCS("is_flipped_h")); ADD_PROPERTY(PropertyInfo(Variant::BOOL,"config/flip_v"),_SCS("set_flip_v"),_SCS("is_flipped_v")); ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"config/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"config/h_frames",PROPERTY_HINT_RANGE,"1,512,1"),_SCS("set_h_frames"),_SCS("get_h_frames")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"config/v_frames",PROPERTY_HINT_RANGE,"1,512,1"),_SCS("set_v_frames"),_SCS("get_v_frames")); + for(int i=0;i<PARAM_MAX;i++) { @@ -1048,6 +1109,7 @@ Particles2D::Particles2D() { set_param(PARAM_INITIAL_ANGLE,0.0); set_param(PARAM_INITIAL_SIZE,1.0); set_param(PARAM_FINAL_SIZE,1.0); + set_param(PARAM_ANIM_SPEED_SCALE,1.0); time=0; @@ -1075,6 +1137,8 @@ Particles2D::Particles2D() { flip_h=false; flip_v=false; + v_frames=1; + h_frames=1; emit_timeout = 0; time_to_live = 0; diff --git a/scene/2d/particles_2d.h b/scene/2d/particles_2d.h index 47bd078a7a..6d91fcafc3 100644 --- a/scene/2d/particles_2d.h +++ b/scene/2d/particles_2d.h @@ -99,6 +99,8 @@ public: PARAM_INITIAL_SIZE, PARAM_FINAL_SIZE, PARAM_HUE_VARIATION, + PARAM_ANIM_SPEED_SCALE, + PARAM_ANIM_INITIAL_POS, PARAM_MAX }; @@ -117,8 +119,9 @@ private: Point2 pos; Vector2 velocity; float rot; + float frame; uint32_t seed; - Particle() { active=false; seed=123465789; rot=0;} + Particle() { active=false; seed=123465789; rot=0; frame=0;} }; Vector<Particle> particles; @@ -146,6 +149,8 @@ private: float time_scale; bool flip_h; bool flip_v; + int h_frames; + int v_frames; Point2 emissor_offset; Vector2 initial_velocity; Vector2 extents; @@ -206,6 +211,13 @@ public: void set_flip_v(bool p_flip); bool is_flipped_v() const; + + void set_h_frames(int p_frames); + int get_h_frames() const; + + void set_v_frames(int p_frames); + int get_v_frames() const; + void set_color_phases(int p_phases); int get_color_phases() const; diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index febec54124..5560274c98 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -31,7 +31,7 @@ void Path2D::_notification(int p_what) { - if (p_what==NOTIFICATION_DRAW && curve.is_valid() && is_inside_scene() && get_scene()->is_editor_hint()) { + if (p_what==NOTIFICATION_DRAW && curve.is_valid() && is_inside_tree() && get_tree()->is_editor_hint()) { //draw the curve!! for(int i=0;i<curve->get_point_count();i++) { @@ -52,7 +52,7 @@ void Path2D::_notification(int p_what) { void Path2D::_curve_changed() { - if (is_inside_scene() && get_scene()->is_editor_hint()) + if (is_inside_tree() && get_tree()->is_editor_hint()) update(); } @@ -135,7 +135,7 @@ void PathFollow2D::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { Node *parent=get_parent(); if (parent) { @@ -147,7 +147,7 @@ void PathFollow2D::_notification(int p_what) { } } break; - case NOTIFICATION_EXIT_SCENE: { + case NOTIFICATION_EXIT_TREE: { path=NULL; diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 78b5e23da0..6f18325212 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -43,13 +43,44 @@ void PhysicsBody2D::_notification(int p_what) { */ } +void PhysicsBody2D::set_one_way_collision_direction(const Vector2& p_dir) { + + one_way_collision_direction=p_dir; + Physics2DServer::get_singleton()->body_set_one_way_collision_direction(get_rid(),p_dir); +} + +Vector2 PhysicsBody2D::get_one_way_collision_direction() const{ + + return one_way_collision_direction; +} + + +void PhysicsBody2D::set_one_way_collision_max_depth(float p_depth) { + + one_way_collision_max_depth=p_depth; + Physics2DServer::get_singleton()->body_set_one_way_collision_max_depth(get_rid(),p_depth); + +} + +float PhysicsBody2D::get_one_way_collision_max_depth() const{ + + return one_way_collision_max_depth; +} + + void PhysicsBody2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask); ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask); + ObjectTypeDB::bind_method(_MD("set_one_way_collision_direction","dir"),&PhysicsBody2D::set_one_way_collision_direction); + ObjectTypeDB::bind_method(_MD("get_one_way_collision_direction"),&PhysicsBody2D::get_one_way_collision_direction); + ObjectTypeDB::bind_method(_MD("set_one_way_collision_max_depth","depth"),&PhysicsBody2D::set_one_way_collision_max_depth); + ObjectTypeDB::bind_method(_MD("get_one_way_collision_max_depth"),&PhysicsBody2D::get_one_way_collision_max_depth); ObjectTypeDB::bind_method(_MD("add_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::add_collision_exception_with); ObjectTypeDB::bind_method(_MD("remove_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::remove_collision_exception_with); ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask")); + ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"one_way_collision/direction"),_SCS("set_one_way_collision_direction"),_SCS("get_one_way_collision_direction")); + ADD_PROPERTYNZ(PropertyInfo(Variant::REAL,"one_way_collision/max_depth"),_SCS("set_one_way_collision_max_depth"),_SCS("get_one_way_collision_max_depth")); } void PhysicsBody2D::set_layer_mask(uint32_t p_mask) { @@ -66,6 +97,7 @@ uint32_t PhysicsBody2D::get_layer_mask() const { PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) { mask=1; + set_one_way_collision_max_depth(0); } @@ -198,7 +230,7 @@ StaticBody2D::~StaticBody2D() { -void RigidBody2D::_body_enter_scene(ObjectID p_id) { +void RigidBody2D::_body_enter_tree(ObjectID p_id) { Object *obj = ObjectDB::get_instance(p_id); Node *node = obj ? obj->cast_to<Node>() : NULL; @@ -218,7 +250,7 @@ void RigidBody2D::_body_enter_scene(ObjectID p_id) { } -void RigidBody2D::_body_exit_scene(ObjectID p_id) { +void RigidBody2D::_body_exit_tree(ObjectID p_id) { Object *obj = ObjectDB::get_instance(p_id); Node *node = obj ? obj->cast_to<Node>() : NULL; @@ -250,18 +282,19 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap if (!E) { E = contact_monitor->body_map.insert(objid,BodyState()); - E->get().rc=0; - E->get().in_scene=node && node->is_inside_scene(); +// E->get().rc=0; + E->get().in_scene=node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->enter_scene,this,SceneStringNames::get_singleton()->_body_enter_scene,make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->exit_scene,this,SceneStringNames::get_singleton()->_body_exit_scene,make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_body_enter_tree,make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_body_exit_tree,make_binds(objid)); if (E->get().in_scene) { emit_signal(SceneStringNames::get_singleton()->body_enter,node); } } + //E->get().rc++; } - E->get().rc++; + if (node) E->get().shapes.insert(ShapePair(p_body_shape,p_local_shape)); @@ -272,24 +305,26 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap } else { - E->get().rc--; + //E->get().rc--; if (node) E->get().shapes.erase(ShapePair(p_body_shape,p_local_shape)); - if (E->get().rc==0) { + bool in_scene = E->get().in_scene; + + if (E->get().shapes.empty()) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->enter_scene,this,SceneStringNames::get_singleton()->_body_enter_scene); - node->disconnect(SceneStringNames::get_singleton()->exit_scene,this,SceneStringNames::get_singleton()->_body_exit_scene); - if (E->get().in_scene) + 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); + if (in_scene) emit_signal(SceneStringNames::get_singleton()->body_exit,obj); } contact_monitor->body_map.erase(E); } - if (node && E->get().in_scene) { + if (node && in_scene) { emit_signal(SceneStringNames::get_singleton()->body_exit_shape,objid,obj,p_body_shape,p_local_shape); } @@ -381,6 +416,7 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { //process remotions + for(int i=0;i<toremove_count;i++) { _body_inout(0,toremove[i].body_id,toremove[i].pair.body_shape,toremove[i].pair.local_shape); @@ -388,6 +424,7 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { //process aditions + for(int i=0;i<toadd_count;i++) { _body_inout(1,toadd[i].id,toadd[i].shape,toadd[i].local_shape); @@ -491,6 +528,42 @@ real_t RigidBody2D::get_bounce() const{ return bounce; } + +void RigidBody2D::set_gravity_scale(real_t p_gravity_scale){ + + gravity_scale=p_gravity_scale; + Physics2DServer::get_singleton()->body_set_param(get_rid(),Physics2DServer::BODY_PARAM_GRAVITY_SCALE,gravity_scale); + +} +real_t RigidBody2D::get_gravity_scale() const{ + + return gravity_scale; +} + +void RigidBody2D::set_linear_damp(real_t p_linear_damp){ + + ERR_FAIL_COND(p_linear_damp<-1); + linear_damp=p_linear_damp; + Physics2DServer::get_singleton()->body_set_param(get_rid(),Physics2DServer::BODY_PARAM_LINEAR_DAMP,linear_damp); + +} +real_t RigidBody2D::get_linear_damp() const{ + + return linear_damp; +} + +void RigidBody2D::set_angular_damp(real_t p_angular_damp){ + + ERR_FAIL_COND(p_angular_damp<-1); + angular_damp=p_angular_damp; + Physics2DServer::get_singleton()->body_set_param(get_rid(),Physics2DServer::BODY_PARAM_ANGULAR_DAMP,angular_damp); + +} +real_t RigidBody2D::get_angular_damp() const{ + + return angular_damp; +} + void RigidBody2D::set_axis_velocity(const Vector2& p_axis) { Vector2 v = state? state->get_linear_velocity() : linear_velocity; @@ -613,6 +686,26 @@ RigidBody2D::CCDMode RigidBody2D::get_continuous_collision_detection_mode() cons } +Array RigidBody2D::get_colliding_bodies() const { + + ERR_FAIL_COND_V(!contact_monitor,Array()); + + Array ret; + ret.resize(contact_monitor->body_map.size()); + int idx=0; + for (const Map<ObjectID,BodyState>::Element *E=contact_monitor->body_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; +} + void RigidBody2D::set_contact_monitor(bool p_enabled) { if (p_enabled==is_contact_monitor_enabled()) @@ -658,6 +751,15 @@ void RigidBody2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_bounce","bounce"),&RigidBody2D::set_bounce); ObjectTypeDB::bind_method(_MD("get_bounce"),&RigidBody2D::get_bounce); + ObjectTypeDB::bind_method(_MD("set_gravity_scale","gravity_scale"),&RigidBody2D::set_gravity_scale); + ObjectTypeDB::bind_method(_MD("get_gravity_scale"),&RigidBody2D::get_gravity_scale); + + ObjectTypeDB::bind_method(_MD("set_linear_damp","linear_damp"),&RigidBody2D::set_linear_damp); + ObjectTypeDB::bind_method(_MD("get_linear_damp"),&RigidBody2D::get_linear_damp); + + ObjectTypeDB::bind_method(_MD("set_angular_damp","angular_damp"),&RigidBody2D::set_angular_damp); + ObjectTypeDB::bind_method(_MD("get_angular_damp"),&RigidBody2D::get_angular_damp); + ObjectTypeDB::bind_method(_MD("set_linear_velocity","linear_velocity"),&RigidBody2D::set_linear_velocity); ObjectTypeDB::bind_method(_MD("get_linear_velocity"),&RigidBody2D::get_linear_velocity); @@ -689,8 +791,10 @@ void RigidBody2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("is_able_to_sleep"),&RigidBody2D::is_able_to_sleep); ObjectTypeDB::bind_method(_MD("_direct_state_changed"),&RigidBody2D::_direct_state_changed); - ObjectTypeDB::bind_method(_MD("_body_enter_scene"),&RigidBody2D::_body_enter_scene); - ObjectTypeDB::bind_method(_MD("_body_exit_scene"),&RigidBody2D::_body_exit_scene); + ObjectTypeDB::bind_method(_MD("_body_enter_tree"),&RigidBody2D::_body_enter_tree); + ObjectTypeDB::bind_method(_MD("_body_exit_tree"),&RigidBody2D::_body_exit_tree); + + ObjectTypeDB::bind_method(_MD("get_colliding_bodies"),&RigidBody2D::get_colliding_bodies); BIND_VMETHOD(MethodInfo("_integrate_forces",PropertyInfo(Variant::OBJECT,"state:Physics2DDirectBodyState"))); @@ -699,6 +803,7 @@ void RigidBody2D::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::REAL,"weight",PROPERTY_HINT_EXP_RANGE,"0.01,65535,0.01",PROPERTY_USAGE_EDITOR),_SCS("set_weight"),_SCS("get_weight")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_friction"),_SCS("get_friction")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_bounce"),_SCS("get_bounce")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity_scale",PROPERTY_HINT_RANGE,"-128,128,0.01"),_SCS("set_gravity_scale"),_SCS("get_gravity_scale")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"custom_integrator"),_SCS("set_use_custom_integrator"),_SCS("is_using_custom_integrator")); ADD_PROPERTY( PropertyInfo(Variant::INT,"continuous_cd",PROPERTY_HINT_ENUM,"Disabled,Cast Ray,Cast Shape"),_SCS("set_continuous_collision_detection_mode"),_SCS("get_continuous_collision_detection_mode")); ADD_PROPERTY( PropertyInfo(Variant::INT,"contacts_reported"),_SCS("set_max_contacts_reported"),_SCS("get_max_contacts_reported")); @@ -707,6 +812,8 @@ void RigidBody2D::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::BOOL,"can_sleep"),_SCS("set_can_sleep"),_SCS("is_able_to_sleep")); ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"velocity/linear"),_SCS("set_linear_velocity"),_SCS("get_linear_velocity")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"velocity/angular"),_SCS("set_angular_velocity"),_SCS("get_angular_velocity")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"damp_override/linear",PROPERTY_HINT_RANGE,"-1,128,0.01"),_SCS("set_linear_damp"),_SCS("get_linear_damp")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"damp_override/angular",PROPERTY_HINT_RANGE,"-1,128,0.01"),_SCS("set_angular_damp"),_SCS("get_angular_damp")); ADD_SIGNAL( MethodInfo("body_enter_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"local_shape"))); ADD_SIGNAL( MethodInfo("body_exit_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"local_shape"))); @@ -731,6 +838,11 @@ RigidBody2D::RigidBody2D() : PhysicsBody2D(Physics2DServer::BODY_MODE_RIGID) { bounce=0; mass=1; friction=1; + + gravity_scale=1; + linear_damp=-1; + angular_damp=-1; + max_contacts_reported=0; state=NULL; @@ -798,7 +910,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { colliding=false; - ERR_FAIL_COND_V(!is_inside_scene(),Vector2()); + ERR_FAIL_COND_V(!is_inside_tree(),Vector2()); Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(get_world_2d()->get_space()); ERR_FAIL_COND_V(!dss,Vector2()); const int max_shapes=32; @@ -831,7 +943,8 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { //motion recover for(int i=0;i<get_shape_count();i++) { - + if (is_shape_set_as_trigger(i)) + continue; if (dss->collide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i),Vector2(),margin,sr,max_shapes,res_shapes,exclude,get_layer_mask(),mask)) collided=true; @@ -851,7 +964,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { //if (d<margin) /// continue; - recover_motion+=(b-a)*0.2; + recover_motion+=(b-a)*0.4; } if (recover_motion==Vector2()) { @@ -875,11 +988,14 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { for(int i=0;i<get_shape_count();i++) { + if (is_shape_set_as_trigger(i)) + continue; float lsafe,lunsafe; bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0,lsafe,lunsafe,exclude,get_layer_mask(),mask); //print_line("shape: "+itos(i)+" travel:"+rtos(ltravel)); if (!valid) { + safe=0; unsafe=0; best_shape=i; //sadly it's the best @@ -911,15 +1027,19 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt*get_shape_transform(best_shape), Vector2(), margin,&rest_info,exclude,get_layer_mask(),mask); if (!c2) { //should not happen, but floating point precision is so weird.. + colliding=false; } else { + //print_line("Travel: "+rtos(travel)); colliding=true; collision=rest_info.point; normal=rest_info.normal; collider=rest_info.collider_id; collider_vel=rest_info.linear_velocity; + collider_shape=rest_info.shape; + collider_metadata=rest_info.metadata; } } @@ -940,7 +1060,7 @@ Vector2 KinematicBody2D::move_to(const Vector2& p_position) { bool KinematicBody2D::can_move_to(const Vector2& p_position, bool p_discrete) { - ERR_FAIL_COND_V(!is_inside_scene(),false); + ERR_FAIL_COND_V(!is_inside_tree(),false); Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(get_world_2d()->get_space()); ERR_FAIL_COND_V(!dss,false); @@ -980,7 +1100,7 @@ bool KinematicBody2D::can_move_to(const Vector2& p_position, bool p_discrete) { bool KinematicBody2D::is_colliding() const { - ERR_FAIL_COND_V(!is_inside_scene(),false); + ERR_FAIL_COND_V(!is_inside_tree(),false); return colliding; } @@ -1008,6 +1128,20 @@ ObjectID KinematicBody2D::get_collider() const { return collider; } + +int KinematicBody2D::get_collider_shape() const { + + ERR_FAIL_COND_V(!colliding,0); + return collider_shape; +} + +Variant KinematicBody2D::get_collider_metadata() const { + + ERR_FAIL_COND_V(!colliding,0); + return collider_metadata; + +} + void KinematicBody2D::set_collide_with_static_bodies(bool p_enable) { collide_static=p_enable; @@ -1071,6 +1205,8 @@ void KinematicBody2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_collision_normal"),&KinematicBody2D::get_collision_normal); ObjectTypeDB::bind_method(_MD("get_collider_velocity"),&KinematicBody2D::get_collider_velocity); ObjectTypeDB::bind_method(_MD("get_collider:Object"),&KinematicBody2D::_get_collider); + ObjectTypeDB::bind_method(_MD("get_collider_shape"),&KinematicBody2D::get_collider_shape); + ObjectTypeDB::bind_method(_MD("get_collider_metadata"),&KinematicBody2D::get_collider_metadata); ObjectTypeDB::bind_method(_MD("set_collide_with_static_bodies","enable"),&KinematicBody2D::set_collide_with_static_bodies); @@ -1107,6 +1243,8 @@ KinematicBody2D::KinematicBody2D() : PhysicsBody2D(Physics2DServer::BODY_MODE_KI colliding=false; collider=0; + collider_shape=0; + margin=0.08; } KinematicBody2D::~KinematicBody2D() { diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 7e3fd978a0..eed43c95be 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -39,6 +39,8 @@ class PhysicsBody2D : public CollisionObject2D { OBJ_TYPE(PhysicsBody2D,CollisionObject2D); uint32_t mask; + Vector2 one_way_collision_direction; + float one_way_collision_max_depth; protected: void _notification(int p_what); @@ -53,6 +55,12 @@ public: void add_collision_exception_with(Node* p_node); //must be physicsbody void remove_collision_exception_with(Node* p_node); + void set_one_way_collision_direction(const Vector2& p_dir); + Vector2 get_one_way_collision_direction() const; + + void set_one_way_collision_max_depth(float p_dir); + float get_one_way_collision_max_depth() const; + PhysicsBody2D(); }; @@ -119,6 +127,9 @@ private: real_t bounce; real_t mass; real_t friction; + real_t gravity_scale; + real_t linear_damp; + real_t angular_damp; Vector2 linear_velocity; real_t angular_velocity; @@ -156,7 +167,7 @@ private: }; struct BodyState { - int rc; + //int rc; bool in_scene; VSet<ShapePair> shapes; }; @@ -170,8 +181,8 @@ private: ContactMonitor *contact_monitor; - void _body_enter_scene(ObjectID p_id); - void _body_exit_scene(ObjectID p_id); + void _body_enter_tree(ObjectID p_id); + void _body_exit_tree(ObjectID p_id); void _body_inout(int p_status, ObjectID p_instance, int p_body_shape,int p_local_shape); @@ -198,6 +209,15 @@ public: void set_bounce(real_t p_bounce); real_t get_bounce() const; + void set_gravity_scale(real_t p_gravity_scale); + real_t get_gravity_scale() const; + + void set_linear_damp(real_t p_linear_damp); + real_t get_linear_damp() const; + + void set_angular_damp(real_t p_angular_damp); + real_t get_angular_damp() const; + void set_linear_velocity(const Vector2& p_velocity); Vector2 get_linear_velocity() const; @@ -229,6 +249,8 @@ public: void set_applied_force(const Vector2& p_force); Vector2 get_applied_force() const; + Array get_colliding_bodies() const; //function for script + RigidBody2D(); ~RigidBody2D(); @@ -254,7 +276,8 @@ class KinematicBody2D : public PhysicsBody2D { Vector2 normal; Vector2 collider_vel; ObjectID collider; - + int collider_shape; + Variant collider_metadata; Variant _get_collider() const; @@ -273,6 +296,8 @@ public: Vector2 get_collision_normal() const; Vector2 get_collider_velocity() const; ObjectID get_collider() const; + int get_collider_shape() const; + Variant get_collider_metadata() const; void set_collide_with_static_bodies(bool p_enable); bool can_collide_with_static_bodies() const; diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 2b4be734af..217a98aaea 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -359,5 +359,6 @@ Polygon2D::Polygon2D() { tex_rot=0; tex_tile=true; tex_scale=Vector2(1,1); + color=Color(1,1,1); rect_cache_dirty=true; } diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index ca3be9aa8f..2db2be123b 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -45,14 +45,14 @@ void Position2D::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { update(); } break; case NOTIFICATION_DRAW: { - if (!is_inside_scene()) + if (!is_inside_tree()) break; - if (get_scene()->is_editor_hint()) + if (get_tree()->is_editor_hint()) _draw_cross(); } break; diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 8479338521..e352ac64f5 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -33,7 +33,7 @@ void RayCast2D::set_cast_to(const Vector2& p_point) { cast_to=p_point; - if (is_inside_scene() && get_scene()->is_editor_hint()) + if (is_inside_tree() && get_tree()->is_editor_hint()) update(); } @@ -82,7 +82,7 @@ Vector2 RayCast2D::get_collision_normal() const{ void RayCast2D::set_enabled(bool p_enabled) { enabled=p_enabled; - if (is_inside_scene() && !get_scene()->is_editor_hint()) + if (is_inside_tree() && !get_tree()->is_editor_hint()) set_fixed_process(p_enabled); if (!p_enabled) collided=false; @@ -101,15 +101,15 @@ void RayCast2D::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { - if (enabled && !get_scene()->is_editor_hint()) + if (enabled && !get_tree()->is_editor_hint()) set_fixed_process(true); else set_fixed_process(false); } break; - case NOTIFICATION_EXIT_SCENE: { + case NOTIFICATION_EXIT_TREE: { if (enabled) set_fixed_process(false); @@ -118,7 +118,7 @@ void RayCast2D::_notification(int p_what) { #ifdef TOOLS_ENABLED case NOTIFICATION_DRAW: { - if (!get_scene()->is_editor_hint()) + if (!get_tree()->is_editor_hint()) break; Matrix32 xf; xf.rotate(cast_to.atan2()); diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp index 80d038f6f8..b170986017 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -45,7 +45,7 @@ void RemoteTransform2D::_update_cache() { void RemoteTransform2D::_update_remote() { - if (!is_inside_scene()) + if (!is_inside_tree()) return; if (!cache) @@ -59,7 +59,7 @@ void RemoteTransform2D::_update_remote() { if (!n) return; - if (!n->is_inside_scene()) + if (!n->is_inside_tree()) return; //todo make faster @@ -77,7 +77,7 @@ void RemoteTransform2D::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - if (!is_inside_scene()) + if (!is_inside_tree()) break; if (cache) { @@ -95,7 +95,7 @@ void RemoteTransform2D::_notification(int p_what) { void RemoteTransform2D::set_remote_node(const NodePath& p_remote_node) { remote_node=p_remote_node; - if (is_inside_scene()) + if (is_inside_tree()) _update_cache(); } diff --git a/scene/2d/remote_transform_2d.h b/scene/2d/remote_transform_2d.h index 9561e72255..05a9b20f6e 100644 --- a/scene/2d/remote_transform_2d.h +++ b/scene/2d/remote_transform_2d.h @@ -38,7 +38,7 @@ class RemoteTransform2D : public Node2D { void _update_remote(); void _update_cache(); - void _node_exited_scene(); + //void _node_exited_scene(); protected: static void _bind_methods(); diff --git a/scene/2d/sample_player_2d.cpp b/scene/2d/sample_player_2d.cpp index bc1734ec06..a231acd13d 100644 --- a/scene/2d/sample_player_2d.cpp +++ b/scene/2d/sample_player_2d.cpp @@ -89,7 +89,7 @@ void SamplePlayer2D::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { SpatialSound2DServer::get_singleton()->source_set_polyphony(get_source_rid(),polyphony); @@ -102,6 +102,7 @@ void SamplePlayer2D::_notification(int p_what) { void SamplePlayer2D::set_sample_library(const Ref<SampleLibrary>& p_library) { library=p_library; + _change_notify(); } Ref<SampleLibrary> SamplePlayer2D::get_sample_library() const { diff --git a/scene/2d/screen_button.cpp b/scene/2d/screen_button.cpp index b606634819..2ac3c06031 100644 --- a/scene/2d/screen_button.cpp +++ b/scene/2d/screen_button.cpp @@ -69,9 +69,9 @@ void TouchScreenButton::_notification(int p_what) { case NOTIFICATION_DRAW: { - if (!is_inside_scene()) + if (!is_inside_tree()) return; - if (!get_scene()->is_editor_hint() && !OS::get_singleton()->has_touchscreen_ui_hint() && visibility==VISIBILITY_TOUCHSCREEN_ONLY) + if (!get_tree()->is_editor_hint() && !OS::get_singleton()->has_touchscreen_ui_hint() && visibility==VISIBILITY_TOUCHSCREEN_ONLY) return; if (finger_pressed!=-1) { @@ -87,13 +87,13 @@ void TouchScreenButton::_notification(int p_what) { } } break; - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { - if (!get_scene()->is_editor_hint() && !OS::get_singleton()->has_touchscreen_ui_hint() && visibility==VISIBILITY_TOUCHSCREEN_ONLY) + if (!get_tree()->is_editor_hint() && !OS::get_singleton()->has_touchscreen_ui_hint() && visibility==VISIBILITY_TOUCHSCREEN_ONLY) return; update(); - if (!get_scene()->is_editor_hint()) + if (!get_tree()->is_editor_hint()) set_process_input(true); if (action.operator String()!="" && InputMap::get_singleton()->has_action(action)) { @@ -129,7 +129,7 @@ String TouchScreenButton::get_action() const { void TouchScreenButton::_input(const InputEvent& p_event) { - if (!get_scene()) + if (!get_tree()) return; if (p_event.device != 0) @@ -149,7 +149,7 @@ void TouchScreenButton::_input(const InputEvent& p_event) { ie.ID=0; ie.action.action=action_id; ie.action.pressed=false; - get_scene()->input_event(ie); + get_tree()->input_event(ie); } finger_pressed=-1; @@ -193,7 +193,7 @@ void TouchScreenButton::_input(const InputEvent& p_event) { ie.ID=0; ie.action.action=action_id; ie.action.pressed=true; - get_scene()->input_event(ie); + get_tree()->input_event(ie); } update(); @@ -213,7 +213,7 @@ void TouchScreenButton::_input(const InputEvent& p_event) { ie.ID=0; ie.action.action=action_id; ie.action.pressed=false; - get_scene()->input_event(ie); + get_tree()->input_event(ie); } finger_pressed=-1; @@ -268,7 +268,7 @@ void TouchScreenButton::_input(const InputEvent& p_event) { ie.ID=0; ie.action.action=action_id; ie.action.pressed=true; - get_scene()->input_event(ie); + get_tree()->input_event(ie); } update(); @@ -289,7 +289,7 @@ void TouchScreenButton::_input(const InputEvent& p_event) { ie.ID=0; ie.action.action=action_id; ie.action.pressed=false; - get_scene()->input_event(ie); + get_tree()->input_event(ie); } finger_pressed=-1; update(); diff --git a/scene/2d/sound_player_2d.cpp b/scene/2d/sound_player_2d.cpp index 2fffef4e51..ef51295476 100644 --- a/scene/2d/sound_player_2d.cpp +++ b/scene/2d/sound_player_2d.cpp @@ -39,7 +39,7 @@ void SoundPlayer2D::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { //find the sound space source_rid = SpatialSound2DServer::get_singleton()->source_create(get_world_2d()->get_sound_space()); @@ -56,7 +56,7 @@ void SoundPlayer2D::_notification(int p_what) { SpatialSound2DServer::get_singleton()->source_set_transform(source_rid,get_global_transform()); } break; - case NOTIFICATION_EXIT_SCENE: { + case NOTIFICATION_EXIT_TREE: { if (source_rid.is_valid()) SpatialSound2DServer::get_singleton()->free(source_rid); diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index 7d033ed87f..82f5a6972a 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -34,6 +34,7 @@ void Sprite::edit_set_pivot(const Point2& p_pivot) { set_offset(p_pivot); + } Point2 Sprite::edit_get_pivot() const { @@ -64,20 +65,20 @@ void Sprite::_notification(int p_what) { break; */ - Size2i s; - Rect2i src_rect; + Size2 s; + Rect2 src_rect; if (region) { s=region_rect.size; src_rect=region_rect; } else { - s = texture->get_size(); - s=s/Size2i(hframes,vframes); + s = Size2(texture->get_size()); + s=s/Size2(hframes,vframes); src_rect.size=s; - src_rect.pos.x+=(frame%hframes)*s.x; - src_rect.pos.y+=(frame/hframes)*s.y; + src_rect.pos.x+=float(frame%hframes)*s.x; + src_rect.pos.y+=float(frame/hframes)*s.y; } @@ -85,7 +86,7 @@ void Sprite::_notification(int p_what) { if (centered) ofs-=s/2; - Rect2i dst_rect(ofs,s); + Rect2 dst_rect(ofs,s); if (hflip) dst_rect.size.x=-dst_rect.size.x; @@ -136,6 +137,7 @@ void Sprite::set_offset(const Point2& p_offset) { offset=p_offset; update(); item_rect_changed(); + _change_notify("offset"); } Point2 Sprite::get_offset() const { @@ -199,6 +201,8 @@ void Sprite::set_frame(int p_frame) { item_rect_changed(); frame=p_frame; + + emit_signal(SceneStringNames::get_singleton()->frame_changed); } int Sprite::get_frame() const { @@ -307,6 +311,8 @@ void Sprite::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_modulate","modulate"),&Sprite::set_modulate); ObjectTypeDB::bind_method(_MD("get_modulate"),&Sprite::get_modulate); + ADD_SIGNAL(MethodInfo("frame_changed")); + ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_texture"),_SCS("get_texture")); ADD_PROPERTY( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered")); ADD_PROPERTY( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset")); @@ -365,7 +371,7 @@ void ViewportSprite::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { if (!viewport_path.is_empty()) { @@ -380,7 +386,7 @@ void ViewportSprite::_notification(int p_what) { item_rect_changed(); } } break; - case NOTIFICATION_EXIT_SCENE: { + case NOTIFICATION_EXIT_TREE: { if (texture.is_valid()) { @@ -422,7 +428,7 @@ void ViewportSprite::set_viewport_path(const NodePath& p_viewport) { viewport_path=p_viewport; update(); - if (!is_inside_scene()) + if (!is_inside_tree()) return; if (texture.is_valid()) { diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 6403454588..9fcf34cee6 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -33,7 +33,7 @@ void TileMap::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { pending_update=true; _update_dirty_quadrants(); @@ -43,7 +43,7 @@ void TileMap::_notification(int p_what) { } break; - case NOTIFICATION_EXIT_SCENE: { + case NOTIFICATION_EXIT_TREE: { _update_quadrant_space(RID()); @@ -68,7 +68,7 @@ void TileMap::_update_quadrant_space(const RID& p_space) { void TileMap::_update_quadrant_transform() { - if (!is_inside_scene()) + if (!is_inside_tree()) return; Matrix32 global_transform = get_global_transform(); @@ -106,9 +106,9 @@ Ref<TileSet> TileMap::get_tileset() const { return tile_set; } -void TileMap::set_cell_size(int p_size) { +void TileMap::set_cell_size(Size2 p_size) { - ERR_FAIL_COND(p_size<1); + ERR_FAIL_COND(p_size.x<1 || p_size.y<1); _clear_quadrants(); cell_size=p_size; @@ -117,7 +117,7 @@ void TileMap::set_cell_size(int p_size) { } -int TileMap::get_cell_size() const { +Size2 TileMap::get_cell_size() const { return cell_size; } @@ -164,13 +164,14 @@ void TileMap::_update_dirty_quadrants() { if (!pending_update) return; - if (!is_inside_scene()) + if (!is_inside_tree()) return; if (!tile_set.is_valid()) return; VisualServer *vs = VisualServer::get_singleton(); Physics2DServer *ps = Physics2DServer::get_singleton(); + Vector2 tofs = get_cell_draw_offset(); while (dirty_quadrant_list.first()) { @@ -178,6 +179,7 @@ void TileMap::_update_dirty_quadrants() { vs->canvas_item_clear(q.canvas_item); ps->body_clear_shapes(q.static_body); + int shape_idx=0; for(int i=0;i<q.cells.size();i++) { @@ -189,7 +191,7 @@ void TileMap::_update_dirty_quadrants() { Ref<Texture> tex = tile_set->tile_get_texture(c.id); Vector2 tile_ofs = tile_set->tile_get_texture_offset(c.id); - Vector2 offset = Point2( E->key().x, E->key().y )*cell_size - q.pos; + Vector2 offset = _map_to_world(E->key().x, E->key().y) - q.pos + tofs; if (!tex.is_valid()) continue; @@ -258,6 +260,8 @@ void TileMap::_update_dirty_quadrants() { ps->body_add_shape(q.static_body,shape->get_rid(),xform); + ps->body_set_shape_metadata(q.static_body,shape_idx++,Vector2(E->key().x,E->key().y)); + } } } @@ -299,17 +303,22 @@ void TileMap::_recompute_rect_cache() { for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) { - Rect2 r( Point2(E->key().x, E->key().y)*cell_size*quadrant_size, Size2(1,1)*cell_size*quadrant_size ); + Rect2 r; + r.pos=_map_to_world(E->key().x*quadrant_size, E->key().y*quadrant_size); + r.expand_to( _map_to_world(E->key().x*quadrant_size+quadrant_size, E->key().y*quadrant_size) ); + r.expand_to( _map_to_world(E->key().x*quadrant_size+quadrant_size, E->key().y*quadrant_size+quadrant_size) ); + r.expand_to( _map_to_world(E->key().x*quadrant_size, E->key().y*quadrant_size+quadrant_size) ); if (E==quadrant_map.front()) r_total=r; else r_total=r_total.merge(r); } + if (r_total==Rect2()) { rect_cache=Rect2(-10,-10,20,20); } else { - rect_cache=r_total; + rect_cache=r_total.grow(MAX(cell_size.x,cell_size.y)*quadrant_size); } item_rect_changed(); @@ -323,8 +332,10 @@ void TileMap::_recompute_rect_cache() { Map<TileMap::PosKey,TileMap::Quadrant>::Element *TileMap::_create_quadrant(const PosKey& p_qk) { Matrix32 xform; - xform.set_origin(Point2(p_qk.x,p_qk.y)*quadrant_size*cell_size); + //xform.set_origin(Point2(p_qk.x,p_qk.y)*cell_size*quadrant_size); Quadrant q; + q.pos = _map_to_world(p_qk.x*quadrant_size,p_qk.y*quadrant_size); + xform.set_origin( q.pos ); q.canvas_item = VisualServer::get_singleton()->canvas_item_create(); VisualServer::get_singleton()->canvas_item_set_parent( q.canvas_item, get_canvas_item() ); VisualServer::get_singleton()->canvas_item_set_transform( q.canvas_item, xform ); @@ -334,14 +345,13 @@ Map<TileMap::PosKey,TileMap::Quadrant>::Element *TileMap::_create_quadrant(const Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_FRICTION,friction); Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_BOUNCE,bounce); - if (is_inside_scene()) { + if (is_inside_tree()) { xform = get_global_transform() * xform; RID space = get_world_2d()->get_space(); Physics2DServer::get_singleton()->body_set_space(q.static_body,space); } Physics2DServer::get_singleton()->body_set_state(q.static_body,Physics2DServer::BODY_STATE_TRANSFORM,xform); - q.pos=Vector2(p_qk.x,p_qk.y)*quadrant_size*cell_size; rect_cache_dirty=true; quadrant_order_dirty=true; @@ -369,7 +379,7 @@ void TileMap::_make_quadrant_dirty(Map<PosKey,Quadrant>::Element *Q) { if (pending_update) return; pending_update=true; - if (!is_inside_scene()) + if (!is_inside_tree()) return; call_deferred("_update_dirty_quadrants"); } @@ -478,8 +488,11 @@ void TileMap::_recreate_quadrants() { } Q->get().cells.insert(E->key()); - + _make_quadrant_dirty(Q); } + + + } void TileMap::_clear_quadrants() { @@ -614,6 +627,152 @@ uint32_t TileMap::get_collision_layer_mask() const { return collision_layer; } +void TileMap::set_mode(Mode p_mode) { + + _clear_quadrants(); + mode=p_mode; + _recreate_quadrants(); + emit_signal("settings_changed"); +} + +TileMap::Mode TileMap::get_mode() const { + return mode; +} + +void TileMap::set_half_offset(HalfOffset p_half_offset) { + + _clear_quadrants(); + half_offset=p_half_offset; + _recreate_quadrants(); + emit_signal("settings_changed"); +} + +Vector2 TileMap::get_cell_draw_offset() const { + + switch(mode) { + + case MODE_SQUARE: { + + return Vector2(); + } break; + case MODE_ISOMETRIC: { + + return Vector2(-cell_size.x*0.5,0); + + } break; + case MODE_CUSTOM: { + + Vector2 min; + min.x = MIN(custom_transform[0].x,min.x); + min.y = MIN(custom_transform[0].y,min.y); + min.x = MIN(custom_transform[1].x,min.x); + min.y = MIN(custom_transform[1].y,min.y); + return min; + } break; + } + + return Vector2(); + +} + +TileMap::HalfOffset TileMap::get_half_offset() const { + return half_offset; +} + +Matrix32 TileMap::get_cell_transform() const { + + switch(mode) { + + case MODE_SQUARE: { + + Matrix32 m; + m[0]*=cell_size.x; + m[1]*=cell_size.y; + return m; + } break; + case MODE_ISOMETRIC: { + + //isometric only makes sense when y is positive in both x and y vectors, otherwise + //the drawing of tiles will overlap + Matrix32 m; + m[0]=Vector2(cell_size.x*0.5,cell_size.y*0.5); + m[1]=Vector2(-cell_size.x*0.5,cell_size.y*0.5); + return m; + + } break; + case MODE_CUSTOM: { + + return custom_transform; + } break; + } + + return Matrix32(); +} + +void TileMap::set_custom_transform(const Matrix32& p_xform) { + + _clear_quadrants(); + custom_transform=p_xform; + _recreate_quadrants(); + emit_signal("settings_changed"); + +} + +Matrix32 TileMap::get_custom_transform() const{ + + return custom_transform; +} + +Vector2 TileMap::_map_to_world(int x,int y,bool p_ignore_ofs) const { + + Vector2 ret = get_cell_transform().xform(Vector2(x,y)); + if (!p_ignore_ofs) { + switch(half_offset) { + + case HALF_OFFSET_X: { + if (ABS(y)&1) { + + ret+=get_cell_transform()[0]*0.5; + } + } break; + case HALF_OFFSET_Y: { + if (ABS(x)&1) { + ret+=get_cell_transform()[1]*0.5; + } + } break; + default: {} + } + } + return ret; +} +Vector2 TileMap::map_to_world(const Vector2& p_pos,bool p_ignore_ofs) const { + + return _map_to_world(p_pos.x,p_pos.y,p_ignore_ofs); +} +Vector2 TileMap::world_to_map(const Vector2& p_pos) const{ + + Vector2 ret = get_cell_transform().affine_inverse().xform(p_pos); + + + switch(half_offset) { + + case HALF_OFFSET_X: { + if (int(ret.y)&1) { + + ret.x-=0.5; + } + } break; + case HALF_OFFSET_Y: { + if (int(ret.x)&1) { + ret.y-=0.5; + } + } break; + default: {} + } + + return ret.floor(); +} + void TileMap::_bind_methods() { @@ -621,10 +780,21 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_tileset","tileset:TileSet"),&TileMap::set_tileset); ObjectTypeDB::bind_method(_MD("get_tileset:TileSet"),&TileMap::get_tileset); + ObjectTypeDB::bind_method(_MD("set_mode","mode"),&TileMap::set_mode); + ObjectTypeDB::bind_method(_MD("get_mode"),&TileMap::get_mode); + + ObjectTypeDB::bind_method(_MD("set_half_offset","half_offset"),&TileMap::set_half_offset); + ObjectTypeDB::bind_method(_MD("get_half_offset"),&TileMap::get_half_offset); + + ObjectTypeDB::bind_method(_MD("set_custom_transform","custom_transform"),&TileMap::set_custom_transform); + ObjectTypeDB::bind_method(_MD("get_custom_transform"),&TileMap::get_custom_transform); ObjectTypeDB::bind_method(_MD("set_cell_size","size"),&TileMap::set_cell_size); ObjectTypeDB::bind_method(_MD("get_cell_size"),&TileMap::get_cell_size); + ObjectTypeDB::bind_method(_MD("_set_old_cell_size","size"),&TileMap::_set_old_cell_size); + ObjectTypeDB::bind_method(_MD("_get_old_cell_size"),&TileMap::_get_old_cell_size); + ObjectTypeDB::bind_method(_MD("set_quadrant_size","size"),&TileMap::set_quadrant_size); ObjectTypeDB::bind_method(_MD("get_quadrant_size"),&TileMap::get_quadrant_size); @@ -650,6 +820,9 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("clear"),&TileMap::clear); + ObjectTypeDB::bind_method(_MD("map_to_world","mappos","ignore_half_ofs"),&TileMap::map_to_world,DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("world_to_map","worldpos"),&TileMap::world_to_map); + ObjectTypeDB::bind_method(_MD("_clear_quadrants"),&TileMap::_clear_quadrants); ObjectTypeDB::bind_method(_MD("_recreate_quadrants"),&TileMap::_recreate_quadrants); ObjectTypeDB::bind_method(_MD("_update_dirty_quadrants"),&TileMap::_update_dirty_quadrants); @@ -657,17 +830,28 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("_set_tile_data"),&TileMap::_set_tile_data); ObjectTypeDB::bind_method(_MD("_get_tile_data"),&TileMap::_get_tile_data); - ADD_PROPERTY( PropertyInfo(Variant::INT,"cell_size",PROPERTY_HINT_RANGE,"1,8192,1"),_SCS("set_cell_size"),_SCS("get_cell_size")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"quadrant_size",PROPERTY_HINT_RANGE,"1,128,1"),_SCS("set_quadrant_size"),_SCS("get_quadrant_size")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"mode",PROPERTY_HINT_ENUM,"Square,Isometric,Custom"),_SCS("set_mode"),_SCS("get_mode")); ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_set",PROPERTY_HINT_RESOURCE_TYPE,"TileSet"),_SCS("set_tileset"),_SCS("get_tileset")); - ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"cell_size",PROPERTY_HINT_RANGE,"1,8192,1",0),_SCS("_set_old_cell_size"),_SCS("_get_old_cell_size")); + ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"cell/size",PROPERTY_HINT_RANGE,"1,8192,1"),_SCS("set_cell_size"),_SCS("get_cell_size")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/quadrant_size",PROPERTY_HINT_RANGE,"1,128,1"),_SCS("set_quadrant_size"),_SCS("get_quadrant_size")); + ADD_PROPERTY( PropertyInfo(Variant::MATRIX32,"cell/custom_transform"),_SCS("set_custom_transform"),_SCS("get_custom_transform")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/half_offset",PROPERTY_HINT_ENUM,"Offset X,Offset Y,Disabled"),_SCS("set_half_offset"),_SCS("get_half_offset")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_friction"),_SCS("get_collision_friction")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_bounce"),_SCS("get_collision_bounce")); ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask")); + ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data")); ADD_SIGNAL(MethodInfo("settings_changed")); BIND_CONSTANT( INVALID_CELL ); + BIND_CONSTANT( MODE_SQUARE ); + BIND_CONSTANT( MODE_ISOMETRIC ); + BIND_CONSTANT( MODE_CUSTOM ); + BIND_CONSTANT( HALF_OFFSET_X ); + BIND_CONSTANT( HALF_OFFSET_Y ); + BIND_CONSTANT( HALF_OFFSET_DISABLED ); + } TileMap::TileMap() { @@ -678,12 +862,14 @@ TileMap::TileMap() { pending_update=false; quadrant_order_dirty=false; quadrant_size=16; - cell_size=64; + cell_size=Size2(64,64); center_x=false; center_y=false; collision_layer=1; friction=1; bounce=0; + mode=MODE_SQUARE; + half_offset=HALF_OFFSET_DISABLED; fp_adjust=0.01; fp_adjust=0.01; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index d21437e30f..4e9e2e7e97 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -37,12 +37,30 @@ class TileMap : public Node2D { OBJ_TYPE( TileMap, Node2D ); +public: + + enum Mode { + MODE_SQUARE, + MODE_ISOMETRIC, + MODE_CUSTOM + }; + + enum HalfOffset { + HALF_OFFSET_X, + HALF_OFFSET_Y, + HALF_OFFSET_DISABLED, + }; +private: Ref<TileSet> tile_set; - int cell_size; + Size2i cell_size; int quadrant_size; bool center_x,center_y; + Mode mode; + Matrix32 custom_transform; + HalfOffset half_offset; + union PosKey { @@ -117,6 +135,12 @@ class TileMap : public Node2D { void _set_tile_data(const DVector<int>& p_data); DVector<int> _get_tile_data() const; + + void _set_old_cell_size(int p_size) { set_cell_size(Size2(p_size,p_size)); } + int _get_old_cell_size() const { return cell_size.x; } + + _FORCE_INLINE_ Vector2 _map_to_world(int p_x,int p_y,bool p_ignore_ofs=false) const; + protected: @@ -132,8 +156,8 @@ public: void set_tileset(const Ref<TileSet>& p_tileset); Ref<TileSet> get_tileset() const; - void set_cell_size(int p_size); - int get_cell_size() const; + void set_cell_size(Size2 p_size); + Size2 get_cell_size() const; void set_quadrant_size(int p_size); int get_quadrant_size() const; @@ -159,10 +183,28 @@ public: void set_collision_bounce(float p_bounce); float get_collision_bounce() const; + void set_mode(Mode p_mode); + Mode get_mode() const; + + void set_half_offset(HalfOffset p_half_offset); + HalfOffset get_half_offset() const; + + void set_custom_transform(const Matrix32& p_xform); + Matrix32 get_custom_transform() const; + + Matrix32 get_cell_transform() const; + Vector2 get_cell_draw_offset() const; + + Vector2 map_to_world(const Vector2& p_pos, bool p_ignore_ofs=false) const; + Vector2 world_to_map(const Vector2& p_pos) const; + void clear(); TileMap(); ~TileMap(); }; +VARIANT_ENUM_CAST(TileMap::Mode); +VARIANT_ENUM_CAST(TileMap::HalfOffset); + #endif // TILE_MAP_H diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index e5eb193f6f..22534eeb0e 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -64,7 +64,7 @@ void VisibilityNotifier2D::_exit_viewport(Viewport* p_viewport){ void VisibilityNotifier2D::set_rect(const Rect2& p_rect){ rect=p_rect; - if (is_inside_scene()) + if (is_inside_tree()) get_world_2d()->_update_notifier(this,get_global_transform().xform(rect)); _change_notify("rect"); @@ -85,7 +85,7 @@ void VisibilityNotifier2D::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_SCENE: { + case NOTIFICATION_ENTER_TREE: { //get_world_2d()-> get_world_2d()->_register_notifier(this,get_global_transform().xform(rect)); @@ -97,12 +97,12 @@ void VisibilityNotifier2D::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - if (get_scene()->is_editor_hint()) { + if (get_tree()->is_editor_hint()) { draw_rect(rect,Color(1,0.5,1,0.2)); } } break; - case NOTIFICATION_EXIT_SCENE: { + case NOTIFICATION_EXIT_TREE: { get_world_2d()->_remove_notifier(this); } break; @@ -190,7 +190,7 @@ void VisibilityEnabler2D::_find_nodes(Node* p_node) { if (add) { - p_node->connect(SceneStringNames::get_singleton()->exit_scene,this,"_node_removed",varray(p_node),CONNECT_ONESHOT); + p_node->connect(SceneStringNames::get_singleton()->exit_tree,this,"_node_removed",varray(p_node),CONNECT_ONESHOT); nodes[p_node]=meta; _change_node_state(p_node,false); } @@ -207,9 +207,9 @@ void VisibilityEnabler2D::_find_nodes(Node* p_node) { void VisibilityEnabler2D::_notification(int p_what){ - if (p_what==NOTIFICATION_ENTER_SCENE) { + if (p_what==NOTIFICATION_ENTER_TREE) { - if (get_scene()->is_editor_hint()) + if (get_tree()->is_editor_hint()) return; @@ -222,9 +222,9 @@ void VisibilityEnabler2D::_notification(int p_what){ } - if (p_what==NOTIFICATION_EXIT_SCENE) { + if (p_what==NOTIFICATION_EXIT_TREE) { - if (get_scene()->is_editor_hint()) + if (get_tree()->is_editor_hint()) return; @@ -235,7 +235,7 @@ void VisibilityEnabler2D::_notification(int p_what){ if (!visible) _change_node_state(E->key(),true); - E->key()->disconnect(SceneStringNames::get_singleton()->exit_scene,this,"_node_removed"); + E->key()->disconnect(SceneStringNames::get_singleton()->exit_tree,this,"_node_removed"); } nodes.clear(); diff --git a/scene/2d/y_sort.cpp b/scene/2d/y_sort.cpp new file mode 100644 index 0000000000..d441abfaf1 --- /dev/null +++ b/scene/2d/y_sort.cpp @@ -0,0 +1,29 @@ +#include "y_sort.h" + + + +void YSort::set_sort_enabled(bool p_enabled) { + + sort_enabled=p_enabled; + VS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(),sort_enabled); +} + +bool YSort::is_sort_enabled() const { + + return sort_enabled; +} + +void YSort::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_sort_enabled","enabled"),&YSort::set_sort_enabled); + ObjectTypeDB::bind_method(_MD("is_sort_enabled"),&YSort::is_sort_enabled); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"sort/enabled"),_SCS("set_sort_enabled"),_SCS("is_sort_enabled")); +} + + +YSort::YSort() { + + sort_enabled=true; + VS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(),true); +} diff --git a/scene/2d/y_sort.h b/scene/2d/y_sort.h new file mode 100644 index 0000000000..6d04a67e42 --- /dev/null +++ b/scene/2d/y_sort.h @@ -0,0 +1,17 @@ +#ifndef Y_SORT_H +#define Y_SORT_H + +#include "scene/2d/node_2d.h" + +class YSort : public Node2D { + OBJ_TYPE(YSort,Node2D); + bool sort_enabled; + static void _bind_methods(); +public: + + void set_sort_enabled(bool p_enabled); + bool is_sort_enabled() const; + YSort(); +}; + +#endif // Y_SORT_H |