diff options
Diffstat (limited to 'scene/2d')
-rw-r--r-- | scene/2d/node_2d.cpp | 6 | ||||
-rw-r--r-- | scene/2d/path_2d.cpp | 270 | ||||
-rw-r--r-- | scene/2d/path_2d.h | 59 |
3 files changed, 331 insertions, 4 deletions
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 85adfbbbde..9c28212529 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -51,9 +51,9 @@ bool Node2D::edit_has_pivot() const { Variant Node2D::edit_get_state() const { Array state; - state.push_back(pos); - state.push_back(angle); - state.push_back(scale); + state.push_back(get_pos()); + state.push_back(get_rot()); + state.push_back(get_scale()); return state; diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index 22d56609ee..febec54124 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -27,7 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "path_2d.h" - +#include "scene/scene_string_names.h" void Path2D::_notification(int p_what) { @@ -90,3 +90,271 @@ Path2D::Path2D() { set_curve(Ref<Curve2D>( memnew( Curve2D ))); //create one by default } + +///////////////////////////////////////////////////////////////////////////////// + + +void PathFollow2D::_update_transform() { + + + if (!path) + return; + + Ref<Curve2D> c =path->get_curve(); + if (!c.is_valid()) + return; + + + float o = offset; + if (loop) + o=Math::fposmod(o,c->get_baked_length()); + + Vector2 pos = c->interpolate_baked(o,cubic); + + if (rotate) { + + Vector2 n = (c->interpolate_baked(o+lookahead,cubic)-pos).normalized(); + Vector2 t = -n.tangent(); + pos+=n*h_offset; + pos+=t*v_offset; + + set_rot(t.atan2()); + + } else { + + pos.x+=h_offset; + pos.y+=v_offset; + } + + set_pos(pos); + +} + +void PathFollow2D::_notification(int p_what) { + + + switch(p_what) { + + case NOTIFICATION_ENTER_SCENE: { + + Node *parent=get_parent(); + if (parent) { + + path=parent->cast_to<Path2D>(); + if (path) { + _update_transform(); + } + } + + } break; + case NOTIFICATION_EXIT_SCENE: { + + + path=NULL; + } break; + } + +} + +void PathFollow2D::set_cubic_interpolation(bool p_enable) { + + cubic=p_enable; +} + +bool PathFollow2D::get_cubic_interpolation() const { + + return cubic; +} + + +bool PathFollow2D::_set(const StringName& p_name, const Variant& p_value) { + + if (p_name==SceneStringNames::get_singleton()->offset) { + set_offset(p_value); + } else if (p_name==SceneStringNames::get_singleton()->unit_offset) { + set_unit_offset(p_value); + } else if (p_name==SceneStringNames::get_singleton()->rotate) { + set_rotate(p_value); + } else if (p_name==SceneStringNames::get_singleton()->v_offset) { + set_v_offset(p_value); + } else if (p_name==SceneStringNames::get_singleton()->h_offset) { + set_h_offset(p_value); + } else if (String(p_name)=="cubic_interp") { + set_cubic_interpolation(p_value); + } else if (String(p_name)=="loop") { + set_loop(p_value); + } else if (String(p_name)=="lookahead") { + set_lookahead(p_value); + } else + return false; + + return true; +} + +bool PathFollow2D::_get(const StringName& p_name,Variant &r_ret) const{ + + if (p_name==SceneStringNames::get_singleton()->offset) { + r_ret=get_offset(); + } else if (p_name==SceneStringNames::get_singleton()->unit_offset) { + r_ret=get_unit_offset(); + } else if (p_name==SceneStringNames::get_singleton()->rotate) { + r_ret=is_rotating(); + } else if (p_name==SceneStringNames::get_singleton()->v_offset) { + r_ret=get_v_offset(); + } else if (p_name==SceneStringNames::get_singleton()->h_offset) { + r_ret=get_h_offset(); + } else if (String(p_name)=="cubic_interp") { + r_ret=cubic; + } else if (String(p_name)=="loop") { + r_ret=loop; + } else if (String(p_name)=="lookahead") { + r_ret=lookahead; + } else + return false; + + return true; + +} +void PathFollow2D::_get_property_list( List<PropertyInfo> *p_list) const{ + + float max=10000; + if (path && path->get_curve().is_valid()) + max=path->get_curve()->get_baked_length(); + p_list->push_back( PropertyInfo( Variant::REAL, "offset", PROPERTY_HINT_RANGE,"0,"+rtos(max)+",0.01")); + p_list->push_back( PropertyInfo( Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE,"0,1,0.0001",PROPERTY_USAGE_EDITOR)); + p_list->push_back( PropertyInfo( Variant::REAL, "h_offset") ); + p_list->push_back( PropertyInfo( Variant::REAL, "v_offset") ); + p_list->push_back( PropertyInfo( Variant::BOOL, "rotate") ); + p_list->push_back( PropertyInfo( Variant::BOOL, "cubic_interp")); + p_list->push_back( PropertyInfo( Variant::BOOL, "loop")); + p_list->push_back( PropertyInfo( Variant::REAL, "lookahead",PROPERTY_HINT_RANGE,"0.001,1024.0,0.001")); +} + + +void PathFollow2D::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_offset","offset"),&PathFollow2D::set_offset); + ObjectTypeDB::bind_method(_MD("get_offset"),&PathFollow2D::get_offset); + + ObjectTypeDB::bind_method(_MD("set_h_offset","h_offset"),&PathFollow2D::set_h_offset); + ObjectTypeDB::bind_method(_MD("get_h_offset"),&PathFollow2D::get_h_offset); + + ObjectTypeDB::bind_method(_MD("set_v_offset","v_offset"),&PathFollow2D::set_v_offset); + ObjectTypeDB::bind_method(_MD("get_v_offset"),&PathFollow2D::get_v_offset); + + ObjectTypeDB::bind_method(_MD("set_unit_offset","unit_offset"),&PathFollow2D::set_unit_offset); + ObjectTypeDB::bind_method(_MD("get_unit_offset"),&PathFollow2D::get_unit_offset); + + ObjectTypeDB::bind_method(_MD("set_rotate","enable"),&PathFollow2D::set_rotate); + ObjectTypeDB::bind_method(_MD("is_rotating"),&PathFollow2D::is_rotating); + + ObjectTypeDB::bind_method(_MD("set_cubic_interpolation","enable"),&PathFollow2D::set_cubic_interpolation); + ObjectTypeDB::bind_method(_MD("get_cubic_interpolation"),&PathFollow2D::get_cubic_interpolation); + + ObjectTypeDB::bind_method(_MD("set_loop","loop"),&PathFollow2D::set_loop); + ObjectTypeDB::bind_method(_MD("has_loop"),&PathFollow2D::has_loop); + + +} + +void PathFollow2D::set_offset(float p_offset) { + + offset=p_offset; + if (path) + _update_transform(); + _change_notify("offset"); + _change_notify("unit_offset"); + +} + +void PathFollow2D::set_h_offset(float p_h_offset) { + + h_offset=p_h_offset; + if (path) + _update_transform(); + +} + +float PathFollow2D::get_h_offset() const { + + return h_offset; +} + +void PathFollow2D::set_v_offset(float p_v_offset) { + + v_offset=p_v_offset; + if (path) + _update_transform(); + +} + +float PathFollow2D::get_v_offset() const { + + return v_offset; +} + + +float PathFollow2D::get_offset() const{ + + return offset; +} + +void PathFollow2D::set_unit_offset(float p_unit_offset) { + + if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) + set_offset(p_unit_offset*path->get_curve()->get_baked_length()); + +} + +float PathFollow2D::get_unit_offset() const{ + + if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) + return get_offset()/path->get_curve()->get_baked_length(); + else + return 0; +} + +void PathFollow2D::set_lookahead(float p_lookahead) { + + lookahead=p_lookahead; + +} + +float PathFollow2D::get_lookahead() const{ + + return lookahead; +} + +void PathFollow2D::set_rotate(bool p_rotate) { + + rotate=p_rotate; + _update_transform(); +} + +bool PathFollow2D::is_rotating() const { + + return rotate; +} + +void PathFollow2D::set_loop(bool p_loop) { + + loop=p_loop; +} + +bool PathFollow2D::has_loop() const{ + + return loop; +} + + +PathFollow2D::PathFollow2D() { + + offset=0; + h_offset=0; + v_offset=0; + path=NULL; + rotate=true; + cubic=true; + loop=true; + lookahead=4; +} diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h index f401f9da4c..90f57c8eac 100644 --- a/scene/2d/path_2d.h +++ b/scene/2d/path_2d.h @@ -54,4 +54,63 @@ public: Path2D(); }; + + +class PathFollow2D : public Node2D { + + OBJ_TYPE(PathFollow2D,Node2D); +public: + + +private: + Path2D *path; + real_t offset; + real_t h_offset; + real_t v_offset; + real_t lookahead; + bool cubic; + bool loop; + bool rotate; + + void _update_transform(); + + +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; + + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_offset(float p_offset); + float get_offset() const; + + void set_h_offset(float p_h_offset); + float get_h_offset() const; + + void set_v_offset(float p_v_offset); + float get_v_offset() const; + + void set_unit_offset(float p_unit_offset); + float get_unit_offset() const; + + void set_lookahead(float p_lookahead); + float get_lookahead() const; + + void set_loop(bool p_loop); + bool has_loop() const; + + void set_rotate(bool p_enabled); + bool is_rotating() const; + + void set_cubic_interpolation(bool p_enable); + bool get_cubic_interpolation() const; + + PathFollow2D(); +}; + + #endif // PATH_2D_H |