예제 #1
0
Point2 TextureProgress::unit_val_to_uv(float val) {
	if (progress.is_null())
		return Point2();

	if (val < 0)
		val += 1;
	if (val > 1)
		val -= 1;

	Point2 p = get_relative_center();

	if (val < 0.125)
		return Point2(p.x + (1 - p.x) * val * 8, 0);
	if (val < 0.25)
		return Point2(1, p.y * (val - 0.125) * 8);
	if (val < 0.375)
		return Point2(1, p.y + (1 - p.y) * (val - 0.25) * 8);
	if (val < 0.5)
		return Point2(1 - (1 - p.x) * (val - 0.375) * 8, 1);
	if (val < 0.625)
		return Point2(p.x * (1 - (val - 0.5) * 8), 1);
	if (val < 0.75)
		return Point2(0, 1 - ((1 - p.y) * (val - 0.625) * 8));
	if (val < 0.875)
		return Point2(0, p.y - p.y * (val - 0.75) * 8);
	else
		return Point2(p.x * (val - 0.875) * 8, 0);
}
예제 #2
0
Point2 TextureProgress::unit_val_to_uv(float val) {
	if (progress.is_null())
		return Point2();

	if (val < 0)
		val += 1;
	if (val > 1)
		val -= 1;

	Point2 p = get_relative_center();

	// Minimal version of Liang-Barsky clipping algorithm
	float angle = (val * Math_TAU) - Math_PI * 0.5;
	Point2 dir = Vector2(Math::cos(angle), Math::sin(angle));
	float t1 = 1.0;
	float cp;
	float cq;
	float cr;
	float edgeLeft = 0.0;
	float edgeRight = 1.0;
	float edgeBottom = 0.0;
	float edgeTop = 1.0;

	for (int edge = 0; edge < 4; edge++) {
		if (edge == 0) {
			if (dir.x > 0)
				continue;
			cp = -dir.x;
			cq = -(edgeLeft - p.x);
		} else if (edge == 1) {
			if (dir.x < 0)
				continue;
			cp = dir.x;
			cq = (edgeRight - p.x);
		} else if (edge == 2) {
			if (dir.y > 0)
				continue;
			cp = -dir.y;
			cq = -(edgeBottom - p.y);
		} else if (edge == 3) {
			if (dir.y < 0)
				continue;
			cp = dir.y;
			cq = (edgeTop - p.y);
		}
		cr = cq / cp;
		if (cr >= 0 && cr < t1)
			t1 = cr;
	}
	return (p + t1 * dir);
}
예제 #3
0
void TextureProgress::_notification(int p_what) {
	const float corners[12] = { -0.125, -0.375, -0.625, -0.875, 0.125, 0.375, 0.625, 0.875, 1.125, 1.375, 1.625, 1.875 };
	switch (p_what) {

		case NOTIFICATION_DRAW: {

			if (nine_patch_stretch && (mode == FILL_LEFT_TO_RIGHT || mode == FILL_RIGHT_TO_LEFT || mode == FILL_TOP_TO_BOTTOM || mode == FILL_BOTTOM_TO_TOP)) {
				if (under.is_valid()) {
					draw_nine_patch_stretched(under, FILL_LEFT_TO_RIGHT, 1.0, tint_under);
				}
				if (progress.is_valid()) {
					draw_nine_patch_stretched(progress, mode, get_as_ratio(), tint_progress);
				}
				if (over.is_valid()) {
					draw_nine_patch_stretched(over, FILL_LEFT_TO_RIGHT, 1.0, tint_over);
				}
			} else {
				if (under.is_valid())
					draw_texture(under, Point2(), tint_under);
				if (progress.is_valid()) {
					Size2 s = progress->get_size();
					switch (mode) {
						case FILL_LEFT_TO_RIGHT: {
							Rect2 region = Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y));
							draw_texture_rect_region(progress, region, region, tint_progress);
						} break;
						case FILL_RIGHT_TO_LEFT: {
							Rect2 region = Rect2(Point2(s.x - s.x * get_as_ratio(), 0), Size2(s.x * get_as_ratio(), s.y));
							draw_texture_rect_region(progress, region, region, tint_progress);
						} break;
						case FILL_TOP_TO_BOTTOM: {
							Rect2 region = Rect2(Point2(), Size2(s.x, s.y * get_as_ratio()));
							draw_texture_rect_region(progress, region, region, tint_progress);
						} break;
						case FILL_BOTTOM_TO_TOP: {
							Rect2 region = Rect2(Point2(0, s.y - s.y * get_as_ratio()), Size2(s.x, s.y * get_as_ratio()));
							draw_texture_rect_region(progress, region, region, tint_progress);
						} break;
						case FILL_CLOCKWISE:
						case FILL_COUNTER_CLOCKWISE:
						case FILL_CLOCKWISE_AND_COUNTER_CLOCKWISE: {
							float val = get_as_ratio() * rad_max_degrees / 360;
							if (val == 1) {
								Rect2 region = Rect2(Point2(), s);
								draw_texture_rect_region(progress, region, region, tint_progress);
							} else if (val != 0) {
								Array pts;
								float direction = mode == FILL_COUNTER_CLOCKWISE ? -1 : 1;
								float start;

								if (mode == FILL_CLOCKWISE_AND_COUNTER_CLOCKWISE) {
									start = rad_init_angle / 360 - val / 2;
								} else {
									start = rad_init_angle / 360;
								}

								float end = start + direction * val;
								pts.append(start);
								pts.append(end);
								float from = MIN(start, end);
								float to = MAX(start, end);
								for (int i = 0; i < 12; i++)
									if (corners[i] > from && corners[i] < to)
										pts.append(corners[i]);
								pts.sort();
								Vector<Point2> uvs;
								Vector<Point2> points;
								uvs.push_back(get_relative_center());
								points.push_back(Point2(s.x * get_relative_center().x, s.y * get_relative_center().y));
								for (int i = 0; i < pts.size(); i++) {
									Point2 uv = unit_val_to_uv(pts[i]);
									if (uvs.find(uv) >= 0)
										continue;
									uvs.push_back(uv);
									points.push_back(Point2(uv.x * s.x, uv.y * s.y));
								}
								Vector<Color> colors;
								colors.push_back(tint_progress);
								draw_polygon(points, colors, uvs, progress);
							}
							if (Engine::get_singleton()->is_editor_hint()) {
								Point2 p = progress->get_size();
								p.x *= get_relative_center().x;
								p.y *= get_relative_center().y;
								p = p.floor();
								draw_line(p - Point2(8, 0), p + Point2(8, 0), Color(0.9, 0.5, 0.5), 2);
								draw_line(p - Point2(0, 8), p + Point2(0, 8), Color(0.9, 0.5, 0.5), 2);
							}
						} break;
						case FILL_BILINEAR_LEFT_AND_RIGHT: {
							Rect2 region = Rect2(Point2(s.x / 2 - s.x * get_as_ratio() / 2, 0), Size2(s.x * get_as_ratio(), s.y));
							draw_texture_rect_region(progress, region, region, tint_progress);
						} break;
						case FILL_BILINEAR_TOP_AND_BOTTOM: {
							Rect2 region = Rect2(Point2(0, s.y / 2 - s.y * get_as_ratio() / 2), Size2(s.x, s.y * get_as_ratio()));
							draw_texture_rect_region(progress, region, region, tint_progress);
						} break;
						default:
							draw_texture_rect_region(progress, Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y)), Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y)), tint_progress);
					}
				}
				if (over.is_valid())
					draw_texture(over, Point2(), tint_over);
			}

		} break;
	}
}