Example #1
0
void Curve2D::_bake_segment2d(
	std::map<float, Vector2>& r_bake, float p_begin,
	float p_end,
	const Vector2& p_a,
	const Vector2& p_out,
	const Vector2& p_b,
	const Vector2& p_in,
	int p_depth,
	int p_max_depth,
	float p_tol
) const {

	float mp = p_begin + (p_end - p_begin) * 0.5;
	Vector2 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
	Vector2 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
	Vector2 end = _bezier_interp(p_end, p_a, p_a + p_out, p_b + p_in, p_b);

	Vector2 na =(mid - beg).normalized();
	Vector2 nb =(end - mid).normalized();
	float dp = na.dot(nb);

	if(dp < cos(deg2rad(p_tol))) {
		r_bake[mp]=mid;
	}

	if(p_depth<p_max_depth) {
		_bake_segment2d(r_bake, p_begin, mp, p_a, p_out, p_b, p_in, p_depth + 1, p_max_depth, p_tol);
		_bake_segment2d(r_bake, mp, p_end, p_a, p_out, p_b, p_in, p_depth + 1, p_max_depth, p_tol);
	}
}
Example #2
0
void GraphEdit::_draw_cos_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color) {

	//cubic bezier code
	float diff = p_to.x - p_from.x;
	float cp_offset;
	int cp_len = get_constant("bezier_len_pos");
	int cp_neg_len = get_constant("bezier_len_neg");

	if (diff > 0) {
		cp_offset = MIN(cp_len, diff * 0.5);
	} else {
		cp_offset = MAX(MIN(cp_len - diff, cp_neg_len), -diff * 0.5);
	}

	Vector2 c1 = Vector2(cp_offset * zoom, 0);
	Vector2 c2 = Vector2(-cp_offset * zoom, 0);

	int lines = 0;

	Vector<Point2> points;
	Vector<Color> colors;
	points.push_back(p_from);
	colors.push_back(p_color);
	_bake_segment2d(points, colors, 0, 1, p_from, c1, p_to, c2, 0, 3, 9, 3, p_color, p_to_color, lines);
	points.push_back(p_to);
	colors.push_back(p_to_color);

#ifdef TOOLS_ENABLED
	p_where->draw_polyline_colors(points, colors, Math::floor(2 * EDSCALE), true);
#else
	p_where->draw_polyline_colors(points, colors, 2, true);
#endif
}
Example #3
0
void GraphEdit::_bake_segment2d(CanvasItem *p_where, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_min_depth, int p_max_depth, float p_tol, const Color &p_color, const Color &p_to_color, int &lines) const {

	float mp = p_begin + (p_end - p_begin) * 0.5;
	Vector2 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
	Vector2 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
	Vector2 end = _bezier_interp(p_end, p_a, p_a + p_out, p_b + p_in, p_b);

	Vector2 na = (mid - beg).normalized();
	Vector2 nb = (end - mid).normalized();
	float dp = Math::rad2deg(Math::acos(na.dot(nb)));

	if (p_depth >= p_min_depth && (dp < p_tol || p_depth >= p_max_depth)) {

		p_where->draw_line(beg, end, p_color.linear_interpolate(p_to_color, mp), 2, true);
		lines++;
	} else {
		_bake_segment2d(p_where, p_begin, mp, p_a, p_out, p_b, p_in, p_depth + 1, p_min_depth, p_max_depth, p_tol, p_color, p_to_color, lines);
		_bake_segment2d(p_where, mp, p_end, p_a, p_out, p_b, p_in, p_depth + 1, p_min_depth, p_max_depth, p_tol, p_color, p_to_color, lines);
	}
}
Example #4
0
void GraphEdit::_bake_segment2d(Vector<Vector2> &points, Vector<Color> &colors, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_min_depth, int p_max_depth, float p_tol, const Color &p_color, const Color &p_to_color, int &lines) const {

	float mp = p_begin + (p_end - p_begin) * 0.5;
	Vector2 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
	Vector2 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
	Vector2 end = _bezier_interp(p_end, p_a, p_a + p_out, p_b + p_in, p_b);

	Vector2 na = (mid - beg).normalized();
	Vector2 nb = (end - mid).normalized();
	float dp = Math::rad2deg(Math::acos(na.dot(nb)));

	if (p_depth >= p_min_depth && (dp < p_tol || p_depth >= p_max_depth)) {

		points.push_back((beg + end) * 0.5);
		colors.push_back(p_color.linear_interpolate(p_to_color, mp));
		lines++;
	} else {
		_bake_segment2d(points, colors, p_begin, mp, p_a, p_out, p_b, p_in, p_depth + 1, p_min_depth, p_max_depth, p_tol, p_color, p_to_color, lines);
		_bake_segment2d(points, colors, mp, p_end, p_a, p_out, p_b, p_in, p_depth + 1, p_min_depth, p_max_depth, p_tol, p_color, p_to_color, lines);
	}
}
Example #5
0
void GraphEdit::_draw_cos_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color) {

#if 1

	//cubic bezier code
	float diff = p_to.x - p_from.x;
	float cp_offset;
	int cp_len = get_constant("bezier_len_pos");
	int cp_neg_len = get_constant("bezier_len_neg");

	if (diff > 0) {
		cp_offset = MAX(cp_len, diff * 0.5);
	} else {
		cp_offset = MAX(MIN(cp_len - diff, cp_neg_len), -diff * 0.5);
	}

	Vector2 c1 = Vector2(cp_offset * zoom, 0);
	Vector2 c2 = Vector2(-cp_offset * zoom, 0);

	int lines = 0;
	_bake_segment2d(p_where, 0, 1, p_from, c1, p_to, c2, 0, 3, 9, 8, p_color, p_to_color, lines);

#else

	static const int steps = 20;

	//old cosine code
	Rect2 r;
	r.pos = p_from;
	r.expand_to(p_to);
	Vector2 sign = Vector2((p_from.x < p_to.x) ? 1 : -1, (p_from.y < p_to.y) ? 1 : -1);
	bool flip = sign.x * sign.y < 0;

	Vector2 prev;
	for (int i = 0; i <= steps; i++) {

		float d = i / float(steps);
		float c = -Math::cos(d * Math_PI) * 0.5 + 0.5;
		if (flip)
			c = 1.0 - c;
		Vector2 p = r.pos + Vector2(d * r.size.width, c * r.size.height);

		if (i > 0) {

			p_where->draw_line(prev, p, p_color.linear_interpolate(p_to_color, d), 2);
		}

		prev = p;
	}
#endif
}
Example #6
0
Vector2Array Curve2D::tesselate(int p_max_stages,float p_tolerance) const {

	Vector2Array tess;


	if (points.size()==0) {
		return tess;
	}
	Vector< Map<float,Vector2> > midpoints;

	midpoints.resize(points.size()-1);

	int pc=1;
	for(int i=0;i<points.size()-1;i++) {

		_bake_segment2d(midpoints[i],0,1,points[i].pos,points[i].out,points[i+1].pos,points[i+1].in,0,p_max_stages,p_tolerance);
		pc++;
		pc+=midpoints[i].size();

	}

	tess.resize(pc);
	Vector2Array::Write bpw=tess.write();
	bpw[0]=points[0].pos;
	int pidx=0;

	for(int i=0;i<points.size()-1;i++) {

		for(Map<float,Vector2>::Element *E=midpoints[i].front();E;E=E->next()) {

			pidx++;
			bpw[pidx] = E->get();
		}

		pidx++;
		bpw[pidx] = points[i+1].pos;

	}

	bpw=Vector2Array::Write ();

	return tess;

}
Example #7
0
Vector2Array Curve2D::tesselate(int p_max_stages,float p_tolerance) const {

	Vector2Array tess;

	if(points.size()==0) {
		return tess;
	}
	std::vector< std::map<float,Vector2> > midpoints;

	midpoints.resize(points.size()-1);

	int pc=1;
	for(int i=0;i<points.size()-1;i++) {

		_bake_segment2d(midpoints[i],0,1,points[i].pos,points[i].out,points[i+1].pos,points[i+1].in,0,p_max_stages,p_tolerance);
		pc++;
		pc+=midpoints[i].size();

	}

	tess.resize(pc);
	tess[0]=points[0].pos;
	int pidx=0;

	for(int i=0;i<points.size()-1;i++) {

		for(std::map<float,Vector2>::const_iterator itr = midpoints[i].begin(); itr != midpoints[i].end(); ++itr) {

			pidx++;
			tess[pidx] = itr->second;
		}

		pidx++;
		tess[pidx] = points[i+1].pos;

	}

	return tess;
}