Beispiel #1
0
std::vector<ImageData> SpriteImporter::splitImagesInGrid(const std::vector<ImageData>& images, Vector2i grid)
{
	std::vector<ImageData> result;

	for (auto& src: images) {
		auto imgSize = src.img->getSize();
		int nX = imgSize.x / grid.x;
		int nY = imgSize.y / grid.y;

		for (int y = 0; y < nY; ++y) {
			for (int x = 0; x < nX; ++x) {
				auto img = std::make_unique<Image>(Image::Format::RGBA, grid);
				img->blitFrom(Vector2i(), *src.img, Rect4i(Vector2i(x, y) * grid, grid.x, grid.y));
				Rect4i trimRect = img->getTrimRect();
				if (trimRect.getWidth() > 0 && trimRect.getHeight() > 0) {
					result.emplace_back();
					auto& dst = result.back();

					String suffix = "_" + toString(x) + "_" + toString(y);

					dst.duration = src.duration;
					dst.frameNumber = src.frameNumber;
					dst.filenames.emplace_back(src.filenames.at(0) + suffix);
					dst.sequenceName = src.sequenceName + suffix;
					dst.img = std::move(img);
					dst.clip = Rect4i({}, grid);
				}
			}
		}
	}

	return result;
}
RectangleSpatialChecker::QueryResults RectangleSpatialChecker::query(Rect4i rect)
{
	QueryResults results;
	results.n = 0;

	if (sweep > 0x7FFFFFFF) {
		resetSweep();
	}
	sweep++;

	// This will work as a poor man's bloom filter
	int resultMask = 0;

	Vector2i p1 = pointToCell(rect.getTopLeft());
	Vector2i p2 = pointToCell(rect.getBottomRight());
	int x0 = p1.x;
	int x1 = p2.x;
	int y0 = p1.y;
	int y1 = p2.y;
	for (int y = y0; y <= y1; y++) {
		for (int x = x0; x <= x1; x++) {
			// Go through each rect in each grid element
			auto& vec = getGridCell(x, y);
			const size_t n = vec.size();
			for (size_t i = 0; i < n; i++) {
				Entry& e = vec[i];

				// Check if they intersect
				if (e.rect.overlaps(rect)) {
					// Check if it's already in the buffer
					if ((resultMask & e.hashMask) != 0) {
						for (size_t j = 0; j < results.n; j++) {
							if (resultsBuffer[j] == e.data) {
								goto endOfCheckLoop; // Oh yeah, baby. I went there.
							}
						}
					}

					// Hash it in the mask
					resultMask |= e.hashMask;

					// Insert into the buffer
					if (results.n < resultsBuffer.size()) {
						resultsBuffer[results.n] = e.data;
					} else {
						resultsBuffer.push_back(e.data);
					}
					results.n++;

					endOfCheckLoop:;
				}
			}
		}
	}

	results.results = resultsBuffer.data();
	return results;
}
Beispiel #3
0
void DX11Painter::setClip(Rect4i clip, bool enable)
{
	if (enable) {
		scissorRaster->bind(video);
		D3D11_RECT rect;
		rect.top = clip.getTop();
		rect.bottom = clip.getBottom();
		rect.left = clip.getLeft();
		rect.right = clip.getRight();
		video.getDeviceContext().RSSetScissorRects(1, &rect);
	} else {
		normalRaster->bind(video);
	}
}
void roundMaskRect(Rect4i & r, const Rect4i & maxRect, int unit)
{
	//Increase width as necessary
	int remainder = unit - (r.width() % unit);
	if (remainder != 0)
	{
		int dist1 = r.x1 - maxRect.x1;
		int dist2 = maxRect.x2 - r.x2;

		//do we have enough room to expand?
		if (remainder <= (dist1 + dist2))
		{
			dist1 = MIN(dist1, remainder);
			r.x1 -= dist1;
			remainder -= dist1;

			dist2 = MIN(dist2, remainder);
			r.x2 += dist2;
		}
	}

	//Increase height as necessary
	remainder = unit - (r.height() % unit);
	if (remainder != 0)
	{
		int dist1 = r.y1 - maxRect.y1;
		int dist2 = maxRect.y2 - r.y2;

		//do we have enough room to expand?
		if (remainder <= (dist1 + dist2))
		{
			dist1 = MIN(dist1, remainder);
			r.y1 -= dist1;
			remainder -= dist1;

			dist2 = MIN(dist2, remainder);
			r.y2 += dist2;
		}
	}

}
bool RectangleSpatialChecker::updateData(Entry& entry, Rect4i prev, Rect4i next)
{
	if (prev == next) {
		return false; // Nothing to do here
	}
	
	int x0, x1, y0, y1;
	x0 = y0 = std::numeric_limits<int>::max();
	x1 = y1 = std::numeric_limits<int>::lowest();
	Rect4i addRect;
	Rect4i delRect;
	bool hasAdd = false;
	bool hasDel = false;

	if (prev.getWidth() > 0 && prev.getHeight() > 0) {
		Vector2i p1 = pointToCell(prev.getTopLeft());
		Vector2i p2 = pointToCell(prev.getBottomRight());
		delRect = Rect4i(p1, p2);
		hasDel = true;
		x0 = p1.x;
		x1 = p2.x;
		y0 = p1.y;
		y1 = p2.y;
	}

	if (next.getWidth() > 0 && next.getHeight() > 0) {
		Vector2i p1 = pointToCell(next.getTopLeft());
		Vector2i p2 = pointToCell(next.getBottomRight());
		addRect = Rect4i(p1, p2);
		hasAdd = true;
		x0 = std::min(x0, p1.x);
		x1 = std::max(x1, p2.x);
		y0 = std::min(y0, p1.y);
		y1 = std::max(y1, p2.y);
	}
	
	for (int y = y0; y <= y1; y++) {
		for (int x = x0; x <= x1; x++) {
			Vector2i p(x, y);
			bool removeHere = hasDel && delRect.isInside(p);
			bool addHere = hasAdd && addRect.isInside(p);
			
			auto& contents = getGridCell(x, y);

			if (addHere && removeHere) {
				// Find existing, then update it with new rect
				for (size_t i = 0; i < contents.size(); i++) {
					if (contents[i].data == entry.data) {
						contents[i].rect = next;
						break;
					}
				}
			} else if (removeHere) {
				// Remove
				//int removed = 0;
				for (size_t i = 0; i < contents.size(); i++) {
					if (contents[i].data == entry.data) {
						if (i != contents.size() - 1) {
							std::swap(contents[i], contents[contents.size() - 1]);
						}
						contents.pop_back();
						break; // Safe to break because there should only ever be one copy of each object in each cell
					}
				}
			} else if (addHere) {
				// Insert, making sure to update rect to new value, since "entry" is still outdated
				contents.push_back(entry);
				contents.back().rect = next;
			}
		}
	}

	// Update the main entry itself
	entry.rect = next;

	return true;
}
Beispiel #6
0
Vector2i SystemSDL::getCenteredWindow(Vector2i size, int screen) const
{
	Rect4i rect = getDisplayRect(screen);
	return rect.getTopLeft() + (rect.getSize() - size) / 2;
}