diff options
Diffstat (limited to 'scene/resources/curve.cpp')
-rw-r--r-- | scene/resources/curve.cpp | 339 |
1 files changed, 1 insertions, 338 deletions
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index 877760c1bd..7fbaa1f73c 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "curve.h" + #include "core_string_names.h" template <class T> @@ -42,344 +43,6 @@ static _FORCE_INLINE_ T _bezier_interp(real_t t, T start, T control_1, T control return start * omt3 + control_1 * omt2 * t * 3.0 + control_2 * omt * t2 * 3.0 + end * t3; } -#if 0 - -int Curve2D::get_point_count() const { - - return points.size(); -} -void Curve2D::add_point(const Vector2& p_pos, const Vector2& p_in, const Vector2& p_out) { - - Point n; - n.pos=p_pos; - n.in=p_in; - n.out=p_out; - points.push_back(n); - emit_signal(CoreStringNames::get_singleton()->changed); -} -void Curve2D::set_point_pos(int p_index, const Vector2& p_pos) { - - ERR_FAIL_INDEX(p_index,points.size()); - - points[p_index].pos=p_pos; - emit_signal(CoreStringNames::get_singleton()->changed); - -} -Vector2 Curve2D::get_point_pos(int p_index) const { - - ERR_FAIL_INDEX_V(p_index,points.size(),Vector2()); - return points[p_index].pos; - -} - - -void Curve2D::set_point_in(int p_index, const Vector2& p_in) { - - ERR_FAIL_INDEX(p_index,points.size()); - - points[p_index].in=p_in; - emit_signal(CoreStringNames::get_singleton()->changed); - -} -Vector2 Curve2D::get_point_in(int p_index) const { - - ERR_FAIL_INDEX_V(p_index,points.size(),Vector2()); - return points[p_index].in; - -} - -void Curve2D::set_point_out(int p_index, const Vector2& p_out) { - - ERR_FAIL_INDEX(p_index,points.size()); - - points[p_index].out=p_out; - emit_signal(CoreStringNames::get_singleton()->changed); -} - -Vector2 Curve2D::get_point_out(int p_index) const { - - ERR_FAIL_INDEX_V(p_index,points.size(),Vector2()); - return points[p_index].out; - -} - - -void Curve2D::remove_point(int p_index) { - - ERR_FAIL_INDEX(p_index,points.size()); - points.remove(p_index); - emit_signal(CoreStringNames::get_singleton()->changed); -} - -Vector2 Curve2D::interpolate(int p_index, float p_offset) const { - - int pc = points.size(); - ERR_FAIL_COND_V(pc==0,Vector2()); - - if (p_index >= pc-1) - return points[pc-1].pos; - else if (p_index<0) - return points[0].pos; - - Vector2 p0 = points[p_index].pos; - Vector2 p1 = p0+points[p_index].out; - Vector2 p3 = points[p_index+1].pos; - Vector2 p2 = p3+points[p_index+1].in; - - return _bezier_interp(p_offset,p0,p1,p2,p3); -} - -Vector2 Curve2D::interpolatef(real_t p_findex) const { - - - if (p_findex<0) - p_findex=0; - else if (p_findex>=points.size()) - p_findex=points.size(); - - return interpolate((int)p_findex,Math::fmod(p_findex,1.0)); - -} - -PoolVector<Point2> Curve2D::bake(int p_subdivs) const { - - int pc = points.size(); - - PoolVector<Point2> ret; - if (pc<2) - return ret; - - ret.resize((pc-1)*p_subdivs+1); - - PoolVector<Point2>::Write w = ret.write(); - const Point *r = points.ptr(); - - for(int i=0;i<pc;i++) { - - int ofs = pc*p_subdivs; - - int limit=(i==pc-1)?p_subdivs+1:p_subdivs; - - for(int j=0;j<limit;j++) { - - Vector2 p0 = r[i].pos; - Vector2 p1 = p0+r[i].out; - Vector2 p3 = r[i].pos; - Vector2 p2 = p3+r[i].in; - real_t t = j/(real_t)p_subdivs; - - w[ofs+j]=_bezier_interp(t,p0,p1,p2,p3); - - } - } - - w = PoolVector<Point2>::Write(); - - return ret; -} - -void Curve2D::advance(real_t p_distance,int &r_index, real_t &r_pos) const { - - int pc = points.size(); - ERR_FAIL_COND(pc<2); - if (r_index<0 || r_index>=(pc-1)) - return; - - Vector2 pos = interpolate(r_index,r_pos); - - float sign=p_distance<0 ? -1 : 1; - p_distance=Math::abs(p_distance); - - real_t base = r_index+r_pos; - real_t top = 0.1; //a tenth is in theory representative - int iterations=32; - - - - for(int i=0;i<iterations;i++) { - - - real_t o=base+top*sign; - if (sign>0 && o >=pc) { - top=pc-base; - break; - } else if (sign<0 && o <0) { - top=-base; - break; - } - - Vector2 new_d = interpolatef(o); - - if (new_d.distance_to(pos) > p_distance) - break; - top*=2.0; - } - - - real_t bottom = 0.0; - iterations=8; - real_t final_offset; - - - for(int i=0;i<iterations;i++) { - - real_t middle = (bottom+top)*0.5; - real_t o=base+middle*sign; - Vector2 new_d = interpolatef(o); - - if (new_d.distance_to(pos) > p_distance) { - bottom=middle; - } else { - top=middle; - } - final_offset=o; - } - - r_index=(int)final_offset; - r_pos=Math::fmod(final_offset,1.0); - -} - -void Curve2D::get_approx_position_from_offset(real_t p_offset,int &r_index, real_t &r_pos,int p_subdivs) const { - - ERR_FAIL_COND(points.size()<2); - - real_t accum=0; - - - - for(int i=0;i<points.size();i++) { - - Vector2 prev_p=interpolate(i,0); - - - for(int j=1;j<=p_subdivs;j++) { - - real_t frac = j/(real_t)p_subdivs; - Vector2 p = interpolate(i,frac); - real_t d = p.distance_to(prev_p); - - accum+=d; - if (accum>p_offset) { - - - r_index=j-1; - if (d>0) { - real_t mf = (p_offset-(accum-d)) / d; - r_pos=frac-(1.0-mf); - } else { - r_pos=frac; - } - - return; - } - - prev_p=p; - } - } - - r_index=points.size()-1; - r_pos=1.0; - - -} - -void Curve2D::set_points_in(const Vector2Array& p_points) { - - points.resize(p_points.size()); - for (int i=0; i<p_points.size(); i++) { - - Point p = points[i]; - p.in = p_points[i]; - points[i] = p; - }; -}; - -void Curve2D::set_points_out(const Vector2Array& p_points) { - - points.resize(p_points.size()); - for (int i=0; i<p_points.size(); i++) { - - Point p = points[i]; - p.out = p_points[i]; - points[i] = p; - }; -}; - -void Curve2D::set_points_pos(const Vector2Array& p_points) { - - points.resize(p_points.size()); - for (int i=0; i<p_points.size(); i++) { - - Point p = points[i]; - p.pos = p_points[i]; - points[i] = p; - }; -}; - -Vector2Array Curve2D::get_points_in() const { - Vector2Array ret; - ret.resize(points.size()); - for (int i=0; i<points.size(); i++) { - ret.set(i, points[i].in); - }; - return ret; -}; - -Vector2Array Curve2D::get_points_out() const { - Vector2Array ret; - ret.resize(points.size()); - for (int i=0; i<points.size(); i++) { - ret.set(i, points[i].out); - }; - return ret; -}; - -Vector2Array Curve2D::get_points_pos() const { - Vector2Array ret; - ret.resize(points.size()); - for (int i=0; i<points.size(); i++) { - ret.set(i, points[i].pos); - }; - return ret; -}; - - -void Curve2D::_bind_methods() { - - ClassDB::bind_method(D_METHOD("get_point_count"),&Curve2D::get_point_count); - ClassDB::bind_method(D_METHOD("add_point","pos","in","out"),&Curve2D::add_point,DEFVAL(Vector2()),DEFVAL(Vector2())); - ClassDB::bind_method(D_METHOD("set_point_pos","idx","pos"),&Curve2D::set_point_pos); - ClassDB::bind_method(D_METHOD("get_point_pos","idx"),&Curve2D::get_point_pos); - ClassDB::bind_method(D_METHOD("set_point_in","idx","pos"),&Curve2D::set_point_in); - ClassDB::bind_method(D_METHOD("get_point_in","idx"),&Curve2D::get_point_in); - ClassDB::bind_method(D_METHOD("set_point_out","idx","pos"),&Curve2D::set_point_out); - ClassDB::bind_method(D_METHOD("get_point_out","idx"),&Curve2D::get_point_out); - ClassDB::bind_method(D_METHOD("remove_point","idx"),&Curve2D::remove_point); - ClassDB::bind_method(D_METHOD("interpolate","idx","t"),&Curve2D::interpolate); - ClassDB::bind_method(D_METHOD("bake","subdivs"),&Curve2D::bake,DEFVAL(10)); - - - ClassDB::bind_method(D_METHOD("set_points_in"),&Curve2D::set_points_in); - ClassDB::bind_method(D_METHOD("set_points_out"),&Curve2D::set_points_out); - ClassDB::bind_method(D_METHOD("set_points_pos"),&Curve2D::set_points_pos); - - ClassDB::bind_method(D_METHOD("get_points_in"),&Curve2D::get_points_in); - ClassDB::bind_method(D_METHOD("get_points_out"),&Curve2D::get_points_out); - ClassDB::bind_method(D_METHOD("get_points_pos"),&Curve2D::get_points_pos); - - ADD_PROPERTY( PropertyInfo( Variant::VECTOR2_ARRAY, "points_in"), "set_points_in","get_points_in"); - ADD_PROPERTY( PropertyInfo( Variant::VECTOR2_ARRAY, "points_out"), "set_points_out","get_points_out"); - ADD_PROPERTY( PropertyInfo( Variant::VECTOR2_ARRAY, "points_pos"), "set_points_pos","get_points_pos"); -} - - -Curve2D::Curve2D() -{ -} - -#endif - const char *Curve::SIGNAL_RANGE_CHANGED = "range_changed"; Curve::Curve() { |